> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Transcription admin routes

> This document is the canonical reference for the Transcription module's administrative surface: which routes exist, what permissions they require, and how they…

**Status:** Active
**Owner:** TR core
**Last updated:** 2026-04-24

This document is the canonical reference for the **Transcription module's
administrative surface**: which routes exist, what permissions they require,
and how they appear (or don't appear) in the global navigation chrome
(sidebar vs breadcrumbs).

It complements:

* [`src/cores/tr/NAVIGATION.md`](https://github.com/Encore-OS/encoreos/blob/development/src/cores/tr/NAVIGATION.md) — short
  in-tree navigation classification table.
* [`src/platform/modules/module-registry/tr-module.ts`](https://github.com/Encore-OS/encoreos/blob/development/src/platform/modules/module-registry/tr-module.ts)
  — sidebar source of truth (`navItems`).
* [`src/platform/navigation/route-labels.ts`](https://github.com/Encore-OS/encoreos/blob/development/src/platform/navigation/route-labels.ts)
  — breadcrumb source of truth (`BASE_ROUTE_LABELS`).
* [`docs/pf/permissions-quick-reference.md`](/pf/permissions-quick-reference)
  — full platform permission catalog.

***

## At-a-glance

| Route                            | Page                              | Required permission(s)                                                                               | Sidebar | Breadcrumb |
| -------------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------- | :-----: | :--------: |
| `/transcription`                 | *(redirect)*                      | None — redirects to `/transcription/vendor-settings`                                                 |    No   |     Yes    |
| `/transcription/vendor-settings` | `TranscriptionVendorSettingsPage` | Page itself: none. Sub-cards gated individually (see [Per-card permissions](#per-card-permissions)). |   Yes   |     Yes    |
| `/transcription/admin-docs`      | `TranscriptionAdminDocsPage`      | `pf.transcription.vendors.manage`                                                                    |   Yes   |     Yes    |

New routes must be added to this table in the same PR — see
[Adding a new route](#adding-a-new-route).

> **Live mirror:** The in-app page at `/transcription/admin-docs` renders the
> same routes/permissions/navigation tables, sourced directly from the route
> catalog, module registry, and `ROUTE_LABELS` so it cannot drift from
> runtime config. Keep this markdown as the canonical narrative reference.

***

## Routes in detail

### `/transcription`

* **Defined in:** [`src/routes/tr.tsx`](https://github.com/Encore-OS/encoreos/blob/development/src/routes/tr.tsx)
* **Behavior:** `<Navigate to="/transcription/vendor-settings" replace />`
* **Permission:** None. The redirect runs before any page-level guard; the
  destination route enforces its own gates.
* **Navigation:**
  * **Sidebar:** Not listed. The sidebar links directly to the destination
    (`/transcription/vendor-settings`).
  * **Breadcrumbs:** Labeled "Transcription" via `BASE_ROUTE_LABELS`. This
    label is what renders as the parent crumb when a user is deeper in the
    module (e.g. `Transcription / Vendor Settings`).

### `/transcription/vendor-settings`

* **Defined in:** [`src/routes/tr.tsx`](https://github.com/Encore-OS/encoreos/blob/development/src/routes/tr.tsx)
* **Page component:** [`TranscriptionVendorSettingsPage`](https://github.com/Encore-OS/encoreos/blob/development/src/cores/tr/pages/TranscriptionVendorSettingsPage.tsx)
* **Permission (page-level):** None. The page renders for any authenticated
  user; each card on the page enforces its own permission, so unauthorized
  users see an empty/locked page rather than a hard 403.
* **Navigation:**
  * **Sidebar:** Listed under "Transcription" with label **"Vendor Settings"**
    and the `Settings` icon. This is the module's `defaultRoute` and
    `settingsRoute`.
  * **Breadcrumbs:** `Transcription / Vendor Settings`.

#### Per-card permissions

The page composes three cards, each gated independently:

| Card                      | Source                                                                                                                                                           | Required permission                                                                      | Behavior when denied                                                 |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| AI Documentation Settings | [`AIDocumentationSettingsCard`](https://github.com/Encore-OS/encoreos/blob/development/src/cores/cl/ai-documentation/components/AIDocumentationSettingsCard.tsx) | `cl.ai_documentation.admin`                                                              | Card hidden.                                                         |
| Generate sample data      | [`TranscriptionSampleDataCard`](https://github.com/Encore-OS/encoreos/blob/development/src/cores/tr/components/TranscriptionSampleDataCard.tsx)                  | `cl.ai_documentation.admin` **or** `pf.transcription.vendors.manage`                     | Card hidden.                                                         |
| Jurisdiction Routing      | [`JurisdictionRoutingTable`](https://github.com/Encore-OS/encoreos/blob/development/src/cores/tr/components/JurisdictionRoutingTable.tsx)                        | View: any authenticated user. Create / edit / delete: `pf.transcription.vendors.manage`. | Table renders read-only; CRUD buttons hidden via `<PermissionGate>`. |

***

## Permission key reference

Declared in [`src/platform/permissions/constants.ts`](https://github.com/Encore-OS/encoreos/blob/development/src/platform/permissions/constants.ts):

| Constant                                | Key                                | Used by                                                                                                                             |
| --------------------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `TRANSCRIPTION_VENDORS_MANAGE`          | `pf.transcription.vendors.manage`  | Jurisdiction Routing CRUD; "Generate sample data" action (alongside `cl.ai_documentation.admin`). Future: Vendor BAA management UI. |
| `TRANSCRIPTION_SETTINGS_VIEW`           | `pf.transcription.settings.view`   | Reserved for the planned Org Defaults card (`pf_transcription_module_settings`). Not yet referenced in code.                        |
| `TRANSCRIPTION_SETTINGS_MANAGE`         | `pf.transcription.settings.manage` | Reserved for the planned Org Defaults card. Not yet referenced in code.                                                             |
| `CL_PERMISSIONS.AI_DOCUMENTATION_ADMIN` | `cl.ai_documentation.admin`        | AI Documentation Settings card; "Generate sample data" action.                                                                      |

All keys must also exist as rows in `pf_module_permissions` (PF-30). Verify
with `npm run audit:permissions`.

***

## Navigation: how each surface is wired

### Sidebar

* **Source of truth:** `TR_MODULE_DEFINITION.navItems` in
  [`src/platform/modules/module-registry/tr-module.ts`](https://github.com/Encore-OS/encoreos/blob/development/src/platform/modules/module-registry/tr-module.ts).
* **Today:** one entry — `Vendor Settings` → `/transcription/vendor-settings`.
* **Module chrome:** the "Transcription" group itself is rendered from the
  module's `name` + `icon` (`Mic`) in the same definition.
* **Sidebar visibility:** governed by the module registry's standard
  permission filtering. The module has no top-level `requiredPermission`
  today, so the group is visible to all authenticated users; the underlying
  pages enforce their own gates.

### Breadcrumbs

* **Source of truth:** `BASE_ROUTE_LABELS` in
  [`src/platform/navigation/route-labels.ts`](https://github.com/Encore-OS/encoreos/blob/development/src/platform/navigation/route-labels.ts).
* Every route a user can land on (including pure redirects like
  `/transcription`) needs a label here — otherwise the breadcrumb component
  falls back to a humanized URL segment, which fails the breadcrumb-coverage
  audit (`npm run audit:breadcrumb-coverage -- --strict`).
* Labels for transcription routes are inline-tagged with `[sidebar]` /
  `[breadcrumb-only]` so the classification is visible at the call site.

### Why a route may be breadcrumb-only

A route that is **not** a sidebar destination still needs a breadcrumb label
when:

* It is a redirect parent (e.g. `/transcription`).
* It is a detail page reached only via in-page action (e.g. a future
  `/transcription/vendors/:id` opened from a row click).
* It is a deep link (e.g. an emailed link to a session detail).

In all these cases, add the route to `BASE_ROUTE_LABELS` only — **do not**
add it to `navItems`.

***

## Adding a new route

When adding a `<Route>` under [`src/routes/tr.tsx`](https://github.com/Encore-OS/encoreos/blob/development/src/routes/tr.tsx):

1. **Decide the surface:** sidebar destination vs breadcrumb-only (see
   criteria above).
2. **Add the label** to `BASE_ROUTE_LABELS` in
   [`src/platform/navigation/route-labels.ts`](https://github.com/Encore-OS/encoreos/blob/development/src/platform/navigation/route-labels.ts),
   tagged `// [sidebar]` or `// [breadcrumb-only]`.
3. **If sidebar:** add an entry to `TR_MODULE_DEFINITION.navItems` in
   [`tr-module.ts`](https://github.com/Encore-OS/encoreos/blob/development/src/platform/modules/module-registry/tr-module.ts)
   with a Lucide icon and the canonical label.
4. **Permissions:** declare any new permission constant in
   [`src/platform/permissions/constants.ts`](https://github.com/Encore-OS/encoreos/blob/development/src/platform/permissions/constants.ts)
   AND add the matching row to `pf_module_permissions` via migration. Run
   `npm run audit:permissions`.
5. **Update this file** — add the route to the [At-a-glance](#at-a-glance)
   table and a [Routes in detail](#routes-in-detail) entry.
6. **Update** [`src/cores/tr/NAVIGATION.md`](https://github.com/Encore-OS/encoreos/blob/development/src/cores/tr/NAVIGATION.md)
   and the doc-comment table in `tr-module.ts` so all three classification
   tables stay in sync.
7. **Verify:** `npm run audit:routes-navigation` and
   `npm run audit:breadcrumb-coverage -- --strict` (both included in
   `npm run validate:governance`).

***

## Out-of-tree references

* Vendor BAA management UI (CRUD on `pf_transcription_vendor_baas`) — planned;
  will use `pf.transcription.vendors.manage`.
* Org Defaults card (`pf_transcription_module_settings`) — planned; will use
  the reserved `pf.transcription.settings.view` /
  `pf.transcription.settings.manage` keys.
* Ambient Review (`/cl/ambient-review`, `/cl/ambient-review/:sessionId`) is
  the consumer of transcription sessions but lives in the **CL** core, not
  the TR module. It is not part of the transcription admin surface and is
  not listed here.

## Related

* [Navigation Standard](/architecture/standards/NAVIGATION_STANDARD)
* [Navigation Audit checklist](https://github.com/Encore-OS/encoreos/blob/development/docs/architecture/reviews/NAVIGATION_AUDIT.md)
* [Breadcrumb Implementation Guide](/development/breadcrumb-implementation-guide)
* [Module permissions matrix](/pf/module-permissions-matrix)
