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:
2026-08-09 22:47:43 +02:00
commit 8580c996c3
1285 changed files with 325780 additions and 0 deletions
+75
View File
@@ -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;