db to user_id
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 1m3s
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 1m3s
This commit is contained in:
@@ -67,6 +67,9 @@ CREATE TRIGGER on_categories_updated BEFORE UPDATE ON public.categories FOR EACH
|
|||||||
DROP TRIGGER IF EXISTS on_flyers_updated ON public.flyers;
|
DROP TRIGGER IF EXISTS on_flyers_updated ON public.flyers;
|
||||||
CREATE TRIGGER on_flyers_updated BEFORE UPDATE ON public.flyers FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at();
|
CREATE TRIGGER on_flyers_updated BEFORE UPDATE ON public.flyers FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at();
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS on_flyer_items_updated ON public.flyer_items;
|
||||||
|
CREATE TRIGGER on_flyer_items_updated BEFORE UPDATE ON public.flyer_items FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at();
|
||||||
|
|
||||||
DROP TRIGGER IF EXISTS on_master_grocery_items_updated ON public.master_grocery_items;
|
DROP TRIGGER IF EXISTS on_master_grocery_items_updated ON public.master_grocery_items;
|
||||||
CREATE TRIGGER on_master_grocery_items_updated BEFORE UPDATE ON public.master_grocery_items FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at();
|
CREATE TRIGGER on_master_grocery_items_updated BEFORE UPDATE ON public.master_grocery_items FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at();
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ CREATE TABLE IF NOT EXISTS public.flyers (
|
|||||||
valid_from DATE,
|
valid_from DATE,
|
||||||
valid_to DATE,
|
valid_to DATE,
|
||||||
store_address TEXT,
|
store_address TEXT,
|
||||||
|
uploaded_by UUID REFERENCES public.users(user_id) ON DELETE SET NULL,
|
||||||
created_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
created_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
||||||
updated_at TIMESTAMPTZ DEFAULT now() NOT NULL
|
updated_at TIMESTAMPTZ DEFAULT now() NOT NULL
|
||||||
);
|
);
|
||||||
@@ -91,6 +92,7 @@ COMMENT ON COLUMN public.flyers.store_id IS 'Foreign key linking this flyer to a
|
|||||||
COMMENT ON COLUMN public.flyers.valid_from IS 'The start date of the sale period for this flyer, extracted by the AI.';
|
COMMENT ON COLUMN public.flyers.valid_from IS 'The start date of the sale period for this flyer, extracted by the AI.';
|
||||||
COMMENT ON COLUMN public.flyers.valid_to IS 'The end date of the sale period for this flyer, extracted by the AI.';
|
COMMENT ON COLUMN public.flyers.valid_to IS 'The end date of the sale period for this flyer, extracted by the AI.';
|
||||||
COMMENT ON COLUMN public.flyers.store_address IS 'The physical store address if it was successfully extracted from the flyer image.';
|
COMMENT ON COLUMN public.flyers.store_address IS 'The physical store address if it was successfully extracted from the flyer image.';
|
||||||
|
COMMENT ON COLUMN public.flyers.uploaded_by IS 'The user who uploaded the flyer. Can be null for anonymous or system uploads.';
|
||||||
|
|
||||||
-- 7. The 'master_grocery_items' table. This is the master dictionary.
|
-- 7. The 'master_grocery_items' table. This is the master dictionary.
|
||||||
CREATE TABLE IF NOT EXISTS public.master_grocery_items (
|
CREATE TABLE IF NOT EXISTS public.master_grocery_items (
|
||||||
@@ -134,7 +136,8 @@ CREATE TABLE IF NOT EXISTS public.flyer_items (
|
|||||||
click_count INTEGER DEFAULT 0 NOT NULL,
|
click_count INTEGER DEFAULT 0 NOT NULL,
|
||||||
master_item_id BIGINT REFERENCES public.master_grocery_items(master_grocery_item_id),
|
master_item_id BIGINT REFERENCES public.master_grocery_items(master_grocery_item_id),
|
||||||
product_id BIGINT,
|
product_id BIGINT,
|
||||||
created_at TIMESTAMPTZ DEFAULT now() NOT NULL
|
created_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT now() NOT NULL
|
||||||
);
|
);
|
||||||
COMMENT ON TABLE public.flyer_items IS 'Stores individual items extracted from a specific flyer.';
|
COMMENT ON TABLE public.flyer_items IS 'Stores individual items extracted from a specific flyer.';
|
||||||
COMMENT ON COLUMN public.flyer_items.flyer_id IS 'Foreign key linking this item to its parent flyer in the `flyers` table.';
|
COMMENT ON COLUMN public.flyer_items.flyer_id IS 'Foreign key linking this item to its parent flyer in the `flyers` table.';
|
||||||
@@ -359,7 +362,7 @@ CREATE INDEX IF NOT EXISTS idx_user_submitted_prices_master_item_id ON public.us
|
|||||||
CREATE TABLE IF NOT EXISTS public.unmatched_flyer_items (
|
CREATE TABLE IF NOT EXISTS public.unmatched_flyer_items (
|
||||||
unmatched_flyer_item_id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
unmatched_flyer_item_id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||||
flyer_item_id BIGINT NOT NULL REFERENCES public.flyer_items(flyer_item_id) ON DELETE CASCADE,
|
flyer_item_id BIGINT NOT NULL REFERENCES public.flyer_items(flyer_item_id) ON DELETE CASCADE,
|
||||||
status TEXT DEFAULT 'pending' NOT NULL CHECK (status IN ('pending', 'reviewed', 'ignored')),
|
status TEXT DEFAULT 'pending' NOT NULL CHECK (status IN ('pending', 'resolved', 'ignored')),
|
||||||
created_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
created_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
||||||
reviewed_at TIMESTAMPTZ,
|
reviewed_at TIMESTAMPTZ,
|
||||||
UNIQUE(flyer_item_id),
|
UNIQUE(flyer_item_id),
|
||||||
@@ -428,8 +431,8 @@ CREATE TABLE IF NOT EXISTS public.recipes (
|
|||||||
protein_grams NUMERIC,
|
protein_grams NUMERIC,
|
||||||
fat_grams NUMERIC,
|
fat_grams NUMERIC,
|
||||||
carb_grams NUMERIC,
|
carb_grams NUMERIC,
|
||||||
avg_rating NUMERIC(2,1) DEFAULT 0.0,
|
avg_rating NUMERIC(2,1) DEFAULT 0.0 NOT NULL,
|
||||||
status TEXT DEFAULT 'private' NOT NULL CHECK (status IN ('private', 'pending_review', 'public')),
|
status TEXT DEFAULT 'private' NOT NULL CHECK (status IN ('private', 'pending_review', 'public', 'rejected')),
|
||||||
rating_count INTEGER DEFAULT 0 NOT NULL,
|
rating_count INTEGER DEFAULT 0 NOT NULL,
|
||||||
created_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
created_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
||||||
updated_at TIMESTAMPTZ DEFAULT now() NOT NULL
|
updated_at TIMESTAMPTZ DEFAULT now() NOT NULL
|
||||||
|
|||||||
29
src/types.ts
29
src/types.ts
@@ -15,7 +15,7 @@ export interface Flyer {
|
|||||||
valid_from?: string | null;
|
valid_from?: string | null;
|
||||||
valid_to?: string | null;
|
valid_to?: string | null;
|
||||||
store_address?: string | null;
|
store_address?: string | null;
|
||||||
uploaded_by?: string | null; // UUID of the user who uploaded it
|
uploaded_by?: string | null; // UUID of the user who uploaded it, can be null for anonymous uploads
|
||||||
store?: Store;
|
store?: Store;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,9 +25,9 @@ export interface UnitPrice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface FlyerItem {
|
export interface FlyerItem {
|
||||||
flyer_item_id?: number;
|
flyer_item_id: number;
|
||||||
flyer_id?: number;
|
flyer_id: number;
|
||||||
created_at?: string;
|
created_at: string;
|
||||||
item: string;
|
item: string;
|
||||||
price_display: string;
|
price_display: string;
|
||||||
price_in_cents: number | null;
|
price_in_cents: number | null;
|
||||||
@@ -41,6 +41,7 @@ export interface FlyerItem {
|
|||||||
product_id?: number | null;
|
product_id?: number | null;
|
||||||
view_count: number;
|
view_count: number;
|
||||||
click_count: number;
|
click_count: number;
|
||||||
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MasterGroceryItem {
|
export interface MasterGroceryItem {
|
||||||
@@ -387,18 +388,6 @@ export interface UserFollow {
|
|||||||
created_at: string;
|
created_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface UnmatchedFlyerItem {
|
|
||||||
unmatched_flyer_item_id: number;
|
|
||||||
status: 'pending' | 'resolved' | 'ignored';
|
|
||||||
created_at: string;
|
|
||||||
flyer_item_id: number;
|
|
||||||
flyer_item_name: string;
|
|
||||||
price_display: string;
|
|
||||||
flyer_id: number;
|
|
||||||
store_name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a flexible but type-safe structure for the `details` object in an activity log.
|
* Defines a flexible but type-safe structure for the `details` object in an activity log.
|
||||||
* It allows for arbitrary string keys but restricts values to primitives,
|
* It allows for arbitrary string keys but restricts values to primitives,
|
||||||
@@ -414,11 +403,9 @@ export interface ActivityLogItem {
|
|||||||
activity_log_id: number;
|
activity_log_id: number;
|
||||||
user_id?: string | null; // UUID
|
user_id?: string | null; // UUID
|
||||||
action: string; // A key for the event type, e.g., 'user_registered'
|
action: string; // A key for the event type, e.g., 'user_registered'
|
||||||
display_text: string; // A pre-formatted message for direct display in the UI
|
display_text: string; // A pre-formatted, user-facing message for direct display in the UI
|
||||||
icon?: string | null; // An optional icon name for the UI
|
icon?: string | null; // An optional icon name for the UI
|
||||||
details: ActivityLogDetails | null; // Structured data for analytics, i18n, etc.
|
details?: ActivityLogDetails | null; // Structured data for analytics, i18n, etc.
|
||||||
activity_type: string; // Add missing property
|
|
||||||
entity_id?: string | null; // Add missing property
|
|
||||||
created_at: string;
|
created_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -652,7 +639,7 @@ export interface MenuPlanShoppingListItem {
|
|||||||
*/
|
*/
|
||||||
export interface UnmatchedFlyerItem {
|
export interface UnmatchedFlyerItem {
|
||||||
unmatched_flyer_item_id: number;
|
unmatched_flyer_item_id: number;
|
||||||
status: 'pending' | 'resolved' | 'ignored';
|
status: 'pending' | 'resolved' | 'ignored'; // 'resolved' is used instead of 'reviewed' from the DB for clarity
|
||||||
created_at: string; // Date string
|
created_at: string; // Date string
|
||||||
flyer_item_id: number;
|
flyer_item_id: number;
|
||||||
flyer_item_name: string;
|
flyer_item_name: string;
|
||||||
|
|||||||
@@ -26,6 +26,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
"noEmit": true
|
"noEmit": true,
|
||||||
}
|
"strict": true, // Enforcing strict mode is a best practice for new projects.
|
||||||
|
"forceConsistentCasingInFileNames": true // Helps prevent casing-related import errors.
|
||||||
|
},
|
||||||
|
"include": ["src", ".vitepress", "vite.config.ts", "vitest.config.ts"],
|
||||||
|
"exclude": ["node_modules", "dist", "coverage"]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user