feat(fase-11): item_tags + shopping_item_tags schema (11.1)
Migration 022 adds two new tables for collective-scoped item tags plus the many-to-many bridge to shopping_items. Tags carry a colour from an 8-preset palette enforced by CHECK. RLS uses is_member for SELECT (guests can see) and is_active_member for writes (guests are read-only). A new STABLE helper item_collective_id(uuid) resolves the parent collective in a single function call so the shopping_item_tags policies do not chain two STABLE lookups. Both tables join the supabase_realtime publication with REPLICA IDENTITY FULL, matching the shape of 007 for shopping_items / shopping_lists. pgTAP 014 covers schema invariants (publication, replica identity, unique + CHECK constraints, cascade behaviour for both tag delete and collective delete). Per-role RLS semantics will be covered by the Vitest integration suite in the next commit — pgTAP runs as postgres which bypasses RLS. Types: ItemTag, ItemWithTags + ItemTagColor in domain.ts; item_tags, shopping_item_tags, item_collective_id added by hand to the curated database.ts (the supabase CLI is not installed locally; just db-types is gated and skips with a notice). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,15 @@ export type MemberRoleEnum = 'admin' | 'member' | 'guest';
|
||||
export type ListStatusEnum = 'active' | 'completed' | 'archived';
|
||||
export type NoteColor = 'yellow' | 'green' | 'blue' | 'pink' | 'purple' | 'orange' | 'gray' | 'red';
|
||||
export type ThemeMode = 'light' | 'dark' | 'system';
|
||||
export type ItemTagColor =
|
||||
| 'slate'
|
||||
| 'red'
|
||||
| 'amber'
|
||||
| 'green'
|
||||
| 'sky'
|
||||
| 'indigo'
|
||||
| 'pink'
|
||||
| 'stone';
|
||||
|
||||
export interface Database {
|
||||
public: {
|
||||
@@ -414,6 +423,45 @@ export interface Database {
|
||||
};
|
||||
Relationships: [];
|
||||
};
|
||||
item_tags: {
|
||||
Row: {
|
||||
id: string;
|
||||
collective_id: string;
|
||||
name: string;
|
||||
color: ItemTagColor;
|
||||
created_at: string;
|
||||
};
|
||||
Insert: {
|
||||
id?: string;
|
||||
collective_id: string;
|
||||
name: string;
|
||||
color?: ItemTagColor;
|
||||
created_at?: string;
|
||||
};
|
||||
Update: {
|
||||
id?: string;
|
||||
collective_id?: string;
|
||||
name?: string;
|
||||
color?: ItemTagColor;
|
||||
created_at?: string;
|
||||
};
|
||||
Relationships: [];
|
||||
};
|
||||
shopping_item_tags: {
|
||||
Row: {
|
||||
item_id: string;
|
||||
tag_id: string;
|
||||
};
|
||||
Insert: {
|
||||
item_id: string;
|
||||
tag_id: string;
|
||||
};
|
||||
Update: {
|
||||
item_id?: string;
|
||||
tag_id?: string;
|
||||
};
|
||||
Relationships: [];
|
||||
};
|
||||
};
|
||||
Views: Record<string, never>;
|
||||
Functions: {
|
||||
@@ -433,6 +481,10 @@ export interface Database {
|
||||
Args: { p_collective_id: string };
|
||||
Returns: boolean;
|
||||
};
|
||||
item_collective_id: {
|
||||
Args: { p_item_id: string };
|
||||
Returns: string;
|
||||
};
|
||||
};
|
||||
Enums: {
|
||||
language_code: LanguageCode;
|
||||
|
||||
@@ -6,8 +6,8 @@ export type AvatarType = 'initials' | 'emoji' | 'upload';
|
||||
export type MemberRole = 'admin' | 'member' | 'guest';
|
||||
export type ListStatus = 'active' | 'completed' | 'archived';
|
||||
// NoteColor is defined in database.ts (matches the Postgres enum) and re-exported via index.ts
|
||||
import type { NoteColor } from './database.js';
|
||||
export type { NoteColor };
|
||||
import type { NoteColor, ItemTagColor } from './database.js';
|
||||
export type { NoteColor, ItemTagColor };
|
||||
export type Language = 'en' | 'es';
|
||||
|
||||
export interface User {
|
||||
@@ -79,6 +79,19 @@ export interface ItemFrequency {
|
||||
last_used_at: string;
|
||||
}
|
||||
|
||||
export interface ItemTag {
|
||||
id: string;
|
||||
collective_id: string;
|
||||
name: string;
|
||||
color: ItemTagColor;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/** Shopping item with the tag rows already joined in. */
|
||||
export interface ItemWithTags extends ShoppingItem {
|
||||
tags: ItemTag[];
|
||||
}
|
||||
|
||||
export interface TaskList {
|
||||
id: string;
|
||||
collective_id: string;
|
||||
|
||||
Reference in New Issue
Block a user