From fdf4d7ec100694c27e5ac0842315673c1b9b093f Mon Sep 17 00:00:00 2001 From: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Date: Sun, 14 Jun 2026 12:40:07 +0500 Subject: [PATCH] feat(ADR-0046): seed Setup & Studio package docs so the docs hub isn't empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A bare install shipped no first-party `doc` metadata, so `/_console/docs` opened empty and ADR-0046 had no reference implementation. Seed one short overview per built-in app, registered inline on each app package's `manifest.register({ docs })` (the TS-first path DocSchema blesses) so they group under Setup and Studio in the hub. - @objectstack/setup: setup_overview (users/auth, roles & permissions, sharing) - @objectstack/studio: studio_overview (metadata-first, draft/overlay precedence per ADR-0005/0033, publish vs deploy) Documents the invisible concepts only (HotCRM principle), links to https://docs.objectstack.ai for depth. No framework change needed — code packages register docs inline, not via os build flat-file collection. Co-Authored-By: Claude Opus 4.8 (1M context) --- .changeset/seed-platform-app-docs-adr0046.md | 28 +++++++++ packages/apps/setup/src/index.ts | 5 ++ packages/apps/setup/src/setup-overview.doc.ts | 55 ++++++++++++++++++ packages/apps/studio/src/index.ts | 10 +++- .../apps/studio/src/studio-overview.doc.ts | 58 +++++++++++++++++++ 5 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 .changeset/seed-platform-app-docs-adr0046.md create mode 100644 packages/apps/setup/src/setup-overview.doc.ts create mode 100644 packages/apps/studio/src/studio-overview.doc.ts diff --git a/.changeset/seed-platform-app-docs-adr0046.md b/.changeset/seed-platform-app-docs-adr0046.md new file mode 100644 index 0000000000..b7cab8d441 --- /dev/null +++ b/.changeset/seed-platform-app-docs-adr0046.md @@ -0,0 +1,28 @@ +--- +"@objectstack/setup": patch +"@objectstack/studio": patch +--- + +feat(ADR-0046): seed first-party package docs for the Setup and Studio apps + +A fresh platform install shipped **no** first-party `doc` metadata, so the +in-product documentation hub (`/_console/docs`) opened completely empty and the +ADR-0046 feature had zero reference implementation. This seeds a deliberately +minimal first version — one short overview per built-in app — so the hub is +non-empty out of the box and there is a worked example to copy. + +- `@objectstack/setup` registers `setup_overview` (for administrators: users & + authentication, the roles & permissions model, and record visibility/sharing). +- `@objectstack/studio` registers `studio_overview` (for builders: the + metadata-first model, the invisible draft/overlay precedence rule per + ADR-0005/ADR-0033, and publish vs deploy). + +Both follow the HotCRM principle — document the *invisible* business logic, not +what the UI already shows — and link to for depth. + +Mechanism note: these are TS-first code packages built by `tsup`, not user apps +built by `os build`, so they do **not** go through the flat `src/docs/*.md` +collection + lint. The docs are declared inline as `Doc` items on each package's +`manifest.register({ docs })` call — the path `DocSchema` explicitly blesses for +TS-first stacks. They register under their owning package id, so the docs hub +groups them under Setup and Studio respectively. No framework change was needed. diff --git a/packages/apps/setup/src/index.ts b/packages/apps/setup/src/index.ts index 9a5d4c1ebc..3af7176fbd 100644 --- a/packages/apps/setup/src/index.ts +++ b/packages/apps/setup/src/index.ts @@ -17,6 +17,8 @@ import { SETUP_APP, SETUP_NAV_CONTRIBUTIONS } from '@objectstack/platform-objects/apps'; +import { SETUP_OVERVIEW_DOC } from './setup-overview.doc.js'; + export const SETUP_APP_PACKAGE_ID = 'com.objectstack.setup'; export const SETUP_APP_NAMESPACE = 'setup'; export const SETUP_APP_VERSION = '9.3.0'; @@ -56,6 +58,8 @@ export class SetupAppPlugin { ...setupAppManifestHeader, apps: [SETUP_APP], navigationContributions: SETUP_NAV_CONTRIBUTIONS, + // ADR-0046 package docs — grouped under "Setup" at /_console/docs. + docs: [SETUP_OVERVIEW_DOC], }); } } @@ -66,3 +70,4 @@ export function createSetupAppPlugin(): SetupAppPlugin { } export { SETUP_APP, SETUP_NAV_CONTRIBUTIONS }; +export { SETUP_OVERVIEW_DOC }; diff --git a/packages/apps/setup/src/setup-overview.doc.ts b/packages/apps/setup/src/setup-overview.doc.ts new file mode 100644 index 0000000000..554773535b --- /dev/null +++ b/packages/apps/setup/src/setup-overview.doc.ts @@ -0,0 +1,55 @@ +// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. + +import type { Doc } from '@objectstack/spec/system'; + +/** + * Setup app overview doc (ADR-0046), registered in this package's manifest so + * it groups under "Setup" in the `/_console/docs` index. + * + * Authored inline rather than as a flat `src/docs/*.md` file because this is a + * TS-first code package built by tsup, not a user app built by `os build` — + * `defineStack({ docs })` / manifest `docs[]` is the supported path for those + * (see `DocSchema` in `@objectstack/spec/system`). The `content` below is plain + * CommonMark + GFM with no images/MDX, per ADR-0046 §3.4. + * + * Principle (from the HotCRM reference docs): document the *invisible* concepts, + * not what the Setup UI already shows on screen. + */ +export const SETUP_OVERVIEW_DOC: Doc = { + name: 'setup_overview', + label: 'Setup overview', + description: 'Orientation for administrators: users, roles & permissions, and record visibility.', + content: `# Setup overview + +Setup is the administrator app for the platform. Its screens are mostly +self-explanatory — this page covers the concepts behind them that the UI does +not make obvious. For the full reference, see . + +## Users & authentication + +Every person who signs in is a \`sys_user\` record. Authentication (passwords, +SSO, API keys, sessions) is handled by the platform's auth layer, so creating a +user here grants *identity*, not access — what they can do is decided entirely +by the roles and permissions assigned to them. Deactivating a user revokes +sign-in without deleting their records, preserving ownership and history. + +## Roles & permissions + +Permission sets define *what* a user can do (which objects and fields they can +read or write, which apps they can open); roles place a user in the +organization hierarchy and drive *which records* they can reach. A user's +effective access is the union of all permission sets granted to them — access is +additive, so you grant capability rather than taking it away. + +## Record visibility (sharing) + +Object-level permissions decide whether a user can touch a *kind* of record; +sharing decides *which* rows of that kind they actually see. Visibility starts +from an org-wide default (private or public) and is then widened by the role +hierarchy and explicit sharing rules — it is never silently narrowed. When a +user "can't see a record they should," the cause is almost always sharing, not +object permissions. + +See for the full security model. +`, +}; diff --git a/packages/apps/studio/src/index.ts b/packages/apps/studio/src/index.ts index a518cb6cc5..e07e09dfe2 100644 --- a/packages/apps/studio/src/index.ts +++ b/packages/apps/studio/src/index.ts @@ -21,6 +21,8 @@ import { STUDIO_APP } from '@objectstack/platform-objects/apps'; +import { STUDIO_OVERVIEW_DOC } from './studio-overview.doc.js'; + export const STUDIO_APP_PACKAGE_ID = 'com.objectstack.studio'; export const STUDIO_APP_NAMESPACE = 'studio'; export const STUDIO_APP_VERSION = '9.3.0'; @@ -59,7 +61,12 @@ export class StudioAppPlugin { async start(ctx: any): Promise { const manifest = ctx?.getService?.('manifest'); if (!manifest || typeof manifest.register !== 'function') return; - manifest.register({ ...studioAppManifestHeader, apps: [STUDIO_APP] }); + manifest.register({ + ...studioAppManifestHeader, + apps: [STUDIO_APP], + // ADR-0046 package docs — grouped under "Studio" at /_console/docs. + docs: [STUDIO_OVERVIEW_DOC], + }); } } @@ -69,3 +76,4 @@ export function createStudioAppPlugin(): StudioAppPlugin { } export { STUDIO_APP }; +export { STUDIO_OVERVIEW_DOC }; diff --git a/packages/apps/studio/src/studio-overview.doc.ts b/packages/apps/studio/src/studio-overview.doc.ts new file mode 100644 index 0000000000..78e6b143b7 --- /dev/null +++ b/packages/apps/studio/src/studio-overview.doc.ts @@ -0,0 +1,58 @@ +// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. + +import type { Doc } from '@objectstack/spec/system'; + +/** + * Studio app overview doc (ADR-0046), registered in this package's manifest so + * it groups under "Studio" in the `/_console/docs` index. + * + * Authored inline rather than as a flat `src/docs/*.md` file because this is a + * TS-first code package built by tsup, not a user app built by `os build` — + * `defineStack({ docs })` / manifest `docs[]` is the supported path for those + * (see `DocSchema` in `@objectstack/spec/system`). The `content` below is plain + * CommonMark + GFM with no images/MDX, per ADR-0046 §3.4. + * + * Principle (from the HotCRM reference docs): document the *invisible* + * business logic, not what the Studio UI already shows on screen. + */ +export const STUDIO_OVERVIEW_DOC: Doc = { + name: 'studio_overview', + label: 'Studio overview', + description: 'Orientation for builders: the metadata-first model, overlay precedence, and publishing.', + content: `# Studio overview + +Studio is the builder app — the workbench for shaping the platform's +*metadata*: objects, fields, views, flows, agents, and the rest. Most of its +screens are self-explanatory; this page covers the one rule that is not visible +on screen but governs everything you do here. For the full reference, see +. + +## Metadata-first + +In Studio you do not edit a running database — you edit *definitions*. Every +object, field, and view is a metadata record, and the live application is +generated from that metadata. This is why a change in Studio can reshape the UI +and the API at once: you are changing the model, not patching a screen. + +## Edits are overlays (the invisible rule) + +Your changes do not mutate the metadata shipped by a package in place. Studio +writes an **overlay** on top of the base definition, and the runtime resolves +the two by precedence: an unpublished **draft** wins for you while you work, a +published **tenant overlay** wins over the package's baseline, and the package +baseline is the fallback (ADR-0005, ADR-0033). The practical consequence: the +base definition is never destroyed, so an overlay can always be reverted to +recover the original — and a field that "won't change" is usually being shadowed +by a higher-precedence layer. + +## Publishing & deploying + +A draft is visible only to you until you **publish** it, which promotes the +overlay so the rest of the tenant sees it. Moving changes between environments +(for example dev → production) is a separate **deploy** step, not an automatic +side effect of publishing — keeping the two distinct is what lets you build +safely in one environment before shipping. + +See for drafts, overlays, and deployment in depth. +`, +};