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
28 changes: 28 additions & 0 deletions .changeset/seed-platform-app-docs-adr0046.md
Original file line number Diff line number Diff line change
@@ -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 <https://docs.objectstack.ai> 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.
5 changes: 5 additions & 0 deletions packages/apps/setup/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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],
});
}
}
Expand All @@ -66,3 +70,4 @@ export function createSetupAppPlugin(): SetupAppPlugin {
}

export { SETUP_APP, SETUP_NAV_CONTRIBUTIONS };
export { SETUP_OVERVIEW_DOC };
55 changes: 55 additions & 0 deletions packages/apps/setup/src/setup-overview.doc.ts
Original file line number Diff line number Diff line change
@@ -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 <https://docs.objectstack.ai>.

## 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 <https://docs.objectstack.ai> for the full security model.
`,
};
10 changes: 9 additions & 1 deletion packages/apps/studio/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -59,7 +61,12 @@ export class StudioAppPlugin {
async start(ctx: any): Promise<void> {
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],
});
}
}

Expand All @@ -69,3 +76,4 @@ export function createStudioAppPlugin(): StudioAppPlugin {
}

export { STUDIO_APP };
export { STUDIO_OVERVIEW_DOC };
58 changes: 58 additions & 0 deletions packages/apps/studio/src/studio-overview.doc.ts
Original file line number Diff line number Diff line change
@@ -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
<https://docs.objectstack.ai>.

## 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 <https://docs.objectstack.ai> for drafts, overlays, and deployment in depth.
`,
};