feat: Fase 2a — shopping lists CRUD
DB: shopping_lists + shopping_items tables with full RLS, pg_cron jobs (archive completed lists after 7 days, purge trash after 7 days). item_frequency table with SECURITY DEFINER trigger that normalises and upserts on every shopping_items INSERT. Frontend: /lists overview (featured card + 2-col grid + trash toggle), /lists/[id] detail (qty stepper, inline edit, swipe-to-reveal-delete, drag & drop reorder via svelte-dnd-action, ItemSuggestions chips). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ export type Json = string | number | boolean | null | { [key: string]: Json | un
|
||||
export type LanguageCode = 'en' | 'es';
|
||||
export type AvatarTypeEnum = 'initials' | 'emoji' | 'upload';
|
||||
export type MemberRoleEnum = 'admin' | 'member' | 'guest';
|
||||
export type ListStatusEnum = 'active' | 'completed' | 'archived';
|
||||
|
||||
export interface Database {
|
||||
public: {
|
||||
@@ -161,6 +162,102 @@ export interface Database {
|
||||
}
|
||||
];
|
||||
};
|
||||
shopping_lists: {
|
||||
Row: {
|
||||
id: string;
|
||||
collective_id: string;
|
||||
name: string;
|
||||
status: ListStatusEnum;
|
||||
created_by: string;
|
||||
created_at: string;
|
||||
completed_at: string | null;
|
||||
deleted_at: string | null;
|
||||
};
|
||||
Insert: {
|
||||
id?: string;
|
||||
collective_id: string;
|
||||
name: string;
|
||||
status?: ListStatusEnum;
|
||||
created_by: string;
|
||||
created_at?: string;
|
||||
completed_at?: string | null;
|
||||
deleted_at?: string | null;
|
||||
};
|
||||
Update: {
|
||||
id?: string;
|
||||
collective_id?: string;
|
||||
name?: string;
|
||||
status?: ListStatusEnum;
|
||||
created_by?: string;
|
||||
created_at?: string;
|
||||
completed_at?: string | null;
|
||||
deleted_at?: string | null;
|
||||
};
|
||||
Relationships: [];
|
||||
};
|
||||
shopping_items: {
|
||||
Row: {
|
||||
id: string;
|
||||
list_id: string;
|
||||
name: string;
|
||||
quantity: number | null;
|
||||
unit: string | null;
|
||||
is_checked: boolean;
|
||||
checked_by: string | null;
|
||||
checked_at: string | null;
|
||||
sort_order: number;
|
||||
created_by: string;
|
||||
created_at: string;
|
||||
};
|
||||
Insert: {
|
||||
id?: string;
|
||||
list_id: string;
|
||||
name: string;
|
||||
quantity?: number | null;
|
||||
unit?: string | null;
|
||||
is_checked?: boolean;
|
||||
checked_by?: string | null;
|
||||
checked_at?: string | null;
|
||||
sort_order?: number;
|
||||
created_by: string;
|
||||
created_at?: string;
|
||||
};
|
||||
Update: {
|
||||
id?: string;
|
||||
list_id?: string;
|
||||
name?: string;
|
||||
quantity?: number | null;
|
||||
unit?: string | null;
|
||||
is_checked?: boolean;
|
||||
checked_by?: string | null;
|
||||
checked_at?: string | null;
|
||||
sort_order?: number;
|
||||
created_by?: string;
|
||||
created_at?: string;
|
||||
};
|
||||
Relationships: [];
|
||||
};
|
||||
item_frequency: {
|
||||
Row: {
|
||||
collective_id: string;
|
||||
name: string;
|
||||
use_count: number;
|
||||
last_used_at: string;
|
||||
};
|
||||
Insert: {
|
||||
collective_id: string;
|
||||
name: string;
|
||||
use_count?: number;
|
||||
last_used_at?: string;
|
||||
};
|
||||
Update: {
|
||||
collective_id?: string;
|
||||
name?: string;
|
||||
use_count?: number;
|
||||
last_used_at?: string;
|
||||
};
|
||||
Relationships: [];
|
||||
};
|
||||
};
|
||||
Views: Record<string, never>;
|
||||
Functions: {
|
||||
@@ -185,6 +282,7 @@ export interface Database {
|
||||
language_code: LanguageCode;
|
||||
avatar_type: AvatarTypeEnum;
|
||||
member_role: MemberRoleEnum;
|
||||
list_status: ListStatusEnum;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,7 +78,6 @@ export interface ShoppingItem {
|
||||
sort_order: number;
|
||||
created_by: string;
|
||||
created_at: string;
|
||||
deleted_at: string | null;
|
||||
}
|
||||
|
||||
export interface ItemFrequency {
|
||||
|
||||
Reference in New Issue
Block a user