From bae584b56bbe15dee007a5b87e9c4159a092cb4a Mon Sep 17 00:00:00 2001 From: Alberto Arroyo Raygada Date: Wed, 8 Jul 2026 00:31:56 -0500 Subject: [PATCH] docs(adr): resolve AR-01 (accept React+Vite) and COH-002 (no Evolith backlog) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AR-01: add ADR T-006 (EN+ES) formally adopting React+Vite as the frontend foundation and superseding the Next.js requirement for the satellite (BFF-fronted SPA, no SSR/SSG dependency); mark ARCHITECTURE_REVIEW risk R1 RESOLVED. COH-002: ratify the current PRD stance (REQ-DIS-07) that Evolith owns no backlog / does no internal decomposition — annotate the backlogs/epics/user_stories(in_refinement/split) tables in tracker-postgresql-data-design.md as OBSOLETE / not implemented; no refinement entity will be built. Both marked DONE in the gap board + catalog. Co-Authored-By: Claude Opus 4.8 --- docs/adrs/T-006-frontend-vite.es.md | 51 +++++++++++++++++++ docs/adrs/T-006-frontend-vite.md | 51 +++++++++++++++++++ .../ARCHITECTURE_REVIEW.md | 2 +- docs/audit/tracker-gap-reference-catalog.md | 4 +- docs/audit/tracker-gap-tracking.md | 4 +- .../design/tracker-postgresql-data-design.md | 4 ++ 6 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 docs/adrs/T-006-frontend-vite.es.md create mode 100644 docs/adrs/T-006-frontend-vite.md diff --git a/docs/adrs/T-006-frontend-vite.es.md b/docs/adrs/T-006-frontend-vite.es.md new file mode 100644 index 00000000..79cd57a8 --- /dev/null +++ b/docs/adrs/T-006-frontend-vite.es.md @@ -0,0 +1,51 @@ +--- +title: "T-006: React + Vite como Base del Frontend (vs Next.js)" +classification: "Product ADR (Tracker-local, EvolithSatellite)" +status: "Active" +owner: "Tracker Frontend Architecture Team" +parent: "../../DECISIONS.md" +date: "2026-07-08" +relatedPhase: "Design" +extends: "None" +overrides: "None" +tags: ["EvolithSatellite", "frontend", "react", "vite", "architecture", "AR-01"] +--- + +# T-006: React + Vite como Base del Frontend (vs Next.js) + +> **Navegación bilingüe:** [English](./T-006-frontend-vite.md) · Español (este documento) +> **ADR Local (`EvolithSatellite`)** — decisión específica del producto, registrada en el `compliance.adrRegistry` del `evolith.yaml` satélite; no se promueve al Core ni está sujeta a las reglas de inmutabilidad del Core (INH-04). + +## 1. Contexto + +Una nota de requisito temprana especificaba **Next.js** para el frontend web de Tracker. La implementación, sin embargo, se construyó sobre **React 19 + Vite** (workspace Nx, `src/apps/tracker-web`). La revisión de arquitectura marcó esta desviación como riesgo **R1** ("Frontend es React+Vite, no Next.js") y gap **AR-01**, con la acción abierta *"Decidir: migrar a Next.js o aceptar React+Vite."* + +Al momento de esta decisión el frontend está completamente construido y operativo sobre Vite: 18+ pantallas conectadas al BFF/API real vía TanStack Query, baseline de typecheck limpio, ESLint en 0 errores y un job de CI (`nx build/lint/typecheck`, AR-04) que valida cada cambio. El port React de `tracker-web` es la superficie de producto en funcionamiento. + +## 2. Drivers de la Decisión + +- La aplicación ya funciona end-to-end sobre React + Vite; migrar de framework sería una reescritura completa con re-testing total. +- Tracker es una **SPA detrás de un BFF**: autenticación, SSR/edge y ruteo de API viven en el BFF backend (`Tracker.Presentation`), no en la capa web. La propuesta de valor server-side de Next.js (SSR/SSG, API routes, middleware) es en gran medida redundante dado el perímetro BFF. +- Vite + Nx da HMR rápido, un build estático simple servido por nginx (ver `src/apps/tracker-web/Dockerfile`) e integración limpia con los targets Nx existentes. +- Ningún requisito del PRD vigente depende de SSR/SSG ni de capacidades específicas de Next.js. + +## 3. Decisión + +**Adoptar React 19 + Vite como la base canónica del frontend de Evolith Tracker.** El requisito original de Next.js queda **formalmente superado** para este satélite. Este ADR es la aceptación registrada para la fila **T-006 (ADR-0044)** de `DECISIONS.md` y **cierra el riesgo R1 / gap AR-01** de ARCHITECTURE_REVIEW. + +Si un requisito futuro necesita genuinamente SSR/SSG, renderizado en edge o ruteo por sistema de archivos que el modelo SPA + BFF no pueda servir, ese requisito se levantará como un ADR nuevo en lugar de reabrir este. + +## 4. Consecuencias + +**Positivas** +- Cero reescritura; el frontend en funcionamiento y validado por CI se mantiene tal cual. +- Despliegue más simple (assets estáticos vía nginx) y un único perímetro de seguridad (el BFF). +- Dev local rápido (Vite HMR) y tooling Nx consistente en todo el workspace. + +**Negativas / Compromisos** +- Sin SSR/SSG ni middleware de Next.js integrados; si alguna vez se requieren, deben introducirse deliberadamente (ADR nuevo). +- SEO / first-paint para páginas públicas no autenticadas no está optimizado de fábrica — aceptable para una herramienta interna de gobierno autenticada. + +**Seguimiento** +- ARCHITECTURE_REVIEW R1 marcado RESUELTO (referencia este ADR). +- Las menciones a "Next.js" del documento de arquitectura objetivo son históricas; este ADR es la autoridad para el stack de frontend. diff --git a/docs/adrs/T-006-frontend-vite.md b/docs/adrs/T-006-frontend-vite.md new file mode 100644 index 00000000..e9a7a585 --- /dev/null +++ b/docs/adrs/T-006-frontend-vite.md @@ -0,0 +1,51 @@ +--- +title: "T-006: React + Vite as the Frontend Foundation (vs Next.js)" +classification: "Product ADR (Tracker-local, EvolithSatellite)" +status: "Active" +owner: "Tracker Frontend Architecture Team" +parent: "../../DECISIONS.md" +date: "2026-07-08" +relatedPhase: "Design" +extends: "None" +overrides: "None" +tags: ["EvolithSatellite", "frontend", "react", "vite", "architecture", "AR-01"] +--- + +# T-006: React + Vite as the Frontend Foundation (vs Next.js) + +> **Bilingual navigation:** English (this document) · [Español](./T-006-frontend-vite.es.md) +> **Local ADR (`EvolithSatellite`)** — product-specific decision, recorded in the satellite `evolith.yaml` `compliance.adrRegistry`; not promoted to Core nor subject to Core immutability rules (INH-04). + +## 1. Context + +An early requirement note specified **Next.js** for the Tracker web frontend. The implementation, however, was built on **React 19 + Vite** (Nx workspace, `src/apps/tracker-web`). The architecture review flagged this divergence as risk **R1** ("Frontend is React+Vite, not Next.js") and gap **AR-01**, with the open action *"Decide: migrate to Next.js or accept React+Vite."* + +At the time of this decision the frontend is fully built and operational on Vite: 18+ screens wired to the real BFF/API via TanStack Query, a typecheck-clean baseline, ESLint at 0 errors, and a CI job (`nx build/lint/typecheck`, AR-04) that gates every change. The `tracker-web` React port is the working product surface. + +## 2. Decision Drivers + +- The application already runs on React + Vite end-to-end; a framework migration would be a full rewrite with complete re-testing. +- Tracker is a **BFF-fronted SPA**: authentication, SSR/edge concerns, and API routing live in the backend BFF (`Tracker.Presentation`), not in the web tier. Next.js's server-side value proposition (SSR/SSG, API routes, middleware) is largely redundant given the BFF perimeter. +- Vite + Nx gives fast HMR, a simple static build served by nginx (see `src/apps/tracker-web/Dockerfile`), and clean integration with the existing Nx targets. +- No product requirement in the current PRD depends on SSR/SSG or Next.js-specific capabilities. + +## 3. Decision + +**Adopt React 19 + Vite as the canonical frontend foundation for Evolith Tracker.** The original Next.js requirement is **formally superseded** for this satellite. This ADR is the recorded acceptance for `DECISIONS.md` row **T-006 (ADR-0044)** and **closes ARCHITECTURE_REVIEW risk R1 / gap AR-01**. + +If a future product requirement genuinely needs SSR/SSG, edge rendering, or file-system routing that the SPA + BFF model cannot serve, that requirement will be raised as a new ADR rather than reopening this one. + +## 4. Consequences + +**Positive** +- Zero rewrite; the working, CI-gated frontend stands as-is. +- Simpler deployment (static assets via nginx) and a single security perimeter (the BFF). +- Fast local dev (Vite HMR) and consistent Nx tooling across the workspace. + +**Negative / Trade-offs** +- No built-in SSR/SSG or Next.js middleware; if ever required, it must be introduced deliberately (new ADR). +- SEO / first-paint for public unauthenticated pages is not optimized out-of-the-box — acceptable for an authenticated internal governance tool. + +**Follow-up** +- ARCHITECTURE_REVIEW R1 marked RESOLVED (references this ADR). +- The target-architecture document's "Next.js" mentions are historical; treat this ADR as the authority for the frontend stack. diff --git a/docs/architecture-review/ARCHITECTURE_REVIEW.md b/docs/architecture-review/ARCHITECTURE_REVIEW.md index 28e2cc19..21f49891 100644 --- a/docs/architecture-review/ARCHITECTURE_REVIEW.md +++ b/docs/architecture-review/ARCHITECTURE_REVIEW.md @@ -691,7 +691,7 @@ flowchart TB | # | Risk | Severity | Impact | Mitigation | |---|------|----------|--------|------------| -| R1 | **Frontend is React+Vite, not Next.js** | CRITICAL | User requirement violated | Decide: migrate to Next.js or accept React+Vite | +| R1 | **Frontend is React+Vite, not Next.js** | ~~CRITICAL~~ **RESOLVED** | Accepted divergence | **Accepted React+Vite** — see ADR [T-006](../adrs/T-006-frontend-vite.md) (2026-07-08). The Next.js requirement is formally superseded for this satellite (BFF-fronted SPA; no SSR/SSG dependency). | | R2 | **No BFF implemented** | HIGH | Core integration has no auth perimeter | Implement BFF before any Core integration | | R3 | **No Docker/K8s manifests** | HIGH | Cannot deploy to K8s | Create Dockerfiles + Kustomize overlays | | R4 | **No CI/CD for build/test** | HIGH | Manual builds, no quality gates | Implement GitHub Actions for .NET + React | diff --git a/docs/audit/tracker-gap-reference-catalog.md b/docs/audit/tracker-gap-reference-catalog.md index 94116d2f..8278c5fd 100644 --- a/docs/audit/tracker-gap-reference-catalog.md +++ b/docs/audit/tracker-gap-reference-catalog.md @@ -513,7 +513,7 @@ This catalog explains each gap: problem, purpose, evidence, closure criteria, an - **Stories:** US-DIS-006,007 - **Criticality:** P0 · **Complexity:** L - **Resolution / Next step:** Pending owner/action definition in this register. - - **Status:** `PENDING` — DECISIÓN, no implementar: la entidad de refinamiento contradice la postura ratificada "Evolith no posee backlog"; reconciliar spec-vs-spec antes de tocar código. + - **Status:** `DONE` (obsoleto) — se ratifica "Evolith no posee backlog"; tablas backlogs/epics/user_stories anotadas OBSOLETAS en `tracker-postgresql-data-design.md`; no se construye entidad de refinamiento. #### COH-003 @@ -1651,7 +1651,7 @@ This catalog explains each gap: problem, purpose, evidence, closure criteria, an - [ ] El framework frontend coincide con el stack requerido por el usuario. - [ ] Si Next.js: SSR/SSG configurado, middleware activo, API routes funcionales. - **Dependencies:** Ninguno — decisiónfundacional. - - **Status:** `PENDING` — DECISIÓN, no bug: React+Vite ratificado provisionalmente (T-006/ADR-0044); falta un ADR formal que acepte/rechace la desviación de Next.js. + - **Status:** `DONE` — decidido aceptar React+Vite; ADR formal [T-006](../adrs/T-006-frontend-vite.md) (EN+ES); ARCHITECTURE_REVIEW R1 RESUELTO; requisito Next.js superado para el satélite. #### AR-02 diff --git a/docs/audit/tracker-gap-tracking.md b/docs/audit/tracker-gap-tracking.md index 8c65142f..483ab6f1 100644 --- a/docs/audit/tracker-gap-tracking.md +++ b/docs/audit/tracker-gap-tracking.md @@ -22,7 +22,7 @@ This board is the single source of truth for Tracker technical debt, gaps, oppor | [`LV-11`](./tracker-gap-reference-catalog.md#lv-11) | Backend build warnings: 64 × CS0108 (per-aggregate `Id` hiding the Shell.Ddd `Entity` base) + 84 × CS8618 (non-nullable uninitialized) + 2 × CS8620. **Fixed:** 150→0 warnings with real fixes (explicit `new` on intentional `Guid Id` hides, `required` on Props records, element-wise nullability widening at 1 call site); no suppression, 428 tests green. | `Backend` | Cross | P2 | M | `DONE` | | [`LV-12`](./tracker-gap-reference-catalog.md#lv-12) | Frontend lint debt: 39 problems (5 errors + 34 warnings). **Fixed:** `--fix` + manual → **0 errors** (dead code / unused-symbol removal, an equivalent if/else, removed 2 stale eslint-disable comments); 8 `any`/non-null-assertion warnings left by design (fixing = typing refactor). Typecheck still 0. | `WEB` | Cross | P3 | S | `DONE` | | [`LV-13`](./tracker-gap-reference-catalog.md#lv-13) | Dev-seed papercut: the DevBypass platform-root tenant (`11111111…`) is a phantom — no seeder creates it, so local dev must create tenants by hand before tenant-scoped screens work. **Fixed:** `DevTenantSeedHostedService` (Development-only gate before any DB access, idempotent, seeds 3 bare demo tenants via `Tenant.Create` + repo — no geo, left for the UI). Testing/Prod no-op. | `Backend/WEB` | Cross | P3 | S | `DONE` | -| [`COH-002`](./tracker-gap-reference-catalog.md#coh-002) | **DECISIÓN, no implementar:** la entidad de refinamiento no está modelada ni persistida; la tabla `user_stories(in_refinement/split)` solo sobrevive en la spec de datos, que ahora **contradice** la postura ratificada "Evolith no posee backlog / sin descomposición interna" (PRD REQ-DIS-07, ddd-model §Boundaries). Reconciliar spec-vs-spec antes de tocar código. | `Backend` | Discovery | P0 | L | `PENDING` | +| [`COH-002`](./tracker-gap-reference-catalog.md#coh-002) | **Decidido (obsoleto):** se ratifica "Evolith no posee backlog / sin descomposición interna" (PRD REQ-DIS-07). Las tablas `backlogs`/`epics`/`user_stories(in_refinement/split)` de `tracker-postgresql-data-design.md` quedan anotadas como OBSOLETAS/no-implementar; no se construye entidad de refinamiento. | `Backend` | Discovery | P0 | L | `DONE` | | [`COH-004`](./tracker-gap-reference-catalog.md#coh-004) | **Hecho (coherencia):** "TestRun" ya no se usa (solo aparece en docs de auditoría); las specs modelan consistentemente TestCycle+TestExecution(+Defect). El contexto QA (`tracker_qa`) sigue sin construir pero es roadmap Fase 3 — se trackea aparte, no bloquea construcción. | `Backend` | QA | P0 | L | `DONE` | | [`CR-21`](./tracker-gap-reference-catalog.md#cr-21) | Las 5 pantallas canónicas están ruteadas y accesibles (Gate Decision/Evaluation = `GateEvaluationMd3` ya existe — la nota "pendiente" estaba desactualizada); único faltante: un **browser de ADRs** dedicado (hoy los ADRs son solo tags en blueprints). | `WEB` | Cross | P1 | S | `IN-PROGRESS` | | [`GAP-010`](./tracker-gap-reference-catalog.md#gap-010) | **Hecho:** existe `reference/knowledge/domain/PRODUCT_VISION.md` (EN) con navegación bilingüe a `PRODUCT_VISION.es.md`. | `Docs` | Cross | P1 | M | `DONE` | @@ -54,7 +54,7 @@ This board is the single source of truth for Tracker technical debt, gaps, oppor | [`COH-009`](./tracker-gap-reference-catalog.md#coh-009) | BR-003 conflated: product-brief = "no deploy without QA gate", but 5+ stories invoke as "human authorization required." Two rules sharing one ID. | `Backend` | Release | P3 | S | `PENDING` | | [`COH-012`](./tracker-gap-reference-catalog.md#coh-012) | Gherkin covers only 2 of 4 CRUD operations (Create, Update). Delete and Read entirely missing. Zero edge cases (invalid data, missing record, duplicates, reordering failure). | `Backend` | Discovery | P3 | S | `PENDING` | | [`GAP-021`](./tracker-gap-reference-catalog.md#gap-021) | Redis in Docker Compose Without Requirement | `Docs` | Cross | P3 | M | `PENDING` | -| [`AR-01`](./tracker-gap-reference-catalog.md#ar-01) | **DECISIÓN (no un bug):** frontend es React+Vite (ratificado provisionalmente T-006/ADR-0044); falta un ADR que acepte o rechace formalmente la desviación del requisito Next.js y cierre ARCHITECTURE_REVIEW R1. | `WEB` | Cross | P0 | L | `PENDING` | +| [`AR-01`](./tracker-gap-reference-catalog.md#ar-01) | **Decidido:** aceptar React+Vite. ADR formal [T-006](../adrs/T-006-frontend-vite.md) (EN+ES) registra la adopción y supera el requisito Next.js para el satélite (SPA detrás del BFF; sin dependencia SSR/SSG); ARCHITECTURE_REVIEW R1 marcado RESUELTO. | `WEB` | Cross | P0 | L | `DONE` | | [`AR-02`](./tracker-gap-reference-catalog.md#ar-02) | Perímetro BFF (auth + contexto tenant + guards de permiso `.RequireTrackerPermission`) y gateways salientes a Core (`CoreEvaluationGateway`/`CoreArchitectureGateway`/`AgentRuntimeGateway`) implementados en `Tracker.Presentation` (no un proyecto `Tracker.BFF` aparte como pedía la aceptación). Falta: verificación e2e contra un Core/UMS real. | `API/Arch` | Cross | P0 | L | `IN-PROGRESS` | | [`AR-03`](./tracker-gap-reference-catalog.md#ar-03) | Dockerfiles multi-stage (api+web) y charts Helm completos en `product/infra/helm/` existen — "despliegue imposible" es falso. Falta: `docker-compose` para dev local y/o overlays Kustomize (se eligió Helm; reconciliar el texto de aceptación). | `Infra` | Cross | P0 | L | `IN-PROGRESS` | | [`AR-04`](./tracker-gap-reference-catalog.md#ar-04) | **Hecho:** `.github/workflows/ci.yml` con quality gates automáticos — job backend (restore, build Release `-warnaserror` = 0 warnings, servicio PostgreSQL + migraciones EF, `dotnet test` con los 428 tests incl. integración LV-10 que ahora **corren** en CI) y job frontend (`nx lint`/`typecheck`/`build` de tracker-web). Dispara en push/PR a main+develop. Falta aún (menor): CI de build de imágenes Docker + deploy. | `Infra` | Cross | P0 | M | `DONE` | diff --git a/reference/specs/design/tracker-postgresql-data-design.md b/reference/specs/design/tracker-postgresql-data-design.md index 90a4d417..b9fbd5b7 100644 --- a/reference/specs/design/tracker-postgresql-data-design.md +++ b/reference/specs/design/tracker-postgresql-data-design.md @@ -116,6 +116,8 @@ CREATE INDEX idx__fts ON .
USING gin(to_tsvector('english' ## 3. Schema: tracker_discovery +> ⚠️ **OBSOLETO en parte (decisión COH-002, 2026-07-08).** Las tablas de **descomposición de backlog** en este schema — `backlogs`, `epics`, `user_stories` (con estados `in_refinement`/`split`) — **no se implementan**. El PRD vigente (`reference/specs/discovery/prd.md`, REQ-DIS-07) y el `ddd-model.md` ratifican que **Evolith no posee un backlog propio ni realiza descomposición interna** (integra descomposición desde herramientas PPM externas vía ACL). Sólo `initiatives` (+ opportunities, refinement soft-refs) son canónicas en Discovery. Estas definiciones se conservan sólo como referencia histórica; ver el board de gaps `docs/audit/tracker-gap-tracking.md` (COH-002). + ### 3.1 initiatives ```sql @@ -222,6 +224,8 @@ CREATE INDEX idx_epics_assignee ON tracker_discovery.epics (tenant_id, assignee_ ### 3.4 user_stories +> ⚠️ **OBSOLETO — NO implementar (COH-002).** Evolith no posee backlog propio; los estados `in_refinement`/`split` y esta tabla no se materializan. Ver el callout al inicio del schema `tracker_discovery`. + ```sql CREATE TABLE tracker_discovery.user_stories ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(),