128 lines
40 KiB
Markdown
128 lines
40 KiB
Markdown
# P5-15 route and visible-action acceptance plan
|
||
|
||
## Final native census successor — P5-15-06
|
||
|
||
[Fresh complete regression](p5-15-06/README.md) retains all32 concrete route patterns (31originals+Analytics), each anonymous/normal/admin entry and refresh:192observations,98selected expected API reads, no500. These journeys assert actual headings/data/destinations/authentication/role denials and retain the repaired AUTH-01 query behavior; HTTP200 alone is not acceptance. [Portable observations](p5-15-06/evidence/validation.json) retain all three census records. All32 matrix rows remain PARTIAL because provider/manual/long-tail acceptance is incomplete; no route or alias is removed. Production main remains unchanged/NO-GO. The planning text below is historical rather than a claim that these fresh checks did not occur.
|
||
|
||
Planning checkpoint: **`46a0c0c6d23464869f50c0d88552963c29cfdacf`**, branch `codex/ui-redesign-phase4`, 2026-10-09. This is source characterization and a future audit plan. **No fresh route/browser/provider/manual checks have run; no acceptance or route-removal decision is made.** The [57-group matrix](PRESERVATION_ACCEPTANCE.md) retains every original sub-workflow.
|
||
|
||
## Original versus current census
|
||
|
||
The [original audited route inventory](../../audit/ROUTE_MAP.md) at Phase 1 contains **31 concrete patterns: 29 pages and two redirect aliases**. The [Phase 3 route/query plan](../../phase-3/ROUTE_PLAN.md), [Phase 5 navigation migration](../NAVIGATION_MIGRATION.md) and [release-candidate census](../release-readiness/PRESERVATION_REVIEW.md#route-census-and-compatibility) establish the compatibility chain.
|
||
|
||
Current [App routing](../../../../job-tracker-ui/src/App.tsx) declares **35 routes** across its outer data-router objects and inner `Route path` elements. Exclude outer `/*`, inner `*` and the duplicate inner `/` redirect infrastructure: **32 unique concrete patterns = all 31 originals + `/analytics`**. Current disposition is **29 pages and three redirects**: `/analytics` adds a page while original `/kanban` becomes a redirect to the integrated Board. The public outer LandingPage owns `/`; its private inner Dashboard redirect is not a second page. RouteErrorPage is an error boundary, not another pattern.
|
||
|
||
[P5-01](../p5-01/README.md) moved navigation entries while retaining original routes; [P5-04b](../p5-04b/README.md) introduced the integrated `/jobs?view=board` and legacy Board redirect; [P5-07](../p5-07/README.md) added meaningful personal `/analytics`. P5-08a/b and P5-09–14 enhance existing workspace/editor paths without adding concrete route patterns. Static presence proves declarations only; direct URL, refresh, Back/Forward, real permissions, dirty Cancel/Discard, safe errors and deployed health remain to be audited.
|
||
|
||
## Exactly 32 current concrete patterns
|
||
|
||
Every row is **PARTIAL** for route acceptance: current source plus linked historical regression exists, but fresh-current, provider or required manual checks remain NOT VERIFIED. No missing test is labelled a functional FAIL. Route columns characterize the actual current behavior rather than narrowing the original capability.
|
||
|
||
| Concrete pattern | Original/current disposition | Current actual owner | Query / action / compatibility semantics and limit | PRES scope | Historical regression anchors / remaining acceptance limit | Planning status |
|
||
|---|---|---|---|---|---|---|
|
||
| `/` | Preserved public page | [LandingPage](../../../../job-tracker-ui/src/views/LandingPage.tsx) | Public product/plans. Authenticated mount replaces to /dashboard; protected-route state is forwarded by login action. Query/capture/landing continuity is a future audit. | E01/E02/E07/E08 | [landing/auth redirect](../../../../job-tracker-ui/src/LandingPage.authRedirect.test.tsx), [landing](../../../../job-tracker-ui/src/landing-page.test.tsx); provider/mobile limits in E01 | **PARTIAL** |
|
||
| `/login` | Preserved public page | [LoginPage](../../../../job-tracker-ui/src/views/LoginPage.tsx) | Local/provider/challenge/configured registration controls; validates local state.from then replaces after sign-in. SessionChanged notice and reset-email prefill remain. | E02–E05/E09 | [login](../../../../job-tracker-ui/src/login-page.test.tsx), [smoke](../../../../job-tracker-ui/e2e/smoke.spec.ts); live auth/provider limits E02–E04 | **PARTIAL** |
|
||
| `/register` | Preserved public page | [LoginPage](../../../../job-tracker-ui/src/views/LoginPage.tsx) | initialMode=register, subject to configuration; uses the same safe post-auth target and provider/challenge boundaries. | E02/E03 | [login](../../../../job-tracker-ui/src/login-page.test.tsx), [local auth](../../../../JobTrackerApi.Tests/LocalAuthIdentityTests.cs); configured/provider limits E02 | **PARTIAL** |
|
||
| `/forgot-password` | Preserved public page | [ForgotPasswordPage](../../../../job-tracker-ui/src/views/ForgotPasswordPage.tsx) | email prefill; explicit reset request. Runtime mail/configuration/browser completion remains unverified. | E02 | [local auth](../../../../JobTrackerApi.Tests/LocalAuthIdentityTests.cs); complete browser/mail journey remains E02 gap | **PARTIAL** |
|
||
| `/reset-password` | Preserved public page | [ResetPasswordPage](../../../../job-tracker-ui/src/views/ResetPasswordPage.tsx) | email/token query; explicit password submit. Invalid/expired/already-used token and sensitive URL handling need acceptance. | E02 | [local auth](../../../../JobTrackerApi.Tests/LocalAuthIdentityTests.cs); complete token submit/mail journey remains E02 gap | **PARTIAL** |
|
||
| `/verify-email` | Preserved public page | [VerifyEmailPage](../../../../job-tracker-ui/src/views/VerifyEmailPage.tsx) | userId/email/token query; verification outcomes remain under identity owner, not shell page placement. | E02 | [verification](../../../../job-tracker-ui/src/verify-email-page.test.tsx), [local auth](../../../../JobTrackerApi.Tests/LocalAuthIdentityTests.cs); actual mail E02 | **PARTIAL** |
|
||
| `/confirm-email-change` | Preserved public page | [VerifyEmailPage emailChange](../../../../job-tracker-ui/src/views/VerifyEmailPage.tsx) | Same page in email-change mode; existing userId/email/token confirmation, independent from Career data. | E06 | [verification](../../../../job-tracker-ui/src/verify-email-page.test.tsx), [local auth](../../../../JobTrackerApi.Tests/LocalAuthIdentityTests.cs); account mutation gaps E06 | **PARTIAL** |
|
||
| `/microsoft-legacy-relink` | Preserved public page | [MicrosoftLegacyRelinkPage](../../../../job-tracker-ui/src/views/MicrosoftLegacyRelinkPage.tsx) | userId/tenantId/objectId/token recovery metadata; actual provider popups/consent/revoke and origin/state unverified. | E03 | [relink](../../../../job-tracker-ui/src/microsoft-legacy-relink-page.test.tsx), [token validator](../../../../JobTrackerApi.Tests/MicrosoftTokenValidatorTests.cs); real consent E03 | **PARTIAL** |
|
||
| `/cv/:slug` | Preserved public page | [PublicCvPage](../../../../job-tracker-ui/src/views/PublicCvPage.tsx) | Published slug owner and anonymous HTML/PDF. No numeric private-editor redirect; publication/revocation and PDF capacity remain protected. | C05/C12 | [public CV](../../../../job-tracker-ui/src/public-cv-page.test.tsx), [PublicCvController](../../../../JobTrackerApi.Tests/PublicCvControllerTests.cs), [smoke](../../../../job-tracker-ui/e2e/smoke.spec.ts); deployed fonts/publication lifecycle C05/C12 | **PARTIAL** |
|
||
| `/dashboard` | Enhanced original page — P5-06 | [DashboardView](../../../../job-tracker-ui/src/components/DashboardView.tsx) | Home reports/onboarding/five owner-local flags and contextual links. Snapshot/trend retries remain separate; period is component state here. | S01/S02/E07–E09 | [P5-06 evidence](../p5-06/README.md), [daily loop](../../../../job-tracker-ui/src/daily-control-loop.test.tsx); metric/preference limits S01/S02 | **PARTIAL** |
|
||
| `/analytics` | Added enhanced page — P5-07 | [AnalyticsPage → DashboardView(mode=analytics)](../../../../job-tracker-ui/src/views/AnalyticsPage.tsx) | Authenticated personal reports use the same existing facts/cohorts. months=6/12/24 is URL state; defaults 12; independent of Dashboard visibility flags. | S01/S02/E07–E09/J05/J09 | [P5-07 evidence](../p5-07/README.md); no new server facts/populations or deployed acceptance S01 | **PARTIAL** |
|
||
| `/discover` | Preserved page; Jobs secondary entry | [JobDiscoveryPage](../../../../job-tracker-ui/src/views/JobDiscoveryPage.tsx) | NAV discovery, saved searches/alerts and detail controls unchanged; no new source/provider scope from relocation. | J01/J02 | [discovery](../../../../job-tracker-ui/src/job-discovery.test.tsx), [smoke](../../../../job-tracker-ui/e2e/smoke.spec.ts); live NAV J01/J02 | **PARTIAL** |
|
||
| `/jobs` | Enhanced original page — P5-03/P5-04b | [JobTable(mode=jobs)](../../../../job-tracker-ui/src/components/JobTable.tsx) | Table default; view=board mounts KanbanBoard within same owner. Shared complete logical query; page/columns/density/selection lifetime remains explicit. | J03–J07/W01/S03 | [P5-03](../p5-03/README.md), [P5-04b](../p5-04b/README.md), [native Board/query integration](../../../../job-tracker-ui/e2e/board-presentation.spec.ts), [integration component](../../../../job-tracker-ui/src/jobs-view-integration.test.tsx); finite-query/scaling limits J03–J07 | **PARTIAL** |
|
||
| `/jobs/:id` | Enhanced original page — P5-08a/b | [ApplicationWorkspacePage](../../../../job-tracker-ui/src/views/ApplicationWorkspacePage.tsx) | Seven URL sections, Application/Timeline sub-navigation, existing domain owners/dirty guards. Legacy section strings and numeric navigation-helper tab arguments retained; numeric values are not URL `section` aliases. followMode is metadata only. | W01–W12/M01/M02/E07–E09 | [P5-08b](../p5-08b/README.md), [route contracts](../../../../job-tracker-ui/src/application-route-contracts.test.ts), [preservation browser](../../../../job-tracker-ui/e2e/redesign-preservation.spec.ts); deferred followMode/manual/provider limits W01–W12 | **PARTIAL** |
|
||
| `/reminders` | Preserved page; Jobs secondary entry | [RemindersView](../../../../job-tracker-ui/src/components/RemindersView.tsx) | Follow-ups retains grouped reasons and workflow actions; existing calendar/rule/date contracts, no newly scheduled interview semantics. | W10/W11 | [daily loop](../../../../job-tracker-ui/src/daily-control-loop.test.tsx), [calendar](../../../../job-tracker-ui/src/application-calendar.test.tsx); F21/provider W11 | **PARTIAL** |
|
||
| `/operations` | Preserved page; utility entry | [OperationsPage](../../../../job-tracker-ui/src/views/OperationsPage.tsx) | Activity/processing list/progress/result/retry/cancel. Bell View all points here; no /notifications page exists. | W12/S02 | [operations](../../../../job-tracker-ui/src/operations-page.test.tsx), [OperationsController](../../../../JobTrackerApi.Tests/OperationsControllerTests.cs); worker/disconnect W12 | **PARTIAL** |
|
||
| `/kanban` | Legacy original pattern; redirect after P5-04b | [LegacyBoardRedirect](../../../../job-tracker-ui/src/App.tsx) | Navigate replace to /jobs with view=board. Clones search and overwrites only view; explicitly preserves hash and location.state. No removal date approved. | J07/W01/E07 | [P5-04b](../p5-04b/README.md), [native Board/query integration](../../../../job-tracker-ui/e2e/board-presentation.spec.ts), [App redirect](../../../../job-tracker-ui/src/App.tsx); physical touch/scaling J07 | **PARTIAL** |
|
||
| `/companies` | Preserved page; Jobs secondary entry | [CompaniesTable](../../../../job-tracker-ui/src/components/CompaniesTable.tsx) | edit=id opens company editor, including command result destination; contacts/pipeline/history remain with existing form owner. | J08 | [companies](../../../../job-tracker-ui/src/companies-relationship.test.tsx), [command](../../../../job-tracker-ui/src/quick-command-preservation.test.tsx); modal-save accessibility J08 | **PARTIAL** |
|
||
| `/offers` | Preserved page; Jobs secondary entry | [OfferComparisonPage](../../../../job-tracker-ui/src/views/OfferComparisonPage.tsx) | Recorded compensation/notes/deadline/source comparison; Dashboard/Analytics offer links continue; no inferred salary calculator. | J09/S01 | [offers](../../../../job-tracker-ui/src/offer-comparison.test.tsx), [P5-07 links](../p5-07/README.md); full mobile/currency review J09 | **PARTIAL** |
|
||
| `/correspondence` | Preserved primary page | [CorrespondenceInboxPage](../../../../job-tracker-ui/src/views/CorrespondenceInboxPage.tsx) | view=review selects GmailReviewPage; other URL view values select inbox. Compose/drafts remain existing in-page state/actions, not new routes. | M01–M06 | [inbox](../../../../job-tracker-ui/src/correspondence-inbox-page.test.tsx), [draft persistence](../../../../JobTrackerApi.Tests/EmailDraftPersistenceTests.cs); live mail/reconnect M01–M06 | **PARTIAL** |
|
||
| `/correspondence/review` | Preserved legacy redirect | [Navigate review alias](../../../../job-tracker-ui/src/App.tsx) | Hard-coded replace to /correspondence?view=review. Does not pass incoming other query, hash or state. Record this existing limit; audit required metadata before parity claims. | M05 | [inbox](../../../../job-tracker-ui/src/correspondence-inbox-page.test.tsx), [review](../../../../job-tracker-ui/src/gmail-review-page.test.tsx); actual provider/create chain M05 | **PARTIAL** |
|
||
| `/profile` | Preserved page; Settings/account entry | [ProfilePage](../../../../job-tracker-ui/src/views/ProfilePage.tsx) | Account identity/avatar/password/email and local security/session cards retained; same page, distinct from canonical Career Profile. | E04–E06 | [profile](../../../../job-tracker-ui/src/profile-page.test.tsx), [2FA](../../../../job-tracker-ui/src/two-factor-settings.test.tsx); complete account/device journeys E04–E06 | **PARTIAL** |
|
||
| `/applications/:id` | Preserved legacy redirect | [LegacyApplicationRedirect](../../../../job-tracker-ui/src/App.tsx) | Replace to /jobs/:id + location.search and state=location.state. Hash is not passed by the current adapter; no alias removal approved. | W01/E07 | [P5-08b](../p5-08b/README.md), [workspace](../../../../job-tracker-ui/src/application-workspace-overlay.test.tsx), [App redirect](../../../../job-tracker-ui/src/App.tsx); legacy sections/followMode W01 | **PARTIAL** |
|
||
| `/career` | Preserved page; Career Profile entry | [CareerWorkspacePage → CareerProfilePage](../../../../job-tracker-ui/src/views/CareerWorkspacePage.tsx) | section=profile/evidence/import; default overview. Structured source/import/evidence/history owners remain; /career/profile is not an App route. | C01–C04 | [Career workspace](../../../../job-tracker-ui/src/career-workspace-page.test.tsx), [profile](../../../../job-tracker-ui/src/profile-page.test.tsx); long-tail/import/provider C01–C04 | **PARTIAL** |
|
||
| `/career/builder` | Preserved page; CVs entry | [CvBuilderPage](../../../../job-tracker-ui/src/views/CvBuilderPage.tsx) | CV library create/copy/delete/templates/manage/publish/share/export. Creates/open navigate to numeric owned editor, public slug remains distinct. | C05 | [builder library](../../../../job-tracker-ui/src/cv-builder-page.test.tsx), [P5-12](../p5-12/README.md); full library/publication chain C05 | **PARTIAL** |
|
||
| `/career/builder/:id` | Enhanced original editor — P5-09–12/P5-14 | [CvBuilderEditor](../../../../job-tracker-ui/src/views/CvBuilderEditor.tsx) | One save/revision/history/preview owner, Content-first local studio tabs and responsive panes. Production CV generation/Apply unavailable guard; P5-13 review deferred. | C06–C12/W05/E07–E09 | [editor](../../../../job-tracker-ui/src/cv-builder-deep-link.test.tsx), [P5-12](../p5-12/README.md), [AI readiness](../p5-13-readiness/README.md); P5-13/P5-14/manual/rendering limits C06–C12 | **PARTIAL** |
|
||
| `/admin/audit` | Preserved authorized admin page | [AdminAuditPage](../../../../job-tracker-ui/src/views/AdminAuditPage.tsx) | Separate audit/history/supported undo/restore; API role checks remain authoritative. Shell visibility is not authorization proof. | A02 | [audit](../../../../job-tracker-ui/src/admin-audit-page.test.tsx), [authorization](../../../../JobTrackerApi.Tests/ApiAuthorizationPostureTests.cs); native undo A02 | **PARTIAL** |
|
||
| `/admin/users` | Preserved authorized admin page | [AdminUsersPage](../../../../job-tracker-ui/src/views/AdminUsersPage.tsx) | Separate users/role/reset/delete/last-admin/self guards; no aggregate Admin page invented. | A01 | [users](../../../../job-tracker-ui/src/admin-users-page.test.tsx), [UsersController](../../../../JobTrackerApi.Tests/UsersControllerTests.cs); revoke/reset A01 | **PARTIAL** |
|
||
| `/admin/system` | Preserved authorized admin page | [AdminSystemPage](../../../../job-tracker-ui/src/views/AdminSystemPage.tsx) | Separate diagnostics/configuration/mail/AI/probe/benchmark/maintenance; visible admin metadata retained, production actions unverified. | A03 | [system](../../../../job-tracker-ui/src/admin-system-page.test.tsx), [maintenance](../../../../JobTrackerApi.Tests/MaintenanceJobDispatcherTests.cs); deployed probes A03 | **PARTIAL** |
|
||
| `/trash` | Enhanced original page — P5-03 | [JobTable(mode=trash)](../../../../job-tracker-ui/src/components/JobTable.tsx) | Deleted-only list and restore/edit; Table-specific utility, no Board view or permanent-delete substitution. | J06/S03 | [P5-03](../p5-03/README.md), [table density](../../../../job-tracker-ui/e2e/table-density.spec.ts); finite restore/bulk/manual J06 | **PARTIAL** |
|
||
| `/settings` | Preserved page; Account entry | [SettingsView](../../../../job-tracker-ui/src/components/SettingsView.tsx) | Existing tabs/mobile selector/data/rules/notifications/AI/privacy/backup/account lifecycle, Profile and Connections links; saves retain existing owners. | S03–S05/J10/E08 | [Settings](../../../../job-tracker-ui/src/settings-view.test.tsx), [native layout](../../../../job-tracker-ui/e2e/settings-page-layout.spec.ts); concurrent saves/billing/restore S03–S05 | **PARTIAL** |
|
||
| `/settings/connected-accounts` | Preserved page; Settings secondary entry | [ConnectedAccountsPage](../../../../job-tracker-ui/src/views/ConnectedAccountsPage.tsx) | Gmail/Graph/IMAP connection status/connect/disconnect distinct from sign-in identity; mail/calendar grants do not authorize new routing/send behavior. | M06/E03 | [connections](../../../../job-tracker-ui/src/email-provider-connections.test.tsx), [native Settings](../../../../job-tracker-ui/e2e/settings-page-layout.spec.ts); actual OAuth/mail/expiry M06 | **PARTIAL** |
|
||
|
||
## Query state and alias behavior to audit
|
||
|
||
| Contract / actual owner | Current source behavior | Required execution acceptance / owner / priority |
|
||
|---|---|---|
|
||
| Jobs filters and shared Board query — [jobsQuery](../../../../job-tracker-ui/src/jobsQuery.ts), [JobTable](../../../../job-tracker-ui/src/components/JobTable.tsx) | `q/status/companyId/location/needsFollowUp/readiness/includeDeleted/sortBy/sortDir` are shared logical inputs. `view=board` is Board only in Jobs mode; other values use Table. Table page uses positive URL page and zero-based local index; Board does not reinterpret it as a population limit. | Audit identical complete IDs, custom statuses, owner/deleted/derived filters, saved-view CRUD, unknown/invalid values and scale. Preserve nonavailable/error semantics and selected scope. Jobs/API owner; H. |
|
||
| Table↔Board view and list mutation — [JobTable](../../../../job-tracker-ui/src/components/JobTable.tsx) | View link clones query, sets `view`, keeps hash and router state while clearing `focusJobId`; switching clears Table page selection. Filter/sort/page update clones other query and replaces history with state, but does not explicitly pass hash. Density is local presentation state, not account/saved-view/API data. | Direct entry, refresh, Back/Forward, page two, zero matches, unknown safe query/hash and select→switch→return; characterize list update hash before promising fidelity. Jobs owner; H. |
|
||
| Legacy Board — [App LegacyBoardRedirect](../../../../job-tracker-ui/src/App.tsx) | `/kanban` clones incoming search, sets `view=board`, replaces history, explicitly retains hash/state. Query-supplied `view=table` is deliberately overwritten. | Native direct/refresh/back and unknown query/hash/state with filtered all-result membership, no loops or mutation. Jobs/shell owner; H. |
|
||
| Legacy application — [App LegacyApplicationRedirect](../../../../job-tracker-ui/src/App.tsx) | `/applications/:id` replaces to `/jobs/:id` with the exact search string and router state. It does not pass hash. | Every legacy section/sub/followMode, invalid/missing/foreign id, state return and hash limit; no implicit AI/send/capture/write. Workspace owner; H. |
|
||
| Review alias — [App Navigate](../../../../job-tracker-ui/src/App.tsx), [inbox adapter](../../../../job-tracker-ui/src/views/CorrespondenceInboxPage.tsx) | `/correspondence/review` hard-codes replace to `/correspondence?view=review`; other incoming query/hash/state are not passed. Inbox reads `view=review`; drafts/compose use existing in-page state. | Direct/refresh/back and required old metadata, reviewed job create/no-write navigation, dirty draft and send-uncertainty boundaries. Existing fidelity limit is not silently declared repaired. Mail owner; H. |
|
||
| Seven job sections — [applicationWorkspace adapter](../../../../job-tracker-ui/src/applicationWorkspace.ts), [workspace navigation](../../../../job-tracker-ui/src/views/ApplicationWorkspacePage.tsx) | Canonical: `overview/match/application/documents/timeline/tasks/interview`. Legacy: analysis→match; cv/cover-letter→application; job-details→overview; checklist/notes→tasks; communication→timeline; portfolio→documents. Unknown section→overview. `sub` selects Application cv/letter/answers/submission or Timeline activity/correspondence. Old cv/letter/communication sections take priority over unrelated sub metadata. | All canonical/legacy entries, disclosure reveal/focus, tab keyboard, unknown key no-write, Back/Forward/refresh, job missing/denied/retry and unsaved letter/answers Cancel/Discard. Workspace/accessibility owner; H. |
|
||
| Numeric navigation-helper tab arguments and follow-up metadata — [jobWorkspaceRoute](../../../../job-tracker-ui/src/jobWorkspaceRoute.ts) | Helper tab arguments map 0→overview, 1→communication, 2→documents, 3→cv, 4→communication, 5→match, 6→analysis, 7→interview, 8→checklist, 9→timeline. These generate section strings, not numeric URL `section` aliases; the helper preserves optional `followMode`. Workspace section/sub change clones current query and retains location.state. **No mode-specific UI consumer exists.** | Retain helper tab-to-section outputs and metadata through section/history/reload; honor [recorded mail-phase deferral](../p5-08b-readiness/README.md). Do not count metadata preservation as compose/follow-up UI acceptance. Workspace/mail owner; H. |
|
||
| Jobs return/focus — [JobTable](../../../../job-tracker-ui/src/components/JobTable.tsx), [workspace close](../../../../job-tracker-ui/src/views/ApplicationWorkspacePage.tsx) | Row entry records numeric `jobListFocusId` on originating history and sends state `from` + `focusJobId`. `from` is pathname/search only. Workspace close replaces to local `from` or `/jobs` and sends numeric focus; no mounted background Jobs assumption. | Real loaded row/card/Board workflow entry, explicit Back/browser Back, safe from/unknown state and missing row, filter/page/focus recovery, dirty cancellation across all shell routes. Workspace/Jobs owner; H. |
|
||
| Capture — [App Shell effect](../../../../job-tracker-ui/src/App.tsx), [captureUrl](../../../../job-tracker-ui/src/captureUrl.ts) | Private Shell resolves `add/addtext`, opens prefilled review, consumes only those keys with history replacement while keeping other search. That navigate call does not explicitly pass hash/state. Opening is not creation. Root public LandingPage authenticated redirect goes to `/dashboard` without explicitly forwarding search. | Characterize root/private/unauthenticated extension/bookmarklet/PWA share, invalid URL, Cancel/reload/no replay/no duplicate write, safe metadata and optional post-create failure. Capture/identity owner; H. |
|
||
| Protected route/login continuity — [App auth guard](../../../../job-tracker-ui/src/App.tsx), [LandingPage](../../../../job-tracker-ui/src/views/LandingPage.tsx), [LoginPage](../../../../job-tracker-ui/src/views/LoginPage.tsx) | Shell denied entry replaces to public `/` with state.from **pathname only**, not search/hash. Landing forwards state to login. Login accepts a local slash path excluding `//` and backslashes, else Dashboard. Authenticated public Landing replaces straight to Dashboard. | Deep links with Jobs filters/sections/capture after session expiry/login, safe malformed external targets, remember/challenge/provider paths and stale-account cancellation. Characterize loss limits; no complete deep-link continuity claim from path presence. Identity owner; H. |
|
||
| Career section — [CareerProfilePage](../../../../job-tracker-ui/src/views/CareerProfilePage.tsx) | `section=profile/evidence/import`, default overview. Canonical source remains separate from account Profile and CV variant settings/history. | Section direct/refresh/back and dirty import/edit/navigation, long-tail saves, raw/history restore and source/variant separation. Career owner; H. |
|
||
| Analytics period — [DashboardView](../../../../job-tracker-ui/src/components/DashboardView.tsx), [AnalyticsPage](../../../../job-tracker-ui/src/views/AnalyticsPage.tsx) | `months=6/12/24`, invalid/default 12; setQuery clones unrelated query. Dashboard uses local period state and five owner-local flags; Analytics shows reports independently. | Exact values/cohorts, Back/refresh/query preservation, independent snapshot/trend failures, no invented metrics and Dashboard flag isolation. Reports owner; M. |
|
||
| Company command/deep edit — [CompaniesTable](../../../../job-tracker-ui/src/components/CompaniesTable.tsx), [QuickCommandDialog](../../../../job-tracker-ui/src/components/QuickCommandDialog.tsx) | Company search result enters `/companies?edit=id`; positive edit key requests existing company form. Form is not relocated or auto-saved by route presence. | Command/direct/refresh, missing/foreign id, retained draft and durable modal error; P4-02-D02 remains open. Companies/accessibility owner; H. |
|
||
| Token and provider URLs — [reset](../../../../job-tracker-ui/src/views/ResetPasswordPage.tsx), [verification](../../../../job-tracker-ui/src/views/VerifyEmailPage.tsx), [relink](../../../../job-tracker-ui/src/views/MicrosoftLegacyRelinkPage.tsx) | Reset email/token; verify userId/email/token; Microsoft relink userId/tenantId/objectId/token. Backend OAuth callbacks/postMessage are separate from React page patterns. | Expired/invalid/missing/used token and safe logs/titles/history, real sandbox popup origin/state/revoke, no identity leakage. Explicit provider approval at execution time. Identity/provider owner; H. |
|
||
| Numeric private CV and public slug — [editor](../../../../job-tracker-ui/src/views/CvBuilderEditor.tsx), [public page](../../../../job-tracker-ui/src/views/PublicCvPage.tsx) | Private variant id controls saved lens/history; public slug publication is independent. Current Production CV suggestion-service generation/Apply returns 503; old assistant affordances may still be visible. P5-13 review UI is absent. | Missing/foreign/unpublished/revoked entry, dirty editor/library/Back, no source/sibling mutation, public/private PDF admission and honest unavailable AI. Preserve [P5-13 exception](../OPEN_BLOCKERS.md#p5-13-deferred-debt-and-return-conditions--2026-10-08); CV/AI owner; H. |
|
||
|
||
## Navigation entries and forbidden removal without replacement
|
||
|
||
Current [App navigation arrays](../../../../job-tracker-ui/src/App.tsx), [AppShell menus/drawer](../../../../job-tracker-ui/src/layout/AppShell.tsx) and [Jobs view owner](../../../../job-tracker-ui/src/components/JobTable.tsx) supply the actual reachable entries. A future audit must demonstrate expanded desktop, collapsed rail menu and scrollable labelled mobile drawer plus successful heading focus and dirty Cancel preservation. A declaration or hidden menu is insufficient.
|
||
|
||
| Original / required entry | Current reachable replacement or retained entry | Removal constraint / required acceptance |
|
||
|---|---|---|
|
||
| Dashboard | Home primary `/dashboard` | Retain reports/flags/onboarding/attention and exact-value links; no replacement by Analytics-only page. |
|
||
| Job applications | Jobs primary `/jobs`; Table default | Preserve filters/saved views/pagination/columns/density/mobile row actions and reviewed Add. |
|
||
| Kanban board separate primary | Jobs Table/Board switch `/jobs?view=board`; legacy `/kanban` redirect retained | Only old primary entry is consolidated; full query/status/mutation/keyboard parity remains protected. No alias removal date. |
|
||
| Discover jobs | Jobs secondary `/discover` | Remain reachable, labelled in narrow/collapsed shell; preserve saved-search/alerts. |
|
||
| Reminders | Jobs secondary `/reminders` with count | Preserve every reminder reason, count and workflow/calendar action; do not replace with only overdue cards. |
|
||
| Companies / Offers / Trash | Jobs secondary `/companies`, `/offers`, `/trash` | Every low-frequency entry stays reachable; Trash is deleted-only restore, never hard delete. Company edit query remains. |
|
||
| Correspondence | Independent primary `/correspondence`; inbox/drafts/review | Never hide global mail in Documents or confuse log with send. Retain review alias and uncertain-send safeguards. |
|
||
| Career workspace | Career Profile `/career` | Canonical facts/import/evidence remain distinct from account Profile and CV editing. No invented `/career/profile` route. |
|
||
| CV Builder | CVs `/career/builder` and numeric editor | Retain create/copy/delete/publication/export, all controls and one persistence owner; new review remains deferred. |
|
||
| Profile former duplicate primary | Settings secondary `/profile` **and** account-menu profile | Both accessible replacement entries exist; security/session/avatar/email/password forms remain under same owner. |
|
||
| Settings / Connections | Settings primary, secondary Connections `/settings/connected-accounts`; existing Settings link | Preserve all tabs/mobile selector/data/privacy/backup/account lifecycle and distinct provider grants. |
|
||
| Audit / Users / System | Separate admin-only bottom navigation entries | Server role checks remain mandatory; do not invent an aggregate `/admin` landing or drop an operational tool. |
|
||
| Language/theme/account Sign out | Header/account controls reuse existing owners | Remain reachable at narrow/collapsed widths and keyboard; UI locale is separate from CV document locale. |
|
||
| Quick search/Add | Header search + Ctrl/Cmd+K; six static commands, job/company results; AddJobModal | Retain exact destinations, failure Retry/stale-result disposal and no-create-on-open boundary. |
|
||
| Bell/activity | Bell NotificationsPopover; View all→`/operations`; operation/result deep links | Preserve read/dismiss/status/retry/cancel. No `/notifications` route or new notification producer inferred. |
|
||
| Admin version/commit | Admin-only shell/account disclosure | Same authorized information remains reachable without narrow-header overlap; public metadata scope not expanded. |
|
||
| Proposed Documents / Notifications / global AI / aggregate Admin | No current standalone routes or dead placeholders | Explicitly deferred/absent. Existing job Documents and contextual AI entries remain; absent new pages cannot justify removing their old owners. |
|
||
| Analytics | Added meaningful `/analytics` primary in Insights | Existing personal facts/cohorts only; no fabricated metric or new aggregate/admin analytics. |
|
||
|
||
## Visible control action audit required for P5-15
|
||
|
||
This is a **source-level action map plus a future manual/native audit checklist**, not a click-through result or complete control census. The larger feature inventory owns sub-actions. Audit role/data/state combinations on every relevant route and all currently visible controls; record named control, expected destination/request, actual result, error/empty/locked/loading/dirty state and focus. H identifies controls requiring behavioral proof beyond a screenshot.
|
||
|
||
| Surface / actual owner | Visible controls and source-defined actions | Required audit / owner / priority |
|
||
|---|---|---|
|
||
| [Shell](../../../../job-tracker-ui/src/layout/AppShell.tsx), [App callbacks](../../../../job-tracker-ui/src/App.tsx) | Navigation parent/child/rail menu/mobile drawer, collapse, skip/main, search, Add on Jobs, bell, Settings/profile, theme/language, Sign out, admin badge disclosure | Every entry in prior table; Escape/close/resize focus, active child/parent, dirty navigation Cancel/Discard and account disposal. Shell/accessibility/identity; H. |
|
||
| [Command palette](../../../../job-tracker-ui/src/components/QuickCommandDialog.tsx) | Six commands: Dashboard, Jobs, Reminders, Companies, Settings, Add review; job→numeric workspace, company→edit query; keyboard selection, Retry, Escape | No mutation on palette/search/route mount, late-result rejection, IME/Enter/arrow behavior, focus after opening/cancel and manual spoken result/error states. P5-02-D01/P5-04b-R01 remain open. Shell; H. |
|
||
| [Bell](../../../../job-tracker-ui/src/components/NotificationsPopover.tsx), [Operations](../../../../job-tracker-ui/src/views/OperationsPage.tsx) | Notification open/read/dismiss/Retry, View all→Operations; operation result link/retry/cancel | Correct owner/deep-link result, no duplicated start, missing/error/long reconnect, announcements/focus; operation utility is not a new notifications page. Operations/shell; H. |
|
||
| [Dashboard/report owner](../../../../job-tracker-ui/src/components/DashboardView.tsx) | Five checkbox flags, month buttons, snapshot/trends Retry, exact-value details, Jobs/Offers and workflow attention links, onboarding actions | Audit owner-local flags vs language-save endpoint, exact existing denominators, loading/error independent states, link destinations and all-hidden fallback. **P5-06-O01 observed language-preference 500 during reads remains unresolved.** Reports/identity; H. |
|
||
| [Jobs/Trash](../../../../job-tracker-ui/src/components/JobTable.tsx), [saved views](../../../../job-tracker-ui/src/components/SavedViewsMenu.tsx) | Filters/sort/page/size/columns/density/view switch, row/card actions, selected bulk status/soft-delete/restore, edit, Settings data link | Correct selected scope/partial failure, no row open from nested action, dirty/Back/focus, all-result parity, native persisted restore and readable long EN/NB. Jobs/API; H. |
|
||
| [Board](../../../../job-tracker-ui/src/components/KanbanBoard.tsx) | Card/workflow entry, pointer/keyboard move, exact-status menu, collapse/group states | Keyboard pickup/drop/cancel, failed move retained, custom-stage group, physical touch/native drag and scale; preserve API raw status identity. Jobs; H. |
|
||
| [Workspace](../../../../job-tracker-ui/src/views/ApplicationWorkspacePage.tsx) | Back/edit, seven sections, Application CV/letter/answers/submission, Timeline activity/correspondence, Documents shortcuts, Notes edit/checklist/calendar | All source-defined destinations and disclosures, legacy key priority, source/archived distinction and independent draft guards. **followMode mode-specific compose UI remains deferred; metadata is not action fulfillment.** Workspace/mail; H. |
|
||
| [Workspace assets](../../../../job-tracker-ui/src/components/ApplicationAssets.tsx), [attachments](../../../../job-tracker-ui/src/components/Attachments.tsx) | Attach/create/copy/detach/tailor CV, manual/AI letter review/save/history, draft save, package capture/detail/archive download, attachment consent/upload/rename/delete | CV source/variant/sibling ownership, reject no-write, dirty Cancel, frozen bytes after mutation/delete, actual upload/download/error; capture is not send. Workspace/storage/AI; H. |
|
||
| [Career](../../../../job-tracker-ui/src/views/CareerProfilePage.tsx) | Overview/structured profile/evidence/import, fields/raw copy/history restore, upload/extract/diff/select/accept/discard/retry/cancel | Canonical scope, low-confidence review, source navigation, long-tail/mobile save, no silent overwrite and interrupted operation behavior. Career/extraction; H. |
|
||
| [CV library](../../../../job-tracker-ui/src/views/CvBuilderPage.tsx), [editor](../../../../job-tracker-ui/src/views/CvBuilderEditor.tsx), [settings](../../../../job-tracker-ui/src/components/cv/CvCustomizeTab.tsx) | Create/copy/delete/templates/publish/share/PDF; Content/Template/Customize/AI Tools/History; source/override/reset/reorder/visibility; undo/redo/save retry/conflict recovery; editor/preview return | Retain P5-14 measured/keyboard/pointer cases; every capability control and locked/unsupported/error state, publication old-link revoke, revision/draft/source/sibling/frozen invariants and private/public export. Physical/zoom/manual AT remains open. CV/renderer; H. |
|
||
| [CV AI affordances](../../../../job-tracker-ui/src/components/cv/AiSectionAssistant.tsx), [DocumentAiTab](../../../../job-tracker-ui/src/views/CvBuilderEditor.tsx) | Existing section/whole-document assistant controls request generation/accept; Production optional service gives 503 unavailable. P5-13 review frame is unimplemented. | Honest error/entitlement/privacy/metering, no provider/write in Production withheld scope, unchanged unrelated AI. No model/UI/responsive review acceptance until exact return conditions. AI/CV; H. |
|
||
| [Inbox](../../../../job-tracker-ui/src/views/CorrespondenceInboxPage.tsx), [job correspondence](../../../../job-tracker-ui/src/components/Correspondence.tsx), [review](../../../../job-tracker-ui/src/views/GmailReviewPage.tsx) | Inbox filters/page/detail/source/link, compose/reply/drafts/confirm send, uncertain new attempt, job manual log/import, Gmail thread/link/move/unlink/sync, reviewed proposed jobs | Native drafts/revisions/context, no automatic resend/create, no log/send conflation, approved sandbox provider/reconnect/attachment proof and human AT; mail-phase followMode remains outstanding. Mail/API; H. |
|
||
| [Settings](../../../../job-tracker-ui/src/components/SettingsView.tsx), [backup](../../../../job-tracker-ui/src/components/BackupCard.tsx), [Connections](../../../../job-tracker-ui/src/components/EmailProviderConnections.tsx) | Tabs/mobile selector; rules/scenario/notification retry, table/theme/language, import/export, privacy/usage/plans, ZIP/backup/deletion confirmation, connection grants/revoke | Correct save owner and dirty tab lifetime; retained notification concurrency 500/rules observation/language 500 investigation, configured billing/deletion/restore guards; provider/production work separately authorized. Settings/API/identity; H. |
|
||
| [Companies](../../../../job-tracker-ui/src/components/CompaniesTable.tsx), [Offers](../../../../job-tracker-ui/src/views/OfferComparisonPage.tsx), [Discovery](../../../../job-tracker-ui/src/views/JobDiscoveryPage.tsx) | Contact/company edit/delete/history/source links, recorded offers/notes/deadline, discovery search/source/sort/detail/save searches/run/pause/delete/dismiss | Durable company modal error P4-02-D02, safe source URLs, native contact/date/saved-search persistence and narrow many-offer/long result traversal. Domain/accessibility; H. |
|
||
| [Admin Users](../../../../job-tracker-ui/src/views/AdminUsersPage.tsx), [Audit](../../../../job-tracker-ui/src/views/AdminAuditPage.tsx), [System](../../../../job-tracker-ui/src/views/AdminSystemPage.tsx) | Role/create/reset/delete, permitted undo/restore, SMTP/probes/benchmarks/maintenance/diagnostics | API role/last-admin/self/recent-auth gates, mounted revoke, persisted successful actions and safe sensitive output. Actual provider/production actions are outside this plan. Admin/operations; H. |
|
||
|
||
## Evidence required before a later acceptance decision
|
||
|
||
Run the agreed applicable regressions at a named source only after execution is authorized; associate each route/visible-action outcome with the original PRES sub-workflow, role/owned fixture, URL/query/state, request/no-write assertions, viewport/theme/locale and focus result. Capture direct entry, refresh, Back/Forward, legacy alias, loading/empty/error/locked state, missing/foreign record, dirty Cancel/Discard and account switch where relevant. Audit human screen-reader names/live announcements, physical touch/software keyboard, 200%/400% zoom, forced colours and text spacing rather than substituting axe incompletes or emulated taps.
|
||
|
||
The source limitations above are future audit inputs, not fresh regression failures or approval to change semantics. Preserve [recorded deferred scope and open issues](../OPEN_BLOCKERS.md). Current deployment/ingress/backup/schema/configuration/rollback/protected CI and actual deployed route acceptance remain NOT VERIFIED under the separate [production NO-GO](../production-release-decision/README.md). This plan does not close P5-15 or authorize implementation, suite execution, provider calls or release.
|