Initial commit — MarineMaintenance v1.0
Marine maintenance management: work orders with photos, ISM/SWP procedures, MSDS, inventory, RFQ/purchases, vessel history, bilingual PDF reports. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+424
@@ -0,0 +1,424 @@
|
||||
-- MARINE MAINTENANCE SYSTEM
|
||||
-- Database Schema v2.0
|
||||
|
||||
PRAGMA foreign_keys = ON;
|
||||
|
||||
-- COMPAÑÍAS
|
||||
CREATE TABLE IF NOT EXISTS companies (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
address TEXT,
|
||||
phone TEXT,
|
||||
email TEXT,
|
||||
website TEXT,
|
||||
logo_path TEXT,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- USUARIOS (roles: superadmin | admin | technician)
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
company_id INTEGER REFERENCES companies(id),
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
email TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
full_name TEXT,
|
||||
role TEXT NOT NULL DEFAULT 'technician',
|
||||
is_active INTEGER DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login TIMESTAMP
|
||||
);
|
||||
|
||||
-- EMBARCACIONES
|
||||
CREATE TABLE IF NOT EXISTS vessels (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
company_id INTEGER REFERENCES companies(id),
|
||||
name TEXT NOT NULL,
|
||||
registration TEXT,
|
||||
vessel_type TEXT,
|
||||
make TEXT,
|
||||
model TEXT,
|
||||
year INTEGER,
|
||||
length_ft REAL,
|
||||
flag TEXT,
|
||||
port_of_registry TEXT,
|
||||
engine_type TEXT,
|
||||
engine_hours REAL DEFAULT 0,
|
||||
owner_name TEXT,
|
||||
owner_phone TEXT,
|
||||
owner_email TEXT,
|
||||
captain_name TEXT,
|
||||
captain_phone TEXT,
|
||||
captain_email TEXT,
|
||||
notes TEXT,
|
||||
photo_path TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- EQUIPOS DE LA EMBARCACIÓN
|
||||
CREATE TABLE IF NOT EXISTS vessel_equipment (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
vessel_id INTEGER NOT NULL REFERENCES vessels(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
equipment_type TEXT,
|
||||
make TEXT,
|
||||
model TEXT,
|
||||
serial_number TEXT,
|
||||
year INTEGER,
|
||||
position TEXT,
|
||||
engine_hours REAL DEFAULT 0,
|
||||
last_service_date DATE,
|
||||
last_service_hours REAL,
|
||||
notes TEXT,
|
||||
is_active INTEGER DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- DOCUMENTOS ADJUNTOS (por embarcación / equipo)
|
||||
CREATE TABLE IF NOT EXISTS vessel_documents (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
vessel_id INTEGER NOT NULL REFERENCES vessels(id) ON DELETE CASCADE,
|
||||
equipment_id INTEGER REFERENCES vessel_equipment(id),
|
||||
doc_type TEXT NOT NULL DEFAULT 'other',
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
filename TEXT NOT NULL,
|
||||
original_filename TEXT,
|
||||
file_size INTEGER,
|
||||
uploaded_by TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- CATEGORÍAS DE REPUESTOS
|
||||
CREATE TABLE IF NOT EXISTS parts_categories (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT
|
||||
);
|
||||
|
||||
-- INVENTARIO
|
||||
CREATE TABLE IF NOT EXISTS parts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
company_id INTEGER REFERENCES companies(id),
|
||||
category_id INTEGER REFERENCES parts_categories(id),
|
||||
part_number TEXT,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
brand TEXT,
|
||||
location TEXT,
|
||||
quantity REAL DEFAULT 0,
|
||||
unit TEXT DEFAULT 'pcs',
|
||||
min_quantity REAL DEFAULT 0,
|
||||
cost_price REAL DEFAULT 0,
|
||||
sale_price REAL DEFAULT 0,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- PROVEEDORES
|
||||
CREATE TABLE IF NOT EXISTS suppliers (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
company_id INTEGER REFERENCES companies(id),
|
||||
name TEXT NOT NULL,
|
||||
contact_name TEXT,
|
||||
phone TEXT,
|
||||
email TEXT,
|
||||
address TEXT,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- COMPRAS
|
||||
CREATE TABLE IF NOT EXISTS purchases (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
company_id INTEGER REFERENCES companies(id),
|
||||
supplier_id INTEGER REFERENCES suppliers(id),
|
||||
vessel_id INTEGER REFERENCES vessels(id), -- embarcación destino
|
||||
work_order_id INTEGER REFERENCES work_orders(id), -- WO relacionada (opcional)
|
||||
purchase_number TEXT, -- número interno
|
||||
invoice_number TEXT, -- número factura proveedor
|
||||
purchase_date DATE NOT NULL,
|
||||
delivery_date DATE, -- fecha entrega esperada
|
||||
received_date DATE, -- fecha recibido real
|
||||
status TEXT DEFAULT 'requested', -- requested|approved|ordered|received|paid|cancelled
|
||||
requested_by TEXT,
|
||||
approved_by TEXT,
|
||||
payment_method TEXT, -- cash|transfer|check|credit
|
||||
payment_reference TEXT,
|
||||
invoice_photo TEXT, -- archivo adjunto factura
|
||||
total_amount REAL DEFAULT 0,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS purchase_items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
purchase_id INTEGER NOT NULL REFERENCES purchases(id) ON DELETE CASCADE,
|
||||
part_id INTEGER REFERENCES parts(id),
|
||||
description TEXT,
|
||||
part_number TEXT, -- número de parte fabricante
|
||||
quantity REAL NOT NULL,
|
||||
unit_cost REAL NOT NULL,
|
||||
total_cost REAL GENERATED ALWAYS AS (quantity * unit_cost) STORED,
|
||||
quantity_received REAL DEFAULT 0, -- lo que realmente llegó
|
||||
notes TEXT
|
||||
);
|
||||
|
||||
-- HISTORIAL DE MOVIMIENTOS DE INVENTARIO
|
||||
CREATE TABLE IF NOT EXISTS inventory_movements (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
part_id INTEGER NOT NULL REFERENCES parts(id),
|
||||
movement_type TEXT NOT NULL, -- in|out|adjustment
|
||||
quantity REAL NOT NULL, -- positivo=entrada, negativo=salida
|
||||
reference_type TEXT, -- purchase|work_order|adjustment
|
||||
reference_id INTEGER, -- id de la compra o WO
|
||||
vessel_id INTEGER REFERENCES vessels(id),
|
||||
notes TEXT,
|
||||
created_by TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ÓRDENES DE TRABAJO
|
||||
CREATE TABLE IF NOT EXISTS work_orders (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
vessel_id INTEGER NOT NULL REFERENCES vessels(id),
|
||||
equipment_id INTEGER REFERENCES vessel_equipment(id),
|
||||
order_number TEXT UNIQUE,
|
||||
status TEXT DEFAULT 'open',
|
||||
work_type TEXT,
|
||||
scope TEXT,
|
||||
description TEXT,
|
||||
root_cause TEXT,
|
||||
repairs_done TEXT,
|
||||
technician TEXT,
|
||||
start_date DATE,
|
||||
end_date DATE,
|
||||
engine_hours_start REAL,
|
||||
engine_hours_end REAL,
|
||||
labor_hours REAL DEFAULT 0,
|
||||
labor_rate REAL DEFAULT 0,
|
||||
billing_type TEXT DEFAULT 'labor_materials', -- lump_sum | labor_only | labor_materials
|
||||
total_parts_cost REAL DEFAULT 0,
|
||||
total_labor_cost REAL GENERATED ALWAYS AS (labor_hours * labor_rate) STORED,
|
||||
notes TEXT,
|
||||
invoice_exported INTEGER DEFAULT 0,
|
||||
system_id INTEGER REFERENCES systems(id),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS work_order_parts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
work_order_id INTEGER NOT NULL REFERENCES work_orders(id) ON DELETE CASCADE,
|
||||
part_id INTEGER REFERENCES parts(id),
|
||||
description TEXT,
|
||||
quantity REAL NOT NULL,
|
||||
unit_cost REAL NOT NULL,
|
||||
total_cost REAL GENERATED ALWAYS AS (quantity * unit_cost) STORED
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS work_order_photos (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
work_order_id INTEGER NOT NULL REFERENCES work_orders(id) ON DELETE CASCADE,
|
||||
photo_type TEXT NOT NULL,
|
||||
filename TEXT NOT NULL,
|
||||
caption TEXT,
|
||||
taken_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS maintenance_schedules (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
vessel_id INTEGER NOT NULL REFERENCES vessels(id),
|
||||
equipment_id INTEGER REFERENCES vessel_equipment(id),
|
||||
task_name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
frequency_days INTEGER,
|
||||
frequency_hours REAL,
|
||||
last_done_date DATE,
|
||||
last_done_hours REAL,
|
||||
next_due_date DATE,
|
||||
next_due_hours REAL,
|
||||
is_active INTEGER DEFAULT 1,
|
||||
notes TEXT
|
||||
);
|
||||
|
||||
-- SISTEMAS (predefinidos + personalizados)
|
||||
CREATE TABLE IF NOT EXISTS systems (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
company_id INTEGER REFERENCES companies(id),
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
is_default INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- EQUIPOS TRABAJADOS EN UNA ORDEN (múltiples por WO)
|
||||
CREATE TABLE IF NOT EXISTS work_order_equipment (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
work_order_id INTEGER NOT NULL REFERENCES work_orders(id) ON DELETE CASCADE,
|
||||
equipment_id INTEGER REFERENCES vessel_equipment(id),
|
||||
description TEXT,
|
||||
notes TEXT,
|
||||
labor_hours REAL DEFAULT 0,
|
||||
labor_rate REAL DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Sistemas predefinidos
|
||||
INSERT OR IGNORE INTO systems (id, name, is_default) VALUES
|
||||
(1, 'Propulsión', 1),
|
||||
(2, 'Generación', 1),
|
||||
(3, 'Navegación y Comunicaciones', 1),
|
||||
(4, 'Sistema Eléctrico', 1),
|
||||
(5, 'Baterías y Carga', 1),
|
||||
(6, 'Hidráulico', 1),
|
||||
(7, 'HVAC / Climatización', 1),
|
||||
(8, 'Plomería / Agua', 1),
|
||||
(9, 'Seguridad', 1),
|
||||
(10, 'Casco y Estructura', 1),
|
||||
(11, 'Otro', 1);
|
||||
|
||||
INSERT OR IGNORE INTO parts_categories (name) VALUES
|
||||
('Motor'),('Hidráulico'),('Eléctrico'),('Electrónico'),
|
||||
('Casco y cubierta'),('Plomería / Sistema de agua'),
|
||||
('HVAC'),('Seguridad'),('Varios');
|
||||
|
||||
-- CONFIGURACIÓN EMAIL POR COMPAÑÍA
|
||||
CREATE TABLE IF NOT EXISTS email_config (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
company_id INTEGER REFERENCES companies(id),
|
||||
smtp_host TEXT,
|
||||
smtp_port INTEGER DEFAULT 587,
|
||||
smtp_user TEXT,
|
||||
smtp_password TEXT,
|
||||
from_name TEXT,
|
||||
from_email TEXT,
|
||||
use_tls INTEGER DEFAULT 1,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- FIRMAS Y PDF GUARDADO en work_orders (columnas extra)
|
||||
-- Se agregan via ALTER TABLE al iniciar si no existen
|
||||
|
||||
-- LOG DE EMAILS ENVIADOS
|
||||
CREATE TABLE IF NOT EXISTS email_log (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
work_order_id INTEGER REFERENCES work_orders(id),
|
||||
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
to_email TEXT NOT NULL,
|
||||
to_name TEXT,
|
||||
subject TEXT,
|
||||
lang TEXT DEFAULT 'es',
|
||||
pdf_filename TEXT,
|
||||
status TEXT DEFAULT 'sent',
|
||||
error_msg TEXT,
|
||||
sent_by TEXT
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS po_items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
po_id INTEGER NOT NULL REFERENCES purchase_orders(id) ON DELETE CASCADE,
|
||||
rfq_item_id INTEGER REFERENCES rfq_items(id),
|
||||
description TEXT NOT NULL,
|
||||
quantity REAL DEFAULT 1,
|
||||
unit TEXT DEFAULT 'pcs',
|
||||
unit_cost REAL DEFAULT 0,
|
||||
total_cost REAL GENERATED ALWAYS AS (quantity * unit_cost) STORED,
|
||||
part_id INTEGER REFERENCES parts(id),
|
||||
received_qty REAL DEFAULT 0,
|
||||
notes TEXT
|
||||
);
|
||||
|
||||
-- MOVIMIENTOS DE INVENTARIO
|
||||
CREATE TABLE IF NOT EXISTS inventory_movements (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
part_id INTEGER REFERENCES parts(id),
|
||||
po_id INTEGER REFERENCES purchase_orders(id),
|
||||
work_order_id INTEGER REFERENCES work_orders(id),
|
||||
vessel_id INTEGER REFERENCES vessels(id),
|
||||
movement_type TEXT NOT NULL, -- in|out|assign_vessel|assign_wo
|
||||
quantity REAL NOT NULL,
|
||||
unit_cost REAL DEFAULT 0,
|
||||
notes TEXT,
|
||||
created_by TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ═══════════════════════════════════════════════════════
|
||||
-- MÓDULO ISM — PROCEDIMIENTOS DE TRABAJO SEGURO
|
||||
-- ═══════════════════════════════════════════════════════
|
||||
|
||||
-- PROCEDIMIENTOS MAESTRO
|
||||
CREATE TABLE IF NOT EXISTS swp (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
company_id INTEGER REFERENCES companies(id),
|
||||
code TEXT NOT NULL, -- SWP-001, SWP-002...
|
||||
title TEXT NOT NULL,
|
||||
category TEXT NOT NULL, -- electrical|mechanical|chemical|confined|height|welding|hull|other
|
||||
status TEXT DEFAULT 'active', -- active|archived
|
||||
current_version_id INTEGER, -- FK a swp_versions (se actualiza al aprobar)
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- VERSIONES DEL PROCEDIMIENTO
|
||||
CREATE TABLE IF NOT EXISTS swp_versions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
swp_id INTEGER NOT NULL REFERENCES swp(id) ON DELETE CASCADE,
|
||||
version TEXT NOT NULL, -- v1.0, v1.1, v2.0
|
||||
purpose TEXT,
|
||||
scope TEXT,
|
||||
hazards TEXT, -- JSON array
|
||||
ppe TEXT, -- JSON array
|
||||
tools TEXT, -- JSON array (herramientas y materiales)
|
||||
steps TEXT, -- JSON array numerado
|
||||
emergency TEXT,
|
||||
ref_standards TEXT, -- JSON array (ISM, SOLAS, OSHA...)
|
||||
status TEXT DEFAULT 'draft', -- draft|active|superseded|archived
|
||||
change_reason TEXT,
|
||||
diff_summary TEXT,
|
||||
created_by TEXT,
|
||||
approved_by TEXT,
|
||||
approved_at TIMESTAMP,
|
||||
effective_date DATE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- FIRMA DEL TÉCNICO AL LEER EL PROCEDIMIENTO EN UNA WO
|
||||
CREATE TABLE IF NOT EXISTS swp_acknowledgements (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
swp_id INTEGER NOT NULL REFERENCES swp(id),
|
||||
swp_version_id INTEGER NOT NULL REFERENCES swp_versions(id),
|
||||
work_order_id INTEGER NOT NULL REFERENCES work_orders(id),
|
||||
technician TEXT NOT NULL,
|
||||
signature TEXT, -- filename de firma
|
||||
acknowledged_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
notes TEXT
|
||||
);
|
||||
|
||||
-- MSDS — FICHAS TÉCNICAS DE SEGURIDAD
|
||||
CREATE TABLE IF NOT EXISTS msds (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
company_id INTEGER REFERENCES companies(id),
|
||||
part_id INTEGER REFERENCES parts(id), -- vinculada a inventario
|
||||
product_name TEXT NOT NULL,
|
||||
manufacturer TEXT,
|
||||
version TEXT DEFAULT 'v1.0',
|
||||
hazard_class TEXT, -- GHS class
|
||||
hazards TEXT, -- descripción de riesgos
|
||||
first_aid TEXT,
|
||||
ppe_required TEXT,
|
||||
handling TEXT,
|
||||
storage TEXT,
|
||||
spill_procedure TEXT,
|
||||
disposal TEXT,
|
||||
ref_standards TEXT,
|
||||
pdf_filename TEXT, -- PDF oficial del fabricante
|
||||
created_by TEXT,
|
||||
updated_by TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
Reference in New Issue
Block a user