# Feature actual: F-148 (Admin: sales dashboard and channel views) ## F-147 cerrada (2026-08-22) — Admin: reporting shell and global filters - `reporting-service.ts`: ReportingService con summary() + sales() usando CTEs SQL parametrizados. - `GET /reporting/summary` + `GET /reporting/sales` con filtros/channel/storeId/terminalId/groupBy/pagination. - 44 tests reporting (14 unit + 15 route + 15 existing); npm run build 0; boundaries 0 nuevas; verify.sh verde; commit `91044da`. - Gates: reviewer ✅ / security ✅ / qa ✅ / document ✅ / leader-close ✅. - **Siguiente**: F-147 (Admin: reporting shell and global filters). - `049_reporting_payment_lines.js`: tabla `reporting_payment_lines` (13 columnas, FK→orders_orders+pos_stores, 3 CHECK, 3 índices), inmutable (refunds como nuevas filas). patrón: INSERT-only. - `reporting-payment-lines.itest.ts` 16/16 ✅ (DB real). - npm run build 0; boundaries 0 nuevas; verify.sh verde; commit `62a368f`. - Gates: reviewer ✅ / security ✅ / qa ✅ / document ✅ / leader-close ✅. - **Siguiente**: F-146 (Reporting: service summary and sales API). ## F-146 cerrada (2026-08-22) — Reporting: service summary and sales API ## F-145 cerrada (2026-08-22) — Reporting: payment lines and POS cash-safe capture ## F-144 cerrada (2026-08-22) — Reporting snapshots: store/VAT/cost/shipping - `048_reporting_store_shipping_snapshots.js`: `orders_orders.store_id` (uuid NOT NULL DEFAULT default-store + FK→pos_stores + idx), `orders_orders.shipping_cents` (integer NOT NULL DEFAULT 0), `orders_items.cost_at_sale_cents` (bigint nullable), `orders_items.vat_rate` (text nullable). - `reporting-snapshots.itest.ts` 3/3 ✅ (DB real, migration 001→048 aplicada). - tsc 0; boundaries 0 nuevas; verify.sh verde; commit `2ea628f`. - Gates: reviewer ✅ / security ✅ / qa ✅ / document ✅ / leader-close ✅. - **Siguiente**: F-145 (Reporting: payment lines and POS cash-safe capture). ## F-138 cerrada (2026-08-22) — auto-seed default price row on variant creation - `POST /products(:id/variants)` create ahora inserta inmediatamente una fila default en `pricing_variant_prices` (`net_unit_amount_cents=0`, `vat_rate='general'`, `currency='EUR'`) vía `PricingService.seedVariantPrice` (inyectado en `CreateProductVariant`, best-effort, `ON CONFLICT DO NOTHING`). Cierra la ventana 404 de `GET /pricing/variants/:id`. Backend-only, sin migración. - Fuente: pricing `seedVariantPrice` (ports+service+PgPricingRepository), catalog `CreateProductVariant` seed (best-effort), `CatalogRoutesDeps += pricing`, `build-app.ts` hoist `pricing` const; `+` tests `variant-use-cases.test.ts` (3) + AC itest en `catalog.itest.ts`. - Gates: implementer ✅ / reviewer APPROVED ✅ / security APPROVED ✅ / qa APPROVED ✅ / leader close ✅. - Verificación: `tsc --noEmit` 0 errores; `npm test` 209 passed / 57 skipped (+3 nuevos); `lint:boundaries` sin violaciones nuevas (R1 preexistente `security.routes.ts → log-broadcaster` no introducido); `./scripts/verify.sh` verde (pre-close + post-close tras corregir `leader-close.json` verdict CLOSED→APPROVED). - Commit: `feat(F-138): completed feature` (fb01593, amendado). ## F-154 cerrada (2026-08-22) — separate customers from internal users - `GET /users` (Customers) now returns **storefront customers only** (`identity_users.role = 'customer'` filtro literal en `PgProfileRepository.listCustomers`, COUNT + SELECT). `GET /users/:id` owner-or-admin inalterado. - `GET /admin/users` (Users) now returns **internos/backoffice only** (`role <> 'customer'` base literal; `?role=admin|editor` afinando dentro de internos; `?role=customer` → vacío). - Frontend: dropdown de Users quita opción `customer` (backend ya fuerza la separación). Customers page sin cambio (llama /users → ahora customer-only). - Tests: 6 nuevos unitarios (mock, sin DB) en `pg-profile-repository.test.ts` (3) + `security.routes.test.ts` (3). `users.itest.ts` AC2/AC3 flip: /users devuelve ben (customer) no ana (admin). Full suite 206 passed / 56 skipped, sin regresiones. - Gates: implementer ✅ / reviewer APPROVED ✅ / security APPROVED ✅ / qa APPROVED ✅ / leader close ✅. - `tsc --noEmit` 0 errores (API + apps/admin); eslint/prettier limpios en archivos tocados; `lint:boundaries` sin violaciones NUEVAS (R1 preexistente en `security.routes.ts → log-broadcaster`, no introducido por F-154, verificado via git diff); `verify.sh` exit 0. - Commit: `feat(F-154): completed feature`. ## F-153 cerrada (2026-08-22) — customer email on order view - Asocia el email del cliente (`identity_users.email`, NOT NULL) al order read model vía `LEFT JOIN identity_users` en el repo, y lo expone en `serializeOrder` (detail + lista) y en la notificación del force-transition admin (usa `order.email`; se elimina el lookup inline). - `OrderView.email?: string | null` (additivo, opcional en fixtures de test → serializado como `null`). Sin migración. Boundary intacta (orders→identity_users es referencia SQL, no import TS). - Tests: 3 nuevos en `pg-order-repository.test.ts` (email resuelto vía JOIN, `null` sin usuario vinculado, `undefined` cuando no existe). Suite 200 passed / 56 skipped, sin regresiones. - Gates: implementer ✅ / reviewer APPROVED ✅ / security APPROVED ✅ / qa APPROVED ✅ / leader close ✅. - `tsc --noEmit` 0 errores; eslint 0; prettier baseline-only; `lint:boundaries` sin violaciones nuevas; `verify.sh` exit 0. - Commit: `feat(F-153): completed feature` + `chore: reset runtime after F-153`. - Pendiente siguiente por orden: **F-154** (separate customers from internal users). ## Sesión 2026-08-22 — F-152 cerrada (emails on account creation + order confirmation) - `F-152` cerrada: welcome email (`account_created`) on `POST /auth/register` y order confirmation email on `POST /payments/webhook` (PaymentSucceeded). Best-effort (fire-and-forget + `request.log.warn`), idempotent (gate `outcome.kind === "processed"`), XSS-safe (`buildWelcomeEmail` escapea name), SMTP config de `store_settings`. - Gates: implementer ✅ / reviewer APPROVED ✅ / security APPROVED ✅ / qa APPROVED ✅ / leader close ✅. - `tsc --noEmit` 0 errores; prettier+eslint limpios en archivos tocados; `lint:boundaries` sin nuevas violaciones; 197 tests ✅; `git diff --check` ✅; `verify.sh` exit 0. - Commits: `feat(F-152): completed feature` + `chore: reset runtime after F-152` (push omitido, sin remote `origin`). - `runtime-status.json` reseteado a idle. - Pendiente siguiente por orden: `F-153` (customer email missing). ## Sesión 2026-08-22 — F-156 cerrada (CMS dynamic rendering) Backlog: **269 features, 212 done, 57 pending, 0 in_progress, 0 blocked**. - `F-156` cerrada: CMS content-managed pages (`/about`, `/contact`, `/shipping`) dejan de servir caché stale. `fetchPage` usa `{ cache: 'no-store' }` y las páginas exportan `dynamic = 'force-dynamic'`; el fallback estático y el RBAC se mantienen. - Gates: implementer ✅ / reviewer APPROVED ✅ / security APPROVED ✅ / qa APPROVED ✅ / leader close ✅. - Verificado runtime: `curl -sI /about` → 200 con `Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate`; verificador temporal de DB apareció y desapareció sin rebuild. - `verify.sh` green; cambios commiteados como `feat(F-156): completed feature`; `runtime-status.json` reseteado a idle. - Pendientes inmediatos por orden sugerido: `F-152` (emails account creation/order confirmation) → `F-153` (customer email missing) → `F-154` (separate customers from internal users). Los tickets Reporting P0 pendientes son `F-143`..`F-150`. ## Sesión 2026-08-21 — Reporting preparado y builds Next estabilizados Backlog: **264 features, 209 done, 55 pending, 0 in_progress, 0 blocked**. - `F-141` cerrada: raíces `turbopack`/`outputFileTracingRoot` explícitas en customer frontend y páginas de catálogo dinámicas para que el build no dependa del API. - `F-142` cerrada: `docs/reporting/REPORTING_ARCHITECTURE.md` y `docs/reporting/REPORTING_TASKS.md` entregados tras analizar modelos reales, datos faltantes, API, rendimiento, caché, RBAC y roadmap P0-P3. - Tickets Reporting P0 abiertos: `F-143`..`F-150`; todos `pending`. - `verify.sh` exit 0 y `runtime-status.json` reseteado a idle. - Próximo ciclo: iniciar `F-143` (contracts, filtros, comparación y RBAC de Reporting) antes de implementar dashboards. ## Sesión 2026-08-21 — backlog cerrado (nota inicial, desfasada) Backlog: 185 features (185 done, 0 pending, 0 in_progress) según la nota original. Últimas features cerradas en esa nota: **F-117**, **F-116**, **F-115**, **F-112**, **F-100**. Tras esa nota se cerraron **18 features adicionales** (F-118..F-135) sin actualizar `current.md`. Quedan reflejadas en `backlog/features.json` y en `work/history.md`. ## F-117 cerrada (2026-08-21) Fix de F-116: renombre las 9 categorías que quedaron en mayúsculas (FRUTAS Y VERDURAS, SNACKS, GRANOLA, SUPLEMENTS, FACIAL, CORPORAL, ASEO PERSONAL, HIERBAS MEDICINALES, PROVEEDORES). Re-ejecución idempotente. ## F-116 cerrada (2026-08-21) Traducción de las 30 categorías legacy a Español Title Case (Alimentación, Cosmética, Bebidas, Vino, Cerveza, Macrobiótica, etc.). Slugs conservados. ## F-115 cerrada (2026-08-21) Rever de F-100: SKU-MV-{uuid} restaurado en creación de producto y lazy migration. Eliminado endpoint `/products/sku:generate` y el editor de SKU en admin. ## F-112 cerrada (2026-08-21) Disclaimer de contenido asistido por IA en la ficha de producto. Migración 040 añade `catalog_products.ai_assisted`. Flag se activa automáticamente al generar contenido con IA. Frontend muestra el `