DKV Pet Flows — Backend Implementation Plan¶
Fecha: 2026-03-25 · Rol: Project Manager
Scope: BACKEND ONLY — Frontend cerrado (flows UI library en desarrollo separado)
Fuente de verdad: dkv-pet-cloud (Health Connect = futurible)
Posicionamiento: Capa de Customer Engagement sobre Health Connect
Decisión de Alcance¶
[!IMPORTANT] Frontend CERRADO para esta conversación. La librería UI core para flows se desarrolla en paralelo.
Un prompt self-contained ha sido generado endocs/prompts/frontend_flows_handoff.mdpara retomar el frontend cuando corresponda.
Esta conversación se centra EXCLUSIVAMENTE en backend: API, persistencia, motor de ejecución, canales, e IA.
Arquitectura Backend (Critical Path)¶
graph TD
subgraph "S0 — Modelo de Datos"
A["☕ Java Records + DTOs<br/>Flow, Node, Edge, Execution"]
B["🗃️ Flow Model JSON Schema<br/>Contrato FE↔BE"]
end
subgraph "S1 — API + Persistencia"
C["🏗️ Quarkus REST API<br/>CRUD /api/flows"]
D["💾 PostgreSQL Schema<br/>flow_definition + JSONB"]
E["✅ Flow Validation<br/>Reglas de nodos y conexiones"]
end
subgraph "S2 — Motor de Ejecución"
F["▶️ Dapr Workflow Engine<br/>Interpreta flow → actividades"]
G["⚡ Trigger Nodes<br/>Webhook, Cron, API Event"]
H["🔍 Logic Nodes<br/>If/Else, Wait, Router"]
end
subgraph "S3 — Canales de Comunicación"
I["📲 Push (Gorush)<br/>APNs + FCM"]
J["✉️ Email (Dapr Binding)"]
K["💬 SMS (Dapr Binding)"]
end
subgraph "S4 — Inteligencia + Monitor"
L["🤖 AI Nodes<br/>LangChain4j"]
M["📊 SSE Monitor<br/>Execution real-time"]
end
A --> C & D & E
B --> C
C & D --> F
F --> G & H
G & H --> I & J & K
F --> L
F --> M
Sprint Breakdown — Backend Only¶
🏁 S0 — Modelo de Datos y Contrato (1 semana)¶
Sprint Goal: Definir el contrato de datos Flow↔API que desbloquea toda la implementación backend.
| # | Story | SP | Priority |
|---|---|---|---|
| 0.1 | Definir Java Records: FlowDefinition, FlowNode, FlowEdge, NodeConfig |
3 | Must |
| 0.2 | Definir Java Records: FlowExecution, ExecutionStep, ExecutionStatus (sealed) |
3 | Must |
| 0.3 | Generar JSON Schema a partir de Records para contrato FE↔BE | 2 | Must |
| 0.4 | Definir NodeCatalog con metadata de 40 nodos (id, categoría, inputs/outputs, color) |
5 | Must |
| 0.5 | Scaffolding Maven modules dentro de dkv-pet-flows-api/ |
2 | Must |
Total: 15 SP · Output: Contrato de datos → desbloquea S1 completo
🏗️ S1 — API REST + Persistencia (2 semanas)¶
Sprint Goal: API funcional que persiste y valida definiciones de flows.
| # | Story | SP | Priority |
|---|---|---|---|
| 1.1 | PostgreSQL schema: flow_definition (JSONB), flow_version, node_config |
5 | Must |
| 1.2 | Quarkus REST: POST /api/flows — crear flow |
3 | Must |
| 1.3 | Quarkus REST: GET /api/flows + GET /api/flows/{id} — listar y obtener |
3 | Must |
| 1.4 | Quarkus REST: PUT /api/flows/{id} — actualizar flow |
3 | Must |
| 1.5 | Quarkus REST: DELETE /api/flows/{id} — borrar flow |
2 | Must |
| 1.6 | Quarkus REST: POST /api/flows/{id}/validate — validar antes de ejecutar |
3 | Must |
| 1.7 | PostgreSQL schema: flow_execution, execution_step (event sourcing) |
3 | Must |
| 1.8 | Versioning: cada save crea nueva versión, rollback posible | 5 | Should |
| 1.9 | Quarkus REST: GET /api/nodes/catalog — devuelve catálogo de 40 nodos |
2 | Should |
Total: 29 SP · Output: API CRUD + validación + persistencia operativa
▶️ S2 — Motor de Ejecución Dapr (2 semanas)¶
Sprint Goal: Flows se ejecutan end-to-end via Dapr Workflows.
| # | Story | SP | Priority |
|---|---|---|---|
| 2.1 | Dapr Workflow: interpretar flow_definition JSON → secuencia de actividades |
13 | Must |
| 2.2 | Nodos Trigger: Webhook receiver, Cron scheduler, API Event listener | 8 | Must |
| 2.3 | Nodos Lógica: If/Else evaluator, Wait (timer), Router (multi-branch) | 8 | Must |
| 2.4 | Event sourcing: cada paso → INSERT en execution_step |
3 | Must |
| 2.5 | Quarkus REST: POST /api/flows/{id}/execute — dispara Dapr workflow |
3 | Must |
| 2.6 | Circuit breaker (Quarkus) + retry configurable por nodo (Dapr YAML) | 3 | Should |
Total: 38 SP · Output: Motor de ejecución operativo con triggers + lógica
📲 S3 — Canales de Comunicación (2 semanas)¶
Sprint Goal: Push, Email y SMS operativos como nodos de acción ejecutables.
| # | Story | SP | Priority |
|---|---|---|---|
| 3.1 | Gorush integration: Push APNs + FCM con rich content (imagen, deep link) | 8 | Must |
| 3.2 | Email Dapr Binding: SMTP/SendGrid con templates Handlebars | 5 | Must |
| 3.3 | SMS Dapr Binding: Twilio/Vonage para mensajes transaccionales | 3 | Must |
| 3.4 | In-App Message: Dapr pub/sub → WebSocket a DKV Mascotas app | 5 | Should |
| 3.5 | In-App Inbox: buzón persistente PostgreSQL + API | 3 | Should |
| 3.6 | Template engine: Handlebars con variables de flow context | 3 | Should |
Total: 27 SP · Output: 3 canales Must operativos + 2 Should
🧠 S4 — Inteligencia IA + Monitor (2 semanas)¶
Sprint Goal: Nodos IA diferenciadores + monitorización en tiempo real.
| # | Story | SP | Priority |
|---|---|---|---|
| 4.1 | SSE endpoint: stream de eventos de ejecución | 5 | Must |
| 4.2 | Execution Log API: historial con filtros, paginación | 3 | Must |
| 4.3 | "IA: Generar Contenido" — LangChain4j → Azure OpenAI | 8 | Must |
| 4.4 | "IA: Best Time to Send" — modelo predictivo hora óptima | 5 | Should |
| 4.5 | "IA: Sentiment" — análisis de respuestas encuestas | 3 | Should |
Total: 24 SP · Output: SSE monitor + 3 nodos IA
Resumen¶
| Sprint | Duración | SP | Output |
|---|---|---|---|
| S0 Modelo de Datos | 1 sem | 15 | Records + JSON Schema + Catálogo |
| S1 API + Persistencia | 2 sem | 29 | CRUD REST + PostgreSQL + Validación |
| S2 Motor Ejecución | 2 sem | 38 | Dapr Workflows + Triggers + Lógica |
| S3 Canales | 2 sem | 27 | Push + Email + SMS |
| S4 IA + Monitor | 2 sem | 24 | LangChain4j + SSE |
| TOTAL | 9 sem | 133 SP |
Semana: 1 2 3 4 5 6 7 8 9
┌──┐
S0 │██│ Modelo de Datos
└──┘
┌────────────┐
S1 │████████████│ API + Persistencia
└────────────┘
┌────────────┐
S2 │████████████│ Motor Ejecución
└────────────┘
┌────────────┐
S3 │████████████│ Canales
└────────────┘
┌────────────┐
S4 │████████████│ IA + Monitor
└────────────┘
Risk Analysis — Detallado¶
Deep dives completos: Cada riesgo tiene su documentación técnica dedicada: - Auditoría dkv-notifications — Erlang/OTP, coexistencia, valoración DevOps - Gorush Setup — APNs, FCM, VAPID, payloads - Spike: Dapr Workflows — Qué es un spike, plan de 2 días - Decisión Stack Backend — ADR: Pekko vs Quarkus+Dapr
dkv-pet-cloud (Spring Boot) es la fuente de verdad del negocio veterinario. Pet Flows consume su API REST para triggers y condiciones. El riesgo: no hay contrato OpenAPI publicado — conocemos los endpoints por el código fuente pero no están formalmente documentados.
Mitigación: Spike de 2 días al inicio de S2 para mapear endpoints, generar OpenAPI schema de facto, y documentar modelos relevantes.
2. dkv-notifications — Auditoría Forense Completa¶
Arquitectura descubierta¶
graph LR
subgraph "dkv-pet-cloud<br/>Spring Boot"
API["REST API"]
end
subgraph "dkv-notifications<br/>Erlang OTP"
NTF["Port 9111"]
DB["PostgreSQL 11.6<br/>DB: dkv_notifications"]
end
subgraph "Gorush 1.16.0"
GR["Port 8088"]
end
API -->|"POST /api/v1"| NTF
NTF -->|"POST /send"| GR
NTF --> DB
GR --> APNs & FCM & WebPush
| Componente | Detalle |
|---|---|
| Imagen | ghcr.io/jaraxasoftware/dkv-notifications |
| Lenguaje | Erlang/OTP — nkpacket, nkserver_ot, lager |
| Puerto | 9111 HTTP + config via YAML volumes |
| DB propia | PostgreSQL 11.6, DB dkv_notifications, pgcrypto |
| Gorush | v1.16.0 — APNs cert (push.pem), FCM key, VAPID |
| Legacy libs | nkpacket, nkserver_ot (heredadas de Netcomp) |
Estrategia: API-Compatible Coexistence¶
[!WARNING] NO absorber dkv-notifications ahora. Es pieza Erlang ligada a Netcomp (go-live julio 2026). Tocar piezas integradas con Netcomp = riesgo de regresión.
FASE 1 (ahora → julio): Pet Flows implementa REST con mismo contrato que dkv-notifications (/api/v1). Ambas apps coexisten. Pet Flows delega a dkv-notifications para push reales.
FASE 2 (post-julio): Pet Flows absorbe la lógica, conserva la DB dkv_notifications, reutiliza Gorush directo (es stateless), elimina contenedor Erlang.
| Aspecto | Fase 1 | Fase 2 |
|---|---|---|
| Riesgo | ✅ Mínimo | ⚠️ Medio |
| Gorush | Via dkv-notifications | Directo via Dapr |
| DB | Separadas | Pet Flows absorbe |
| Containers | PF + NTF + Gorush | PF + Gorush |
3. "¿Qué es un spike?"¶
Un spike es una investigación técnica con timebox fijo (1-2 días). No produce código de producción — produce una decisión informada.
Spike Dapr Workflows: crear un workflow trivial (log → wait → log), ejecutar con dapr run, verificar event sourcing. Output = "sabemos cómo funciona, podemos estimar S2 con confianza". Sin esto, el riesgo es descubrir problemas inesperados en un sprint de 38 SP.
4. "Gorush setup" — Qué implica¶
| Requisito | Dificultad | Detalle |
|---|---|---|
Certificado APNs (.pem) |
🔴 Alta | Requiere cuenta Apple Developer de DKV |
| API Key FCM | 🟡 Media | Proyecto Firebase de DKV |
| VAPID Keys (Web Push) | 🟢 Auto | Se generan automáticamente |
| gorush.config | 🟢 Baja | YAML con puertos y rutas |
[!TIP] Buena noticia:
push.pemya existe en el repo. Solo verificar vigencia y obtener el actualizado.
Mitigación: FCM-only en dev (no necesita cert de Apple). APNs para staging.
Tabla resumen¶
| Risk | Prob. | Impact | Mitigation |
|---|---|---|---|
| dkv-pet-cloud API sin OpenAPI | M | H | Spike 2 días |
| Coexistencia con dkv-notifications | L | M | API-compatible, absorción post julio |
| Dapr Workflow learning curve | M | H | Spike en S0 |
| Gorush certificados APNs | M | M | FCM-only en dev |
| LangChain4j latencia | M | M | Timeout + fallback |
Verification Plan¶
Automated Tests¶
./mvnw quarkus:test— Integration tests REST API + PostgreSQL./mvnw quarkus:dev -Dquarkus.test.continuous-testing=enabled
Manual Verification¶
- Fin S1: CRUD flow via curl/HTTPie, verificar en PostgreSQL
- Fin S2: Ejecutar flow completo trigger → wait → log
- Fin S3: Flow end-to-end = trigger → wait → push via dkv-notifications