Shared requirements (SHR-*)
Behavior both apps get from the shared packages (@enode/core, @enode/ui).
Each app's catalog references these instead of restating them. See the
overview for the ID scheme and status legend.
Areas: AUTH (authentication flow) · I18N (translations) · UNITS
(measurement system) · ERR (error handling).
Authentication (SHR-AUTH)
Shared flow: @enode/core/auth/use-auth-flow + @enode/ui/auth steps. See
auth.md for the architecture.
| ID | Requirement | Status | Tests |
|---|---|---|---|
| SHR-AUTH-01 | A user can sign in with email and password; on success the app stores a session token and navigates to its main screen. | stable | TRK-ST-1.1, POR-ST-1.1 |
| SHR-AUTH-02 | A returning user with a stored token skips the login screen on cold start and lands directly on the app's main screen. | stable | TRK-ST-1.4, POR-ST-1.4 |
| SHR-AUTH-03 | A user can register a new account (Pro license flavor); validation errors from the backend are shown on the relevant step. | stable | TRK-ST-1.3, POR-ST-1.3 |
| SHR-AUTH-04 | A legacy (enode Pro) user can start the migration path from the auth screen. | stable | POR-ST-12.1 |
| SHR-AUTH-05 | Signing out clears the session and returns to the login screen; protected routes bounce unauthenticated users (401) back to login. | stable | TRK-ST-1.5, POR-ST-1.5 |
| SHR-AUTH-06 | When the account's device-session limit is reached (HTTP 310), the user gets a dialog to free a device slot and can then continue. | stable | POR-ST-1.6 |
| SHR-AUTH-07 | An invited user (HTTP 312) is taken through the invitation-acceptance dialog before continuing. | stable | POR-ST-1.7 |
| SHR-AUTH-08 | A user whose onboarding is incomplete (HTTP 311) is redirected into the onboarding flow. | stable | POR-ST-1.8 |
Internationalization (SHR-I18N)
See i18n.md.
| ID | Requirement | Status | Tests |
|---|---|---|---|
| SHR-I18N-01 | All app-static UI text renders through the translation system; no raw translation keys or undefined appear on screen. | stable | TRK-ST-9.4, POR-ST-16.3 |
| SHR-I18N-02 | The user can switch the app language in settings; visible UI text updates without reinstalling (over-the-air catalogs). | stable | TRK-ST-9.3 |
| SHR-I18N-03 | Server-entity names (exercises, metrics, muscles) resolve to localized display names by id, independent of the static-UI language mechanism. | stable | TRK-ST-9.3 |
Units (SHR-UNITS)
| ID | Requirement | Status | Tests |
|---|---|---|---|
| SHR-UNITS-01 | The user can switch between metric and imperial in settings; every displayed weight/height/load converts accordingly. | stable | TRK-ST-9.2, POR-ST-5.6 |
| SHR-UNITS-02 | Unit-displaying views update immediately on toggle (no reload needed). | stable | TRK-ST-9.2 |
Archived users (SHR-ARCH)
availability is a single flat state, so a user is never both archived and
blocked (see TRK-WORKOUT-05). Archiving is entirely the
backend's business; the clients only react to it.
| ID | Requirement | Status | Tests |
|---|---|---|---|
| SHR-ARCH-01 | Archived users are retired from day-to-day work: they never appear on a live surface — no athlete picker, roster, scheduling flow, search typeahead, or performance axis offers them, in either app. | stable | POR-ST-17.1, TRK-ST-4.9 |
| SHR-ARCH-02 | An athlete archived after being scheduled is hidden from that workout and gets no training session, so nothing can be recorded for them. Re-confirming the athlete picker drops them from the workout. | stable | TRK-ST-4.9 |
| SHR-ARCH-03 | Archiving is a compartment, not a deletion: an archived user's data stays reachable — the Users page's Archived view, History's Archived filter, and data export by explicit selection. | stable | POR-ST-17.2, POR-ST-17.3 |
| SHR-ARCH-04 | Saving a workout whose participants include an archived athlete does not remove them from the schedule — only an explicit athlete edit does. | stable | POR-ST-17.4 |
Error handling (SHR-ERR)
One shared error engine; see error-handling.md.
| ID | Requirement | Status | Tests |
|---|---|---|---|
| SHR-ERR-01 | Losing connectivity shows the offline surface (banner/card) instead of raw request errors; regaining connectivity clears it. | stable | TRK-ST-8.1, POR-ST-16.1 |
| SHR-ERR-02 | Recoverable request failures surface as a toast/inline alert with the backend's localized message when available, otherwise a generic translated fallback. | stable | TRK-ST-10.2, POR-ST-16.2 |
| SHR-ERR-03 | Application errors (4xx/5xx) offer Try again and Report actions; blocking errors use the blocking dialog and halt the flow. | stable | POR-ST-16.2 |
| SHR-ERR-04 | Views that need reference data gate on it: missing data renders an explicit error/retry state, never an empty-but-broken view. | stable | TRK-ST-2.4, POR-ST-16.4 |
Coverage
Filled per protocol — see the coverage tables in tracking-system-tests.md and portal-system-tests.md.