Sistema Financiero uses a single-table architecture powered by Supabase (PostgreSQL). All financial transactions are stored in the transacciones table with Row Level Security (RLS) enabled for multi-tenant data isolation.
The core table that stores all income and expense transactions:
-- Table: transacciones (Stores all income and expenses)CREATE TABLE transacciones ( -- Primary Key id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), -- Core Transaction Fields fecha TIMESTAMP NOT NULL DEFAULT NOW(), tipo TEXT CHECK (tipo IN ('ingreso', 'gasto')) NOT NULL, monto NUMERIC(10, 2) NOT NULL CHECK (monto > 0), categoria TEXT NOT NULL, -- Optional Details concepto TEXT DEFAULT 'Transacción manual', descripcion TEXT, metodo_pago TEXT CHECK (metodo_pago IN ('Efectivo', 'Tarjeta', 'Transferencia')), registrado_por TEXT, foto_url TEXT, -- Metadata usuario_id UUID REFERENCES auth.users(id), created_at TIMESTAMP DEFAULT NOW());
-- Performance indexesCREATE INDEX idx_transacciones_fecha ON transacciones(fecha DESC);CREATE INDEX idx_transacciones_tipo ON transacciones(tipo);CREATE INDEX idx_transacciones_usuario ON transacciones(usuario_id);
1
Date Index
The idx_transacciones_fecha index enables fast date range queries for dashboard filters.
2
Type Index
The idx_transacciones_tipo index speeds up filtering by income/expense type.
3
User Index
The idx_transacciones_usuario index is critical for RLS policy enforcement.
-- Policy: Users can only see their own transactionsCREATE POLICY "Users can view own transactions" ON transacciones FOR SELECT USING (auth.uid() = usuario_id);CREATE POLICY "Users can insert own transactions" ON transacciones FOR INSERT WITH CHECK (auth.uid() = usuario_id);
How it works:
auth.uid() returns the authenticated user’s UUID
All SELECT queries automatically filter by usuario_id
Stores receipt/ticket images uploaded via OCR feature.
-- Create storage bucket (run in Supabase Dashboard)INSERT INTO storage.buckets (id, name, public)VALUES ('facturas', 'facturas', true);-- Allow authenticated users to uploadCREATE POLICY "Users can upload receipts" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'facturas' AND auth.role() = 'authenticated');-- Allow public read accessCREATE POLICY "Public read access" ON storage.objects FOR SELECT USING (bucket_id = 'facturas');