docs: add quixzoom-auth-core product to AAMOS
- Product documentation in docs/products/ - Updated MEMORY.md with product info - quiXzoom Auth Core as AAMOS Identity product
This commit is contained in:
@@ -0,0 +1,285 @@
|
||||
-- ═══════════════════════════════════════════════════════════════════════════
|
||||
-- AAMOS Admin v2 — Setup script (idempotent)
|
||||
-- ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
-- Enable UUID extension
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
-- ── Customers (Kunder) ─────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS billing_customers (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
customer_type TEXT NOT NULL DEFAULT 'company',
|
||||
org_nr TEXT,
|
||||
name TEXT NOT NULL,
|
||||
email TEXT,
|
||||
phone TEXT,
|
||||
address TEXT,
|
||||
postal_code TEXT,
|
||||
city TEXT,
|
||||
country TEXT DEFAULT 'SE',
|
||||
reference TEXT,
|
||||
notes TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
payment_terms_days INTEGER DEFAULT 30,
|
||||
vat_number TEXT,
|
||||
platform_customer_id TEXT,
|
||||
platform_synced_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_customers_status ON billing_customers (status);
|
||||
CREATE INDEX IF NOT EXISTS idx_customers_org_nr ON billing_customers (org_nr);
|
||||
|
||||
-- ── Leads ──────────────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS crm_leads (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
email TEXT,
|
||||
phone TEXT,
|
||||
company TEXT,
|
||||
source TEXT NOT NULL DEFAULT 'web',
|
||||
status TEXT NOT NULL DEFAULT 'new',
|
||||
notes TEXT,
|
||||
converted_at TIMESTAMPTZ,
|
||||
converted_to_customer_id UUID REFERENCES billing_customers(id),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_leads_status ON crm_leads (status);
|
||||
CREATE INDEX IF NOT EXISTS idx_leads_source ON crm_leads (source);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_leads_email ON crm_leads (email);
|
||||
|
||||
-- ── Mail Messages ──────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS mail_messages (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
from_email TEXT NOT NULL,
|
||||
from_name TEXT,
|
||||
to_email TEXT,
|
||||
subject TEXT,
|
||||
body TEXT,
|
||||
folder TEXT NOT NULL DEFAULT 'inbox',
|
||||
status TEXT NOT NULL DEFAULT 'unread',
|
||||
source TEXT,
|
||||
source_url TEXT,
|
||||
lead_id UUID REFERENCES crm_leads(id),
|
||||
in_reply_to UUID REFERENCES mail_messages(id),
|
||||
read_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_mail_folder ON mail_messages (folder);
|
||||
CREATE INDEX IF NOT EXISTS idx_mail_status ON mail_messages (status);
|
||||
CREATE INDEX IF NOT EXISTS idx_mail_source ON mail_messages (source);
|
||||
CREATE INDEX IF NOT EXISTS idx_mail_lead ON mail_messages (lead_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_mail_created ON mail_messages (created_at DESC);
|
||||
|
||||
-- ── Agreements ─────────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS billing_agreements (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
agreement_number TEXT NOT NULL UNIQUE,
|
||||
customer_id UUID NOT NULL REFERENCES billing_customers(id),
|
||||
agreement_type TEXT NOT NULL DEFAULT 'kommersiellt',
|
||||
status TEXT NOT NULL DEFAULT 'draft',
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
start_date DATE NOT NULL,
|
||||
end_date DATE,
|
||||
auto_renew BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
renewal_period_months INTEGER,
|
||||
billing_frequency TEXT NOT NULL DEFAULT 'monthly',
|
||||
billing_day INTEGER NOT NULL DEFAULT 1,
|
||||
payment_terms_days INTEGER NOT NULL DEFAULT 30,
|
||||
amount NUMERIC(18,2) NOT NULL DEFAULT 0,
|
||||
currency TEXT NOT NULL DEFAULT 'SEK',
|
||||
vat_rate NUMERIC(5,2) NOT NULL DEFAULT 25.0,
|
||||
next_invoice_date DATE,
|
||||
last_invoice_date DATE,
|
||||
platform_agreement_id TEXT,
|
||||
platform_synced_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agreements_customer ON billing_agreements (customer_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_agreements_status ON billing_agreements (status);
|
||||
|
||||
-- ── Invoices ───────────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS billing_invoices (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
invoice_number TEXT NOT NULL UNIQUE,
|
||||
customer_id UUID NOT NULL REFERENCES billing_customers(id),
|
||||
agreement_id UUID REFERENCES billing_agreements(id),
|
||||
invoice_type TEXT NOT NULL DEFAULT 'standard',
|
||||
status TEXT NOT NULL DEFAULT 'draft',
|
||||
customer_name TEXT NOT NULL,
|
||||
customer_address TEXT,
|
||||
customer_postal TEXT,
|
||||
customer_city TEXT,
|
||||
customer_email TEXT,
|
||||
customer_reference TEXT,
|
||||
invoice_date DATE NOT NULL,
|
||||
due_date DATE NOT NULL,
|
||||
delivery_date DATE,
|
||||
sent_at TIMESTAMPTZ,
|
||||
paid_at TIMESTAMPTZ,
|
||||
credited_at TIMESTAMPTZ,
|
||||
currency TEXT NOT NULL DEFAULT 'SEK',
|
||||
subtotal NUMERIC(18,2) NOT NULL DEFAULT 0,
|
||||
vat_total NUMERIC(18,2) NOT NULL DEFAULT 0,
|
||||
total NUMERIC(18,2) NOT NULL DEFAULT 0,
|
||||
amount_paid NUMERIC(18,2) NOT NULL DEFAULT 0,
|
||||
amount_due NUMERIC(18,2) NOT NULL DEFAULT 0,
|
||||
vat_specification JSONB NOT NULL DEFAULT '{}',
|
||||
journal_entry_id UUID,
|
||||
ledger_posted_at TIMESTAMPTZ,
|
||||
reminder_count INTEGER NOT NULL DEFAULT 0,
|
||||
last_reminder_at TIMESTAMPTZ,
|
||||
reminder_fee NUMERIC(18,2) DEFAULT 0,
|
||||
interest_fee NUMERIC(18,2) DEFAULT 0,
|
||||
pdf_generated_at TIMESTAMPTZ,
|
||||
pdf_url TEXT,
|
||||
platform_invoice_id TEXT,
|
||||
platform_synced_at TIMESTAMPTZ,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_invoices_customer ON billing_invoices (customer_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_invoices_status ON billing_invoices (status);
|
||||
CREATE INDEX IF NOT EXISTS idx_invoices_dates ON billing_invoices (invoice_date, due_date);
|
||||
|
||||
-- ── Invoice Lines ──────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS billing_invoice_lines (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
invoice_id UUID NOT NULL REFERENCES billing_invoices(id) ON DELETE CASCADE,
|
||||
line_number INTEGER NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
quantity NUMERIC(12,2) NOT NULL DEFAULT 1,
|
||||
unit TEXT,
|
||||
unit_price NUMERIC(18,2) NOT NULL,
|
||||
line_total NUMERIC(18,2) NOT NULL,
|
||||
vat_rate NUMERIC(5,2) NOT NULL,
|
||||
vat_amount NUMERIC(18,2) NOT NULL,
|
||||
line_total_incl_vat NUMERIC(18,2) NOT NULL,
|
||||
revenue_account TEXT NOT NULL DEFAULT '3000',
|
||||
cost_center TEXT,
|
||||
project_code TEXT,
|
||||
UNIQUE (invoice_id, line_number)
|
||||
);
|
||||
|
||||
-- ── Payments ───────────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS billing_payments (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
invoice_id UUID NOT NULL REFERENCES billing_invoices(id),
|
||||
payment_date DATE NOT NULL,
|
||||
amount NUMERIC(18,2) NOT NULL,
|
||||
currency TEXT NOT NULL DEFAULT 'SEK',
|
||||
payment_method TEXT NOT NULL,
|
||||
payment_reference TEXT,
|
||||
bank_transaction_id TEXT,
|
||||
reconciliation_status TEXT NOT NULL DEFAULT 'unreconciled',
|
||||
reconciled_at TIMESTAMPTZ,
|
||||
journal_entry_id UUID,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_payments_invoice ON billing_payments (invoice_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_payments_reconciliation ON billing_payments (reconciliation_status);
|
||||
|
||||
-- ── Automations ────────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS automations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
trigger_type TEXT NOT NULL,
|
||||
frequency TEXT,
|
||||
action TEXT NOT NULL,
|
||||
action_config JSONB NOT NULL DEFAULT '{}',
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
last_run_at TIMESTAMPTZ,
|
||||
last_run_status TEXT,
|
||||
last_run_result JSONB,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ── Automation Logs ────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS automation_logs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
automation_id UUID NOT NULL REFERENCES automations(id),
|
||||
status TEXT NOT NULL,
|
||||
result JSONB,
|
||||
executed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ── Settings ───────────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
id INTEGER PRIMARY KEY DEFAULT 1,
|
||||
company_name TEXT NOT NULL DEFAULT 'LandveX AB',
|
||||
org_nr TEXT DEFAULT '559141-7042',
|
||||
vat_nr TEXT DEFAULT 'SE559141704201',
|
||||
address TEXT,
|
||||
postal_code TEXT,
|
||||
city TEXT,
|
||||
payment_terms_days INTEGER DEFAULT 30,
|
||||
default_vat_rate NUMERIC(5,2) DEFAULT 25.0,
|
||||
bank_account TEXT,
|
||||
bankgiro TEXT,
|
||||
postgiro TEXT,
|
||||
swish_number TEXT,
|
||||
logo_url TEXT,
|
||||
email_from TEXT,
|
||||
email_reply_to TEXT,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
INSERT INTO settings (id) VALUES (1) ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ── Bank Transactions ──────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS bank_transactions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
transaction_date DATE NOT NULL,
|
||||
description TEXT,
|
||||
amount NUMERIC(18,2) NOT NULL,
|
||||
currency TEXT NOT NULL DEFAULT 'SEK',
|
||||
reference TEXT,
|
||||
bank_account TEXT,
|
||||
matched_at TIMESTAMPTZ,
|
||||
matched_by TEXT,
|
||||
reconciled_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ── Audit Log ──────────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS audit_log (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id TEXT,
|
||||
entity_type TEXT NOT NULL,
|
||||
entity_id TEXT NOT NULL,
|
||||
action TEXT NOT NULL,
|
||||
before_state JSONB,
|
||||
after_state JSONB,
|
||||
ip_address TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ── Platform Sync Queue ────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS platform_sync_queue (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
entity_type TEXT NOT NULL,
|
||||
entity_id UUID NOT NULL,
|
||||
action TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
error_message TEXT,
|
||||
retry_count INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
processed_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
-- Insert test data
|
||||
INSERT INTO billing_customers (name, email, org_nr, status)
|
||||
VALUES ('Testkund AB', 'test@kund.se', '555555-5555', 'active')
|
||||
ON CONFLICT DO NOTHING;
|
||||
Reference in New Issue
Block a user