Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
168 lines
5.4 KiB
SQL
168 lines
5.4 KiB
SQL
-- +goose Up
|
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|
|
|
CREATE TABLE companies (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name TEXT NOT NULL,
|
|
language TEXT NOT NULL DEFAULT 'en',
|
|
merge_products_by_gtin BOOLEAN NOT NULL DEFAULT false,
|
|
legacy_company_id TEXT UNIQUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
email TEXT NOT NULL UNIQUE,
|
|
name TEXT,
|
|
password_hash TEXT,
|
|
must_set_password BOOLEAN NOT NULL DEFAULT true,
|
|
email_verified_at TIMESTAMPTZ,
|
|
is_platform_admin BOOLEAN NOT NULL DEFAULT false,
|
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
legacy_user_id TEXT UNIQUE,
|
|
last_login_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE memberships (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
role TEXT NOT NULL DEFAULT 'member' CHECK (role IN ('admin', 'member')),
|
|
status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'inactive')),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE (company_id, user_id)
|
|
);
|
|
|
|
CREATE INDEX memberships_user_id_idx ON memberships(user_id);
|
|
CREATE INDEX memberships_company_id_idx ON memberships(company_id);
|
|
|
|
CREATE TABLE invites (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
email TEXT NOT NULL,
|
|
role TEXT NOT NULL DEFAULT 'member' CHECK (role IN ('admin', 'member')),
|
|
token TEXT NOT NULL UNIQUE,
|
|
invited_by UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
accepted_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX invites_company_email_idx ON invites(company_id, email);
|
|
|
|
CREATE TABLE sessions (
|
|
token TEXT PRIMARY KEY,
|
|
data BYTEA NOT NULL,
|
|
expiry TIMESTAMPTZ NOT NULL
|
|
);
|
|
|
|
CREATE INDEX sessions_expiry_idx ON sessions(expiry);
|
|
|
|
CREATE TABLE api_keys (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
name TEXT,
|
|
key_hash TEXT NOT NULL UNIQUE,
|
|
key_prefix TEXT NOT NULL,
|
|
last_used_at TIMESTAMPTZ,
|
|
revoked_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX api_keys_company_id_idx ON api_keys(company_id);
|
|
|
|
CREATE TABLE company_settings (
|
|
company_id UUID PRIMARY KEY REFERENCES companies(id) ON DELETE CASCADE,
|
|
settings JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE plans (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
description TEXT,
|
|
monthly_credits INT NOT NULL,
|
|
yearly_credits INT,
|
|
max_products INT,
|
|
is_custom BOOLEAN NOT NULL DEFAULT false,
|
|
term TEXT NOT NULL DEFAULT 'monthly',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE company_plans (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
plan_id BIGINT NOT NULL REFERENCES plans(id),
|
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
billing_cycle_start TIMESTAMPTZ NOT NULL,
|
|
next_billing_date TIMESTAMPTZ NOT NULL,
|
|
contract_start_date TIMESTAMPTZ,
|
|
contract_end_date TIMESTAMPTZ,
|
|
custom_monthly_credits INT,
|
|
total_credits_allocated INT,
|
|
custom_max_products INT,
|
|
contract_reference TEXT,
|
|
notes TEXT,
|
|
is_trial BOOLEAN NOT NULL DEFAULT false,
|
|
trial_ends_at TIMESTAMPTZ,
|
|
trial_credits INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX company_plans_company_id_idx ON company_plans(company_id);
|
|
|
|
CREATE TABLE billing_cycles (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
start_date TIMESTAMPTZ NOT NULL,
|
|
end_date TIMESTAMPTZ NOT NULL,
|
|
credits_used INT NOT NULL DEFAULT 0,
|
|
products_processed INT NOT NULL DEFAULT 0,
|
|
invoice_amount INT,
|
|
invoice_notes TEXT,
|
|
is_invoiced BOOLEAN NOT NULL DEFAULT false,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX billing_cycles_company_id_idx ON billing_cycles(company_id);
|
|
|
|
CREATE TABLE credit_balances (
|
|
company_id UUID PRIMARY KEY REFERENCES companies(id) ON DELETE CASCADE,
|
|
total_credits INT NOT NULL DEFAULT 0,
|
|
used_credits INT NOT NULL DEFAULT 0,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE processing_costs (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
feature_name TEXT NOT NULL UNIQUE,
|
|
cost_per_unit INT NOT NULL,
|
|
description TEXT,
|
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- +goose Down
|
|
DROP TABLE IF EXISTS processing_costs;
|
|
DROP TABLE IF EXISTS credit_balances;
|
|
DROP TABLE IF EXISTS billing_cycles;
|
|
DROP TABLE IF EXISTS company_plans;
|
|
DROP TABLE IF EXISTS plans;
|
|
DROP TABLE IF EXISTS company_settings;
|
|
DROP TABLE IF EXISTS api_keys;
|
|
DROP TABLE IF EXISTS sessions;
|
|
DROP TABLE IF EXISTS invites;
|
|
DROP TABLE IF EXISTS memberships;
|
|
DROP TABLE IF EXISTS users;
|
|
DROP TABLE IF EXISTS companies;
|