Files
Autonomous-Bug-Explorer/.ralph/fix_plan.md

445 lines
29 KiB
Markdown

# 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<T, E> 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<Result<TRes, TErr>>
- [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<void>
- [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 [COMPLETO]
Spec: `.ralph/specs/phase-02-shared-infrastructure.md`
- [x] 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`
- [x] 2.2: Crear `src/shared/infrastructure/Config.ts` — Zod schema para TODAS las env vars con defaults sensatos
- [x] 2.3: Crear `src/shared/infrastructure/Logger.ts` — Pino factory: createLogger(config) retorna pino.Logger, pino-pretty en dev
- [x] 2.4: Crear `src/shared/infrastructure/DatabaseConnection.ts` — Kysely factory: createDatabase(config) soporta SQLite (default) y PostgreSQL (si config.db.driver === 'postgres')
- [x] 2.5: Crear `src/shared/infrastructure/InProcessEventBus.ts` — implementa EventBus con Node EventEmitter, logging de eventos, error handling en handlers
- [x] 2.6: Crear `src/shared/infrastructure/StorageProvider.ts` — interface IStorageProvider (save/get/delete/exists) + LocalStorageProvider (filesystem)
- [x] 2.7: Crear `src/shared/infrastructure/index.ts` — barrel export
- [x] 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
- [x] 2.9: Crear `src/db/migrator.ts` — setup Kysely Migrator + función runMigrations()
- [x] 2.10: Añadir script `"db:migrate"` a package.json
- [x] 2.11: Tests: Config validation (valid + invalid), EventBus (publish/subscribe/error handling), StorageProvider (save/get/delete)
- [x] 2.12: Verificar build completo + commit: `fase(2): shared infrastructure layer`
---
## Phase 3: Crawling Module — Domain + Application [COMPLETO]
Spec: `.ralph/specs/phase-03-crawling-domain.md`
- [x] 3.1: Crear `src/modules/crawling/domain/entities/CrawlSession.ts` — AggregateRoot con url, status, seed, maxStates, statesVisited, config
- [x] 3.2: Crear `src/modules/crawling/domain/entities/CrawlState.ts` — Entity con url, title, domSnapshot, visitCount
- [x] 3.3: Crear `src/modules/crawling/domain/entities/CrawlAction.ts` — Entity con type, selector, value, seed, stateId, sequenceOrder
- [x] 3.4: Crear value objects: `Url.ts`, `Selector.ts`, `SessionStatus.ts` (running/completed/failed/stopped)
- [x] 3.5: Crear events: `CrawlStarted.ts`, `StateDiscovered.ts`, `ActionExecuted.ts`, `CrawlCompleted.ts`, `CrawlFailed.ts`
- [x] 3.6: Crear ports: `ICrawlerEngine.ts` (launch/close/discoverActions/executeAction/captureState), `ICrawlSessionRepository.ts` (save/findById/findAll/update), `IStateRepository.ts`
- [x] 3.7: Crear `application/commands/StartCrawlCommand.ts` — use case que valida config, crea CrawlSession, emite CrawlStarted
- [x] 3.8: Crear `application/commands/StopCrawlCommand.ts` — use case que para sesión, emite CrawlCompleted
- [x] 3.9: Crear `application/queries/GetSessionQuery.ts` y `ListSessionsQuery.ts`
- [x] 3.10: Crear `modules/crawling/index.ts` — barrel export público
- [x] 3.11: Tests: CrawlSession creation + domain events, StartCrawlCommand con mock repository
- [x] 3.12: Verificar build + commit: `fase(3): crawling module domain and application`
---
## Phase 4: Crawling Module — Infrastructure (migración código existente) [COMPLETO]
Spec: `.ralph/specs/phase-04-crawling-infrastructure.md`
- [x] 4.1: Copiar `src/plugins/agents/PlaywrightAgent.ts``src/modules/crawling/infrastructure/adapters/PlaywrightCrawlerEngine.ts`, adaptar para implementar ICrawlerEngine port
- [x] 4.2: Copiar `src/core/StateGraph.ts``src/modules/crawling/infrastructure/adapters/StateGraph.ts`, mantener lógica BFS
- [x] 4.3: Copiar `src/core/ExplorationEngine.ts``src/modules/crawling/infrastructure/adapters/ExplorationOrchestrator.ts`, adaptar para usar ports en vez de imports directos
- [x] 4.4: Crear `infrastructure/repositories/KyselyCrawlSessionRepository.ts` — implementa ICrawlSessionRepository con Kysely
- [x] 4.5: Crear `infrastructure/repositories/KyselyStateRepository.ts`
- [x] 4.6: Crear `infrastructure/http/CrawlingController.ts` — Express routes: POST /api/sessions, GET /api/sessions, GET /api/sessions/:id, DELETE /api/sessions/:id
- [x] 4.7: Verificar que crear sesión + ejecutar crawl funciona end-to-end
- [x] 4.8: Verificar build + commit: `fase(4): crawling infrastructure with migrated code`
---
## Phase 5: Findings Module [COMPLETO]
Spec: `.ralph/specs/phase-05-findings-module.md`
- [x] 5.1: Crear `domain/entities/Finding.ts` — AggregateRoot con severity, type, evidence, status, actionTrace
- [x] 5.2: Crear value objects: `Severity.ts` (low/medium/high/critical), `FindingType.ts`, `Evidence.ts`, `FindingStatus.ts` (open/investigating/resolved/closed)
- [x] 5.3: Crear events: `FindingCreated.ts`, `FindingResolved.ts`, `FindingEnriched.ts`
- [x] 5.4: Crear ports: `IFindingRepository.ts`, `IAIEnricher.ts`
- [x] 5.5: Crear commands: `CreateFindingCommand.ts`, `EnrichFindingCommand.ts`, `ResolveFindingCommand.ts`
- [x] 5.6: Crear queries: `GetFindingQuery.ts`, `ListFindingsQuery.ts` (filtros: severity, type, session, status, search), `FindingStatsQuery.ts`
- [x] 5.7: Crear `event-handlers/OnAnomalyDetected.ts` — escucha eventos crawling → crea Finding
- [x] 5.8: Crear `infrastructure/repositories/KyselyFindingRepository.ts`
- [x] 5.9: Migrar exporters existentes → `infrastructure/exporters/` (MarkdownExporter, JSONExporter)
- [x] 5.10: Crear `infrastructure/exporters/PlaywrightScriptExporter.ts` — genera test Playwright reproducible desde actionTrace
- [x] 5.11: Crear `infrastructure/http/FindingsController.ts` — routes para anomalies existentes + nuevas
- [x] 5.12: Migración Kysely: tabla findings con columnas status, browser, ai_enrichment_json
- [x] 5.13: Tests: Finding aggregate, CreateFinding, ListFindings con filtros
- [x] 5.14: Verificar build + commit: `fase(5): findings module complete`
---
## Phase 6: Fuzzing Module [COMPLETO]
Spec: `.ralph/specs/phase-06-fuzzing-module.md`
- [x] 6.1: Crear domain: `FuzzSession.ts` (AggregateRoot), `FuzzResult.ts` (Entity)
- [x] 6.2: Crear value objects: `FuzzStrategy.ts`, `FuzzPayload.ts`, `Seed.ts`, `FuzzIntensity.ts`
- [x] 6.3: Crear events: `FuzzStarted.ts`, `VulnerabilityDetected.ts`, `FuzzCompleted.ts`
- [x] 6.4: Crear port: `IFuzzerEngine.ts`
- [x] 6.5: Crear `commands/RunFuzzCommand.ts`
- [x] 6.6: Crear `event-handlers/OnActionExecuted.ts` — escucha crawling → trigger fuzzing
- [x] 6.7: Migrar las 5 estrategias existentes → `infrastructure/strategies/` (Empty, Oversized, SpecialChars, TypeMismatch, Boundary)
- [x] 6.8: Migrar `FuzzingEngine.ts` y `InputTypeDetector.ts``infrastructure/adapters/`
- [x] 6.9: Crear `infrastructure/http/FuzzingController.ts`
- [x] 6.10: Tests: cada estrategia de fuzzing genera payloads válidos
- [x] 6.11: Verificar build + commit: `fase(6): fuzzing module complete`
---
## Phase 7: API Server Refactor + Composition Root [COMPLETO]
Spec: `.ralph/specs/phase-07-api-server.md`
- [x] 7.1: Crear `src/api/middleware/errorHandler.ts` — AppError hierarchy (ValidationError, AuthenticationError, ForbiddenError, NotFoundError) + global error handler
- [x] 7.2: Crear `src/api/middleware/requestId.ts` — genera UUID por request, adjunta a req + pino child logger
- [x] 7.3: Crear `src/api/middleware/notFound.ts` — 404 handler para rutas no encontradas
- [x] 7.4: Crear `src/api/server.ts` — Express app con middleware stack: requestId → helmet → cors → rateLimit → bodyParser → routes → notFound → errorHandler
- [x] 7.5: Crear `src/api/router.ts` — registra routes de TODOS los módulos (crawling, findings, fuzzing)
- [x] 7.6: Crear `src/realtime/SocketGateway.ts` — socket.io server que subscribe a EventBus y emite a clientes
- [x] 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
- [x] 7.8: Implementar graceful shutdown en main.ts: SIGTERM/SIGINT → stop accepting → close sockets → close db → flush logs → exit
- [x] 7.9: Health endpoints: GET /health/live (process alive), GET /health/ready (DB check)
- [x] 7.10: Verificar que TODOS los endpoints existentes siguen funcionando tras refactor
- [x] 7.11: Verificar build + commit: `fase(7): api server refactor with composition root`
---
## Phase 8: Job Queue System [COMPLETO]
Spec: `.ralph/specs/phase-08-job-queue.md`
- [x] 8.1: Crear `src/jobs/JobQueue.ts` — interface: enqueue, start, pause, waitForActive
- [x] 8.2: Crear `src/jobs/SQLiteJobQueue.ts` — tabla jobs con status/type/payload/attempts/run_at, polling worker
- [x] 8.3: Migración Kysely: tabla jobs
- [x] 8.4: Crear `src/jobs/workers/ExplorationWorker.ts` — ejecuta crawl como job
- [x] 8.5: Crear `src/jobs/workers/ReportWorker.ts` — genera reports en background
- [x] 8.6: Integrar job queue en main.ts, mover exploraciones de sync a job-based
- [x] 8.7: Tests: enqueue → dequeue → complete cycle, failed job retry
- [x] 8.8: Verificar build + commit: `fase(8): sqlite job queue system`
---
## Phase 9: Auth Module [COMPLETO]
Spec: `.ralph/specs/phase-09-auth-module.md`
- [x] 9.1: Instalar: `npm i @casl/ability argon2 cookie-parser` (custom auth sin better-auth, per spec nota)
- [x] 9.2: Crear domain: `User.ts` (AggregateRoot), `Organization.ts` (AggregateRoot), `ApiKey.ts` (Entity)
- [x] 9.3: Crear value objects: `Email.ts`, `Role.ts` (owner/admin/member/viewer), `Permission.ts`
- [x] 9.4: Crear events: `UserCreated.ts`, `UserLoggedIn.ts`, `OrgCreated.ts`, `MemberInvited.ts`
- [x] 9.5: Crear ports: `IUserRepository.ts`, `IOrganizationRepository.ts`, `IApiKeyRepository.ts`, `ISessionRepository.ts`
- [x] 9.6: Crear commands: `RegisterCommand.ts`, `LoginCommand.ts`, `CreateOrganizationCommand.ts`, `InviteMemberCommand.ts`, `CreateApiKeyCommand.ts`
- [x] 9.7: Crear queries: `GetUserQuery.ts`, `ListOrgMembersQuery.ts`
- [x] 9.8: Crear `infrastructure/auth/PasswordService.ts` — argon2 hash/verify
- [x] 9.9: Crear `infrastructure/casl/AbilityFactory.ts` — define permisos por role
- [x] 9.10: Crear `application/middleware/AuthMiddleware.ts` — cookie → Bearer → API key → 401
- [x] 9.11: Crear `application/middleware/RBACMiddleware.ts` — verifica permisos CASL
- [x] 9.12: Crear `infrastructure/repositories/KyselyUserRepository.ts` + Org + ApiKey + Session repos
- [x] 9.13: Crear `infrastructure/http/AuthController.ts` — register, login, logout, me, setup-required, setup, orgs, api-keys
- [x] 9.14: Migración Kysely: tablas users, organizations, org_members, api_keys, auth_sessions
- [x] 9.15: First-run detection: si 0 users → GET /api/auth/setup-required retorna { required: true }
- [x] 9.16: POST /api/auth/setup — crea primer user como owner + organización default
- [x] 9.17: Integrar AuthMiddleware en todas las rutas /api/ excepto /api/auth/*
- [x] 9.18: Tests: Email, Role, User, Organization, RegisterCommand, LoginCommand, CASL (23 tests)
- [x] 9.19: Verificar build + commit: `fase(9): auth module with better-auth and casl`
---
## Phase 10: Frontend — shadcn/ui Shell [COMPLETO]
Spec: `.ralph/specs/phase-10-frontend-shell.md`
- [x] 10.1: En frontend/: instalar shadcn/ui con `npx shadcn@latest init` (Vite, Zinc, CSS variables, Tailwind)
- [x] 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
- [x] 10.3: Instalar deps: `npm i @tanstack/react-query @tanstack/react-table zustand react-hook-form @hookform/resolvers framer-motion react-hotkeys-hook`
- [x] 10.4: Crear layout: `components/layout/AppSidebar.tsx` — sidebar collapsible con nav items (Dashboard, Explorations, Findings, Reports, Settings)
- [x] 10.5: Crear `components/layout/TopBar.tsx` — logo, search trigger (⌘K), theme toggle, user avatar menu
- [x] 10.6: Crear `components/layout/AppLayout.tsx` — wrapper: Sidebar + TopBar + Content outlet
- [x] 10.7: Crear `components/layout/CommandPalette.tsx` — ⌘K con shadcn Command component
- [x] 10.8: Crear ThemeProvider: dark mode como default, toggle dark/light, persistir en localStorage
- [x] 10.9: Crear `lib/api.ts` — API client con fetch, credentials: include, auto-redirect a /login en 401
- [x] 10.10: Crear `lib/queryClient.ts` — TanStack Query provider
- [x] 10.11: Crear `stores/uiStore.ts` — Zustand: sidebarCollapsed, theme
- [x] 10.12: Crear pages/Login.tsx — form email + password con shadcn
- [x] 10.13: Crear pages/Setup.tsx — wizard first-run (crear admin + nombre org)
- [x] 10.14: Crear `components/layout/ProtectedRoute.tsx` — check auth, redirect a /login o /setup
- [x] 10.15: Actualizar App.tsx con React Router: / (dashboard), /login, /setup, /sessions/:id, /findings/:id, /settings — todo wrapped en ProtectedRoute excepto login/setup
- [x] 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`