evOo-local/docs/PRODUCTION-READINESS.md
cynarAI e4b995ec14
Production readiness Phase 2: DE profile facts, mobile audit, route matrix E2E (#176)
* feat(web): Phase 2 production readiness — locale, mobile, E2E matrix

Localize onboarding focus facts by profile locale (DE assertion).
Add mobile overflow/touch audits, deep-link matrix, extended console
checks, and E2E for empty project, session unavailable, and teaching
composer. Safe-area and Heute header layout on 390px viewports.

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(e2e): stabilize Phase 2 specs for mobile shell and empty project

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(api): satisfy typecheck for focusFactValue

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(api): type-safe focusFactValue lookup

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(api): narrow focus fact locale key

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(api): use FocusOptionId union for fact lookup

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* test(web): align Shell header control assertions with touch targets

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* style(web): format desktop header control test

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(web): stabilize Phase 2 E2E (settings i18n, empty project, chart plot load)

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(web): empty project E2E simulates pre-start bootstrap; relax module recovery wait

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(web): format empty-project E2E; stabilize chart-links cold Plot load

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* test(web): run chart-links E2E serially to reuse warmed Plot module

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* style(web): format chart-links E2E

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
2026-10-07 15:26:09 +02:00

175 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# evOo-local production readiness
Audit of user journeys, automated coverage, known defects, and backlog. Scope: web app (`apps/web`), API, shared packages; mobile (`apps/mobile`) noted where CI does not cover it.
## Product surfaces
| Surface | Entry | Locales in CI |
|--------|--------|----------------|
| Desktop web | ≥768px viewport | EN + DE in targeted specs |
| Mobile web | 390×844, touch | EN + DE in targeted specs |
| API / Postgres journeys | `packages/testkit` | EN |
| Mobile native | Expo app | Maestro smoke only (not full matrix) |
## User journey inventory
Legend: **E2E** = Playwright under `apps/web/e2e/`; **Unit** = vitest in app/packages; **PG** = postgres journey in testkit; **Gap** = missing or partial automation.
### First run & onboarding
| Journey | Routes / UI | Desktop E2E | Mobile E2E | Unit/PG | Gaps |
|--------|-------------|-------------|------------|---------|------|
| Sign up | `/sign-up` | `golden`, `first-run-onboarding-ux` | same | auth PG | — |
| Look category & swipe | `/onboarding` emoji step | `onboarding-oo-swipe`, `onboarding-emoji-first` | swipe spec (desktop viewport) | — | Mobile-specific swipe gestures |
| Name Oo | name step | `first-run-onboarding-ux` | partial | — | — |
| Language | language step | `first-run-onboarding-ux`, `ui-locale` | DE skip label | — | — |
| Voice | voice step | `first-run-onboarding-ux`, `voice` | DE voices | — | Offline voice errors (no vendor names in UI) |
| Integrations / scan | optional steps | `onboarding-discovery`, `onboarding-complete` | — | onboarding PG | — |
| Reload mid-onboarding | `/onboarding` | `onboarding-reload-persistence` | same | `onboarding-draft.test` | — |
| Intake cards (focus, goal, rhythm, quiet hours) | `/app/g/…` | `onboarding-intake` | **`onboarding-intake-de`** | onboarding-intake PG | Full DE rhythm/quiet copy in cards (UI localized; server stores locale-aware focus facts) |
| Deep link `/onboarding` while signed in | redirect rules | **`route-deep-link-matrix`** | same | — | — |
### Session & auth
| Journey | Routes | E2E | Gaps |
|--------|--------|-----|------|
| Sign in / out | `/sign-in`, `/` | `auth-lifecycle`, `browser-auth` | Tailscale / cookie edge cases |
| Password reset | `/forgot-password`, `/reset-password` | `auth-lifecycle` | — |
| Session unavailable / retry | `/app` loading | **`session-unavailable`**, `module-recovery` | — |
| Welcome (signed out) | `/` | `smoke`, **`route-deep-link-matrix`** | — |
### Heute (daily brief)
| Journey | Route | E2E | Gaps |
|--------|-------|-----|------|
| Open Heute | `/app/heute` | `heute-brief`, **`mobile-layout-audit`** | — |
| Coach / goals list | Heute UI | `heute-brief` | — |
| Deep link reload | `/app/heute` | **`route-deep-link-matrix`**, **`journey-console-errors`** | — |
### 1:1 & group chat
| Journey | Route | E2E | Gaps |
|--------|-------|-----|------|
| Main conversation | `/app/g/:groupId` | `main-conversation`, `first-conversation` | — |
| Bot thread | `/app/:botId` | many specs | — |
| Send message | composer | `message-send` | — |
| Streaming / progress | transcript | `chat-progress-messages`, `chat-queued-progress` | Real LLM latency (mocked) |
| Queued / slow model UI | composer + transcript | `chat-queued-progress` | Multi-run queue depth |
| Errors & retry | composer banner | `run-failure`, `computer-screen-error` | — |
| Stop run | composer | `golden` | — |
| Peer / group | `/app/g/…` | `group-chats`, `peer-messages` | — |
| Console cleanliness | main paths | **`journey-console-errors`** (full route + settings matrix) | — |
### Oos (bots)
| Journey | E2E | Gaps |
|--------|-----|------|
| Create / name / archive / delete | `bot-crud`, `new-bot-ux` | — |
| Switch bot / sidebar | `sidebar-nav`, `unterhaltungen-sidebar` | — |
| Avatar / look | `oo-avatar`, `look-suggestion` | — |
| Capabilities | `bot-capabilities` | — |
| Team vs dedicated computer | `team-computer` | Real docker teardown in PG |
### Projekte
| Journey | E2E | Gaps |
|--------|-----|------|
| Create project space | `spaces`, `adaptive-workspace` | — |
| Bind folder + git | `project-main-agent` | — |
| Timeline / goals | `project-main-agent` | Voice-first goal card |
| Empty project | **`empty-project-state`** | — |
### Settings
| Journey | E2E | Gaps |
|--------|-----|------|
| General / account | `settings-shell`, `user-profile` | — |
| Language (UI locale) | `ui-locale` | — |
| Voice | `voice`, `media-settings` | — |
| Goal / intake copy (DE) | **`onboarding-intake-de`** (focus fact in profile) | Extend locale matrix beyond DE |
| Privacy / delete account | `settings-privacy` | — |
| Model connection | `model-settings`, `models-managed` | Offline model banner |
| Notifications / quiet hours | `notification-settings` | — |
| Messaging | `messaging-settings` | — |
### Account & space deletion
| Journey | E2E / PG | Gaps |
|--------|----------|------|
| Delete account (API) | PG journey 11, **`account-delete-sandbox.postgres`** | — |
| Delete empty space | authorization PG | — |
### Empty, error, offline
| Journey | Coverage | Gaps |
|--------|------------|------|
| No model connected | `model-settings`, composer banner | — |
| Server unreachable | **`session-unavailable`** | — |
| Empty inbox / no bots | partial | — |
| Teaching blocks composer | **`teaching-composer`** | — |
### Navigation, keyboard, a11y
| Journey | E2E | Gaps |
|--------|-----|------|
| Escape closes mobile drawer | `first-run-onboarding-ux` mobile | — |
| Command palette | `command-palette` | — |
| Mention picker keyboard | `mention-picker-keyboard` | — |
| Collapsible sidebar | `collapsible-sidebar-sections`, `mobile-sidebar-swipe` | — |
| Mobile 390px overflow | **`mobile-layout-audit`** | Broader route list |
| Touch targets ≥44px | **`mobile-layout-audit`** | Broader control list |
| Focus management on drawer close | mobile esc test | Broader focus trap review |
### Integrations & MCP
| Journey | E2E | Gaps |
|--------|-----|------|
| Integration setup | `integration-setup` | — |
| MCP OAuth callback | `mcp-oauth` | — |
| GraphQL integrations | `graphql-integrations` | — |
## Prioritized defect list
Severity: **P0** ship blocker · **P1** major UX/trust · **P2** polish · **P3** nice-to-have
### Fixed in Phase 1 ([PR #175](https://github.com/cynarAI/evOo-local/pull/175))
| ID | Sev | Issue | Fix |
|----|-----|-------|-----|
| PR1-1 | P1 | Reload during onboarding lost look/name/step | Session draft via `onboarding-draft.ts` |
| PR1-2 | P1 | DE UI: goal placeholder / discovery “Chief of Staff” English | Lingui for discovery; intake DE E2E |
| PR1-3 | P1 | Account delete left team sandbox + homes | Scoped `destroySpaceSandboxes` on account delete |
| PR1-4 | P1 | Chat felt idle while queued / slow send | Composer `sending`+run chrome; queued label; 120s watchdog |
| PR1-5 | P2 | Console errors on main journeys | Initial `journey-console-errors` spec |
### Fixed in Phase 2 (this PR)
| ID | Sev | Issue | Fix |
|----|-----|-------|-----|
| R2-1 | P1 | Profile focus fact values stored in English for DE users | `focusFactValue()` in `onboarding-intake.ts`; DE assertion in `onboarding-intake-de` |
| R2-2 | P1 | PG journey: account delete sandbox/home teardown | Phase 1 `account-delete-sandbox.postgres` + journey 11 |
| R2-3 | P2 | Persona-test console/network errors | Extended `journey-console-errors` + deep-link matrix; benign React Router / source-map filtering |
| R2-4 | P2 | 390px layout overflow | Heute header wrap; shell safe-area; **`mobile-layout-audit`** |
| R2-5 | P2 | Touch targets &lt;44px | `rk-touch-target` on mobile nav/back; **`mobile-layout-audit`** |
| R2-6 | P2 | Deep link / reload matrix | **`route-deep-link-matrix`** |
| R2-7 | P2 | Empty project / SessionUnavailable / teaching composer E2E | **`empty-project-state`**, **`session-unavailable`**, **`teaching-composer`** |
### Remaining — Phase 3+
| ID | Sev | Issue | Notes |
|----|-----|-------|-------|
| R3-1 | P2 | Offline / model-not-connected on mobile web | Dedicated E2E with RPC fixtures |
| R3-2 | P2 | Intake card rhythm/quiet option labels server-side for non-EN history | Cards localized in web; stored English option labels for agent history |
| R3-3 | P3 | Mobile native parity for onboarding reload | Expo secure store draft |
| R3-4 | P3 | Intake card English questions in non-EN tests | Extend locale matrix beyond DE |
| R3-5 | P3 | NPS/SUS follow-ups from persona round 2 | Product research, not CI |
| R3-6 | P3 | Tailscale / exotic auth cookie edge cases | Manual / staging |
## CI gates (Product)
Lint · Typecheck · Unit · Postgres journeys · Production builds · Web E2E (Playwright). Desktop Electron E2E runs in CI virtual display only.
## How to extend this doc
When adding a journey spec, update the table row and move defects from **Remaining** to **Fixed** with PR link. Keep user-visible copy quoted in PR descriptions when introducing new strings.