Skip to content

Commit 56571d6

Browse files
xuyushun441-sysos-zhuangclaude
authored
feat(console): DocPage resolves docs package-scoped (ADR-0048) (#1708)
The doc viewer at /apps/:appName/docs/:name now threads the route's package-id segment into meta.getItem('doc', name, { packageId: appName }) so the single-doc fetch is package-scoped (prefer-local) on the server. Two installed packages may ship a doc with the same bare name and each resolves within its own package, so doc names no longer need a globally-unique namespace prefix. The legacy top-level /docs/:name path (no appName) keeps context-free behavior. Verified end-to-end in the browser against a real collision: /apps/ com.example.showcase/docs/showcase_index and /apps/com.objectstack.studio/docs/ showcase_index render each package's own doc. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 77d765d commit 56571d6

2 files changed

Lines changed: 20 additions & 3 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
"@object-ui/console": patch
3+
---
4+
5+
ADR-0048: DocPage resolves docs package-scoped. The doc viewer at
6+
`/apps/:appName/docs/:name` now passes the route's package segment as
7+
`getItem('doc', name, { packageId })`, so the single-doc fetch is package-scoped
8+
(prefer-local) on the server. Two installed packages may ship a doc with the
9+
same bare name and each resolves within its own package — doc names no longer
10+
need a globally-unique namespace prefix (the prefix becomes a convention, like
11+
`page`/`dashboard`/`report`). The legacy top-level `/docs/:name` path (no
12+
`appName`) keeps its context-free behavior.

apps/console/src/pages/DocPage.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ interface DocItem {
3434
* "not found" notice — never an install-time or hard failure.
3535
*/
3636
export default function DocPage() {
37-
const { name } = useParams<{ name: string }>();
37+
// `appName` is the parent route's package-id segment
38+
// (/apps/:appName/docs/:name); undefined on the legacy top-level /docs/:name.
39+
const { name, appName } = useParams<{ name: string; appName?: string }>();
3840
const navigate = useNavigate();
3941
const adapter = useAdapter();
4042
const [doc, setDoc] = useState<DocItem | null>(null);
@@ -47,7 +49,10 @@ export default function DocPage() {
4749
if (!name || !adapter) return;
4850
setState('loading');
4951
try {
50-
const raw: any = await adapter.getClient().meta.getItem('doc', name);
52+
// ADR-0048 — pass the route's package so the single-doc fetch is
53+
// package-scoped (prefer-local) on the server. With this, doc names
54+
// need not be globally namespace-prefixed; the prefix becomes optional.
55+
const raw: any = await adapter.getClient().meta.getItem('doc', name, appName ? { packageId: appName } : undefined);
5156
const item = raw?.item ?? raw?.data ?? raw;
5257
if (cancelled) return;
5358
if (item && typeof item.content === 'string') {
@@ -73,7 +78,7 @@ export default function DocPage() {
7378
return () => {
7479
cancelled = true;
7580
};
76-
}, [name, adapter]);
81+
}, [name, appName, adapter]);
7782

7883
// SPA navigation for rewritten doc-to-doc links: anchors render as
7984
// plain <a href="/docs/...">; intercept same-app clicks so following a

0 commit comments

Comments
 (0)