Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 173 additions & 37 deletions docs/site-map.md

Large diffs are not rendered by default.

106 changes: 89 additions & 17 deletions scripts/generate-site-map.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,6 +9,8 @@ import {
unsubmittedModeSearchRedirectEntries,
} from "@/lib/consolidated-mode-home-redirect";
import { documentsSearchHref, DOCUMENTS_MODE_HOME_ROUTE } from "@/lib/document-flow-routes";
import { factsheetSlugs } from "@/components/factsheets/factsheets-data";
import { dictionaryEntries, dictionaryTopics } from "@/lib/dictionary-data";
import { differentialRecords } from "@/lib/differentials";
import { dsmDiagnoses } from "@/lib/dsm";
import { formulationMechanisms } from "@/lib/formulation";
Expand DownExpand Up@@ -74,55 +76,81 @@ const documentedRedirectTargets: Record<string, string> = {
// (line 14). Pin the canonical target here so the generated map does not report the
// invalid-id fallback that its first-`redirect()` regex would otherwise capture.
"/documents/source": "/documents/[id]",
"/documents/source/evidence": "/documents/[id]",
};

const routeDescriptions: Record<string, string> = {
"/": "Main Clinical KB shell.",
"/applications": "Legacy application launcher redirect to Tools.",
"/calculators": "Psychiatry rating scale scoring and clinical decision calculators.",
"/dictionary": "Clinical dictionary home with term search and category navigation.",
"/dictionary/[slug]": "Source-governed clinical term definition, distinction, and reference detail.",
"/dictionary/browse": "A–Z clinical term and abbreviation catalogue browser.",
"/dictionary/compare": "Side-by-side clinical term definition and nuance comparison.",
"/dictionary/search": "Source-linked clinical term and abbreviation search surface.",
"/dictionary/sources": "Clinical dictionary governance, references, and source catalogue.",
"/dictionary/topics": "Clinical dictionary topic category index.",
"/dictionary/topics/[slug]": "Clinical dictionary topic category term list.",
"/differentials": "Differentials home and search surface.",
"/differentials/compare":
"Compare queue: empty state or selected diagnosis ids (Search edit links preserve ids); Open comparison launches a catalogue presentation workflow or an ad-hoc workspace (`workspace=1`).",
"/differentials/diagnoses": "Diagnosis stream.",
"/differentials/diagnoses/[slug]": "Differential diagnosis detail.",
"/differentials/presentations": "Presentation catalogue stream.",
"/differentials/presentations/[slug]": "Presentation comparison workflow.",
"/dsm": "DSM-5 Diagnosis home.",
"/dsm/search": "DSM diagnosis search and catalogue browser.",
"/dsm/compare": "DSM diagnosis comparison.",
"/dsm/diagnoses/[slug]": "DSM diagnosis criteria and information.",
"/dsm/diagnoses/[slug]/differentials": "DSM diagnosis differential considerations.",
"/documents": "Documents mode home and source document library surface.",
"/documents/[id]": "Document viewer/detail page.",
"/documents/search": "Documents search command centre.",
"/documents/source": "Compatibility redirect to the canonical live document viewer when a valid id is supplied.",
"/documents/source/evidence": "Compatibility redirect sharing the canonical live document viewer handoff.",
"/dsm": "DSM-5 Diagnosis home.",
"/dsm/compare": "DSM diagnosis comparison.",
"/dsm/diagnoses/[slug]": "DSM diagnosis criteria and information.",
"/dsm/diagnoses/[slug]/differentials": "DSM diagnosis differential considerations.",
"/dsm/search": "DSM diagnosis search and catalogue browser.",
"/factsheets": "Patient information factsheets home and topic browser.",
"/factsheets/[slug]": "Plain-language patient factsheet reading and printable handout view.",
"/factsheets/search": "Patient information factsheet search command centre.",
"/favourites": "Saved clinical items and sets.",
"/forms": "Forms home and search surface.",
"/forms/[slug]": "Registry-backed form detail.",
"/formulation": "Clinical formulation home and local mechanism search surface.",
"/formulation/[slug]": "Formulation mechanism decision-support guide.",
"/formulation/builder": "Structured clinical formulation builder.",
"/formulation/compare": "Side-by-side mechanism comparison.",
"/formulation/map": "Formulation mechanism domain map.",
"/medications": "Medication mode home.",
"/medications/[slug]": "Medication detail.",
"/privacy": "Privacy and data-processing governance draft.",
"/reference/colour-coding": "Clinical domain and category colour-coding palette reference.",
"/safety-plan": "Patient safety plan generator (Stanley-Brown six steps) — a Tools-page clinical tool.",
"/services": "Services home and search surface.",
"/services/[slug]": "Registry-backed service detail.",
"/formulation": "Clinical formulation home and local mechanism search surface.",
"/formulation/[slug]": "Formulation mechanism decision-support guide.",
"/formulation/builder": "Structured clinical formulation builder.",
"/formulation/compare": "Side-by-side mechanism comparison.",
"/formulation/map": "Formulation mechanism domain map.",
"/specifiers": "Psychiatric specifier home and local search surface.",
"/specifiers/[slug]": "Psychiatric specifier decision-support guide.",
"/specifiers/builder": "Structured diagnostic wording builder.",
"/specifiers/compare": "Side-by-side psychiatric specifier comparison.",
"/specifiers/map": "Psychiatric specifier family map.",
"/therapy-compass": "Therapy home (source-grounded therapy decision support).",
"/therapy-compass/search": "Therapy library search surface.",
"/therapy-compass/recommend": "Recommend a therapy from a clinical question and constraints.",
"/therapy-compass/compare": "Side-by-side therapy comparison.",
"/therapy-compass/pathways": "Problem-based clinical therapy pathways.",
"/therapy-compass/review": "Therapy records awaiting qualified-clinician source review.",
"/therapy-compass/[slug]": "Therapy record detail.",
"/therapy-compass/[slug]/brief": "Therapy brief-intervention view.",
"/therapy-compass/[slug]/sheet": "Therapy patient-sheet builder.",
"/therapy-compass/compare": "Side-by-side therapy comparison.",
"/therapy-compass/pathways": "Problem-based clinical therapy pathways.",
"/therapy-compass/recommend": "Recommend a therapy from a clinical question and constraints.",
"/therapy-compass/review": "Therapy records awaiting qualified-clinician source review.",
"/therapy-compass/search": "Therapy library search surface.",
"/tools": "Clinical tools and applications launcher directory.",
"/ward-management": "Statewide psychiatry ward demand, bed capacity, and patient flow console.",
"/ward-management/capacity": "Ward bed availability, unit occupancy, and staffing capacity.",
"/ward-management/constellation": "Statewide psychiatric hospital network constellation view.",
"/ward-management/exceptions": "Patient flow exceptions, delays, and escalation alerts.",
"/ward-management/governance": "Ward coordination governance, compliance, and audit log.",
"/ward-management/movements": "Scheduled and completed patient transfers and bed movements.",
"/ward-management/network": "Psychiatric bed network status and regional catchment map.",
"/ward-management/patients/[patientId]": "Synthetic patient placement and transfer trajectory detail.",
"/ward-management/queue": "Priority referral queue and triage waiting list.",
"/ward-management/transport": "Patient inter-hospital transfer and transport logistics.",
};

const publicRouteHandlerDescriptions: Record<string, string> = {
Expand All@@ -131,39 +159,52 @@ const publicRouteHandlerDescriptions: Record<string, string> = {
};

const apiDescriptions: Record<string, string> = {
"/api/account/favourites": "Account saved favourites operations.",
"/api/account/preferences": "Account density, motion, and UI preferences.",
"/api/answer": "Generate answer response.",
"/api/answer/stream": "Streaming answer response.",
"/api/answer-feedback": "Answer quality feedback submission.",
"/api/differentials": "Differential diagnosis catalogue operations.",
"/api/differentials/[slug]": "Differential diagnosis detail endpoint.",
"/api/differentials/presentations/[slug]": "Presentation workflow comparison data endpoint.",
"/api/documents": "Document collection operations.",
"/api/documents/[id]": "Document detail operations.",
"/api/documents/[id]/labels": "Document label operations.",
"/api/documents/[id]/reindex": "Single-document reindex operation.",
"/api/documents/[id]/reviews": "Document clinical review audit log.",
"/api/documents/[id]/search": "Search within one document.",
"/api/documents/[id]/signed-url": "Private document signed URL.",
"/api/documents/[id]/summarize": "Document summary operation.",
"/api/documents/[id]/table-facts": "Document table facts.",
"/api/documents/bulk": "Bulk document operations.",
"/api/documents/bulk/reindex": "Bulk reindex operation.",
"/api/documents/signed-urls": "Bulk private document signed URLs.",
"/api/eval-cases": "Evaluation case data.",
"/api/health": "Health check.",
"/api/health/ready": "Readiness health check.",
"/api/images/[id]/signed-url": "Private image signed URL.",
"/api/images/signed-urls": "Bulk private image signed URLs.",
"/api/ingestion/batches": "Ingestion batch state.",
"/api/ingestion/jobs": "Ingestion job collection.",
"/api/ingestion/jobs/[id]/retry": "Retry ingestion job.",
"/api/ingestion/quality": "Ingestion quality reporting.",
"/api/jobs": "Administrator/ops job listing (not a client product API; see docs/api-jobs-ops-surface.md).",
"/api/local-project-id": "Local project identity guard.",
"/api/medications": "Medication catalog collection operations.",
"/api/medications/[slug]": "Medication detail endpoint.",
"/api/registry/records": "Registry record collection.",
"/api/registry/records/[slug]": "Registry record detail.",
"/api/search": "Search endpoint.",
"/api/search/interaction": "Search interaction telemetry.",
"/api/search/universal": "Cross-entity universal search endpoint.",
"/api/setup-status": "Setup status.",
"/api/upload": "Upload endpoint.",
"/api/webhooks/railway": "Railway deploy webhook -> chat forwarder.",
"/api/webhooks/supabase/document-change": "Supabase document-change webhook -> ingestion enqueue.",
};

const routeOwnershipRows = [
["Root dashboard and query modes", "src/app/page.tsx, src/lib/app-modes.ts"],
["Root dashboard and query modes", "src/app/(search-app)/page.tsx, src/lib/app-modes.ts"],
["Global shell layouts", "src/app/*/layout.tsx, src/components/clinical-dashboard/global-search-shell.tsx"],
["Services", "src/app/(search-app)/services, src/lib/services.ts, src/app/api/registry/records"],
["Forms", "src/app/(search-app)/forms, src/lib/forms.ts, src/app/api/registry/records"],
Expand All@@ -180,6 +221,13 @@ const routeOwnershipRows = [
"src/app/(search-app)/medications, src/components/clinical-dashboard/medication-prescribing-workspace.tsx",
],
["Documents", "src/app/(search-app)/documents, src/lib/document-flow-routes.ts"],
["Calculators", "src/app/(search-app)/calculators, src/components/calculators"],
["Therapy Compass", "src/app/(search-app)/therapy-compass, src/lib/therapies.ts"],
["Factsheets", "src/app/(search-app)/factsheets, src/components/factsheets"],
["Dictionary", "src/app/(search-app)/dictionary, src/lib/dictionary.ts"],
["Ward Management", "src/app/ward-management, src/components/ward-management"],
["Safety Plan", "src/app/safety-plan, src/components/patient-safety-plan.tsx"],
["Privacy", "src/app/privacy"],
["Tools", "src/components/applications-launcher-page.tsx"],
["Mockups", "src/app/mockups"],
] as const;
Expand DownExpand Up@@ -451,7 +499,7 @@ function renderModePageIndex() {
"`/dictionary/search` is also a query-free browse surface; `/dictionary/browse`, `/topics`, `/topics/[slug]`, `/compare`, `/sources` and `/dictionary/[slug]` records.",
},
{
mode: "Therapy",
mode: "Therapy Compass",
home: appModeHomeHref("therapy-compass"),
search: appModeHomeHref("therapy-compass", { query: "CBT", focus: true, run: true }),
detail:
Expand DownExpand Up@@ -499,6 +547,10 @@ function renderSiteMapRaw(data = collectSiteMapData()) {
"/formulation/[slug]",
"/therapy-compass/[slug]",
"/medications/[slug]",
"/dictionary/[slug]",
"/dictionary/topics/[slug]",
"/factsheets/[slug]",
"/ward-management/patients/[patientId]",
].includes(route.route),
);
const mockupRoutes = data.pageRoutes.filter((route) => route.route.startsWith("/mockups"));
Expand DownExpand Up@@ -571,13 +623,33 @@ function renderSiteMapRaw(data = collectSiteMapData()) {
...renderSlugInventory("Therapy slugs", "/therapy-compass/[slug]", therapySlugs()),
"",
...renderSlugInventory("Medication slugs", "/medications/[slug]", medicationSlugs),
"",
...renderSlugInventory("Factsheet slugs", "/factsheets/[slug]", factsheetSlugs()),
"",
...renderSlugInventory(
"Clinical dictionary term slugs",
"/dictionary/[slug]",
dictionaryEntries.map((entry) => entry.slug),
),
"",
...renderSlugInventory(
"Clinical dictionary topic slugs",
"/dictionary/topics/[slug]",
dictionaryTopics.map((topic) => topic.slug),
),
]),
...section("Document viewer route", [
bullet(
"/documents/[id]",
"Document viewer/detail page. Individual document IDs are intentionally not enumerated in this sitemap.",
),
]),
...section("Ward management patient route", [
bullet(
"/ward-management/patients/[patientId]",
"Synthetic patient placement and transfer trajectory detail. Synthetic patient IDs are generated runtime data and intentionally not enumerated in this sitemap.",
),
]),
...section("Mockup/prototype routes", [
...mockupRoutes.map((route) => routeLine(route, routeDescriptions)),
...(data.nonRoutedMockupArtifacts.length
Expand Down
12 changes: 12 additions & 0 deletions src/app/(search-app)/formulation/[slug]/page.tsx
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
import type { Metadata } from "next";
import { notFound } from "next/navigation";

import { FormulationMechanismPage } from "@/components/formulation/formulation-mechanism-page";
import { findFormulationMechanism, formulationMechanisms } from "@/lib/formulation";

export const dynamicParams = false;

export function generateStaticParams() {
return formulationMechanisms.map((mechanism) => ({ slug: mechanism.id }));
}

export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
const { slug } = await params;
const mechanism = findFormulationMechanism(slug);
return {
title: mechanism ? `${mechanism.name} — Formulation` : "Formulation mechanism not found",
description: mechanism?.summary,
};
}

export default async function FormulationMechanismRoute({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const mechanism = findFormulationMechanism(slug);
Expand Down
6 changes: 3 additions & 3 deletions src/app/mockups/layout.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,14 +5,14 @@ import type { ReactNode } from "react";

import { mockupsEnabled } from "@/lib/env";
import { DEVELOPER_AREA_HEADER } from "@/lib/developer-area/headers";
import { PRIVATE_APP_ROBOTS_METADATA } from "@/lib/crawler-policy";

import { MockupsLayoutClient } from "./mockups-layout-client";
import "./mockups.css";

// Design-exploration prototypes: shipped for shareability, but never indexed
// (belt-and-braces alongside the robots.ts /mockups/ disallow).
// Design-exploration prototypes: shipped for shareability, but never indexed.
export const metadata: Metadata = {
robots: { index: false, follow: false },
robots: PRIVATE_APP_ROBOTS_METADATA,
};

export default async function MockupsLayout({ children }: { children: ReactNode }) {
Expand Down
Loading
Loading