Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
-- +goose Up
|
||||
-- Sales contact leads + admin-prepared payment quotes (custom/Enterprise deals).
|
||||
|
||||
CREATE TABLE sales_leads (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
email TEXT NOT NULL,
|
||||
company_name TEXT,
|
||||
phone TEXT,
|
||||
message TEXT NOT NULL,
|
||||
estimated_skus INT,
|
||||
source TEXT NOT NULL DEFAULT 'pricing'
|
||||
CHECK (char_length(source) BETWEEN 1 AND 64),
|
||||
status TEXT NOT NULL DEFAULT 'new'
|
||||
CHECK (status IN ('new', 'contacted', 'quoted', 'won', 'closed')),
|
||||
company_id UUID REFERENCES companies(id) ON DELETE SET NULL,
|
||||
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
admin_notes TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT sales_leads_name_len CHECK (char_length(btrim(name)) BETWEEN 1 AND 200),
|
||||
CONSTRAINT sales_leads_email_len CHECK (char_length(btrim(email)) BETWEEN 3 AND 320),
|
||||
CONSTRAINT sales_leads_message_len CHECK (char_length(btrim(message)) BETWEEN 1 AND 10000),
|
||||
CONSTRAINT sales_leads_company_name_len CHECK (company_name IS NULL OR char_length(company_name) <= 200),
|
||||
CONSTRAINT sales_leads_phone_len CHECK (phone IS NULL OR char_length(phone) <= 40),
|
||||
CONSTRAINT sales_leads_admin_notes_len CHECK (admin_notes IS NULL OR char_length(admin_notes) <= 10000),
|
||||
CONSTRAINT sales_leads_estimated_skus_chk CHECK (estimated_skus IS NULL OR estimated_skus >= 0)
|
||||
);
|
||||
|
||||
CREATE INDEX sales_leads_status_created_idx ON sales_leads (status, created_at DESC);
|
||||
CREATE INDEX sales_leads_email_idx ON sales_leads (lower(email), created_at DESC);
|
||||
CREATE INDEX sales_leads_company_idx ON sales_leads (company_id) WHERE company_id IS NOT NULL;
|
||||
|
||||
CREATE TABLE sales_quotes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
lead_id UUID NOT NULL REFERENCES sales_leads(id) ON DELETE CASCADE,
|
||||
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
||||
plan_id BIGINT REFERENCES plans(id) ON DELETE SET NULL,
|
||||
plan_name TEXT NOT NULL,
|
||||
monthly_credits INT NOT NULL DEFAULT 0,
|
||||
max_products INT,
|
||||
currency TEXT NOT NULL DEFAULT 'usd',
|
||||
total_amount_cents INT NOT NULL,
|
||||
installment_count INT NOT NULL DEFAULT 1,
|
||||
installment_interval TEXT NOT NULL DEFAULT 'month'
|
||||
CHECK (installment_interval IN ('month', 'quarter', 'year')),
|
||||
installment_amount_cents INT NOT NULL,
|
||||
term_months INT,
|
||||
stripe_product_id TEXT,
|
||||
stripe_price_id TEXT,
|
||||
stripe_checkout_session_id TEXT,
|
||||
checkout_url TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'draft'
|
||||
CHECK (status IN ('draft', 'ready', 'sent', 'paid', 'canceled')),
|
||||
created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
paid_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT sales_quotes_plan_name_len CHECK (char_length(btrim(plan_name)) BETWEEN 1 AND 120),
|
||||
CONSTRAINT sales_quotes_currency_len CHECK (char_length(currency) BETWEEN 3 AND 10),
|
||||
CONSTRAINT sales_quotes_total_chk CHECK (total_amount_cents > 0),
|
||||
CONSTRAINT sales_quotes_installment_count_chk CHECK (installment_count BETWEEN 1 AND 60),
|
||||
CONSTRAINT sales_quotes_installment_amount_chk CHECK (installment_amount_cents > 0),
|
||||
CONSTRAINT sales_quotes_monthly_credits_chk CHECK (monthly_credits >= 0),
|
||||
CONSTRAINT sales_quotes_max_products_chk CHECK (max_products IS NULL OR max_products >= 0),
|
||||
CONSTRAINT sales_quotes_term_months_chk CHECK (term_months IS NULL OR term_months BETWEEN 1 AND 120)
|
||||
);
|
||||
|
||||
CREATE INDEX sales_quotes_lead_idx ON sales_quotes (lead_id, created_at DESC);
|
||||
CREATE INDEX sales_quotes_company_status_idx ON sales_quotes (company_id, status, created_at DESC);
|
||||
CREATE INDEX sales_quotes_status_idx ON sales_quotes (status, created_at DESC);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS sales_quotes;
|
||||
DROP TABLE IF EXISTS sales_leads;
|
||||
Reference in New Issue
Block a user