Repository navigation
Route Map
EPIC-21 (UX restructure, #2190) — implemented in #2201; targets roll out per story. This page lists every URL the app serves and where it lands after the restructure. It implements the route policy of ADR-038 §3: today's URLs are kept, every old URL lands in one hop, and URLs written outside the app (vCards, calendar feeds) are permanent.
Source: the runtime route map shared/src/routes/routeMap.ts (exported from @cornerstone/shared), which
the client router, the generated redirects, the server's vCard/iCal/OIDC writers and the E2E page objects
all use. The notes on this page come from the curated record plan/restructure/routemap.json (one entry
per row below). npm run plan:check fails on every pull request when the two files disagree on any
routing field, when client/src/App.tsx serves a route the map lacks, or when a done/interim entry is
not served as the map says. A route change edits routeMap.ts, routemap.json and this page in the same
pull request.
The tables below show each entry's final target. What is served today is in Rollout stage.
| Column | Meaning |
|---|---|
| Current URL | A path (or path + query, or a condition) that can be requested today |
| After | What it serves after the restructure: the same path (a page), or the single-hop redirect target |
| Change |
kept · new · moved · merged · retired · redirect (unchanged legacy redirect) · retargeted · repair (fixes a URL the app emits today that 404s) · query-map · conditional · redirect-becomes-page
|
| Section | The sidebar section that owns the page (its entry is highlighted, its breadcrumb is built from it) |
| Guard |
public (no session) · member (any signed-in user) · admin (route-guarded; members get "No access") |
| Gate |
none · paperless · paperless+ai — the integration that must be configured |
| Permanent | yes = written outside the app; never removed, exempt from any future URL normalisation |
| Query carried | Query parameters the page reads or the redirect carries over |
Redirects are client-side, use replace, carry the query string, and never chain (ADR-038 §3.3, §3.5).
| Measure | Count |
|---|---|
| Entries | 90 |
| Pages after the change | 43 (31 kept or moved incl. / and *, 12 new) |
| Path redirects | 31 |
| Query maps | 11 (1 live, 10 planned) |
| Conditional redirects | 5 |
| Permanent URLs | 5 (/project/work-items/:id, /project/household-items/:id, /project/milestones/:id, /budget/vendors/:id, /companies/:id) |
Q13 keeps today's URLs, but most target pages do not exist yet, so every entry of the route map carries a
stage next to its final target. The story that builds a target page flips the stage to done and
deletes interim in the same pull request.
| Stage | Count | Meaning |
|---|---|---|
done |
58 | Served exactly as the tables below say |
interim |
14 | Served today, not yet in final form: today's page still serves it, or a one-hop redirect to today's equivalent |
planned |
18 | Not served yet: 9 new pages, 2 repair redirects, 4 query maps, 3 conditional redirects |
Planned query maps keep rendering today's page with the query intact until their story lands.
A query map whose base path is a page is served by that page itself (stage: 'interim',
interim: 'page'): the router cannot apply it, because RouteRedirect handles only redirect bases, and a
done query map on a page base fails plan:check (rule 4). See Page-served query maps. Code can
link only to served route ids (routeUrl() rejects planned ones at compile time and run time).
| Current URL | Final target | Served today | Removed by |
|---|---|---|---|
/ |
Home page | redirect → /project/overview
|
P3.3 Home (#2230) |
/project/overview |
redirect → /
|
page (today's dashboard) | P3.3 Home (#2230) |
/project |
redirect → /
|
redirect → /project/overview
|
P3.3 Home (#2230) |
/tags |
redirect → /areas
|
redirect → /settings/manage
|
P1.11 Areas index (#2218) |
/budget/sources |
redirect → /budget/financing#sources
|
page | P4.10 Financing (#2242) |
/budget/subsidies |
redirect → /budget/financing#grants
|
page | P4.10 Financing (#2242) |
/project/household-items/:id/edit |
redirect → /project/household-items/:id?edit=overview
|
page | P5.5 Purchase page (#2249) |
/household-items/:id/edit |
redirect → /project/household-items/:id?edit=overview
|
redirect → /project/household-items/:id/edit
|
P5.5 Purchase page (#2249) |
The six Companies entries (/companies, /companies/:id, /settings/vendors, /settings/vendors/:id,
/budget/vendors, /budget/vendors/:id) are done since P1.7 (#2213):
the two Companies pages are served at their final URLs and the four old URLs redirect to them in one hop
(LIVE_REDIRECT_ROUTES). The Company page keeps today's content until its redesign (5.10b).
/budget/categories is done since P1.9 (#2215): it
redirects in one hop to /settings/manage#cost-categories (interim removed).
/settings is done since P0.12 (#2205): it lands on Project setup
(/settings/manage), the page the sidebar's Settings opens.
The sidebar has an interim layer of its own for the same reason. Until Financing is served, Money shows
Funding sources, Grants and Bank report as views (/budget/sources, /budget/subsidies,
/budget/reports), each marked interimUntil: 'financing' in NavConfig. They disappear when financing
is served, and P4.10 deletes them from NavConfig
(Architecture › Sidebar).
| URL | Served as | Note |
|---|---|---|
/companies |
interim redirect → /settings/vendors
|
Lets code and vCards use the final Companies URLs now |
/companies/:id |
interim redirect → /settings/vendors/:id
|
Written into every vCard from #2201 (permanent) |
/schedule/milestones |
redirect → /project/milestones
|
Repair (done) |
/schedule/milestones/:id |
redirect → /project/milestones/:id
|
Repair (done): the URL Home milestone links emitted, a 404 before (D-01) |
Also changed: / now lands on /project/overview in one hop (it took two: / → /project →
/project/overview); redirects now carry the query string and the hash; and the Paperless-off
conditional on /budget/invoices/new/paperless is live (client RouteGate). The member guard on
/settings/users and /settings/backups (#2200) is checked against the map's guard. The other three
conditional redirects stay planned (see ADR-038 Deviation Log).
| Prefix | Section | Note |
|---|---|---|
/ |
Home | renders Home (today it redirects to /project/overview) |
/project/work-items, /project/milestones, /schedule/*
|
Tasks | Tasks list; Schedule, Calendar and Milestones are views under Tasks |
/project/household-items |
Purchases | |
/diary |
Site diary | people's entries only; system events move to /history
|
/photos |
Photos | |
/budget/* |
Money | overview, Invoices (offers inside), Financing, bank report |
/companies |
Companies | new prefix; was /settings/vendors
|
/areas, /history, /documents
|
secondary group | new prefixes |
/settings/* |
Settings | Project setup, Account, Users, Backups, Integrations |
/setup, /login
|
— | outside the shell |
31 entries.
| Current URL | After | Change | Section | Guard | Gate | Permanent | Query carried | Note |
|---|---|---|---|---|---|---|---|---|
/setup |
/setup |
kept | Auth | public | none | — | — | Unchanged (works today). After setup, Home shows the first-run checklist. |
/login |
/login |
kept | Auth | public | none | — |
next, error
|
Unchanged look; keeps ?next= for local and SSO sign-in (the SSO button passes it as ?redirect=, which server/src/routes/oidc.ts already validates; fixes D-13). ?error= from the OIDC callback stays.
|
/project/work-items |
/project/work-items |
kept | Tasks | member | none | — |
q, sortBy, sortOrder, page, pageSize, filters, group
|
Tasks › Tasks list (h1 'Tasks'). Sidebar 'Tasks' always opens this page. Default grouping by time window. |
/project/work-items/new |
/project/work-items/new |
kept | Tasks | member | none | — | areaId |
Opens the New task dialog (ObjectForm) over the page you came from, or over the Tasks list on a deep link (#2212, Architecture › Dialog routes); Cancel returns to the origin. ?areaId= pre-fills the area. URL and create E2E entry points stay. |
/project/work-items/:id |
/project/work-items/:id |
kept | Tasks | member | none | yes |
tab, depError, edit
|
Task page. ?tab=overview|timing|cost|diary|history (replace). ?depError= opens the Timing tab. Stored in iCal events (calendarIcal.ts), so permanent. |
/project/household-items |
/project/household-items |
kept | Purchases | member | none | — |
q, sortBy, sortOrder, page, pageSize, filters |
Purchases list (h1 'Purchases'). |
/project/household-items/new |
/project/household-items/new |
kept | Purchases | member | none | — |
areaId, companyId
|
Opens the New purchase dialog over the page you came from, or over the Purchases list on a deep link (#2212). ?areaId= and ?companyId= pre-fill the area and the vendor. |
/project/household-items/:id |
/project/household-items/:id |
kept | Purchases | member | none | yes |
tab, edit
|
Purchase page; ?tab=overview|timing|cost|diary|history. Stored in iCal events (delivery dates), so permanent. |
/project/milestones |
/project/milestones |
kept | Tasks | member | none | — |
q, sortBy, sortOrder, page, pageSize, filters |
Tasks › Milestones (h1 'Milestones'); target-date filter. |
/project/milestones/new |
/project/milestones/new |
kept | Tasks | member | none | — | date |
Opens the New milestone dialog over the page you came from, or over the Milestones list on a deep link (#2212). ?date= pre-fills the target date. |
/project/milestones/:id |
/project/milestones/:id |
kept | Tasks | member | none | yes | tab |
Milestone page; ?tab=work|history. Stored in iCal events, so permanent. |
/budget/overview |
/budget/overview |
kept | Money | member | none | — |
paymentStatus, deselectedSources, by
|
Money (overview; h1 'Money'): Left to spend headline, funding rows, breakdown. ?paymentStatus= and ?deselectedSources= kept; new ?by=area|type|category|source. |
/budget/invoices |
/budget/invoices |
kept | Money | member | none | — |
q, sortBy, sortOrder, page, pageSize, filters, status, create, kind, companyId
|
Money › Invoices (h1 'Invoices'): offers and invoices in one list (§2.0 #3) with status chips To pay · Offers · Paid · Submitted · All and paging. ?status= keeps the stored values (pending, quotation, paid, claimed); default To pay. ?create=1 opens the New invoice dialog. Interim until P4.9 (#2212): ?create=1 opens today's create modal (or the Paperless picker), kind=offer presets status quotation, ?companyId= pre-fills the company; the page then removes these keys (replace). |
/budget/invoices/new/paperless |
/budget/invoices/new/paperless |
kept | Money | member | paperless+ai | — | documentId |
'New from document' page (Paperless + AI). The document id moves from history state into ?documentId= so a reload works (fixes D-12). Conditional redirects below when an integration is off. |
/budget/invoices/:id |
/budget/invoices/:id |
kept | Money | member | none | — | tab |
One page for offers and invoices; converting an offer keeps id and URL. Breadcrumb Money › Invoices for both kinds. ?tab=cost|payments|history. |
/budget/invoices/:id/auto-itemize/:documentId |
/budget/invoices/:id/auto-itemize/:documentId |
kept | Money | member | paperless+ai | — | — | 'Split with AI' page (Paperless + AI only); URL kept, h1 renamed. Conditional redirect below when an integration is off. |
/budget/reports |
/budget/reports |
kept | Money | member | none | — |
sourceId, type
|
Bank report, child of Financing (breadcrumb Money › Financing). ?sourceId= kept; new ?type= preset. |
/schedule/gantt |
/schedule/gantt |
kept | Tasks | member | none | — |
filter, zoom, group
|
Tasks › Schedule (h1 'Schedule'); a view under Tasks in the sidebar (no sidebar entry of its own, no tab row). ?filter= kept. |
/schedule/calendar |
/schedule/calendar |
kept | Tasks | member | none | — | calendarMode |
Tasks › Calendar (h1 'Calendar'). ?calendarMode= kept. |
/diary |
/diary |
kept | Site diary | member | none | — |
q, types, dateFrom, dateTo
|
Site diary list (h1 'Site diary'): people's entries only, grouped by week, photo-first. ?filterMode is mapped below; manual is the only mode. |
/diary/new |
/diary/new |
kept | Site diary | member | none | — |
areaId, date
|
Capture screen: no type-picker page; type selector inside; always a new entry (offers 'Add to that entry instead' when the same date and title exist); no draft until the first photo or character. Entry points: phone +, 'Log today', New menu. |
/diary/:id |
/diary/:id |
kept | Site diary | member | none | — | — | Diary entry page (photos first). An automatic entry opened by an old link renders the event layout with breadcrumb History and a link to its object. |
/diary/:id/edit |
/diary/:id/edit |
kept | Site diary | member | none | — | — | The same capture screen in edit mode. |
/photos |
/photos |
kept | Photos | member | none | — | area |
Photos (spots). Photos without an area form a neutral 'No area' group (§2.0 #24): no Unsorted banner, no Tidy-up row; area tags can be set in place (multi-select) and in the viewer. ?area= filters rows. |
/photos/spot/:areaKey/:orientationKey |
/photos/spot/:areaKey/:orientationKey |
kept | Photos | member | none | — | photo |
Spot viewer (visible title; 'n of N', newest = 1). ?photo= kept. none/none is the 'No area · No orientation' spot and stays a page (§2.0 #24). |
/settings/profile |
/settings/profile |
kept | Settings | member | none | — | — | Settings › Account (h1 'Account'); a view under Settings while inside Settings, and the avatar menu's Account. |
/settings/manage |
/settings/manage |
kept | Settings | member | none | — | tab |
Settings › Project setup (one page with sections, opens on House). ?tab= values are mapped below. |
/settings/users |
/settings/users |
kept | Settings | admin | none | — | — | Settings › Users (admin; the route itself is role-guarded, D-23). |
/settings/backups |
/settings/backups |
kept | Settings | admin | none | — | — | Settings › Backups (admin, role-guarded). |
* |
* |
kept | System | member | none | — | — | 404 'Page not found' with 'Go to Home'; no sidebar item highlighted. |
/ |
/ |
redirect-becomes-page | Home | member | none | — | — | Was an index redirect to /project -> /project/overview; now renders Home directly (no hop). |
11 entries.
| Current URL | After | Change | Section | Guard | Gate | Permanent | Query carried | Note |
|---|---|---|---|---|---|---|---|---|
/budget/financing |
/budget/financing |
new | Money | member | none | — | — | NEW Money › Financing (h1 'Financing'): funding sources and grants; Add funding source, Add grant (§2.0 #11); Prepare bank report. |
/budget/financing/sources/:id |
/budget/financing/sources/:id |
new | Money | member | none | — | tab |
NEW Funding source page (summary, Overview, Cost with Move, History incl. bank report events; Documents panel when Paperless is on). |
/budget/financing/grants/:id |
/budget/financing/grants/:id |
new | Money | member | none | — | tab |
NEW Grant page: rate, eligible-costs cap, expected grant, eligible tasks and purchases (linking from the grant side), History. |
/budget/invoices/:id/convert |
/budget/invoices/:id/convert |
new | Money | member | none | — | — | NEW Convert offer to final invoice page (replaces the 108-field modal; dense cost-line table grouped by task). |
/companies |
/companies |
new | Companies | member | none | — |
q, sortBy, sortOrder, page, pageSize, filters, create, trades
|
Companies list (moved from /settings/vendors), flat A–Z; Trade chips filter (tradeId, inside filters). ?trades=1 opens the Trades sheet (Back closes it). ?create=1 (old links, New-menu bookmarks) is replaced by the New company dialog, /companies/new, in deep-link mode. #2213. |
/companies/new |
/companies/new |
new | Companies | member | none | — | — | Opens the New company dialog (ObjectForm) over the page you came from, or over the Companies list on a deep link (Architecture › Dialog routes). #2213. |
/companies/:id |
/companies/:id |
new | Companies | member | none | yes | tab |
Company page, served since #2213 with today's content; the redesign (Overview, Work, Payments, Site diary, History) is 5.10b. Permanent (vCard URL). |
/areas |
/areas |
new | Areas | member | none | — | — | NEW Areas index (tree with counts; the one home for managing areas); sidebar secondary group. |
/areas/:id |
/areas/:id |
new | Areas | member | none | — | — | NEW Area page (sections Now & next here, Latest from the site, Companies here, Rooms, Cost; each links into its filtered home list). |
/history |
/history |
new | History | member | none | — |
q, type, object, dateFrom, dateTo, include
|
NEW History: all system events (filters type, object, date; include diary entries); sidebar secondary group. |
/documents |
/documents |
new | Documents | member | paperless | — |
q, type, sort
|
NEW Documents (Paperless library; only when Paperless is configured, else the conditional redirect above). |
/settings/integrations |
/settings/integrations |
new | Settings | admin | none | — | — | NEW Settings › Integrations (admin, read-only status of Paperless, AI, SSO, DAV, backups, currency/VAT, events, photo storage, proxy). The only place environment-variable names appear. |
31 entries.
| Current URL | After | Change | Section | Guard | Gate | Permanent | Query carried | Note |
|---|---|---|---|---|---|---|---|---|
/project/overview |
/ |
moved | Home | member | none | — | all query parameters | Home moves to the root; one hop. |
/project/household-items/:id/edit |
/project/household-items/:id?edit=overview |
retired | Purchases | member | none | — | all query parameters | Separate edit page retired; opens the page with the Overview section in edit mode (one hop). |
/budget/sources |
/budget/financing#sources |
merged | Money | member | none | — | all query parameters | Merged into Financing; query string carried. |
/budget/subsidies |
/budget/financing#grants |
merged | Money | member | none | — | all query parameters | Merged into Financing (grants section); query string carried. |
/settings/vendors |
/companies |
moved | Companies | member | none | — | all query parameters | Companies leave Settings (working data, 93% referenced); query string carried. |
/settings/vendors/:id |
/companies/:id |
moved | Companies | member | none | — | all query parameters | Company page. |
/project |
/ |
retargeted | Home | member | none | — | all query parameters | Retargeted: one hop to Home. |
/budget |
/budget/overview |
redirect | Money | member | none | — | all query parameters | Unchanged target (the Money overview). |
/budget/categories |
/settings/manage#cost-categories |
retargeted | Settings | member | none | — | all query parameters | Retargeted from ?tab=budget-categories to the section anchor. |
/schedule |
/schedule/gantt |
retargeted | Tasks | member | none | — | all query parameters | Query now preserved (#2201). ?view=calendar is the query map to /schedule/calendar (see Query maps, live from #2202, D-11); any other view value lands here with the query carried. |
/settings |
/settings/manage |
retargeted | Settings | member | none | — | all query parameters | Retargeted: the sidebar's Settings opens Project setup; Account is one click away under Settings and in the avatar menu. |
/work-items |
/project/work-items |
redirect | Tasks | member | none | — | all query parameters | Legacy; unchanged target. |
/work-items/new |
/project/work-items/new |
redirect | Tasks | member | none | — | all query parameters | Legacy; unchanged target. |
/work-items/:id |
/project/work-items/:id |
redirect | Tasks | member | none | — | all query parameters | Legacy; unchanged target. |
/household-items |
/project/household-items |
redirect | Purchases | member | none | — | all query parameters | Legacy; unchanged target. |
/household-items/new |
/project/household-items/new |
redirect | Purchases | member | none | — | all query parameters | Legacy; unchanged target. |
/household-items/:id |
/project/household-items/:id |
redirect | Purchases | member | none | — | all query parameters | Legacy; unchanged target. |
/household-items/:id/edit |
/project/household-items/:id?edit=overview |
retargeted | Purchases | member | none | — | all query parameters | Legacy; retargeted to the final page in one hop. |
/invoices |
/budget/invoices |
redirect | Money | member | none | — | all query parameters | Legacy; unchanged target. |
/invoices/:id |
/budget/invoices/:id |
redirect | Money | member | none | — | all query parameters | Legacy; unchanged target. |
/timeline |
/schedule/gantt |
redirect | Tasks | member | none | — | all query parameters | Legacy; unchanged target (Tasks › Schedule). |
/manage |
/settings/manage |
redirect | Settings | member | none | — | all query parameters | Legacy; unchanged target (Project setup; it used to open on Areas, now on House). |
/tags |
/areas |
retargeted | Areas | member | none | — | all query parameters | Legacy; retargeted to the Areas index, the closest match to the old tag list and to the Areas tab it opened (C-13). |
/profile |
/settings/profile |
redirect | Settings | member | none | — | all query parameters | Legacy; unchanged target (Account). |
/admin/users |
/settings/users |
redirect | Settings | admin | none | — | all query parameters | Legacy; unchanged target. |
/budget/vendors |
/companies |
retargeted | Companies | member | none | — | all query parameters | Legacy; retargeted in one hop (was a chain via /settings/vendors). |
/budget/vendors/:id |
/companies/:id |
retargeted | Companies | member | none | yes | all query parameters | Legacy; retargeted in one hop. PERMANENT: server/src/services/vendorVcard.ts:84 and :143 write this URL into every vCard served over CardDAV, so it lives in the household's address books. Story 0.10 switches the server to route helpers; this redirect stays forever. |
/schedule/milestones |
/project/milestones |
repair | Tasks | member | none | — | all query parameters | New: makes the URL family emitted by the old Home cards valid. |
/schedule/milestones/:id |
/project/milestones/:id |
repair | Tasks | member | none | — | all query parameters | New: the URL every Home milestone link emits today, a 404 (D-01). |
/budget/financing/sources |
/budget/financing#sources |
repair | Money | member | none | — | all query parameters | New index route so the parent of a funding source page never 404s (C-13). |
/budget/financing/grants |
/budget/financing#grants |
repair | Money | member | none | — | all query parameters | New index route so the parent of a grant page never 404s (C-13). |
11 entries: 1 live (done, #2202), 6 page-served (interim, interim: 'page', #2215), 4 planned.
Query maps consume the keys they match. The matched pair is removed from the carried query: the
target of /schedule?view=calendar is /schedule/calendar, not /schedule/calendar?view=calendar.
Every other incoming pair and the hash are still carried, and target-defined keys still win (ADR-038
§3.3). A query map takes precedence over the path redirect of the same path; a request whose query
does not match falls through to that path redirect (/schedule?view=gantt → /schedule/gantt?view=gantt).
A live query map must sit on a live redirect route. Query maps apply only through RouteRedirect
(client/src/navigation/), which serves the routes in LIVE_REDIRECT_ROUTES; a page route never reads
them. build-routes rule 4 (npm run plan:check) therefore rejects a done query map whose base path is
served as a page. liveQueryMaps() (shared/src/routes/redirects.ts) is the only definition of a live
query map, used by both the router and resolveLocation. The planned /diary?filterMode=… maps need
/diary to become a redirect, or the router to apply query maps on pages, before they go live.
| Current URL | After | Change | Section | Guard | Gate | Permanent | Query carried | Note |
|---|---|---|---|---|---|---|---|---|
/schedule?view=calendar |
/schedule/calendar |
query-map | Tasks | member | none | — | all other query parameters | Live (#2202, D-11): the old Calendar view link lands on the Calendar view; view is consumed. |
/diary?filterMode=automatic |
/history |
query-map | History | member | none | — |
q, dateFrom, dateTo, types->type
|
Query map: system events live on the History page; q, dateFrom, dateTo carried; types mapped to the History type filter. |
/diary?filterMode=all |
/history?include=diary |
query-map | History | member | none | — |
q, dateFrom, dateTo, types->type
|
Query map: the old 'All' mode = History with diary entries included; same parameters carried. |
/budget/invoices?openOnly=true |
/budget/invoices?status=pending |
query-map | Money | member | none | — | all query parameters | Query map: the old open-items view = the To pay status (the default), which also lists offers with a progress payment to pay. |
/settings/manage?tab=areas |
/areas |
query-map | Areas | member | none | — | all query parameters | Query map: areas leave Settings for the Areas index. |
/settings/manage?tab=household |
/settings/manage#house |
query-map | Settings | member | none | — | all query parameters | Query map to the section anchor (House = name, address, entry language). |
/settings/manage?tab=trades |
/settings/manage#trades |
query-map | Settings | member | none | — | all query parameters | Query map to the section anchor. |
/settings/manage?tab=orientations |
/settings/manage#orientations |
query-map | Settings | member | none | — | all query parameters | Query map to the section anchor. |
/settings/manage?tab=hi-categories |
/settings/manage#purchase-categories |
query-map | Settings | member | none | — | all query parameters | Query map to the section anchor. |
/settings/manage?tab=budget-categories |
/settings/manage#cost-categories |
query-map | Settings | member | none | — | all query parameters | Query map to the section anchor. |
/project/work-items/:id?depError= |
/project/work-items/:id?tab=timing&depError= |
query-map | Tasks | member | none | — | all query parameters | Query map: the dependency error opens on the Timing tab. |
5 entries.
| Current URL | After | Change | Section | Guard | Gate | Permanent | Query carried | Note |
|---|---|---|---|---|---|---|---|---|
/budget/invoices/new/paperless (Paperless off) |
/budget/invoices?create=1 |
conditional | Money | member | paperless | — | all query parameters | When Paperless is not configured: the New invoice dialog opens instead; nobody sees configuration text. |
/budget/invoices/new/paperless (AI off) |
/budget/invoices?create=1&documentId= |
conditional | Money | member | paperless | — | all query parameters | When Paperless is on but AI is off: the New invoice dialog opens with the document's title, correspondent and date pre-filled (document-first without AI). |
/budget/invoices/:id/auto-itemize/:documentId (Paperless or AI off) |
/budget/invoices/:id?tab=cost |
conditional | Money | member | paperless+ai | — | all query parameters | When Paperless or AI is not configured: the record's Cost tab opens (grid entry is available there). |
/documents (Paperless off) |
/ |
conditional | Documents | member | paperless | — | all query parameters | When Paperless is not configured: Home; the Documents nav item is not rendered. |
/settings/users, /settings/backups, /settings/integrations (member) |
* (No access) |
conditional | Settings | admin | none | — | all query parameters | Role guard: members get the "No access" page with "Go to Home" (D-23). |
Since P1.9 (#2215) the six
/settings/manage?tab=… entries are stage: 'interim' with interim: 'page' (to and match unchanged):
Project setup reads ?tab=, replaces the URL in history (no new entry) with the section anchor and drops
tab; an unknown value only drops tab. They stay interim while /settings/manage is a page, since a
done query map needs a redirect base (plan:check rule 4).
| Current URL | Final target | Served today by Project setup |
|---|---|---|
/settings/manage?tab=household |
/settings/manage#house |
#house |
/settings/manage?tab=budget-categories |
/settings/manage#cost-categories |
#cost-categories |
/settings/manage?tab=hi-categories |
/settings/manage#purchase-categories |
#purchase-categories |
/settings/manage?tab=orientations |
/settings/manage#orientations |
#orientations |
/settings/manage?tab=trades |
/settings/manage#trades |
#trades (the pointer row to Companies › Trades) |
/settings/manage?tab=areas |
/areas |
#areas (the interim Areas card) while areas is unserved; a replace navigation to routeUrl('areas') once P1.11 (#2218) serves it |
| Date | Section | Deviation | Resolution |
|---|---|---|---|
| 2026-10-08 | New pages, Query maps | The plan's routemap.json (91 entries) predates owner decision §2.0 #3 and listed a separate Offers page /budget/offers plus the query map /budget/invoices?status=quotation → /budget/offers. |
Applied §2.0 #3: offers live inside the Invoices list (Offers chip = ?status=quotation, a stored value that needs no map). Both entries dropped. |
| 2026-10-08 | Pages kept, Path redirects |
routemap.json predates §2.0 #24 and listed the repair /photos/spot/none/none → /photos?view=unsorted and a ?view=unsorted state of /photos (the Unsorted mode). |
Applied §2.0 #24: no Unsorted mode. /photos/spot/none/none stays a page (it is matched by the spot-viewer route) and view is no longer carried by /photos. |
| 2026-10-08 | New pages |
routemap.json marked /companies/:id as not permanent, although plan story 0.10 switches vendorVcard.ts to route helpers, after which every vCard carries /companies/:id. |
Marked permanent (ADR-038 §3.4). /budget/vendors/:id stays permanent for vCards written before the switch. |
| 2026-10-08 | Several notes | Notes in routemap.json describe tab rows on Tasks, Money and Settings, superseded by §2.0 #1, #2 and #14 (the sidebar is the navigation, views show under their section). |
Notes of the affected rows rewritten to the views model. |
| 2026-10-09 | Pages kept or moved | The * (404) row listed guard public, but in client/src/App.tsx the catch-all route sits inside the AuthGuard layout route: a signed-out visitor to an unknown URL is sent to /login first and sees the 404 only after signing in. |
Guard corrected to member here and in plan/restructure/routemap.json (#2191). |
| 2026-10-10 | Header, Rollout stage | The page said the route map in shared/src/routes/ would become the source of truth and this page would be regenerated from it, and listed only final targets. |
#2201: routeMap.ts is the runtime source, routemap.json stays the curated notes record (plan:check enforces agreement), and this page is maintained from the notes. Added the Rollout stage section (16 interim entries with the story that removes each, the 4 newly served URLs). |
| 2026-10-10 | Query maps, Summary, Rollout stage | #2201 left /schedule?view=calendar on the path redirect (/schedule/gantt?view=calendar, the Schedule view) and its note promised the Calendar mapping; no query map was live and the page did not say whether a map carries the key it matched. |
#2202: added the first live query map /schedule?view=calendar → /schedule/calendar (stage: done), and the rule "query maps consume their matched keys". Counts updated (89 entries, 49 done, 11 query maps). |
| 2026-10-10 | Rollout stage |
/settings was interim (one hop to /settings/profile, Account) while the sidebar still had no Settings link to Project setup. |
#2205 (P0.12): stage: done, interim removed; /settings lands on /settings/manage in one hop. Counts updated (50 done, 15 interim). Interim Money views in NavConfig recorded under Interim targets. |
| 2026-10-11 | Pages kept, New pages | The three /…/new dialog routes carried no query and said the dialog opens over the list only; /budget/invoices did not carry the New menu's kind/companyId, and /companies did not carry create. |
#2212 (P1.6): carries set to exactly the keys each target reads (task areaId; purchase areaId, companyId; milestone date; invoices + kind, companyId; companies + create), in routeMap.ts and routemap.json alike. Dialogs open over the page you came from (Architecture › Dialog routes). |
| 2026-10-11 | Summary, Rollout stage, New pages | #2213 (P1.7) served the Companies pages. The six Companies entries were interim; the list carried group for a "group by Trade" that the story dropped (the Trade chips filter instead), lacked trades for the Trades sheet, and there was no create URL for the company ObjectForm. |
Six entries done (interim removed), new dialog route companyNew (/companies/new, parent companies); /companies carries create and trades, not group. Counts updated (90 entries, 57 done, 9 interim). |
| 2026-10-15 | Rollout stage, Interim targets, Query maps | #2215 (P1.9, decision E3). The page listed the six /settings/manage?tab=… query maps as planned and /budget/categories as interim. Project setup now serves the six URLs itself, and a done query map on a page base fails plan:check rule 4. |
Six entries interim with interim: 'page', /budget/categories done (interim removed) in shared/src/routes/routeMap.ts (routemap.json has no stage). New subsection Page-served query maps. Counts 58 done, 14 interim, 18 planned (query maps 4 planned). |