mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 20:23:17 +00:00
<!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## Validación de endpoints y SPs Se probaron todos los endpoints nuevos (gastos, almacén, control presupuestal, IAM) y sus RPCs asociados. ### Bugs corregidos en migraciones/SQL 1. **IAM grants en schema core** — `iam-004e` intentaba `GRANT` sobre `core` con rol `iam_owner` (sin permiso). Los grants cruzados se movieron a `core-027-iam-rpc-cross-grants.sql`. 2. **`_cost_settings` ambiguo** — columnas `budget_warn_pct` etc. colisionaban con `RETURNS TABLE` en PL/pgSQL, rompiendo `fn_expense_create` y control presupuestal. Corregido en `core-028-fix-cost-settings-ambiguous.sql`. ### Tests añadidos - `api/cost_modules_test.ts` — CRUD RPC gastos, flujo almacén completo, control presupuestal, IAM permisos - `scripts/crud-smoke-test.sh` — smoke HTTP de todos los endpoints nuevos ### Resultados - `deno test cost_modules_test.ts` — 5/5 OK - `./scripts/crud-smoke-test.sh` — todos los checks OK (gastos CRUD, IVA, cost-settings, almacén, transferencias, cost-control, IAM) <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-eeec3b5c-f789-43e8-a353-0755e4706377?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-eeec3b5c-f789-43e8-a353-0755e4706377&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div>
103 lines
5.1 KiB
SQL
103 lines
5.1 KiB
SQL
--liquibase formatted sql
|
|
-- PANELS · core · gastos, IVA y configuración de control de costos
|
|
|
|
--changeset panel:core-018a-tenant-cost-settings endDelimiter:; splitStatements:true
|
|
--preconditions onFail:MARK_RAN
|
|
--precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='core' AND table_name='tenant_cost_settings'
|
|
CREATE TABLE core.tenant_cost_settings (
|
|
tenant_id INTEGER PRIMARY KEY,
|
|
budget_warn_pct NUMERIC(5,2) NOT NULL DEFAULT 85,
|
|
budget_critical_pct NUMERIC(5,2) NOT NULL DEFAULT 100,
|
|
default_iva_rate NUMERIC(5,4) NOT NULL DEFAULT 0.16,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
--changeset panel:core-018b-expense-entries endDelimiter:; splitStatements:true
|
|
--preconditions onFail:MARK_RAN
|
|
--precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='core' AND table_name='expense_entries'
|
|
CREATE TABLE core.expense_entries (
|
|
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
tenant_id INTEGER NOT NULL,
|
|
company_id BIGINT NOT NULL REFERENCES core.companies(id),
|
|
project_id BIGINT REFERENCES core.projects(id) ON DELETE SET NULL,
|
|
expense_date DATE NOT NULL,
|
|
source TEXT NOT NULL DEFAULT 'manual' CHECK (source IN ('manual', 'payroll', 'destajo')),
|
|
source_ref_id BIGINT,
|
|
description TEXT NOT NULL DEFAULT '',
|
|
supplier_name TEXT NOT NULL DEFAULT '',
|
|
supplier_rfc TEXT NOT NULL DEFAULT '',
|
|
budget_chapter_id BIGINT REFERENCES core.budget_chapters(id) ON DELETE SET NULL,
|
|
budget_item_id BIGINT REFERENCES core.budget_items(id) ON DELETE SET NULL,
|
|
quantity NUMERIC(14,4) NOT NULL DEFAULT 0,
|
|
unit TEXT NOT NULL DEFAULT '',
|
|
unit_price NUMERIC(14,4) NOT NULL DEFAULT 0,
|
|
subtotal NUMERIC(14,2) NOT NULL DEFAULT 0,
|
|
iva_rate NUMERIC(5,4) NOT NULL DEFAULT 0.16,
|
|
iva_amount NUMERIC(14,2) NOT NULL DEFAULT 0,
|
|
total NUMERIC(14,2) NOT NULL DEFAULT 0,
|
|
tax_included BOOLEAN NOT NULL DEFAULT false,
|
|
is_deductible BOOLEAN NOT NULL DEFAULT true,
|
|
counts_toward_budget BOOLEAN NOT NULL DEFAULT true,
|
|
is_locked BOOLEAN NOT NULL DEFAULT false,
|
|
status TEXT NOT NULL DEFAULT 'confirmed' CHECK (status IN ('draft', 'confirmed', 'void')),
|
|
created_by_id INTEGER,
|
|
created_by_name TEXT NOT NULL DEFAULT '',
|
|
notes TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX idx_core_expense_entries_tenant ON core.expense_entries(tenant_id);
|
|
CREATE INDEX idx_core_expense_entries_project_date ON core.expense_entries(project_id, expense_date);
|
|
CREATE INDEX idx_core_expense_entries_budget_item ON core.expense_entries(budget_item_id);
|
|
CREATE UNIQUE INDEX idx_core_expense_entries_source_ref
|
|
ON core.expense_entries(source, source_ref_id)
|
|
WHERE source_ref_id IS NOT NULL AND status <> 'void';
|
|
|
|
--changeset panel:core-018c-expense-attachments endDelimiter:; splitStatements:true
|
|
--preconditions onFail:MARK_RAN
|
|
--precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='core' AND table_name='expense_attachments'
|
|
CREATE TABLE core.expense_attachments (
|
|
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
expense_id BIGINT NOT NULL REFERENCES core.expense_entries(id) ON DELETE CASCADE,
|
|
original_name TEXT NOT NULL,
|
|
mime TEXT NOT NULL,
|
|
size_bytes BIGINT NOT NULL,
|
|
sha256 TEXT NOT NULL,
|
|
iv TEXT NOT NULL,
|
|
storage_name TEXT NOT NULL,
|
|
uploaded_by_id INTEGER,
|
|
uploaded_by_name TEXT NOT NULL DEFAULT '',
|
|
uploaded_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
--changeset panel:core-018d-iva-period-manual endDelimiter:; splitStatements:true
|
|
--preconditions onFail:MARK_RAN
|
|
--precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='core' AND table_name='iva_period_entries'
|
|
CREATE TABLE core.iva_period_entries (
|
|
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
tenant_id INTEGER NOT NULL,
|
|
company_id BIGINT NOT NULL REFERENCES core.companies(id),
|
|
period_year INTEGER NOT NULL,
|
|
period_month INTEGER NOT NULL CHECK (period_month BETWEEN 1 AND 12),
|
|
iva_trasladado NUMERIC(14,2) NOT NULL DEFAULT 0,
|
|
notes TEXT NOT NULL DEFAULT '',
|
|
updated_by_name TEXT NOT NULL DEFAULT '',
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE (tenant_id, company_id, period_year, period_month)
|
|
);
|
|
CREATE INDEX idx_core_iva_period_tenant ON core.iva_period_entries(tenant_id);
|
|
|
|
--changeset panel:core-018e-destajo-budget-item endDelimiter:; splitStatements:true
|
|
ALTER TABLE core.destajo_jobs
|
|
ADD COLUMN IF NOT EXISTS budget_item_id BIGINT REFERENCES core.budget_items(id) ON DELETE SET NULL;
|
|
|
|
--changeset panel:core-018f-warehouse-material-budget-links endDelimiter:; splitStatements:true
|
|
--preconditions onFail:MARK_RAN
|
|
--precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='core' AND table_name='warehouse_material_budget_links'
|
|
CREATE TABLE core.warehouse_material_budget_links (
|
|
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
material_id BIGINT NOT NULL,
|
|
budget_item_id BIGINT NOT NULL REFERENCES core.budget_items(id) ON DELETE CASCADE,
|
|
conversion_factor NUMERIC(14,6) NOT NULL DEFAULT 1,
|
|
UNIQUE (material_id, budget_item_id)
|
|
);
|