-- +goose Up CREATE TABLE categories ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE, name TEXT NOT NULL, unique_id TEXT NOT NULL, parent_unique_id TEXT, path TEXT, level INT NOT NULL DEFAULT 0, position INT NOT NULL DEFAULT 0, is_active BOOLEAN NOT NULL DEFAULT true, description TEXT, prompt TEXT, metadata JSONB NOT NULL DEFAULT '{}'::jsonb, config JSONB NOT NULL DEFAULT '{}'::jsonb, title_template JSONB, description_template JSONB, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), UNIQUE (company_id, unique_id) ); CREATE INDEX categories_company_id_idx ON categories(company_id); CREATE TABLE attributes ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE, attribute_key TEXT NOT NULL, name TEXT NOT NULL, value_type TEXT NOT NULL DEFAULT 'string', unit TEXT, example TEXT, parent_key TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), UNIQUE (company_id, attribute_key) ); CREATE INDEX attributes_company_id_idx ON attributes(company_id); CREATE TABLE category_attributes ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE, category_unique_id TEXT NOT NULL, attribute_id UUID NOT NULL REFERENCES attributes(id) ON DELETE CASCADE, required BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), UNIQUE (company_id, category_unique_id, attribute_id) ); CREATE INDEX category_attributes_company_id_idx ON category_attributes(company_id); CREATE TABLE custom_variables ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE, name TEXT NOT NULL, value TEXT NOT NULL DEFAULT '', description TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), UNIQUE (company_id, name) ); CREATE INDEX custom_variables_company_id_idx ON custom_variables(company_id); CREATE TABLE files ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE, user_id UUID REFERENCES users(id) ON DELETE SET NULL, name TEXT NOT NULL, path TEXT, content_type TEXT, size_bytes BIGINT NOT NULL DEFAULT 0, status TEXT NOT NULL DEFAULT 'uploaded', metadata JSONB NOT NULL DEFAULT '{}'::jsonb, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX files_company_id_idx ON files(company_id); CREATE TABLE raw_products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE, gtin TEXT NOT NULL, feed_id UUID, feed_ids JSONB, raw_data JSONB NOT NULL DEFAULT '{}'::jsonb, mapped_data JSONB NOT NULL DEFAULT '{}'::jsonb, sync_job_id UUID, is_processed BOOLEAN NOT NULL DEFAULT false, processing_status TEXT NOT NULL DEFAULT 'unprocessed' CHECK (processing_status IN ('unprocessed', 'processing', 'processed', 'failed')), file_id UUID REFERENCES files(id) ON DELETE SET NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX raw_products_company_id_idx ON raw_products(company_id); CREATE INDEX raw_products_gtin_idx ON raw_products(gtin); CREATE INDEX raw_products_feed_id_idx ON raw_products(feed_id); CREATE INDEX raw_products_processing_status_idx ON raw_products(processing_status); CREATE TABLE processed_products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE, user_id UUID REFERENCES users(id) ON DELETE SET NULL, product_id TEXT, name TEXT, category TEXT, description TEXT, processed_description TEXT, attributes JSONB, processed_attributes JSONB, status TEXT, gpt_response JSONB, total_tokens INT, feed_id UUID, raw_product_id UUID REFERENCES raw_products(id) ON DELETE SET NULL, processed_name TEXT, meta_title TEXT, meta_description TEXT, last_transition_at TIMESTAMPTZ, structured_description JSONB, field_sources JSONB, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX processed_products_company_id_idx ON processed_products(company_id); CREATE INDEX processed_products_raw_product_id_idx ON processed_products(raw_product_id); CREATE INDEX processed_products_product_id_idx ON processed_products(product_id); -- +goose Down DROP TABLE IF EXISTS processed_products; DROP TABLE IF EXISTS raw_products; DROP TABLE IF EXISTS files; DROP TABLE IF EXISTS custom_variables; DROP TABLE IF EXISTS category_attributes; DROP TABLE IF EXISTS attributes; DROP TABLE IF EXISTS categories;