# ABE Enterprise Refactor — Fix Plan ## REGLAS CRÍTICAS 1. NO pasar a la siguiente tarea si el build falla 2. Hacer `git commit` después de CADA tarea completada 3. Leer la spec en `.ralph/specs/` ANTES de cada phase 4. Los tests DEBEN pasar antes de marcar [x] 5. Formato commit: `git commit -m "fase(X.Y): descripción"` --- ## Phase 0: Hotfix — Build actual funcional [COMPLETO] - [x] 0.1: Fix errores TypeScript en src/ que impidan compilación (IAnomaly import, NodeListOf iterator, cualquier otro) - [x] 0.2: Verificar `npm run build` pasa con 0 errores - [x] 0.3: Verificar `cd frontend && npm run build` pasa con 0 errores - [x] 0.4: Verificar que la app arranca con `npm run dev` sin crash - [x] 0.5: Commit: `git add -A && git commit -m "fase(0): fix build errors"` --- ## Phase 1: Shared Domain — Building Blocks [COMPLETO] Spec: `.ralph/specs/phase-01-shared-domain.md` - [x] 1.1: Crear directorio `src/shared/domain/` - [x] 1.2: Crear `src/shared/domain/Result.ts` — Result con Ok(), Err(), isOk(), isErr() - [x] 1.3: Crear `src/shared/domain/UniqueId.ts` — UUID v4 wrapper con create(), toString(), equals() - [x] 1.4: Crear `src/shared/domain/Entity.ts` — base class con _id: UniqueId, equals() - [x] 1.5: Crear `src/shared/domain/AggregateRoot.ts` — extends Entity + domainEvents[], addDomainEvent(), clearEvents() - [x] 1.6: Crear `src/shared/domain/ValueObject.ts` — base class inmutable con props frozen, equals() - [x] 1.7: Crear `src/shared/domain/DomainEvent.ts` — interface: eventId, eventName, aggregateId, occurredOn, payload - [x] 1.8: Crear `src/shared/application/UseCase.ts` — interface: execute(req) → Promise> - [x] 1.9: Crear `src/shared/application/EventBus.ts` — interface: publish(event), subscribe(name, handler) - [x] 1.10: Crear `src/shared/application/EventHandler.ts` — interface: handle(event) → Promise - [x] 1.11: Crear `src/shared/domain/index.ts` — barrel export de todo shared/domain - [x] 1.12: Crear `src/shared/application/index.ts` — barrel export de todo shared/application - [x] 1.13: Tests unitarios: Result (Ok/Err/isOk/isErr), Entity (equals by id), ValueObject (equals by props), UniqueId (create/equals) - [x] 1.14: Verificar build completo + commit: `fase(1): shared domain building blocks` --- ## Phase 2: Shared Infrastructure [PENDIENTE] Spec: `.ralph/specs/phase-02-shared-infrastructure.md` - [ ] 2.1: Instalar deps: `npm i kysely better-sqlite3 pino pino-pretty zod helmet express-rate-limit dotenv uuid` + `npm i -D @types/better-sqlite3 @types/uuid` - [ ] 2.2: Crear `src/shared/infrastructure/Config.ts` — Zod schema para TODAS las env vars con defaults sensatos - [ ] 2.3: Crear `src/shared/infrastructure/Logger.ts` — Pino factory: createLogger(config) retorna pino.Logger, pino-pretty en dev - [ ] 2.4: Crear `src/shared/infrastructure/DatabaseConnection.ts` — Kysely factory: createDatabase(config) soporta SQLite (default) y PostgreSQL (si config.db.driver === 'postgres') - [ ] 2.5: Crear `src/shared/infrastructure/InProcessEventBus.ts` — implementa EventBus con Node EventEmitter, logging de eventos, error handling en handlers - [ ] 2.6: Crear `src/shared/infrastructure/StorageProvider.ts` — interface IStorageProvider (save/get/delete/exists) + LocalStorageProvider (filesystem) - [ ] 2.7: Crear `src/shared/infrastructure/index.ts` — barrel export - [ ] 2.8: Crear `src/db/migrations/001_initial_schema.ts` — migración Kysely que crea las tablas existentes (sessions, states, actions, anomalies, notifications) con IF NOT EXISTS - [ ] 2.9: Crear `src/db/migrator.ts` — setup Kysely Migrator + función runMigrations() - [ ] 2.10: Añadir script `"db:migrate"` a package.json - [ ] 2.11: Tests: Config validation (valid + invalid), EventBus (publish/subscribe/error handling), StorageProvider (save/get/delete) - [ ] 2.12: Verificar build completo + commit: `fase(2): shared infrastructure layer` --- ## Phase 3: Crawling Module — Domain + Application [PENDIENTE] Spec: `.ralph/specs/phase-03-crawling-domain.md` - [ ] 3.1: Crear `src/modules/crawling/domain/entities/CrawlSession.ts` — AggregateRoot con url, status, seed, maxStates, statesVisited, config - [ ] 3.2: Crear `src/modules/crawling/domain/entities/CrawlState.ts` — Entity con url, title, domSnapshot, visitCount - [ ] 3.3: Crear `src/modules/crawling/domain/entities/CrawlAction.ts` — Entity con type, selector, value, seed, stateId, sequenceOrder - [ ] 3.4: Crear value objects: `Url.ts`, `Selector.ts`, `SessionStatus.ts` (running/completed/failed/stopped) - [ ] 3.5: Crear events: `CrawlStarted.ts`, `StateDiscovered.ts`, `ActionExecuted.ts`, `CrawlCompleted.ts`, `CrawlFailed.ts` - [ ] 3.6: Crear ports: `ICrawlerEngine.ts` (launch/close/discoverActions/executeAction/captureState), `ICrawlSessionRepository.ts` (save/findById/findAll/update), `IStateRepository.ts` - [ ] 3.7: Crear `application/commands/StartCrawlCommand.ts` — use case que valida config, crea CrawlSession, emite CrawlStarted - [ ] 3.8: Crear `application/commands/StopCrawlCommand.ts` — use case que para sesión, emite CrawlCompleted - [ ] 3.9: Crear `application/queries/GetSessionQuery.ts` y `ListSessionsQuery.ts` - [ ] 3.10: Crear `modules/crawling/index.ts` — barrel export público - [ ] 3.11: Tests: CrawlSession creation + domain events, StartCrawlCommand con mock repository - [ ] 3.12: Verificar build + commit: `fase(3): crawling module domain and application` --- ## Phase 4: Crawling Module — Infrastructure (migración código existente) [PENDIENTE] Spec: `.ralph/specs/phase-04-crawling-infrastructure.md` - [ ] 4.1: Copiar `src/plugins/agents/PlaywrightAgent.ts` → `src/modules/crawling/infrastructure/adapters/PlaywrightCrawlerEngine.ts`, adaptar para implementar ICrawlerEngine port - [ ] 4.2: Copiar `src/core/StateGraph.ts` → `src/modules/crawling/infrastructure/adapters/StateGraph.ts`, mantener lógica BFS - [ ] 4.3: Copiar `src/core/ExplorationEngine.ts` → `src/modules/crawling/infrastructure/adapters/ExplorationOrchestrator.ts`, adaptar para usar ports en vez de imports directos - [ ] 4.4: Crear `infrastructure/repositories/KyselyCrawlSessionRepository.ts` — implementa ICrawlSessionRepository con Kysely - [ ] 4.5: Crear `infrastructure/repositories/KyselyStateRepository.ts` - [ ] 4.6: Crear `infrastructure/http/CrawlingController.ts` — Express routes: POST /api/sessions, GET /api/sessions, GET /api/sessions/:id, DELETE /api/sessions/:id - [ ] 4.7: Verificar que crear sesión + ejecutar crawl funciona end-to-end - [ ] 4.8: Verificar build + commit: `fase(4): crawling infrastructure with migrated code` --- ## Phase 5: Findings Module [PENDIENTE] Spec: `.ralph/specs/phase-05-findings-module.md` - [ ] 5.1: Crear `domain/entities/Finding.ts` — AggregateRoot con severity, type, evidence, status, actionTrace - [ ] 5.2: Crear value objects: `Severity.ts` (low/medium/high/critical), `FindingType.ts`, `Evidence.ts`, `FindingStatus.ts` (open/investigating/resolved/closed) - [ ] 5.3: Crear events: `FindingCreated.ts`, `FindingResolved.ts`, `FindingEnriched.ts` - [ ] 5.4: Crear ports: `IFindingRepository.ts`, `IAIEnricher.ts` - [ ] 5.5: Crear commands: `CreateFindingCommand.ts`, `EnrichFindingCommand.ts`, `ResolveFindingCommand.ts` - [ ] 5.6: Crear queries: `GetFindingQuery.ts`, `ListFindingsQuery.ts` (filtros: severity, type, session, status, search), `FindingStatsQuery.ts` - [ ] 5.7: Crear `event-handlers/OnAnomalyDetected.ts` — escucha eventos crawling → crea Finding - [ ] 5.8: Crear `infrastructure/repositories/KyselyFindingRepository.ts` - [ ] 5.9: Migrar exporters existentes → `infrastructure/exporters/` (MarkdownExporter, JSONExporter) - [ ] 5.10: Crear `infrastructure/exporters/PlaywrightScriptExporter.ts` — genera test Playwright reproducible desde actionTrace - [ ] 5.11: Crear `infrastructure/http/FindingsController.ts` — routes para anomalies existentes + nuevas - [ ] 5.12: Migración Kysely: tabla findings con columnas status, browser, ai_enrichment_json - [ ] 5.13: Tests: Finding aggregate, CreateFinding, ListFindings con filtros - [ ] 5.14: Verificar build + commit: `fase(5): findings module complete` --- ## Phase 6: Fuzzing Module [PENDIENTE] Spec: `.ralph/specs/phase-06-fuzzing-module.md` - [ ] 6.1: Crear domain: `FuzzSession.ts` (AggregateRoot), `FuzzResult.ts` (Entity) - [ ] 6.2: Crear value objects: `FuzzStrategy.ts`, `FuzzPayload.ts`, `Seed.ts`, `FuzzIntensity.ts` - [ ] 6.3: Crear events: `FuzzStarted.ts`, `VulnerabilityDetected.ts`, `FuzzCompleted.ts` - [ ] 6.4: Crear port: `IFuzzerEngine.ts` - [ ] 6.5: Crear `commands/RunFuzzCommand.ts` - [ ] 6.6: Crear `event-handlers/OnActionExecuted.ts` — escucha crawling → trigger fuzzing - [ ] 6.7: Migrar las 5 estrategias existentes → `infrastructure/strategies/` (Empty, Oversized, SpecialChars, TypeMismatch, Boundary) - [ ] 6.8: Migrar `FuzzingEngine.ts` y `InputTypeDetector.ts` → `infrastructure/adapters/` - [ ] 6.9: Crear `infrastructure/http/FuzzingController.ts` - [ ] 6.10: Tests: cada estrategia de fuzzing genera payloads válidos - [ ] 6.11: Verificar build + commit: `fase(6): fuzzing module complete` --- ## Phase 7: API Server Refactor + Composition Root [PENDIENTE] Spec: `.ralph/specs/phase-07-api-server.md` - [ ] 7.1: Crear `src/api/middleware/errorHandler.ts` — AppError hierarchy (ValidationError, AuthenticationError, ForbiddenError, NotFoundError) + global error handler - [ ] 7.2: Crear `src/api/middleware/requestId.ts` — genera UUID por request, adjunta a req + pino child logger - [ ] 7.3: Crear `src/api/middleware/notFound.ts` — 404 handler para rutas no encontradas - [ ] 7.4: Crear `src/api/server.ts` — Express app con middleware stack: requestId → helmet → cors → rateLimit → bodyParser → routes → notFound → errorHandler - [ ] 7.5: Crear `src/api/router.ts` — registra routes de TODOS los módulos (crawling, findings, fuzzing) - [ ] 7.6: Crear `src/realtime/SocketGateway.ts` — socket.io server que subscribe a EventBus y emite a clientes - [ ] 7.7: Crear `src/main.ts` — composition root: load config → create logger → create db → run migrations → create event bus → create repositories → create use cases → subscribe handlers → create controllers → create Express → create socket.io → start listening - [ ] 7.8: Implementar graceful shutdown en main.ts: SIGTERM/SIGINT → stop accepting → close sockets → close db → flush logs → exit - [ ] 7.9: Health endpoints: GET /health/live (process alive), GET /health/ready (DB check) - [ ] 7.10: Verificar que TODOS los endpoints existentes siguen funcionando tras refactor - [ ] 7.11: Verificar build + commit: `fase(7): api server refactor with composition root` --- ## Phase 8: Job Queue System [PENDIENTE] Spec: `.ralph/specs/phase-08-job-queue.md` - [ ] 8.1: Crear `src/jobs/JobQueue.ts` — interface: enqueue, start, pause, waitForActive - [ ] 8.2: Crear `src/jobs/SQLiteJobQueue.ts` — tabla jobs con status/type/payload/attempts/run_at, polling worker - [ ] 8.3: Migración Kysely: tabla jobs - [ ] 8.4: Crear `src/jobs/workers/ExplorationWorker.ts` — ejecuta crawl como job - [ ] 8.5: Crear `src/jobs/workers/ReportWorker.ts` — genera reports en background - [ ] 8.6: Integrar job queue en main.ts, mover exploraciones de sync a job-based - [ ] 8.7: Tests: enqueue → dequeue → complete cycle, failed job retry - [ ] 8.8: Verificar build + commit: `fase(8): sqlite job queue system` --- ## Phase 9: Auth Module [PENDIENTE] Spec: `.ralph/specs/phase-09-auth-module.md` - [ ] 9.1: Instalar: `npm i better-auth @casl/ability argon2` - [ ] 9.2: Crear domain: `User.ts` (AggregateRoot), `Organization.ts` (AggregateRoot), `Team.ts` (Entity), `ApiKey.ts` (Entity) - [ ] 9.3: Crear value objects: `Email.ts`, `Role.ts` (owner/admin/member/viewer), `Permission.ts` - [ ] 9.4: Crear events: `UserCreated.ts`, `UserLoggedIn.ts`, `OrgCreated.ts`, `MemberInvited.ts` - [ ] 9.5: Crear ports: `IUserRepository.ts`, `IOrganizationRepository.ts` - [ ] 9.6: Crear commands: `RegisterCommand.ts`, `LoginCommand.ts`, `CreateOrganizationCommand.ts`, `InviteMemberCommand.ts`, `CreateApiKeyCommand.ts` - [ ] 9.7: Crear queries: `GetUserQuery.ts`, `ListOrgMembersQuery.ts` - [ ] 9.8: Crear `infrastructure/better-auth/authConfig.ts` — setup Better Auth con SQLite adapter, email+password, organization plugin con roles - [ ] 9.9: Crear `infrastructure/casl/AbilityFactory.ts` — define permisos por role (owner: manage all, admin: manage all except delete org, member: create/read sessions+findings, viewer: read all) - [ ] 9.10: Crear `application/middleware/AuthMiddleware.ts` — intenta session cookie → JWT → API key → 401 - [ ] 9.11: Crear `application/middleware/RBACMiddleware.ts` — verifica permisos CASL por ruta - [ ] 9.12: Crear `infrastructure/repositories/KyselyUserRepository.ts` - [ ] 9.13: Crear `infrastructure/http/AuthController.ts` — POST /api/auth/register, POST /api/auth/login, POST /api/auth/logout, GET /api/auth/me, GET /api/auth/setup-required - [ ] 9.14: Migración Kysely: tablas users, organizations, teams, org_members, api_keys, auth_sessions - [ ] 9.15: First-run detection: si 0 users → GET /api/auth/setup-required retorna { required: true } - [ ] 9.16: POST /api/auth/setup — crea primer user como owner + organización default - [ ] 9.17: Integrar AuthMiddleware en todas las rutas /api/ excepto /health/* y /api/auth/* - [ ] 9.18: Tests: register, login, RBAC permissions (admin can create session, viewer cannot) - [ ] 9.19: Verificar build + commit: `fase(9): auth module with better-auth and casl` --- ## Phase 10: Frontend — shadcn/ui Shell [PENDIENTE] Spec: `.ralph/specs/phase-10-frontend-shell.md` - [ ] 10.1: En frontend/: instalar shadcn/ui con `npx shadcn@latest init` (Vite, Zinc, CSS variables, Tailwind) - [ ] 10.2: Instalar componentes shadcn: button, input, card, badge, dialog, dropdown-menu, command, sidebar, tabs, table, toast, form, separator, avatar, skeleton, tooltip, sheet, select, textarea, label, switch, alert - [ ] 10.3: Instalar deps: `npm i @tanstack/react-query @tanstack/react-table zustand react-hook-form @hookform/resolvers framer-motion react-hotkeys-hook` - [ ] 10.4: Crear layout: `components/layout/AppSidebar.tsx` — sidebar collapsible con nav items (Dashboard, Explorations, Findings, Reports, Settings) - [ ] 10.5: Crear `components/layout/TopBar.tsx` — logo, search trigger (⌘K), theme toggle, user avatar menu - [ ] 10.6: Crear `components/layout/AppLayout.tsx` — wrapper: Sidebar + TopBar + Content outlet - [ ] 10.7: Crear `components/layout/CommandPalette.tsx` — ⌘K con shadcn Command component - [ ] 10.8: Crear ThemeProvider: dark mode como default, toggle dark/light, persistir en localStorage - [ ] 10.9: Crear `lib/api.ts` — API client con fetch, credentials: include, auto-redirect a /login en 401 - [ ] 10.10: Crear `lib/queryClient.ts` — TanStack Query provider - [ ] 10.11: Crear `stores/uiStore.ts` — Zustand: sidebarCollapsed, theme - [ ] 10.12: Crear pages/Login.tsx — form email + password con shadcn - [ ] 10.13: Crear pages/Setup.tsx — wizard first-run (crear admin + nombre org) - [ ] 10.14: Crear `components/layout/ProtectedRoute.tsx` — check auth, redirect a /login o /setup - [ ] 10.15: Actualizar App.tsx con React Router: / (dashboard), /login, /setup, /sessions/:id, /findings/:id, /settings — todo wrapped en ProtectedRoute excepto login/setup - [ ] 10.16: Verificar frontend build + commit: `fase(10): frontend shadcn-ui shell with auth` --- ## Phase 11: Dashboard Page [PENDIENTE] Spec: `.ralph/specs/phase-11-dashboard.md` - [ ] 11.1: Instalar en frontend: `npm i tremor recharts` - [ ] 11.2: Crear `hooks/useFindings.ts` — TanStack Query hooks: useFindings, useFindingStats - [ ] 11.3: Crear `hooks/useSessions.ts` — TanStack Query hooks: useSessions, useSession - [ ] 11.4: Crear `hooks/useSocket.ts` — socket.io-client connection con auto-reconnect - [ ] 11.5: Crear `components/dashboard/KPICards.tsx` — 4 cards Tremor: Total Findings, Critical/High, Active Sessions, Coverage - [ ] 11.6: Crear `components/dashboard/TrendChart.tsx` — Recharts AreaChart stacked por severity, últimos 30 días - [ ] 11.7: Crear `components/dashboard/SeverityDistribution.tsx` — Recharts PieChart con colores por severity - [ ] 11.8: Crear `components/dashboard/RecentFindings.tsx` — TanStack Table, 10 rows, click → /findings/:id - [ ] 11.9: Crear `components/dashboard/ActiveSessions.tsx` — lista con progress bars, click → /sessions/:id - [ ] 11.10: Crear `components/dashboard/QuickActions.tsx` — botón "New Exploration" prominente - [ ] 11.11: Crear `pages/Dashboard.tsx` — ensambla todo, responsive 2col desktop 1col mobile - [ ] 11.12: Conectar real-time: socket events actualizan KPIs y recent findings - [ ] 11.13: Verificar frontend build + commit: `fase(11): dashboard page with charts and realtime` --- ## Phase 12: Sessions Pages [PENDIENTE] Spec: `.ralph/specs/phase-12-sessions-pages.md` - [ ] 12.1: Crear `components/sessions/NewExplorationForm.tsx` — React Hook Form + Zod: URL, seed, maxStates, maxDepth, allowedDomains (chips), excludedPaths (chips), auth type (none/cookies/headers/login_flow) con campos condicionales, fuzzing toggle + intensity, collapsible advanced section - [ ] 12.2: Crear `pages/sessions/SessionList.tsx` — TanStack Table: status badge, url, findings count, duration, created at; sortable + filterable - [ ] 12.3: Crear `pages/sessions/SessionDetail.tsx` — layout con tabs - [ ] 12.4: Crear `components/sessions/LiveFeed.tsx` — streaming WebSocket con auto-scroll, colores por event type (verde state, amarillo action, rojo anomaly) - [ ] 12.5: Crear `components/sessions/SessionFindings.tsx` — findings de esta sesión con severity badges - [ ] 12.6: Crear `components/sessions/SessionConfig.tsx` — ExplorationConfig read-only - [ ] 12.7: Progress bar estados explorados / maxStates - [ ] 12.8: Stop button funcional (DELETE /api/sessions/:id) - [ ] 12.9: Verificar frontend build + commit: `fase(12): session pages with live feed` --- ## Phase 13: Findings Pages [PENDIENTE] Spec: `.ralph/specs/phase-13-findings-pages.md` - [ ] 13.1: Crear `pages/findings/FindingsList.tsx` — TanStack Table con filtros: severity multi-select, type multi-select, status, session dropdown, text search - [ ] 13.2: Crear `pages/findings/FindingDetail.tsx` — split layout - [ ] 13.3: Crear `components/findings/ReproductionSteps.tsx` — numbered step cards con action type, selector, screenshot thumb - [ ] 13.4: Crear `components/findings/EvidencePanel.tsx` — tabs: Console (syntax-highlighted), Network (request/response table), DOM (snapshot viewer) - [ ] 13.5: Crear `components/findings/AIAnalysisPanel.tsx` — muestra enrichment si existe, o botón "Analyze with AI" - [ ] 13.6: Export buttons: "Export as Playwright", "Export as Markdown", "Export as JSON" - [ ] 13.7: Status workflow buttons: open → investigating → resolved → closed - [ ] 13.8: `components/common/SeverityBadge.tsx` — reutilizable con colores critical=rojo, high=naranja, medium=amarillo, low=azul - [ ] 13.9: Verificar frontend build + commit: `fase(13): findings pages with detail view` --- ## Phase 14: Settings Pages [PENDIENTE] Spec: `.ralph/specs/phase-14-settings-pages.md` - [ ] 14.1: Crear `pages/settings/SettingsLayout.tsx` — layout con sidebar navigation entre sections - [ ] 14.2: Section "Profile" — cambiar nombre, email, password - [ ] 14.3: Section "Organization" — nombre org, invitar miembros, manage roles - [ ] 14.4: Section "API Keys" — crear (con nombre + permisos), listar, revocar - [ ] 14.5: Section "Exploration Defaults" — form con defaults para nuevas exploraciones - [ ] 14.6: Section "Notifications" — Slack webhook URL, min severity - [ ] 14.7: Section "Appearance" — tema dark/light, accent color - [ ] 14.8: Section "License" — ver status licencia, input para activar key - [ ] 14.9: Verificar frontend build + commit: `fase(14): settings pages` --- ## Phase 15: Reporting Module [PENDIENTE] Spec: `.ralph/specs/phase-15-reporting.md` - [ ] 15.1: Crear domain: `Report.ts` (AggregateRoot), value objects `ReportFormat.ts` (pdf/html/json), `DateRange.ts` - [ ] 15.2: Crear port: `IReportGenerator.ts` - [ ] 15.3: Crear `commands/GenerateReportCommand.ts` — crea report con findings de un rango de fechas/sesión - [ ] 15.4: Crear `infrastructure/generators/HTMLReportGenerator.ts` — genera HTML report completo - [ ] 15.5: Crear `infrastructure/generators/PDFReportGenerator.ts` — usa Playwright para renderizar HTML → PDF - [ ] 15.6: Crear `infrastructure/http/ReportingController.ts` — POST /api/reports, GET /api/reports, GET /api/reports/:id/download - [ ] 15.7: Integrar con job queue: generación async - [ ] 15.8: Migración Kysely: tabla reports - [ ] 15.9: Frontend: `pages/Reports.tsx` — generar (dialog con filtros), listar, descargar - [ ] 15.10: Tests: GenerateReportCommand con mock generator - [ ] 15.11: Verificar build completo + commit: `fase(15): reporting module with pdf generation` --- ## Phase 16: Integrations Module [PENDIENTE] Spec: `.ralph/specs/phase-16-integrations.md` - [ ] 16.1: Instalar: `npm i @slack/web-api @octokit/rest` - [ ] 16.2: Crear domain: `Integration.ts` (Entity), `WebhookEndpoint.ts` (Entity) - [ ] 16.3: Crear value objects: `IntegrationType.ts` (jira/slack/github/webhook), `WebhookSecret.ts` - [ ] 16.4: Crear port: `IIntegrationProvider.ts` (sendFinding) - [ ] 16.5: Crear `infrastructure/webhooks/WebhookDispatcher.ts` — HMAC-SHA256 signature, retry con exponential backoff (3 intentos) - [ ] 16.6: Crear `infrastructure/providers/SlackProvider.ts` — Block Kit message con severity, description, link - [ ] 16.7: Crear `infrastructure/providers/GitHubIssuesProvider.ts` — crea issue con reproduction steps - [ ] 16.8: Crear `infrastructure/providers/JiraProvider.ts` — REST API v3, crea issue con screenshots - [ ] 16.9: Crear `event-handlers/OnFindingCreated.ts` — dispatch a todas las integrations activas - [ ] 16.10: Crear `infrastructure/http/IntegrationsController.ts` — CRUD integrations + webhooks - [ ] 16.11: Migración Kysely: tables integrations, webhook_endpoints, webhook_deliveries - [ ] 16.12: Frontend: Settings/Integrations con forms por provider (Slack webhook URL, Jira config, GitHub token, custom webhook) - [ ] 16.13: Tests: webhook dispatch + HMAC verification - [ ] 16.14: Verificar build completo + commit: `fase(16): integrations module` --- ## Phase 17: Licensing Module [PENDIENTE] Spec: `.ralph/specs/phase-17-licensing.md` - [ ] 17.1: Crear domain: `License.ts` (Entity), value objects `LicensePlan.ts` (free/pro/enterprise), `FeatureEntitlement.ts` - [ ] 17.2: Crear port: `ILicenseValidator.ts` (validate, getEntitlements) - [ ] 17.3: Crear `infrastructure/RSALicenseValidator.ts` — verifica firma RSA-2048 con public key bundled - [ ] 17.4: Crear feature flags: `FREE_FEATURES`, `PRO_FEATURES`, `ENTERPRISE_FEATURES` arrays - [ ] 17.5: Crear `infrastructure/middleware/FeatureGateMiddleware.ts` — checkea feature en license antes de permitir request - [ ] 17.6: Crear `infrastructure/http/LicensingController.ts` — POST /api/license/activate, GET /api/license/status - [ ] 17.7: Crear `scripts/generate-license.ts` — CLI tool para generar license keys firmadas (uso interno) - [ ] 17.8: Integrar gate checks en rutas Pro/Enterprise (reporting, integrations, etc.) - [ ] 17.9: Frontend: License section en Settings - [ ] 17.10: Tests: valid license passes, expired fails, wrong signature fails, feature gate blocks - [ ] 17.11: Verificar build completo + commit: `fase(17): licensing module with RSA validation` --- ## Phase 18: CLI + CI/CD [PENDIENTE] Spec: `.ralph/specs/phase-18-cli-cicd.md` - [ ] 18.1: Instalar: `npm i commander` - [ ] 18.2: Refactorizar `src/cli/abe.ts` con commander: comando `explore` con flags --url, --config (json file), --output (json|junit|markdown), --fail-on-severity, --api-key - [ ] 18.3: Comando `abe report` — genera report de una sesión por id - [ ] 18.4: Comando `abe status` — ping al servidor, muestra sessions activas - [ ] 18.5: Output JUnit XML: cada finding = failing test, cada state sin findings = passing test - [ ] 18.6: Exit codes: 0=clean, 1=findings over threshold, 2=error - [ ] 18.7: Crear `.github/actions/abe-explore/action.yml` — GitHub Action composite - [ ] 18.8: Crear `Dockerfile.ci` — imagen con Chromium para CI (basada en mcr.microsoft.com/playwright) - [ ] 18.9: Crear `.github/workflows/abe-example.yml` — ejemplo completo - [ ] 18.10: Actualizar README.md con sección CLI - [ ] 18.11: Verificar build completo + commit: `fase(18): cli and cicd integration` --- ## Phase 19: Scheduling Module Refactor [PENDIENTE] - [ ] 19.1: Migrar scheduling existente → nueva estructura modular (domain/application/infrastructure) - [ ] 19.2: Crear Schedule aggregate con cron validation (Zod) - [ ] 19.3: Integrar con job queue - [ ] 19.4: Crear SchedulingController con CRUD + toggle - [ ] 19.5: Frontend: Schedules section en Settings - [ ] 19.6: Verificar build + commit: `fase(19): scheduling module refactor` --- ## Phase 20: Visual Regression Refactor [PENDIENTE] - [ ] 20.1: Migrar visual regression existente → nueva estructura modular - [ ] 20.2: Integrar con StorageProvider para screenshots - [ ] 20.3: Refactorizar frontend /visual-review con shadcn/ui components - [ ] 20.4: Verificar build + commit: `fase(20): visual regression refactor` --- ## Phase 21: API Documentation [PENDIENTE] - [ ] 21.1: Instalar: `npm i @asteasolutions/zod-to-openapi @scalar/express-api-reference` - [ ] 21.2: Crear Zod schemas compartidos para TODOS los endpoints (request + response) - [ ] 21.3: Generar OpenAPI 3.1 spec desde Zod schemas - [ ] 21.4: Montar Scalar UI en GET /api-docs - [ ] 21.5: Servir spec JSON en GET /api-docs/openapi.json - [ ] 21.6: Verificar que todos los endpoints están documentados - [ ] 21.7: Verificar build + commit: `fase(21): openapi documentation with scalar` --- ## Phase 22: Docker Production [PENDIENTE] - [ ] 22.1: Refactorizar Dockerfile backend: multi-stage, node:20-alpine, tini como init, non-root user, HEALTHCHECK - [ ] 22.2: Refactorizar frontend Dockerfile: multi-stage build + nginx - [ ] 22.3: Actualizar docker-compose.yml: healthcheck, restart policies, volumes, env_file - [ ] 22.4: Crear docker-compose.prod.yml - [ ] 22.5: Crear .dockerignore optimizado - [ ] 22.6: CMD DEBE ser `["tini", "--", "node", "dist/main.js"]` — NUNCA npm - [ ] 22.7: Verificar imagen final < 200MB - [ ] 22.8: Verificar docker compose up funciona end-to-end - [ ] 22.9: Commit: `fase(22): docker production setup` --- ## Phase 23: Observability [PENDIENTE] - [ ] 23.1: Request correlation: requestId en CADA log entry via pino child logger - [ ] 23.2: Structured error logging con contexto (userId, sessionId, etc.) - [ ] 23.3: Liveness probe: GET /health/live - [ ] 23.4: Readiness probe: GET /health/ready (DB + job queue check) - [ ] 23.5: Startup probe: medir tiempo de arranque, loguear - [ ] 23.6: Commit: `fase(23): observability and health probes` --- ## Phase 24: Onboarding + First-Run [PENDIENTE] - [ ] 24.1: Detectar first-run en frontend (GET /api/auth/setup-required) - [ ] 24.2: Wizard multi-step: paso 1 crear admin, paso 2 nombre org, paso 3 "Start your first exploration" con URL input - [ ] 24.3: Empty states: ilustraciones/mensajes en tablas vacías ("No findings yet. Start an exploration!") - [ ] 24.4: Commit: `fase(24): onboarding and first-run experience` --- ## Phase 25: Polish + Quality [PENDIENTE] - [ ] 25.1: Audit TypeScript strict — eliminar TODOS los `any` restantes - [ ] 25.2: Loading skeletons en todas las pages (shadcn Skeleton) - [ ] 25.3: Error boundaries en cada page - [ ] 25.4: Keyboard shortcuts: ⌘K (command palette), Esc (close dialogs), N (new exploration from dashboard) - [ ] 25.5: Responsive mobile: sidebar collapse, tables scroll, forms stack - [ ] 25.6: README.md profesional: badges (build, license, version), screenshots, features list, quick start, CLI docs, architecture diagram, contributing - [ ] 25.7: CONTRIBUTING.md - [ ] 25.8: LICENSE files: MIT para core, archivo LICENSE-ENTERPRISE separado - [ ] 25.9: Commit: `fase(25): polish and quality improvements` --- ## Phase 26: SSO Enterprise [PENDIENTE — ENTERPRISE ONLY] - [ ] 26.1: SAML 2.0 via @node-saml/passport-saml con MultiSamlStrategy - [ ] 26.2: OIDC via openid-client (Okta, Azure AD, Google Workspace) - [ ] 26.3: Per-organization IdP configuration - [ ] 26.4: LDAP/AD integration via passport-ldapauth - [ ] 26.5: MFA (TOTP) support - [ ] 26.6: Audit log completo (who did what, when) - [ ] 26.7: Session management dashboard (ver/revocar sessions activas) - [ ] 26.8: Feature-gated tras LICENSE enterprise - [ ] 26.9: Commit: `fase(26): enterprise sso saml oidc ldap` --- ## Phase 27: Advanced Enterprise [PENDIENTE — ENTERPRISE ONLY] - [ ] 27.1: Data retention policies (auto-delete findings > X days) - [ ] 27.2: Backup/restore CLI tool - [ ] 27.3: White-labeling (CSS custom properties + logo upload) - [ ] 27.4: PostgreSQL support validado end-to-end - [ ] 27.5: Email notifications (nodemailer + templates) - [ ] 27.6: Kubernetes Helm chart - [ ] 27.7: Commit: `fase(27): advanced enterprise features`