Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions docs/adrs/T-006-frontend-vite.es.md
Original file line number Diff line number Diff line change
@@ -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.
51 changes: 51 additions & 0 deletions docs/adrs/T-006-frontend-vite.md
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion docs/architecture-review/ARCHITECTURE_REVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
4 changes: 2 additions & 2 deletions docs/audit/tracker-gap-reference-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions docs/audit/tracker-gap-tracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` |
Expand Down Expand Up @@ -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` |
Expand Down
4 changes: 4 additions & 0 deletions reference/specs/design/tracker-postgresql-data-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ CREATE INDEX idx_<table>_fts ON <schema>.<table> 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
Expand Down Expand Up @@ -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(),
Expand Down
Loading