Files
AR-VMS-Seaman/VMS_Sailor_v2_Parte_06_Sprints_y_reglas.md
T
alro65 deb04c9315 sprint-0: fundaciones VMS-Sailor
Sprint 0 completo del producto VMS-Sailor (Vessel Management System
integrado para buques 30-40m). Brief de referencia en
VMS_Sailor_v2_Parte_*.md (intacto).

Core (vmssailor.core, 95.17% coverage, 99 tests verde):
- ShipCoord: sistema naval x_pp/y_cl/z_bl frozen
- Vessel, Deck, Bulkhead
- Equipment, EquipmentModel, Sensor, EquipmentSpec
- Tag, AlarmConfig, TagBinding, Scaling
- CardInstance, Bus, Topology con validacion 21 puntos I/O AR-NMEA-IO-v1.0
- Alarm, PermissiveRule, Condition
- Project agregado raiz con validacion cross-entity
- Persistencia portable .vmsproj (SQLite) con roundtrip verificable

Biblioteca curada seed (vmssailor.library):
- systems_catalog.json completo (catalogo maestro Parte 1 sec 7)
- 2 vessels: Sunseeker 76, Ferretti 850
- 2 motores: MTU 12V 2000 M96, Volvo D13-900
- 1 genset: Northern Lights M65C13
- yacht_motor_planeo.yaml (reglas heuristicas)
- TODO marcado data_source=seed_estimate - requiere validacion datasheets

Tools:
- vms-validate-library: CLI valida biblioteca completa
- vms-generate-test-project: CLI demo + verificacion roundtrip persistencia

Design System + 8 mockups HTML estaticos:
- docs/design_system.md (paleta Deep Ocean, gradientes, typography, motion)
- docs/brand/ (logo + variantes SVG)
- docs/mockups/splash, studio_main, runtime_overview,
  runtime_mimic_fuel (P&ID animado), runtime_alarms, runtime_trim (panel
  estrella con horizonte artificial), mobile_overview, mobile_trim
- docs/mockups/index.html (galeria)

Firmware (Sprint 12+ implementacion):
- firmware/ar_nmea_io_v1/src/config/pinout.h con macros GPIO

Decisiones autonomas documentadas en docs/decisions_sprint0.md.

Stack: Python 3.11 + uv + Pydantic v2 + SQLite stdlib + hatchling +
pytest 9 + ruff + mypy. Sin PySide6, FastAPI, Flutter ni firmware
funcional (entran en sprints siguientes).

Criterio de aceptacion Sprint 0: cumplido.
- uv sync: OK
- pytest: 99/99 verde
- cov vmssailor.core: 95.17% (objetivo >=80%)
- ruff: clean
- vms-validate-library: OK
- vms-generate-test-project: INTEGRIDAD OK

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 07:26:06 -04:00

19 KiB

VMS-Sailor · Brief para Claude Code · Parte 6 de 6

Plan de sprints completo, modelo de datos core, reglas de oro

Esta es la última parte. Asume que ya leíste Partes 1-5.


1. Ubicación del proyecto

Todo va en D:/Proyectos Software/VMS-Sailor/.

  • Si la carpeta no existe, créala.
  • Si existe vacía, úsala.
  • Si tiene contenido previo, pregúntame antes de tocar nada.
  • Git desde el primer commit. Cada sprint termina con commit etiquetado (sprint-0, sprint-1, etc.).

.gitignore debe incluir:

__pycache__/
*.pyc
.venv/
dist/
build/
*.egg-info/
.idea/
.vscode/
logs/
*.vmspack
*.vmsdelta
licenses/local/
mobile/build/
firmware/.pio/
firmware/.vscode/
*.bin
historian.duckdb
secrets/

2. Estructura raíz del repositorio

D:/Proyectos Software/VMS-Sailor/
├── README.md
├── LICENSE.txt
├── CHANGELOG.md
├── pyproject.toml
├── requirements.txt
├── requirements-dev.txt
├── .gitignore
│
├── studio_main.py                    # Entry point del Studio
├── runtime_server_main.py            # Entry point del servicio Windows
├── runtime_client_main.py            # Entry point del cliente desktop
│
├── vmssailor/                        # Código Python compartido
│   ├── __init__.py
│   ├── version.py
│   ├── core/                         # Modelo de datos compartido (CRÍTICO)
│   ├── library/                      # Biblioteca curada (solo Studio)
│   ├── studio/                       # App Studio (Parte 2)
│   ├── runtime/                      # App Runtime (Parte 3)
│   ├── shared/                       # Utilidades compartidas
│   └── tests/                        # Tests Python
│
├── firmware/                         # Firmware ESP32 (Parte 4)
│   └── ar_nmea_io_v1/
│
├── mobile/                           # App Flutter (Parte 5)
│   └── lib/
│
├── docs/                             # Documentación técnica
├── installer/                        # WiX MSI scripts
├── tools/                            # Scripts auxiliares
└── projects/                         # Proyectos de buques específicos (git-ignored excepto seed)

3. Modelo de datos core (Sprint 0)

Este es el corazón del sistema. Lo construimos en Sprint 0 antes de cualquier UI.

Coordenadas navales

from dataclasses import dataclass

@dataclass(frozen=True)
class ShipCoord:
    """Coordenadas en el marco del buque.

    x_pp : metros desde Perpendicular de Popa (Pp), positivo hacia proa.
    y_cl : metros desde Línea de Crujía (CL), positivo a estribor, negativo a babor.
    z_bl : metros desde Línea Base (BL), positivo hacia arriba.
    """
    x_pp: float
    y_cl: float
    z_bl: float

Entidades principales

Vessel
 └── Deck[]                  Cubiertas con polígono 2D vista planta + altura

Project (instancia de un buque específico para un cliente)
 ├── vessel_ref              referencia a Vessel de biblioteca o importado
 ├── name                    "M/Y Aurora"
 ├── customer
 ├── systems_enabled         List[SystemId]
 ├── equipment               List[Equipment]
 ├── tags                    List[Tag]
 ├── cards                   List[CardInstance]
 └── topology                Topology

Equipment
 ├── id
 ├── model_ref               referencia a EquipmentModel
 ├── tag_prefix              "ME_PORT", "GEN_1"
 ├── location: ShipCoord
 ├── deck_id
 └── system_id

EquipmentModel (en biblioteca)
 ├── id                      "mtu_12v_2000_m96"
 ├── manufacturer            "MTU"
 ├── model_name              "12V 2000 M96"
 ├── category                ENGINE_MAIN | GENSET | PUMP | ...
 ├── specs                   potencia, RPM nominales, peso, dimensiones
 └── default_sensors         List[Sensor]

Sensor
 ├── id
 ├── name                    "Oil Pressure"
 ├── type                    TEMPERATURE | PRESSURE | LEVEL | RPM | VOLTAGE | ...
 ├── unit_si                 "bar", "C", "rpm"
 ├── range_normal            (min, max)
 ├── alarm_low               (value, priority)
 ├── alarm_high              (value, priority)
 └── default_signal_type     RTD_PT100 | 4-20MA | 0-10V | PULSE | ...

Tag (punto I/O concreto)
 ├── id                      autogenerado "ME_PORT.OIL_PRESS"
 ├── description
 ├── value                   float | bool | str
 ├── quality                 GOOD | BAD | UNCERTAIN
 ├── timestamp
 ├── unit_si
 ├── range_normal
 ├── alarms                  List[AlarmConfig]
 ├── controllable            bool
 ├── control_mode            MONITOR | MANUAL | AUTO | FUTURE
 ├── authority_required      BRIDGE | ENGINE | EITHER
 ├── protocol                MODBUS_RTU | MODBUS_TCP | NMEA2000 | J1939
 ├── address                 dirección Modbus o ID CAN
 ├── scaling                 raw → engineering
 └── physical_binding        TagBinding

TagBinding (cómo un tag se mapea a un canal físico)
 ├── card_id
 ├── channel_type            AI | DI | DO | RPM
 ├── channel_number          1-10 (o 1-5 para DI, 1-4 para AI)
 ├── signal_type             4-20MA | 0-10V | RTD_PT100 | RELAY_NO | ...
 ├── scaling                 raw_min, raw_max, eng_min, eng_max
 ├── filter                  NONE | MOVING_AVG | MEDIAN | DEADBAND | RATE_LIMIT
 └── update_rate_ms

CardInstance (una tarjeta AR-NMEA-IO en un proyecto concreto)
 ├── id                      "card_001"
 ├── serial_number           "ARC-2026-00153"
 ├── slot_number             1-16 (dipswitch físico)
 ├── physical_location       "Sala máquinas, panel principal"
 ├── ship_coord              ShipCoord aproximada
 ├── bus_role                MODBUS_SLAVE | MODBUS_MASTER | NMEA2000_NODE | DUAL | BRIDGE
 ├── modbus_address          1-247 si esclava
 ├── bus_segment             "bus_main"
 └── firmware_version

Topology (la red completa del proyecto)
 ├── buses                   List[Bus]
 └── cards                   List[CardInstance]

Bus
 ├── id                      "bus_main"
 ├── protocol                MODBUS_RTU | NMEA2000
 ├── physical_port           "COM3" | "USB-CAN0"
 ├── baud_rate
 ├── parity, stop_bits       (Modbus RTU)
 └── termination

Alarm (instancia activa)
 ├── id
 ├── tag_id
 ├── priority                EMERGENCY | HIGH | LOW | INFO
 ├── state                   ACTIVE | ACK | CLEARED
 ├── timestamp_active
 ├── timestamp_ack
 ├── timestamp_cleared
 ├── acknowledged_by
 └── message

PermissiveRule
 ├── action_id               "START_ME_PORT"
 ├── conditions              List[Condition]
 └── on_fail_message

Condition
 ├── tag_ref
 ├── operator                EQ | NEQ | GT | LT | BETWEEN | IS_TRUE | IS_FALSE
 ├── threshold
 ├── severity                FAIL | WARNING
 └── message_on_fail

Persistencia

  • Biblioteca curada: archivos JSON/YAML versionados en git
  • Proyecto en Studio: archivo único .vmsproj (SQLite portable)
  • Paquete distribuible: .vmspack = ZIP firmado con manifest.json + project.db + mímicos + firmware + assets
  • Runtime a bordo: descomprime .vmspack en %PROGRAMDATA%/VMS-Sailor/project/
  • Capas: cada capa es un .vmsdelta separado en %PROGRAMDATA%/VMS-Sailor/layers/
  • Historian: DuckDB en %PROGRAMDATA%/VMS-Sailor/historian.duckdb
  • Auditoría: SQLite append-only en %PROGRAMDATA%/VMS-Sailor/audit.db

4. Plan completo de sprints

Sprint 0 — Fundaciones (2-3 semanas)

Objetivo: estructura completa del proyecto + modelo de datos + biblioteca seed mínima.

Entregables:

  • Repositorio Git inicializado con la estructura completa (stubs creados)
  • pyproject.toml, requirements.txt, .gitignore
  • Módulo vmssailor.core completo con tests (cobertura ≥80%)
  • Persistencia: serialización/deserialización a .vmsproj
  • Biblioteca seed mínima:
    • 2 yates motor (Sunseeker 76, Ferretti 850)
    • 2 motores principales (MTU 12V 2000 M96, Volvo D13 900hp)
    • 1 genset (Northern Lights M65C13)
    • 1 archivo de reglas (yacht_motor_planeo.yaml)
    • systems_catalog.json completo (todos los sistemas de la Parte 1)
  • Validador de biblioteca: tools/validate_library.py
  • Tests unitarios para core (cobertura ≥80%)
  • README con setup
  • Pinout inicial del firmware en firmware/ar_nmea_io_v1/src/config/pinout.h (sin firmware funcional aún)

Criterio de aceptación: pytest pasa todo, validate_library.py pasa todo, se puede crear/guardar/leer un Project programáticamente desde script.

Sprint 1 — Studio shell + wizard básico (3-4 semanas)

  • QApplication del Studio con ventana principal y menú
  • Wizard pasos 1-4 funcional (tipo, plantilla, dimensiones, sistemas)
  • Visualización de silueta en QGraphicsView con sistema de coordenadas naval (rejilla en metros desde Pp)
  • Sin paso 5-8 aún (mocked)
  • Se puede crear proyecto desde wizard y guardarlo como .vmsproj

Sprint 2 — Wizard completo + editor de equipos (3-4 semanas)

  • Pasos 5-8 del wizard: motor de reglas YAML, propuesta de equipos, refinamiento manual con drag-and-drop, paso 7 de topología
  • Editor de equipos: CRUD, vista planta, vista lista
  • Más buques en biblioteca: 5-7 yates motor + 2 pesqueros + 1 patrullero
  • Más equipos en biblioteca: 10+ motores, 6+ gensets, bombas básicas

Sprint 3 — Editor de mímicos + tags + alarmas (3-4 semanas)

  • Editor visual de mímicos por sistema (QGraphicsView con símbolos arrastrables)
  • Editor de tags: tabla con filtros, edición de direcciones, escalado, control_mode
  • Editor de alarmas: límites, prioridades, histéresis, mensajes
  • Símbolos básicos: motor, bomba, válvula, tanque, sensor, indicador, línea

Sprint 4 — Runtime servidor base (4-5 semanas)

  • Servicio Windows operativo (pywin32) arrancando al boot
  • Driver Modbus TCP funcional (pymodbus)
  • Driver Modbus RTU funcional
  • tag_store en memoria con pub/sub
  • Historian básico DuckDB con retención configurable
  • Alarm engine con evaluación de límites, prioridades, ack
  • API REST/WebSocket básica
  • Simulador del Studio que inyecta valores en servidor de pruebas

Sprint 5 — NMEA 2000 + Log Book básico (3-4 semanas)

  • Driver NMEA 2000 (CAN) suscribiendo a PGNs configurados
  • Log Book básico:
    • Auto-detección arranque/parada motores
    • Snapshots periódicos cada 15 min
    • Registro de alarmas con ack
    • Entradas manuales
    • Firma digital inmutable
  • Cliente desktop básico (login + overview + lista de sistemas)

Sprint 6 — Cliente desktop completo (3-4 semanas)

  • Renderizado completo de mímicos desde .vmspack
  • Panel de alarmas viviente con ack
  • Trends básicos (gráficas tiempo real con fl_chart Python equivalente: pyqtgraph)
  • Login con tres perfiles
  • Permisos por rol
  • Vista de logbook
  • Vista de soporte y auditoría (Admin solo)

Sprint 7 — Empaquetador + activación + MSI (3 semanas)

  • package_builder genera .vmspack desde proyecto del Studio
  • delta_builder genera .vmsdelta
  • hwid_binder liga paquete a HWID destino
  • Activación online inicial del Runtime
  • WiX scripts para generar instalador MSI Windows con servicio
  • Activación del Studio (protegerlo a mi PC)

Sprint 8 — Permissive + Authority + Stability (3-4 semanas)

  • Permissive engine completo con todas las pre-condiciones
  • Editor de permissives en Studio
  • Authority manager: transferencia bilateral puente↔máquinas
  • Override de emergencia (E-stop)
  • Stability monitor con los 3 niveles + envelope + modo manual owner
  • UI de autoridad y stability en clientes desktop

Sprint 9 — Layer Config Engine (3 semanas)

  • Carga de capas en orden al boot
  • Aplicación de deltas firmados con verificación criptográfica
  • Snapshots automáticos antes de aplicar
  • Rollback granular accesible al owner
  • Schema validation entre versiones
  • UI de gestión de actualizaciones en cliente desktop (orden de trabajo + disponibilidad)

Sprint 10 — Telemetría + VPN + auditoría (2-3 semanas)

  • Telemetría de salud transparente (visible al owner, pausable)
  • Soporte WireGuard externo (cliente VPN en Runtime)
  • Endpoints administrativos solo desde IP del túnel
  • Auditoría completa de sesiones VPN
  • Vista de "Soporte y Auditoría" en cliente

Sprint 11 — VMS-Sailor Mobile (Flutter) (4-5 semanas)

  • Setup proyecto Flutter
  • Enrollment flow con QR
  • Login + TOTP + biométrico
  • Cliente WebSocket + REST
  • Pantallas: Overview, Lista sistemas, Mímico, Alarmas con notificaciones
  • Panel Trim y Maniobra destacado
  • Build iOS + Android

Sprint 12 — Firmware ESP32 base (4 semanas)

  • Setup PlatformIO o ESP-IDF
  • Modbus RTU esclava funcional
  • Discovery broadcast + config push desde VMS
  • Lectura de 5 DI + 4 AI con oversampling
  • Comando de 10 DO
  • Lectura de RPM
  • Filtros locales (moving average, median, deadband)
  • Tests con simulador y banco de pruebas

Sprint 13 — Firmware NMEA 2000 + J1939 (3 semanas)

  • Stack NMEA 2000 funcional
  • Publicación de PGNs estándar (127488, 127489, 127505, 127508)
  • Listener J1939 para motores que hablan ese protocolo
  • Modo dual (Modbus + NMEA 2000 simultáneo)

Sprint 14 — OTA + permissives locales + alarmas locales (3 semanas)

  • Cliente OTA seguro con verificación de firma
  • Rollback automático si firmware nuevo falla
  • Permissives locales críticos (E-stop) ejecutándose en la tarjeta
  • Alarmas locales con umbrales
  • Health reporter cada 60s

Sprint 15 — Pruebas integradas + hardening (3 semanas)

  • Pruebas de integración VMS + tarjetas reales
  • Pruebas de stress (alta carga de tags, alarmas masivas)
  • Pruebas de fallo (cable cortado, tarjeta sin energía, bus colgado)
  • Watchdog y recovery automático
  • Documentación de operador y mantenimiento

Sprint 16+ — Refinamientos y extensiones

  • Log Book regulatorio completo (MARPOL, IMO)
  • Integración Seakeeper, Quick MC², CMC stabilizers
  • Cotizador de expansiones
  • Generador paramétrico de silueta
  • Plantillas adicionales (offshore support, ferries más grandes)
  • Edge cases y polishing
  • Manuales de usuario completos

5. Reglas de oro (recordatorio)

  1. Antes de cada sprint, me presentas plan detallado de lo que vas a hacer y esperas mi OK. No improvises features.

  2. Cada cambio importante se discute primero en chat. Yo decido alcance.

  3. Tests obligatorios para todo lo que toca core y runtime/server. UI más relajada pero pytest-qt en flujos críticos. Firmware: Unity + PlatformIO test runner. Mobile: tests de widget Flutter.

  4. No agregues dependencias sin preguntarme primero.

  5. Mantén consistencia con mis otras apps (AR ShipDesign, AR-ElecArrangement, AR-StabCol): misma filosofía UX, mismo idioma por defecto (español), mismo manejo de coordenadas navales.

  6. Documenta normativa cuando implementes algo regulado:

    • IEC 60092-504 (electrical installations in ships - automation)
    • IACS UR E22 (computer-based systems)
    • ABYC E-11 (electrical)
    • NMEA 2000 (protocolo, PGNs)
    • SAE J1939 (CAN motores)
    • IMO MARPOL/SOLAS (log book — sprint 16+)
  7. Sin red de salida en Runtime salvo:

    • Activación inicial de licencia (Studio → mi servidor)
    • Túnel VPN administrativa (cliente WireGuard externo)
    • Telemetría técnica solo si el owner la habilita

    Sin telemetría implícita NUNCA.

  8. La biblioteca curada es ORO. Cualquier cambio en formato de archivos de biblioteca requiere migración para los proyectos existentes.

  9. El Runtime debe ser inmutable para el cliente. El cliente no puede editar tags, alarmas, mímicos, topología. Solo opera lo que el Studio le entregó vía paquetes y deltas firmados.

  10. Auditoría siempre activa en Runtime:

    • Cada ack de alarma
    • Cada solicitud de autoridad
    • Cada override de permissive
    • Cada conexión VPN mía con timestamps y endpoints accedidos
    • Cada aplicación de delta
    • Cada rollback
    • Cada enrolamiento/revocación de dispositivo móvil
  11. Coordenadas navales consistentes en TODO el código: ShipCoord siempre, conversión a pantalla solo en renderers.

  12. Unidades SI internas siempre: m, kg, Pa, °C, s. Conversión a imperial solo en UI cuando el usuario lo pida.

  13. Idioma: español por defecto, inglés como segundo. Strings en vmssailor/i18n/.

  14. AR-ECDIS es producto separado, no se desarrolla en este repositorio. Solo se asume que publica al backbone NMEA 2000 datos de navegación y actitud (PGN 127257) que el VMS-Sailor consume.

  15. Firmware y software van juntos. El mismo .vmspack que configura el Runtime incluye los binarios de firmware para las tarjetas del proyecto. Versionados consistentemente.


6. Cómo proceder ahora

Paso 1. Confirma que entendiste el alcance global de las 6 partes. Pregunta cualquier duda ANTES de tocar código.

Paso 2. Verifica si existe D:/Proyectos Software/VMS-Sailor/. Si está vacía, OK. Si tiene contenido, pregúntame.

Paso 3. Presenta tu plan detallado del Sprint 0: lista de archivos que vas a crear, librerías que vas a usar, tests que vas a escribir. Espera mi OK.

Paso 4. Cuando dé OK, ejecutas el Sprint 0 completo. Al final me presentas:

  • Repositorio completo con commit sprint-0
  • Resultado de pytest (todo en verde)
  • Resultado de validate_library.py (todo en verde)
  • Script de demo tools/generate_test_project.py que crea proyecto de prueba, lo guarda como .vmsproj y lo lee de vuelta para verificar integridad

Paso 5. Yo reviso, doy feedback, y cuando apruebo, taggeas sprint-0-approved y pasamos al Sprint 1.


7. Información adicional

  • Mi código LiveCode original de VMS-Sailor: NO TENGO. Construimos desde cero.
  • Capturas de pantalla de mímicos comerciales (Kongsberg K-Chief, Praxis Mega-Guard, Wärtsilä NACOS) como referencia visual: te los pasaré en mensajes posteriores si hace falta.
  • El servidor de licencias para activación es proyecto APARTE que no se construye aquí; solo el cliente de activación dentro del Runtime y dentro del Studio.
  • WireGuard se gestiona externamente; solo helpers en Runtime, no embebido.
  • Cualquier feature que se te ocurra que NO esté en estas 6 partes, lo discutes conmigo antes.
  • El hardware AR-NMEA-IO-v1.0 ya está diseñado (PCB esquemático en archivos del proyecto), no se modifica en este desarrollo. El firmware sí lo escribimos desde cero.

Fin del brief completo (Partes 1-6).

Comienza confirmando que entendiste el alcance global, y luego preséntame tu plan del Sprint 0.