fix(ui): prefix audit board route (#10830)

<!-- Write all pull request text in Simplified Technical English
(ASD-STE100): short sentences, one instruction per sentence, simple
approved vocabulary, and the active voice. -->

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board UI keeps company work under a company-prefixed route.
> - The Audit sidebar link used a bare `/audit` path.
> - The route helper treated `audit` as a company prefix because the
board-route list did not include it.
> - The router also had no redirect for a bare `/audit` deep link.
> - This pull request registers Audit in both places and adds regression
coverage.
> - The benefit is that the Audit sidebar link and old bare deep links
open the active company's audit feed.

## Linked Issues or Issue Description

Related PR: #9744

**What happened?**

The Audit sidebar link opened `/audit`. The router interpreted `AUDIT`
as a company prefix and showed the invalid-company page.

**Expected behavior**

The Audit sidebar link must open `/<company-prefix>/audit`. A bare
`/audit` deep link must redirect to the active company.

**Steps to reproduce**

1. Open a company board.
2. Select Audit in the sidebar.
3. Observe that the app opens `/audit` and shows an invalid-company
error.

**Paperclip version or commit**

Reproduced on master after #9744.

**Deployment mode**

Board UI in local or self-hosted deployments.

## What Changed

- Added `audit` to the board-route root list.
- Added the unprefixed `/audit` redirect route.
- Added regression tests for Audit prefixing, prefix extraction, and
relative-path conversion.

## Verification

- `pnpm exec vitest run ui/src/lib/company-routes.test.ts`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm check:token-gates`
- Manual check: select Audit in the sidebar and confirm the URL is
`/<company-prefix>/audit` and the audit feed renders.

## Risks

- Low risk. This change only reserves one existing board route and adds
one redirect.
- A company cannot use `AUDIT` as an issue prefix after this change.
That prefix already conflicts with the existing Audit board page.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex with GPT-5. The runtime does not expose a more specific
model ID or context-window size. The agent used reasoning, repository
tools, code execution, and test execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dotta 2026-08-04 23:07:24 -05:00 committed by GitHub
parent e8ae5286eb
commit f0ed524ffa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 9 additions and 0 deletions

View File

@ -577,6 +577,7 @@ export function App() {
<Route path="pipelines/:pipelineId/items/:caseId" element={<UnprefixedBoardRedirect />} />
<Route path="pipelines/:pipelineId/cases/:caseId" element={<UnprefixedBoardRedirect />} />
<Route path="artifacts" element={<UnprefixedBoardRedirect />} />
<Route path="audit" element={<UnprefixedBoardRedirect />} />
<Route path="decisions" element={<UnprefixedBoardRedirect />} />
<Route path="u/:userSlug" element={<UnprefixedBoardRedirect />} />
<Route path="skills/studio" element={<UnprefixedBoardRedirect />} />

View File

@ -88,6 +88,13 @@ describe("company routes", () => {
expect(toCompanyRelativePath("/PAP/artifacts")).toBe("/artifacts");
});
it("treats /audit as a board route that needs a company prefix", () => {
expect(isBoardPathWithoutPrefix("/audit")).toBe(true);
expect(extractCompanyPrefixFromPath("/audit")).toBeNull();
expect(applyCompanyPrefix("/audit", "PAP")).toBe("/PAP/audit");
expect(toCompanyRelativePath("/PAP/audit")).toBe("/audit");
});
it("treats /tools routes as board routes that need a company prefix", () => {
expect(isBoardPathWithoutPrefix("/tools")).toBe(true);
expect(isBoardPathWithoutPrefix("/tools/runtime")).toBe(true);

View File

@ -19,6 +19,7 @@ const BOARD_ROUTE_ROOTS = new Set([
"costs",
"usage",
"activity",
"audit",
"decisions",
"inbox",
"board-chat",