647 lines
20 KiB
Markdown
647 lines
20 KiB
Markdown
# Schema: service_management
|
|
|
|
## Descripcion
|
|
|
|
Schema que gestiona las ordenes de servicio, diagnosticos, cotizaciones y todo el flujo operativo del taller.
|
|
|
|
**NOTA:** Este schema depende de `erp-core` para autenticacion y tenants. La columna `tenant_id` referencia a `core.tenants(id)`.
|
|
|
|
## Tablas
|
|
|
|
### service_orders
|
|
|
|
Ordenes de servicio (trabajo).
|
|
|
|
```sql
|
|
CREATE TABLE service_management.service_orders (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL, -- Referencia a core.tenants
|
|
|
|
-- Identificacion
|
|
order_number VARCHAR(20) NOT NULL,
|
|
|
|
-- Relaciones
|
|
customer_id UUID NOT NULL, -- Referencia a core.partners
|
|
vehicle_id UUID NOT NULL REFERENCES vehicle_management.vehicles(id),
|
|
quote_id UUID REFERENCES quotes(id),
|
|
|
|
-- Asignacion
|
|
assigned_to UUID, -- Referencia a core.users
|
|
bay_id UUID REFERENCES service_management.work_bays(id),
|
|
|
|
-- Estado
|
|
status VARCHAR(30) DEFAULT 'received'
|
|
CHECK (status IN ('received', 'diagnosed', 'quoted', 'approved',
|
|
'in_progress', 'waiting_parts', 'completed', 'delivered', 'cancelled')),
|
|
|
|
priority VARCHAR(20) DEFAULT 'normal'
|
|
CHECK (priority IN ('low', 'normal', 'high', 'urgent')),
|
|
|
|
-- Fechas
|
|
received_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
promised_at TIMESTAMP WITH TIME ZONE,
|
|
started_at TIMESTAMP WITH TIME ZONE,
|
|
completed_at TIMESTAMP WITH TIME ZONE,
|
|
delivered_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
-- Kilometraje
|
|
odometer_in INTEGER CHECK (odometer_in >= 0),
|
|
odometer_out INTEGER CHECK (odometer_out >= 0),
|
|
|
|
-- Sintomas reportados
|
|
customer_symptoms TEXT,
|
|
|
|
-- Totales
|
|
labor_total DECIMAL(12,2) DEFAULT 0 CHECK (labor_total >= 0),
|
|
parts_total DECIMAL(12,2) DEFAULT 0 CHECK (parts_total >= 0),
|
|
discount DECIMAL(12,2) DEFAULT 0 CHECK (discount >= 0),
|
|
tax DECIMAL(12,2) DEFAULT 0 CHECK (tax >= 0),
|
|
grand_total DECIMAL(12,2) DEFAULT 0 CHECK (grand_total >= 0),
|
|
|
|
-- Notas
|
|
internal_notes TEXT,
|
|
customer_notes TEXT,
|
|
|
|
-- Audit
|
|
created_by UUID,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
CONSTRAINT uq_order_number UNIQUE(tenant_id, order_number),
|
|
CONSTRAINT chk_odometer CHECK (odometer_out IS NULL OR odometer_out >= odometer_in)
|
|
);
|
|
|
|
CREATE INDEX idx_orders_tenant ON service_management.service_orders(tenant_id);
|
|
CREATE INDEX idx_orders_status ON service_management.service_orders(status);
|
|
CREATE INDEX idx_orders_vehicle ON service_management.service_orders(vehicle_id);
|
|
CREATE INDEX idx_orders_customer ON service_management.service_orders(customer_id);
|
|
CREATE INDEX idx_orders_date ON service_management.service_orders(received_at DESC);
|
|
|
|
-- RLS completo (SELECT, INSERT, UPDATE, DELETE)
|
|
SELECT create_tenant_rls_policies('service_management', 'service_orders');
|
|
```
|
|
|
|
### work_bays
|
|
|
|
Bahias de trabajo del taller.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.work_bays (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
name VARCHAR(50) NOT NULL,
|
|
description VARCHAR(200),
|
|
|
|
-- Tipo
|
|
bay_type VARCHAR(50)
|
|
CHECK (bay_type IN ('general', 'diagnostic', 'heavy_duty', 'quick_service')),
|
|
|
|
-- Estado actual (current_order_id es NULLABLE para evitar referencia circular)
|
|
status VARCHAR(20) DEFAULT 'available'
|
|
CHECK (status IN ('available', 'occupied', 'maintenance', 'reserved')),
|
|
current_order_id UUID REFERENCES service_management.service_orders(id),
|
|
|
|
-- Capacidad
|
|
max_weight DECIMAL(10,2) CHECK (max_weight > 0),
|
|
has_lift BOOLEAN DEFAULT FALSE,
|
|
has_pit BOOLEAN DEFAULT FALSE,
|
|
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_bays_tenant ON service_management.work_bays(tenant_id);
|
|
CREATE INDEX idx_bays_status ON service_management.work_bays(status);
|
|
|
|
SELECT create_tenant_rls_policies('service_management', 'work_bays');
|
|
```
|
|
|
|
### order_items
|
|
|
|
Lineas de trabajo/refacciones en la orden.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.order_items (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
order_id UUID NOT NULL REFERENCES service_orders(id) ON DELETE CASCADE,
|
|
|
|
-- Tipo
|
|
item_type VARCHAR(20) NOT NULL
|
|
CHECK (item_type IN ('service', 'part')),
|
|
|
|
-- Referencia
|
|
service_id UUID REFERENCES service_management.services(id),
|
|
part_id UUID REFERENCES parts_management.parts(id),
|
|
|
|
-- Descripcion (puede ser personalizada)
|
|
description VARCHAR(500) NOT NULL,
|
|
|
|
-- Cantidades y precios
|
|
quantity DECIMAL(10,3) DEFAULT 1 CHECK (quantity > 0),
|
|
unit_price DECIMAL(12,2) NOT NULL CHECK (unit_price >= 0),
|
|
discount_pct DECIMAL(5,2) DEFAULT 0 CHECK (discount_pct >= 0 AND discount_pct <= 100),
|
|
subtotal DECIMAL(12,2) NOT NULL CHECK (subtotal >= 0),
|
|
|
|
-- Estado
|
|
status VARCHAR(20) DEFAULT 'pending'
|
|
CHECK (status IN ('pending', 'in_progress', 'completed', 'cancelled')),
|
|
|
|
-- Para mano de obra
|
|
estimated_hours DECIMAL(5,2) CHECK (estimated_hours > 0),
|
|
actual_hours DECIMAL(5,2) CHECK (actual_hours >= 0),
|
|
|
|
-- Mecanico que realizo
|
|
performed_by UUID,
|
|
completed_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
-- Notas
|
|
notes TEXT,
|
|
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_order_items_order ON service_management.order_items(order_id);
|
|
CREATE INDEX idx_order_items_type ON service_management.order_items(item_type);
|
|
```
|
|
|
|
### order_status_history
|
|
|
|
Historial de cambios de estado.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.order_status_history (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
order_id UUID NOT NULL REFERENCES service_orders(id) ON DELETE CASCADE,
|
|
|
|
from_status VARCHAR(30),
|
|
to_status VARCHAR(30) NOT NULL,
|
|
|
|
changed_by UUID,
|
|
notes TEXT,
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_status_history_order ON service_management.order_status_history(order_id);
|
|
CREATE INDEX idx_status_history_date ON service_management.order_status_history(created_at DESC);
|
|
```
|
|
|
|
### services
|
|
|
|
Catalogo de servicios del taller.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.services (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
code VARCHAR(20) NOT NULL,
|
|
name VARCHAR(200) NOT NULL,
|
|
description TEXT,
|
|
|
|
-- Categoria
|
|
category_id UUID REFERENCES service_management.service_categories(id),
|
|
|
|
-- Precios
|
|
price DECIMAL(12,2) NOT NULL CHECK (price >= 0),
|
|
cost DECIMAL(12,2) CHECK (cost >= 0),
|
|
|
|
-- Tiempo estimado
|
|
estimated_hours DECIMAL(5,2) CHECK (estimated_hours > 0),
|
|
|
|
-- Estado
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
CONSTRAINT uq_service_code UNIQUE(tenant_id, code)
|
|
);
|
|
|
|
CREATE INDEX idx_services_tenant ON service_management.services(tenant_id);
|
|
CREATE INDEX idx_services_code ON service_management.services(code);
|
|
CREATE INDEX idx_services_category ON service_management.services(category_id);
|
|
|
|
SELECT create_tenant_rls_policies('service_management', 'services');
|
|
```
|
|
|
|
### service_categories
|
|
|
|
Categorias de servicios.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.service_categories (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
name VARCHAR(100) NOT NULL,
|
|
description VARCHAR(300),
|
|
color VARCHAR(7),
|
|
icon VARCHAR(50),
|
|
|
|
parent_id UUID REFERENCES service_management.service_categories(id),
|
|
sort_order INTEGER DEFAULT 0,
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_service_cat_tenant ON service_management.service_categories(tenant_id);
|
|
CREATE INDEX idx_service_cat_parent ON service_management.service_categories(parent_id);
|
|
|
|
SELECT create_tenant_rls_policies('service_management', 'service_categories');
|
|
```
|
|
|
|
### diagnostics
|
|
|
|
Diagnosticos realizados.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.diagnostics (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
order_id UUID REFERENCES service_orders(id),
|
|
vehicle_id UUID NOT NULL REFERENCES vehicle_management.vehicles(id),
|
|
|
|
-- Tipo
|
|
diagnostic_type VARCHAR(50) NOT NULL
|
|
CHECK (diagnostic_type IN ('scanner', 'injector_test', 'pump_test',
|
|
'compression', 'turbo_test', 'other')),
|
|
|
|
-- Equipo usado
|
|
equipment VARCHAR(200),
|
|
|
|
-- Fecha y tecnico
|
|
performed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
performed_by UUID,
|
|
|
|
-- Resultado general
|
|
result VARCHAR(20)
|
|
CHECK (result IN ('pass', 'fail', 'needs_attention')),
|
|
summary TEXT,
|
|
|
|
-- Datos crudos (JSON)
|
|
raw_data JSONB,
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_diagnostics_tenant ON service_management.diagnostics(tenant_id);
|
|
CREATE INDEX idx_diagnostics_vehicle ON service_management.diagnostics(vehicle_id);
|
|
CREATE INDEX idx_diagnostics_order ON service_management.diagnostics(order_id);
|
|
CREATE INDEX idx_diagnostics_type ON service_management.diagnostics(diagnostic_type);
|
|
|
|
SELECT create_tenant_rls_policies('service_management', 'diagnostics');
|
|
```
|
|
|
|
### diagnostic_items
|
|
|
|
Items/hallazgos del diagnostico.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.diagnostic_items (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
diagnostic_id UUID NOT NULL REFERENCES diagnostics(id) ON DELETE CASCADE,
|
|
|
|
-- Tipo de item
|
|
item_type VARCHAR(50) NOT NULL
|
|
CHECK (item_type IN ('dtc_code', 'test_result', 'measurement', 'observation')),
|
|
|
|
-- Para codigos DTC
|
|
code VARCHAR(20),
|
|
description VARCHAR(500),
|
|
severity VARCHAR(20)
|
|
CHECK (severity IN ('critical', 'warning', 'info')),
|
|
|
|
-- Para mediciones
|
|
parameter VARCHAR(100),
|
|
value DECIMAL(12,4),
|
|
unit VARCHAR(20),
|
|
min_ref DECIMAL(12,4),
|
|
max_ref DECIMAL(12,4),
|
|
status VARCHAR(20)
|
|
CHECK (status IN ('ok', 'warning', 'fail')),
|
|
|
|
-- Componente afectado
|
|
component VARCHAR(100),
|
|
cylinder INTEGER CHECK (cylinder > 0 AND cylinder <= 12),
|
|
|
|
notes TEXT,
|
|
sort_order INTEGER DEFAULT 0,
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_diag_items_diagnostic ON service_management.diagnostic_items(diagnostic_id);
|
|
CREATE INDEX idx_diag_items_type ON service_management.diagnostic_items(item_type);
|
|
```
|
|
|
|
### diagnostic_photos
|
|
|
|
Fotos de evidencia.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.diagnostic_photos (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
diagnostic_id UUID NOT NULL REFERENCES diagnostics(id) ON DELETE CASCADE,
|
|
|
|
url VARCHAR(500) NOT NULL,
|
|
thumbnail_url VARCHAR(500),
|
|
|
|
description VARCHAR(300),
|
|
category VARCHAR(50)
|
|
CHECK (category IN ('before', 'damage', 'process', 'after', 'other')),
|
|
|
|
file_size INTEGER CHECK (file_size > 0),
|
|
mime_type VARCHAR(50),
|
|
|
|
sort_order INTEGER DEFAULT 0,
|
|
uploaded_by UUID,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_diag_photos_diagnostic ON service_management.diagnostic_photos(diagnostic_id);
|
|
```
|
|
|
|
### diagnostic_recommendations
|
|
|
|
Recomendaciones de reparacion.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.diagnostic_recommendations (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
diagnostic_id UUID NOT NULL REFERENCES diagnostics(id) ON DELETE CASCADE,
|
|
|
|
-- Vinculo a hallazgo
|
|
diagnostic_item_id UUID REFERENCES diagnostic_items(id),
|
|
|
|
-- Descripcion
|
|
description TEXT NOT NULL,
|
|
|
|
-- Prioridad
|
|
priority VARCHAR(20) DEFAULT 'medium'
|
|
CHECK (priority IN ('critical', 'high', 'medium', 'low')),
|
|
|
|
urgency VARCHAR(20) DEFAULT 'soon'
|
|
CHECK (urgency IN ('immediate', 'soon', 'scheduled', 'preventive')),
|
|
|
|
-- Servicio sugerido
|
|
suggested_service_id UUID REFERENCES service_management.services(id),
|
|
estimated_cost DECIMAL(12,2) CHECK (estimated_cost >= 0),
|
|
|
|
-- Estado
|
|
status VARCHAR(20) DEFAULT 'pending'
|
|
CHECK (status IN ('pending', 'approved', 'declined', 'completed')),
|
|
|
|
notes TEXT,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_diag_rec_diagnostic ON service_management.diagnostic_recommendations(diagnostic_id);
|
|
CREATE INDEX idx_diag_rec_status ON service_management.diagnostic_recommendations(status);
|
|
```
|
|
|
|
### quotes
|
|
|
|
Cotizaciones.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.quotes (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Identificacion
|
|
quote_number VARCHAR(20) NOT NULL,
|
|
|
|
-- Relaciones
|
|
customer_id UUID NOT NULL,
|
|
vehicle_id UUID NOT NULL REFERENCES vehicle_management.vehicles(id),
|
|
diagnostic_id UUID REFERENCES diagnostics(id),
|
|
|
|
-- Estado
|
|
status VARCHAR(20) DEFAULT 'draft'
|
|
CHECK (status IN ('draft', 'sent', 'viewed', 'approved', 'rejected', 'expired', 'converted')),
|
|
|
|
-- Fechas
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
sent_at TIMESTAMP WITH TIME ZONE,
|
|
viewed_at TIMESTAMP WITH TIME ZONE,
|
|
responded_at TIMESTAMP WITH TIME ZONE,
|
|
expires_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
-- Totales
|
|
labor_total DECIMAL(12,2) DEFAULT 0 CHECK (labor_total >= 0),
|
|
parts_total DECIMAL(12,2) DEFAULT 0 CHECK (parts_total >= 0),
|
|
discount DECIMAL(12,2) DEFAULT 0 CHECK (discount >= 0),
|
|
discount_reason VARCHAR(200),
|
|
tax DECIMAL(12,2) DEFAULT 0 CHECK (tax >= 0),
|
|
grand_total DECIMAL(12,2) DEFAULT 0 CHECK (grand_total >= 0),
|
|
|
|
-- Vigencia
|
|
validity_days INTEGER DEFAULT 15 CHECK (validity_days > 0),
|
|
|
|
-- Terminos
|
|
terms TEXT,
|
|
notes TEXT,
|
|
|
|
-- Conversion
|
|
converted_order_id UUID REFERENCES service_orders(id),
|
|
|
|
-- Aprobacion digital
|
|
approved_by_name VARCHAR(200),
|
|
approval_signature TEXT,
|
|
approval_ip INET,
|
|
|
|
-- Audit
|
|
created_by UUID,
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
CONSTRAINT uq_quote_number UNIQUE(tenant_id, quote_number)
|
|
);
|
|
|
|
CREATE INDEX idx_quotes_tenant ON service_management.quotes(tenant_id);
|
|
CREATE INDEX idx_quotes_status ON service_management.quotes(status);
|
|
CREATE INDEX idx_quotes_customer ON service_management.quotes(customer_id);
|
|
CREATE INDEX idx_quotes_date ON service_management.quotes(created_at DESC);
|
|
|
|
SELECT create_tenant_rls_policies('service_management', 'quotes');
|
|
```
|
|
|
|
### quote_items
|
|
|
|
Lineas de cotizacion.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.quote_items (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
quote_id UUID NOT NULL REFERENCES quotes(id) ON DELETE CASCADE,
|
|
|
|
-- Tipo
|
|
item_type VARCHAR(20) NOT NULL
|
|
CHECK (item_type IN ('service', 'part')),
|
|
|
|
-- Referencia
|
|
service_id UUID REFERENCES service_management.services(id),
|
|
part_id UUID REFERENCES parts_management.parts(id),
|
|
|
|
description VARCHAR(500) NOT NULL,
|
|
|
|
quantity DECIMAL(10,3) DEFAULT 1 CHECK (quantity > 0),
|
|
unit_price DECIMAL(12,2) NOT NULL CHECK (unit_price >= 0),
|
|
discount_pct DECIMAL(5,2) DEFAULT 0 CHECK (discount_pct >= 0 AND discount_pct <= 100),
|
|
subtotal DECIMAL(12,2) NOT NULL CHECK (subtotal >= 0),
|
|
|
|
-- Para conversion parcial
|
|
is_approved BOOLEAN DEFAULT TRUE,
|
|
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_quote_items_quote ON service_management.quote_items(quote_id);
|
|
```
|
|
|
|
### quote_tracking
|
|
|
|
Tracking de cotizaciones enviadas.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.quote_tracking (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
quote_id UUID NOT NULL REFERENCES quotes(id) ON DELETE CASCADE,
|
|
|
|
event_type VARCHAR(30) NOT NULL
|
|
CHECK (event_type IN ('sent_email', 'sent_whatsapp', 'opened', 'link_clicked', 'approved', 'rejected')),
|
|
|
|
channel VARCHAR(20)
|
|
CHECK (channel IN ('email', 'whatsapp', 'link', 'sms')),
|
|
|
|
ip_address INET,
|
|
user_agent TEXT,
|
|
device_type VARCHAR(20),
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_quote_tracking_quote ON service_management.quote_tracking(quote_id);
|
|
CREATE INDEX idx_quote_tracking_date ON service_management.quote_tracking(created_at DESC);
|
|
```
|
|
|
|
### quote_followups
|
|
|
|
Seguimiento de cotizaciones.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.quote_followups (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
quote_id UUID NOT NULL REFERENCES quotes(id) ON DELETE CASCADE,
|
|
|
|
action VARCHAR(100) NOT NULL,
|
|
notes TEXT,
|
|
|
|
next_action VARCHAR(100),
|
|
next_action_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
created_by UUID,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_quote_followups_quote ON service_management.quote_followups(quote_id);
|
|
CREATE INDEX idx_quote_followups_next ON service_management.quote_followups(next_action_at);
|
|
```
|
|
|
|
### test_types
|
|
|
|
Tipos de prueba configurables.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.test_types (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID, -- NULL = tipo global del sistema
|
|
|
|
name VARCHAR(100) NOT NULL,
|
|
description TEXT,
|
|
|
|
component_type VARCHAR(50)
|
|
CHECK (component_type IN ('injector', 'pump', 'turbo', 'engine', 'electrical', 'other')),
|
|
|
|
is_system BOOLEAN DEFAULT FALSE,
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_test_types_tenant ON service_management.test_types(tenant_id);
|
|
CREATE INDEX idx_test_types_component ON service_management.test_types(component_type);
|
|
```
|
|
|
|
### test_parameters
|
|
|
|
Parametros de prueba.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.test_parameters (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
test_type_id UUID NOT NULL REFERENCES test_types(id) ON DELETE CASCADE,
|
|
|
|
name VARCHAR(100) NOT NULL,
|
|
unit VARCHAR(20),
|
|
data_type VARCHAR(20) DEFAULT 'numeric'
|
|
CHECK (data_type IN ('numeric', 'boolean', 'text', 'select')),
|
|
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_test_params_type ON service_management.test_parameters(test_type_id);
|
|
```
|
|
|
|
### parameter_references
|
|
|
|
Valores de referencia por motor.
|
|
|
|
```sql
|
|
CREATE TABLE service_management.parameter_references (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
parameter_id UUID NOT NULL REFERENCES test_parameters(id) ON DELETE CASCADE,
|
|
engine_model_id UUID REFERENCES vehicle_management.engine_catalog(id),
|
|
|
|
min_value DECIMAL(12,4),
|
|
max_value DECIMAL(12,4),
|
|
nominal_value DECIMAL(12,4),
|
|
tolerance_pct DECIMAL(5,2) CHECK (tolerance_pct >= 0),
|
|
|
|
source VARCHAR(200),
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
|
|
CONSTRAINT uq_param_engine UNIQUE(parameter_id, engine_model_id),
|
|
CONSTRAINT chk_min_max CHECK (max_value IS NULL OR min_value IS NULL OR max_value >= min_value)
|
|
);
|
|
|
|
CREATE INDEX idx_param_refs_param ON service_management.parameter_references(parameter_id);
|
|
CREATE INDEX idx_param_refs_engine ON service_management.parameter_references(engine_model_id);
|
|
```
|
|
|
|
## Relacion con erp-core
|
|
|
|
Este schema utiliza las siguientes referencias a erp-core:
|
|
|
|
| Columna | Referencia erp-core |
|
|
|---------|---------------------|
|
|
| `tenant_id` | `core.tenants(id)` |
|
|
| `customer_id` | `core.partners(id)` |
|
|
| `created_by`, `assigned_to`, `performed_by` | `auth.users(id)` |
|
|
|
|
---
|
|
|
|
**Creado por:** Requirements-Analyst
|
|
**Fecha:** 2025-12-06
|
|
**Actualizado:** 2025-12-06 (Correccion tenant_id, CHECK constraints, RLS completo)
|