Overview
Alternativa Verde uses PostgreSQL as its database system with a normalized relational schema. The database tracks collection centers, their members, generators (clients), vehicles, collection tickets, and material dispatches.Extensions
The schema uses the following PostgreSQL extensions:- pg_trgm: Enables trigram-based similarity searches for efficient ILIKE queries on text fields
Tables
collection_centers - Collection Center Information
collection_centers - Collection Center Information
Stores information about each collection center location.
Schema
Fields
- id: Unique identifier (format:
cc_[timestamp]) - name: Center name (e.g., “Centro de Acopio Puerto Ordaz”)
- state: State/province where center is located
- city: City location
- address: Full address
- is_active: Whether center is currently operational
- created_at: Record creation timestamp
Indexes
collection_center_members - Center Staff
collection_center_members - Center Staff
Stores team members working at each collection center.
Schema
Fields
- id: Unique identifier (format:
ccm_[timestamp]) - center_id: Foreign key to collection_centers
- full_name: Member’s full name
- cedula: National ID number
- phone: Contact phone number
- role: Job role (e.g., “Recolector”, “Jefe de Operaciones”)
- is_active: Whether member is currently active
- created_at: Record creation timestamp
Relationships
- Belongs to: collection_centers (CASCADE delete)
- Referenced by: tickets.collector_member_id
Indexes
app_configuration - Global Settings
app_configuration - Global Settings
Single-row configuration table for global application settings.
Schema
Fields
- id: Always 1 (enforced by CHECK constraint)
- collection_center_id: Currently active collection center
- updated_at: Last update timestamp
Design Note
This table is constrained to a single row (CHECK (id = 1)) to ensure only one active configuration exists. The initial row is inserted automatically:generators - Client Information
generators - Client Information
Stores information about generators (clients who provide used oil).
Schema
Fields
- id: Unique identifier (format:
gen_[timestamp]) - name: Business/generator name
- rif: Tax identification number (RIF)
- phone: Contact phone
- address: Physical address
- sector: Geographic sector/neighborhood
- collection_mode: Collection frequency (“Semanal”, “Quincenal”, “Mensual”, “Fortuito”)
- collection_center_id: Assigned collection center
- created_at: Record creation timestamp
Relationships
- Belongs to: collection_centers
- Referenced by: tickets.generator_id (CASCADE delete)
Indexes
vehicles - Collection Vehicles
vehicles - Collection Vehicles
Stores vehicle information used for material collection and transport.
Schema
Fields
- id: Unique identifier (format:
veh_[timestamp]) - plate: License plate number (UNIQUE constraint)
- brand: Vehicle brand/manufacturer
- model: Vehicle model
- owner: Vehicle owner name
- is_default: Whether this is the default vehicle for the center
- collection_center_id: Assigned collection center
- created_at: Record creation timestamp
Relationships
- Belongs to: collection_centers
- Referenced by: dispatches.vehicle_id
Indexes
tickets - Collection Tickets
tickets - Collection Tickets
Records individual collection events (material intake from generators).
Schema
Fields
- id: Unique identifier (format:
t_[timestamp]) - ticket_number: Human-readable ticket number (format:
AV-[STATE]-[YEAR]-[SEQUENCE]) - date: Collection date (stored as TEXT in DD/MM/YYYY or YYYY-MM-DD format)
- generator_id: Foreign key to generators
- generator_name: Denormalized generator name for reporting
- material_type: Type of material collected (e.g., “Aceite Vegetal Usado (AVU) - No Peligroso”)
- quantity: Quantity in liters
- material_state: State of material (“Bruto”, “Filtrado”)
- collection_center_id: Foreign key to collection center
- collector_member_id: Foreign key to collector member
- collector_name: Denormalized collector name
- vehicle_plate: Vehicle used for collection
- created_at: Record creation timestamp
Relationships
- Belongs to: generators (CASCADE delete), collection_centers, collection_center_members
Indexes
dispatches - Material Dispatches
dispatches - Material Dispatches
Records outbound shipments of collected materials to processing facilities.
Schema
Fields
- id: Unique identifier (format:
disp_[timestamp]) - date: Dispatch date (TEXT format: DD/MM/YYYY or YYYY-MM-DD)
- description: Material description
- presentation: Presentation format (e.g., “Litros”)
- dispatched_quantity: Quantity dispatched
- destination_name: Destination facility name
- destination_rif: Destination tax ID
- destination_address: Destination address
- vehicle_id: Foreign key to vehicles
- driver_name: Driver’s name
- driver_id: Driver’s ID number
- minec_guide_number: MINEC guide number (regulatory document)
- collection_center_id: Originating collection center
- created_at: Record creation timestamp
Relationships
- Belongs to: vehicles, collection_centers
Indexes
Performance Optimizations
Standard Indexes
The schema includes strategic B-tree indexes for:- Foreign key relationships (faster JOINs)
- Frequently queried fields (name, date, created_at)
- Boolean flags (is_default, is_active)
Trigram Indexes
GIN trigram indexes enable efficient partial string matching:ILIKE '%search%' queries for ticket and generator searches.
Migrations
The schema file (db/schema.sql) is consolidated and includes all migrations. To apply the schema:
Loading Seed Data
After creating the schema, load initial data:Data Integrity
Referential Integrity
- CASCADE: When a generator is deleted, all its tickets are also deleted
- SET NULL: When a collection center is deleted, related records preserve data but clear the foreign key
Constraints
- UNIQUE: Vehicle plates and ticket numbers must be unique
- CHECK: app_configuration enforces single-row constraint
- NOT NULL: Critical fields like names and dates are required
Query Patterns
Date Handling
Dates are stored as TEXT but queried with PostgreSQL date functions:Ticket Numbering
Ticket numbers follow the format:AV-[STATE_CODE]-[YEAR]-[SEQUENCE]
- STATE_CODE: First 3 letters of the state name (normalized)
- YEAR: Extracted from ticket date
- SEQUENCE: Zero-padded 4-digit number
AV-BOL-2026-0001, AV-MER-2026-0023