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>
175 lines
8.9 KiB
Markdown
175 lines
8.9 KiB
Markdown
# 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 <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.
|