feat: CRM Clinicas SaaS - MVP completo

- Auth: Login/Register con creacion de clinica
- Dashboard: KPIs reales, graficas recharts
- Pacientes: CRUD completo con busqueda
- Agenda: FullCalendar, drag-and-drop, vista recepcion
- Expediente: Notas SOAP, signos vitales, CIE-10
- Facturacion: Facturas con IVA, campos CFDI SAT
- Inventario: Productos, stock, movimientos, alertas
- Configuracion: Clinica, equipo, catalogo servicios
- Supabase self-hosted: 18 tablas con RLS multi-tenant
- Docker + Nginx para produccion

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
Consultoria AS
2026-03-03 07:04:14 +00:00
commit 79b5d86325
1612 changed files with 109181 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
CREATE TABLE services_catalog (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
clinic_id UUID NOT NULL REFERENCES clinics(id) ON DELETE CASCADE,
name TEXT NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL DEFAULT 0,
sat_product_key TEXT,
sat_unit_key TEXT DEFAULT 'E48',
tax_rate DECIMAL(4,2) NOT NULL DEFAULT 0.16,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE invoices (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
clinic_id UUID NOT NULL REFERENCES clinics(id) ON DELETE CASCADE,
patient_id UUID NOT NULL REFERENCES patients(id),
invoice_number TEXT NOT NULL,
cfdi_uuid TEXT,
cfdi_status TEXT NOT NULL DEFAULT 'draft' CHECK (cfdi_status IN ('draft','stamped','cancelled')),
cfdi_xml_url TEXT,
cfdi_pdf_url TEXT,
uso_cfdi TEXT DEFAULT 'S01',
forma_pago TEXT DEFAULT '01',
metodo_pago TEXT DEFAULT 'PUE',
subtotal DECIMAL(10,2) NOT NULL DEFAULT 0,
tax_amount DECIMAL(10,2) NOT NULL DEFAULT 0,
total DECIMAL(10,2) NOT NULL DEFAULT 0,
payment_status TEXT NOT NULL DEFAULT 'pending' CHECK (payment_status IN ('pending','partial','paid')),
paid_amount DECIMAL(10,2) NOT NULL DEFAULT 0,
due_date DATE,
created_by UUID REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(clinic_id, invoice_number)
);
CREATE INDEX idx_invoices_patient ON invoices(patient_id);
CREATE INDEX idx_invoices_status ON invoices(clinic_id, payment_status);
CREATE TABLE invoice_items (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
invoice_id UUID NOT NULL REFERENCES invoices(id) ON DELETE CASCADE,
service_id UUID REFERENCES services_catalog(id),
product_id UUID,
description TEXT NOT NULL,
quantity DECIMAL(10,2) NOT NULL DEFAULT 1,
unit_price DECIMAL(10,2) NOT NULL DEFAULT 0,
tax_rate DECIMAL(4,2) NOT NULL DEFAULT 0.16,
total DECIMAL(10,2) NOT NULL DEFAULT 0
);
CREATE TABLE payments (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
clinic_id UUID NOT NULL REFERENCES clinics(id) ON DELETE CASCADE,
invoice_id UUID NOT NULL REFERENCES invoices(id) ON DELETE CASCADE,
amount DECIMAL(10,2) NOT NULL,
payment_method TEXT NOT NULL DEFAULT 'cash' CHECK (payment_method IN ('cash','card','transfer','other')),
reference TEXT,
received_by UUID REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
ALTER TABLE services_catalog ENABLE ROW LEVEL SECURITY;
CREATE POLICY "View clinic services" ON services_catalog FOR SELECT USING (clinic_id = auth.clinic_id());
CREATE POLICY "Manage clinic services" ON services_catalog FOR ALL USING (clinic_id = auth.clinic_id());
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;
CREATE POLICY "View clinic invoices" ON invoices FOR SELECT USING (clinic_id = auth.clinic_id());
CREATE POLICY "Insert clinic invoices" ON invoices FOR INSERT WITH CHECK (clinic_id = auth.clinic_id());
CREATE POLICY "Update clinic invoices" ON invoices FOR UPDATE USING (clinic_id = auth.clinic_id());
ALTER TABLE invoice_items ENABLE ROW LEVEL SECURITY;
CREATE POLICY "View invoice items" ON invoice_items FOR SELECT USING (EXISTS (SELECT 1 FROM invoices WHERE invoices.id = invoice_items.invoice_id AND invoices.clinic_id = auth.clinic_id()));
CREATE POLICY "Manage invoice items" ON invoice_items FOR ALL USING (EXISTS (SELECT 1 FROM invoices WHERE invoices.id = invoice_items.invoice_id AND invoices.clinic_id = auth.clinic_id()));
ALTER TABLE payments ENABLE ROW LEVEL SECURITY;
CREATE POLICY "View clinic payments" ON payments FOR SELECT USING (clinic_id = auth.clinic_id());
CREATE POLICY "Insert clinic payments" ON payments FOR INSERT WITH CHECK (clinic_id = auth.clinic_id());