Skip to content

Planning audit — updated 2026-07-16 against the coach-me app repo

What's left to handle during development.

Foundation infrastructure (monorepo, local Docker Compose, env matrix, executable CI, migrate/seed wiring), the cross-system authority set, and the pre-development decisions are all in place and recorded in their authority docs. This page no longer repeats them — it tracks only what still needs deciding, building, or proving as milestones proceed.

Where things stand

The entire M1 backend is implemented. Foundation, Onboard, the event/outbox standard, and Assign are merged to master (2026-07-18). The Execute backend — the Offline Sync Protocol (device registration/revocation, batched push with per-operation receipts and exact-replay, workspace-bounded pull slice) plus the workout-log aggregate with conflict semantics, outbox events, and integrity-scan coverage — is on the app repo's m3/complete branch (2026-07-18, pending merge). Cross-client push isolation, receipt-overwrite races, and revoked-device enforcement were review-hardened with dedicated e2e evidence. apps/web remains a stub and no mobile apps exist — the remaining M1 work is the web/mobile surfaces on top of this API, plus the open items below.

M1/M2 backend — open calls from review

Recorded during the 2026-07-18 implementation reviews; each needs a deliberate product/contract answer, none blocks the next milestone.

  • Same-day correction windowWorkout Logging grants corrections until end of the same local day (COMPLETED → CORRECTED), but M1 has no revision model and returns LIFECYCLE_CLOSED for any mutation of a closed log. Accept the M1 deferral or schedule the revisions sub-feature.

  • Old-snapshot submissionsOffline Workout Mode accepts submissions against a package that was valid at training start; M1 conflicts every non-ACTIVE assignment as SUPERSEDED_ASSIGNMENT because no snapshot model exists (same root as the assignment-snapshot call below).

  • Delta sync ownership — M1 pull is full-state; clientCursor/serverCursor are shape-compatible but non-functional watermarks (documented on the DTOs). Decide which milestone owns real incremental sync and a receipt cursor.

  • Pull visibility of PUBLISHED/PAUSED assignments — M1 serves ACTIVE only; the Workflow State Map supports both readings once those states become creatable.

  • Checksum enforcement posture — replay divergence rejects as PAYLOAD_INVALID; full server-side verification needs the docs to specify payload canonicalization and the hash algorithm.

  • Assignment snapshot immutability — M1 assignments reference the live editable program, so a coach edit changes an assigned client's plan (deviation from Program Builder's immutable-snapshot rule, recorded as TODOs in code). Accept live-tree reads until the version/snapshot model lands, or edit-lock assigned programs (supersede-to-edit) in the interim?

  • Workflow correlation propagation — each HTTP operation mints a fresh correlationId, so one relationship's created/consumed/activated/assigned events carry unrelated ids. Decide the continuation mechanism (e.g. persist a workflow correlation id on the invitation/relationship) per the Event And Outbox Standard.

  • Questionnaire-gate clearing leg — the implemented assignment gate treats "a submission row exists" as submitted; the docs also clear the block on explicitly cancelled questionnaires, a mechanism M1 lacks. Confirm cancellation-clearing waits for the Forms model.

  • Idempotency body fingerprint — receipts are keyed by (workspace, endpoint, key) with no request-body hash, so key reuse across different bodies silently replays the wrong resource. Extend the API Contract Standard to mandate a fingerprint?

  • Revoke vs unassign replay consistency — unassign now replays an accepted cancel with 200; invitation revoke still returns 409 on repeat (the earlier recorded deviation). Align revoke to replay semantics?

  • Activation gate — the code activates a relationship on profile completion with the questionnaire pending, following client-login-during-onboarding and onboarding-workflow; confirm the M1 scope line "completes profile and one questionnaire" was a deliverables list, not an activation gate.

  • Coach-registration email binding — invitation accept now binds to the verified provider email claim; coach registration still accepts a body-supplied email. Decide whether registration should also bind to the claim.

  • Idempotency receipts retain the raw invite token for the 24-hour replay window; alternative is token-less replay at the cost of useless retries.

  • Repeat revoke returns 409 rather than replaying the prior result — a minor deviation from strict command-retry semantics in the API Contract Standard.

  • Auth-identity uniqueness (carried from Foundation) — schema indexes (provider, issuer, subject); the Domain Model Map wording includes a tenant component. Add the column or amend the map.

  • Migration-history cutoff (carried from Foundation) — record in the Toolchain Contract when migration history becomes append-only; migrations 0001/0002 already follow append-only.

Open decisions

Small, deferrable calls that bite when a specific feature reaches them — not before.

  • Object-storage service + region — the two-bucket topology (media, documents) is set; the service and region wait on a PDPL residency review (a legal call, not technical). Blocks the first media upload, not Milestone 1.
  • Staging object-storage backend — MinIO is approved local-only, so the staging VPS has no approved storage backend yet. Cheap to settle in the Integration Register; blocks nothing today.
  • Telegram OIDC login spike — validate BotFather → Keycloak generic OIDC → phone consent before treating Telegram as a conditional V1 login provider. Parallel to Milestone 1.
  • Production topology + data region — staging is decided (Hostinger KVM 4 on Compose behind Traefik). Production host and region remain deliberately open until real data is near.
  • Media-processing limits and integration quotas — set before UI commits to them.

Foundation — implemented, pending merge

All five execution items landed on the app repo's foundation/complete branch (2026-07-17), reviewed against the authority docs and gated by a green pnpm verify with the tenant-fence negative tests executing against Postgres in CI. Two follow-ups surfaced during review and need a deliberate call:

  • Auth-identity uniqueness — the schema indexes (provider, issuer, subject); the Domain Model Map words ProviderRef uniqueness as provider, issuer, tenant, subject. Practically safe today because Keycloak encodes the realm in the issuer URL, but schema and map now disagree — either add the tenant component or amend the map.
  • Migration-history convention — the initial migration was regenerated in place (replace, don't stack) during Foundation; fine while no promoted environment exists, but an explicit cutoff after which history becomes append-only should be recorded in the Toolchain Contract.

The deliberately deferred release-gate capabilities (coverage thresholds, Playwright/Maestro E2E, security scanners, the worker/BullMQ service, the upgraded seeded-migration gate) remain tracked in the app repo's docs/foundation-todo.md.

Launch evidence to produce during milestones

Each authority exists; implementation must now prove it. This is milestone exit-criteria work, not a start blocker.

  • Workflow State Map — map each milestone to authority-owned entry/exit/terminal states; provide integration evidence for the invitation → onboarding → assignment → execution → review → offboarding transitions and for skip/pause/resume/reactivation.
  • Privacy And Retention — UAE PDPL and per-GCC-country legal review; prove consent/version capture, export, deletion/anonymization, retention expiry, media purge, and legal hold; map schema fields, media, mobile caches, and telemetry to the approved data classes; confirm the wellness-only boundary before launch.
  • Roles And Permissions — encode one-active-relationship, self-coaching, lifecycle, and source-context rules in schema and guards; prove mobile-cache isolation, ended/retained access, telemetry minimization, and raw-data denial; implement target-scoped, reason-coded, time-limited, audited support/admin grants.
  • Environment Runbook (production) — prove backup, restore, rollback, and deployment gates before production data exists; add worker/BullMQ services and Expo/mobile deep-link surfaces as those apps arrive.
  • API / Event / Offline contracts — generate OpenAPI clients and prove validation, errors, idempotency, correlation, and contract-drift; implement and test transactional outbox publishing, bounded retries, dead letters, and recovery; implement and test device registration, local outbox, receipts, conflicts, and replay.
  • Observability Plan — select and approve Grafana Cloud, Sentry, and protected Alloy in the Integration Register; implement retention, named MFA access, environment filtering, source maps, dashboards, alerts, and synthetics; capture staging evidence for redaction, symbolication, queue/provider diagnosis, and alert delivery.
  • Test And Release Gate — implement the Toolchain-owned scripts and required GitHub Actions checks; create the versioned synthetic fixture baseline and staging suites; generate a release report that proves every required check and captures go/no-go.
  • Toolchain Contract (mobile + E2E) — wire Playwright and Maestro as the web and mobile surfaces exist; define mobile build profiles; prove code-ownership boundaries across apps/* and shared packages once mobile is scaffolded.

Product behavior still to define

Concrete flows the feature pages do not yet specify. These need product decisions before or during the milestone that touches them.

Coach Setup

  • Workspace setup wizard: profile, brand, timezone, language, units, default questionnaire, default reminders.
  • First usable state before templates, clients, or integrations exist.
  • Import path for existing clients, starting measurements, and legacy program PDFs.

Client Lifecycle

  • Lead, invited, onboarding, active, trial, paused, ended, deleted, reactivated — linked to the Workflow State Map and Privacy And Retention boundaries.
  • How a client changes coach after a relationship ends, returns after a break, or moves through deletion and export.

Daily Coach Loop

  • Morning triage, check-in review, workout review, nutrition exceptions, message replies, end-of-day follow-up.
  • Expected coach actions per task type, not just task display.
  • What is urgent enough for push vs inbox vs daily digest.

Client Exceptions

  • Travel, illness, injury, pain notes, Ramadan, vacation, missed logs, skipped workouts, partial meals, equipment unavailable.
  • Which exceptions pause adherence penalties and risk flags; which create coach tasks immediately.

Nutrition Reality

  • Coach-authored/workspace foods, missing/regional foods, Arabic names, custom foods, recipe ownership (comprehensive food providers and barcode scanning are Post-V1).
  • Allergy and dietary-restriction enforcement at publish time.
  • What happens when a client logs food outside the meal plan.

Support And Abuse

  • Account recovery, provider account change, duplicate account merge, failed invitation diagnosis.
  • Message/media redaction, blocked users, harassment reports, support viewing policy.
  • Admin tools for stuck uploads, failed jobs, bad provider data, and data repair.

Architecture docs still missing

The other cross-cutting concerns now have authority docs. These three do not, and should exist before implementation commits to schemas and APIs.

AreaMissing decisionWhy it matters
Media securityVirus scanning, EXIF stripping, signed-URL TTLs, thumbnails, encryption, private preview, moderation, CDN policy.Progress photos, voice notes, attachments, receipts, and form uploads are sensitive and high-volume.
PerformanceExpected workspace sizes, client counts, media volume, API latency budgets, sync payload limits, provider quotas.The program builder, Today view, progress timeline, and inbox need different designs at 20 clients vs 2,000.
SecurityThreat model, rate-limit strategy, secret management, dependency scanning, CSP/CORS, mobile token storage, audit scope.Auth, invitations, media URLs, and health data are likely attack targets.

Tooling still to define

The stack is named and the api/web toolchain runs. These conventions are not yet settled.

  • Backend — Drizzle schema naming, transaction helpers, repository conventions; BullMQ operational controls for retries, stuck jobs, dead letters, scheduled jobs; OpenAPI source of truth and DTO validation library.
  • Mobile — Expo/EAS setup, app identifiers, deep/universal links, push credentials, build profiles, OTA policy; SQLite migration strategy, secure storage, offline test harness, device matrix; mobile E2E and release smoke tests.
  • Web — component system, table/grid, form, drag-and-drop, charts, RTL strategy, accessibility testing; Next.js App Router data-fetching/caching convention; admin/support screen access model.
  • Operations — request/correlation IDs, redaction, metrics, tracing, error reporting, uptime checks; runbooks for failed invitation, failed upload, missing notification, provider outage, stuck queue, data restore; security-update cadence and dependency-vulnerability process.

Build sequence

The private milestone sequence that delivers Public V1 (Core Coaching + Nutrition Baseline) without pretending the whole launch scope is a tiny first release. Coach web is the primary creation surface, client mobile the execution surface, coach mobile a review/communication/task/progress surface.

MilestoneScope
FoundationImplemented on foundation/complete (2026-07-17): IdentityAccess + workspace migration, tenant fence with CI evidence tests, real seed, realm audience client, structured logging, generated clients exercised, full Compose profile.
Onboard (M1)Backend implemented on m1/complete (2026-07-18): registration, invitations, relationship, profile + questionnaire, integrity scan in CI. Web/mobile surfaces remain.
Assign (M1)Backend implemented on m2/complete (2026-07-18): catalog, program aggregate, assignments with questionnaire gate + idempotent commands + lifecycle events. Coach web UI, supersets/drop sets/media remain.
Execute (M1)Backend implemented on m3/complete (2026-07-18): devices, sync push/pull with receipts and conflicts, workout logs. Client mobile app (Today view, offline queue UI) and check-ins remain.
Review (M1)Coach sees profile readiness, submitted workout, basic progress timeline, and messages the client. Push covers core reminders and messages only.
ExpandNutrition baseline, meal swaps, capped voice notes, deterministic risk flags, coach-mobile lightweight actions, launch hardening. Full Priority view, full coach-mobile builders, business dashboards, payments, wearables, and broad integrations stay Post-V1.

Readiness gate — still unchecked

Settled gate items are omitted. These remain before broad feature implementation and launch.

  • Legal — health/nutrition legal posture and disclaimers reviewed; UAE PDPL + target-country privacy posture confirmed.
  • Risk — threat model covering invitations, auth, relationship access, media URLs, offline storage, and support access; object-storage residency resolved.
  • Quality — configured observability providers with redaction/access/retention/dashboards/alerts/synthetics and staging evidence; Test-and-Release CI workflows, fixtures, suites, and a passing release report; security, accessibility, RTL, offline-sync, and app-store smoke tests in the gate.
  • Team — definition of done for backend/web/mobile/docs; ownership assigned for bounded contexts and shared packages; a decision log; a runbook for adding a feature page without inventing new cross-cutting conventions; acceptance tests that prove the core coaching loop end to end.

CoachMe internal planning documentation.