panels-origin/api/schema.sql
2026-08-21 16:55:01 -05:00

252 lines
8.4 KiB
SQL

PRAGMA foreign_keys = ON;
PRAGMA journal_mode = WAL;
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
display_name TEXT NOT NULL,
company_id INTEGER REFERENCES companies(id),
tenant_id INTEGER,
role TEXT NOT NULL DEFAULT 'user',
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS companies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
code TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
parent_id INTEGER REFERENCES companies(id),
kind TEXT NOT NULL DEFAULT 'sub' CHECK (kind IN ('principal', 'sub')),
status TEXT NOT NULL DEFAULT 'activo' CHECK (status IN ('activo', 'inactivo')),
tenant_id INTEGER,
registro_patronal TEXT NOT NULL DEFAULT '',
razon_social TEXT NOT NULL DEFAULT '',
nombre_comercial TEXT NOT NULL DEFAULT '',
rfc TEXT NOT NULL DEFAULT '',
regimen_fiscal TEXT NOT NULL DEFAULT '',
clase_riesgo TEXT NOT NULL DEFAULT '',
domicilio_fiscal TEXT NOT NULL DEFAULT '',
codigo_postal TEXT NOT NULL DEFAULT '',
ciudad TEXT NOT NULL DEFAULT '',
estado TEXT NOT NULL DEFAULT '',
telefono TEXT NOT NULL DEFAULT '',
email TEXT NOT NULL DEFAULT '',
representante_legal TEXT NOT NULL DEFAULT '',
giro TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS risk_levels (
code TEXT PRIMARY KEY,
label TEXT NOT NULL,
color TEXT NOT NULL,
text_color TEXT NOT NULL DEFAULT '#FFFFFF'
);
CREATE TABLE IF NOT EXISTS badge_themes (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
layout TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS projects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
code TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
address TEXT NOT NULL DEFAULT '',
stage TEXT NOT NULL DEFAULT '',
status TEXT NOT NULL DEFAULT 'activo' CHECK (status IN ('activo', 'pausado', 'concluido', 'cancelado')),
theme_id TEXT NOT NULL REFERENCES badge_themes(id),
logo_left_path TEXT,
logo_right_path TEXT,
company_id INTEGER REFERENCES companies(id),
tenant_id INTEGER,
contract_amount REAL,
start_date TEXT,
end_date TEXT,
resident_name TEXT NOT NULL DEFAULT '',
siroc TEXT NOT NULL DEFAULT '',
payroll_tax_pct REAL NOT NULL DEFAULT 4,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS workers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
first_name TEXT NOT NULL,
middle_name TEXT,
last_name_p TEXT NOT NULL,
last_name_m TEXT NOT NULL,
curp TEXT NOT NULL COLLATE NOCASE,
rfc TEXT NOT NULL COLLATE NOCASE,
nss TEXT NOT NULL,
phone TEXT NOT NULL,
email TEXT NOT NULL,
address TEXT NOT NULL,
blood_type TEXT,
hire_type TEXT NOT NULL,
company_id INTEGER REFERENCES companies(id),
tenant_id INTEGER,
position TEXT NOT NULL,
risk_code TEXT NOT NULL REFERENCES risk_levels(code),
work_type TEXT NOT NULL CHECK (work_type IN ('N', 'D')),
daily_wage REAL NOT NULL DEFAULT 0,
needs_badge INTEGER NOT NULL DEFAULT 1,
status TEXT NOT NULL DEFAULT 'activo' CHECK (status IN ('activo', 'baja')),
pipeline_status TEXT NOT NULL DEFAULT 'incompleto',
imss_status TEXT NOT NULL DEFAULT 'sin_alta' CHECK (imss_status IN ('sin_alta', 'alta', 'baja_imss')),
imss_company_id INTEGER REFERENCES companies(id),
imss_alta_at TEXT,
imss_baja_at TEXT,
last_rehire_at TEXT,
vcard_password_enc TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_workers_curp ON workers(curp);
CREATE UNIQUE INDEX IF NOT EXISTS idx_workers_rfc ON workers(rfc);
CREATE UNIQUE INDEX IF NOT EXISTS idx_workers_nss ON workers(nss);
CREATE TABLE IF NOT EXISTS assignments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
worker_id INTEGER NOT NULL REFERENCES workers(id) ON DELETE CASCADE,
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
active INTEGER NOT NULL DEFAULT 1,
start_date TEXT NOT NULL,
end_date TEXT,
UNIQUE (worker_id, project_id)
);
CREATE TABLE IF NOT EXISTS document_types (
code TEXT PRIMARY KEY,
label TEXT NOT NULL,
required INTEGER NOT NULL DEFAULT 1,
validity_mode TEXT NOT NULL DEFAULT 'none' CHECK (validity_mode IN ('none', 'freshness', 'expiry')),
freshness_days INTEGER,
requires_issued_at INTEGER NOT NULL DEFAULT 0,
requires_expires_at INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE IF NOT EXISTS documents (
id INTEGER PRIMARY KEY AUTOINCREMENT,
worker_id INTEGER NOT NULL REFERENCES workers(id) ON DELETE CASCADE,
type_code TEXT NOT NULL REFERENCES document_types(code),
original_name TEXT NOT NULL,
mime TEXT NOT NULL,
size_bytes INTEGER NOT NULL,
sha256 TEXT NOT NULL,
iv TEXT NOT NULL,
storage_name TEXT NOT NULL,
is_current INTEGER NOT NULL DEFAULT 1,
parse_status TEXT NOT NULL DEFAULT 'manual',
issued_at TEXT,
expires_at TEXT,
imss_company_id INTEGER REFERENCES companies(id),
imss_alta_at TEXT,
uploaded_by INTEGER REFERENCES users(id),
uploaded_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS project_document_types (
code TEXT PRIMARY KEY,
label TEXT NOT NULL,
required INTEGER NOT NULL DEFAULT 1
);
CREATE TABLE IF NOT EXISTS project_documents (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
type_code TEXT NOT NULL REFERENCES project_document_types(code),
original_name TEXT NOT NULL,
mime TEXT NOT NULL,
size_bytes INTEGER NOT NULL,
sha256 TEXT NOT NULL,
iv TEXT NOT NULL,
storage_name TEXT NOT NULL,
is_current INTEGER NOT NULL DEFAULT 1,
parse_status TEXT NOT NULL DEFAULT 'manual',
uploaded_by INTEGER REFERENCES users(id),
uploaded_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS badge_jobs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
status TEXT NOT NULL DEFAULT 'done',
pdf_path TEXT,
created_by INTEGER REFERENCES users(id),
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS badge_job_people (
job_id INTEGER NOT NULL REFERENCES badge_jobs(id) ON DELETE CASCADE,
worker_id INTEGER NOT NULL REFERENCES workers(id),
delivered INTEGER NOT NULL DEFAULT 0,
delivered_at TEXT,
PRIMARY KEY (job_id, worker_id)
);
CREATE TABLE IF NOT EXISTS loans (
id INTEGER PRIMARY KEY AUTOINCREMENT,
worker_id INTEGER NOT NULL REFERENCES workers(id) ON DELETE CASCADE,
amount REAL NOT NULL,
balance REAL NOT NULL,
weekly_payment REAL NOT NULL,
note TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS attendance (
id INTEGER PRIMARY KEY AUTOINCREMENT,
worker_id INTEGER NOT NULL REFERENCES workers(id) ON DELETE CASCADE,
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
work_date TEXT NOT NULL,
present INTEGER NOT NULL DEFAULT 1,
UNIQUE (worker_id, project_id, work_date)
);
CREATE TABLE IF NOT EXISTS payroll_periods (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
week_start TEXT NOT NULL,
week_end TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'draft',
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS payroll_lines (
id INTEGER PRIMARY KEY AUTOINCREMENT,
period_id INTEGER NOT NULL REFERENCES payroll_periods(id) ON DELETE CASCADE,
worker_id INTEGER NOT NULL REFERENCES workers(id),
days REAL NOT NULL DEFAULT 0,
daily_wage REAL NOT NULL,
gross REAL NOT NULL,
discounts REAL NOT NULL DEFAULT 0,
loan_payment REAL NOT NULL DEFAULT 0,
net REAL NOT NULL
);
CREATE TABLE IF NOT EXISTS budget_chapters (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
parent_id INTEGER REFERENCES budget_chapters(id) ON DELETE SET NULL,
code TEXT NOT NULL DEFAULT '',
name TEXT NOT NULL,
wbs TEXT NOT NULL DEFAULT '',
sort_order INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE IF NOT EXISTS budget_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
chapter_id INTEGER REFERENCES budget_chapters(id) ON DELETE SET NULL,
code TEXT NOT NULL DEFAULT '',
description TEXT NOT NULL,
unit TEXT NOT NULL DEFAULT '',
quantity REAL NOT NULL DEFAULT 0,
unit_price REAL NOT NULL DEFAULT 0,
amount REAL NOT NULL DEFAULT 0,
wbs TEXT NOT NULL DEFAULT '',
sort_order INTEGER NOT NULL DEFAULT 0
);