Files
musadaq-saas/scripts/schema.sql
2026-05-04 14:40:41 +03:00

183 lines
8.1 KiB
SQL

-- ════════════════════════════════════════════════════════════
-- مُصادَق — Database Schema v1.0
-- ════════════════════════════════════════════════════════════
-- Tenants (Accounting Offices)
CREATE TABLE tenants (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
phone VARCHAR(20),
status ENUM('active', 'suspended', 'trial') DEFAULT 'trial',
trial_ends_at DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Users
CREATE TABLE users (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
tenant_id CHAR(36) NOT NULL,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
password_hash VARCHAR(255) NOT NULL,
role ENUM('super_admin','admin','accountant','viewer') NOT NULL,
company_id CHAR(36) NULL, -- assigned company for accountant
refresh_token_hash VARCHAR(255) NULL,
is_active BOOLEAN DEFAULT TRUE,
last_login_at DATETIME NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uq_tenant_email (tenant_id, email),
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
);
-- API Keys (for external integrations / mobile scanner)
CREATE TABLE api_keys (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
tenant_id CHAR(36) NOT NULL,
user_id CHAR(36) NOT NULL,
name VARCHAR(100) NOT NULL,
public_key VARCHAR(64) NOT NULL UNIQUE,
secret_hash VARCHAR(255) NOT NULL, -- bcrypt hash of secret
last_used_at DATETIME NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Companies
CREATE TABLE companies (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
tenant_id CHAR(36) NOT NULL,
name VARCHAR(255) NOT NULL,
name_en VARCHAR(255) NULL,
tax_identification_number VARCHAR(20) NOT NULL,
address TEXT NULL,
jofotara_client_id_encrypted TEXT NULL,
jofotara_secret_key_encrypted TEXT NULL,
jofotara_income_source_sequence VARCHAR(50) NULL,
certificate_path VARCHAR(255) NULL,
certificate_password_encrypted VARCHAR(500) NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_name (name),
INDEX idx_tin (tax_identification_number),
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
);
-- Subscriptions
CREATE TABLE subscriptions (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
tenant_id CHAR(36) NOT NULL UNIQUE,
plan ENUM('basic','office','pro','enterprise') NOT NULL DEFAULT 'basic',
max_companies INT NOT NULL DEFAULT 5,
max_invoices_per_month INT NOT NULL DEFAULT 100,
price_jod DECIMAL(10,2) NOT NULL DEFAULT 0,
invoices_used_this_month INT NOT NULL DEFAULT 0,
status ENUM('active','past_due','cancelled') DEFAULT 'active',
current_period_start DATETIME NULL,
current_period_end DATETIME NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
);
-- Invoices
CREATE TABLE invoices (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
tenant_id CHAR(36) NOT NULL,
company_id CHAR(36) NOT NULL,
invoice_number VARCHAR(100) NULL,
invoice_date DATE NULL,
invoice_type ENUM('cash','credit') DEFAULT 'cash',
ubl_type_code CHAR(3) DEFAULT '388',
payment_method_code CHAR(3) DEFAULT '013',
supplier_tin TEXT NULL,
supplier_name TEXT NULL,
supplier_address TEXT NULL,
buyer_tin TEXT NULL,
buyer_national_id TEXT NULL,
buyer_name TEXT NULL,
subtotal DECIMAL(15,3) DEFAULT 0,
discount_total DECIMAL(15,3) DEFAULT 0,
tax_amount DECIMAL(15,3) DEFAULT 0,
grand_total DECIMAL(15,3) DEFAULT 0,
currency_code CHAR(3) DEFAULT 'JOD',
status ENUM('extracted', 'approved', 'rejected') DEFAULT 'extracted',
jofotara_uuid VARCHAR(255) NULL,
qr_code TEXT NULL,
original_file_path TEXT NULL,
invoice_category VARCHAR(20) DEFAULT 'simplified',
validation_errors JSON NULL,
ai_confidence_score DECIMAL(4,3) NULL,
ai_prompt_tokens INT DEFAULT 0,
ai_completion_tokens INT DEFAULT 0,
ai_total_cost DECIMAL(10,6) DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at DATETIME NULL,
INDEX idx_tenant (tenant_id),
INDEX idx_company (company_id),
INDEX idx_status (status),
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE,
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
FOREIGN KEY (uploaded_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- JoFotara Submissions (Audit Trail)
CREATE TABLE jofotara_submissions (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
invoice_id CHAR(36) NOT NULL,
company_id CHAR(36) NOT NULL,
tenant_id CHAR(36) NOT NULL,
xml_payload LONGTEXT NULL,
xml_hash VARCHAR(64) NULL,
jofotara_uuid VARCHAR(255) NULL,
qr_code_raw TEXT NULL,
response_code VARCHAR(20) NULL,
response_body JSON NULL,
status ENUM('pending','submitted','accepted','rejected','error') DEFAULT 'pending',
error_message TEXT NULL,
retry_count TINYINT DEFAULT 0,
submitted_at DATETIME NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (invoice_id) REFERENCES invoices(id) ON DELETE CASCADE,
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Invoice Lines
CREATE TABLE invoice_lines (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
invoice_id CHAR(36) NOT NULL,
line_number INT NOT NULL,
description TEXT NOT NULL,
quantity DECIMAL(15,3) NOT NULL,
unit_price DECIMAL(15,3) NOT NULL,
discount DECIMAL(15,3) DEFAULT 0,
tax_rate DECIMAL(5,4) NOT NULL,
line_total DECIMAL(15,3) NOT NULL,
FOREIGN KEY (invoice_id) REFERENCES invoices(id) ON DELETE CASCADE
);
-- Audit Logs
CREATE TABLE audit_logs (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
tenant_id CHAR(36) NULL,
user_id CHAR(36) NULL,
action VARCHAR(100) NOT NULL,
entity_type VARCHAR(50) NULL,
entity_id CHAR(36) NULL,
old_data JSON NULL,
new_data JSON NULL,
ip_address VARCHAR(45) NULL,
user_agent VARCHAR(500) NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_tenant (tenant_id),
INDEX idx_action (action),
INDEX idx_created (created_at)
);