|
| 1 | +# ObjectStack Showcase (`@objectstack/example-showcase`) |
| 2 | + |
| 3 | +> A kitchen-sink workspace that exercises **every metadata type, every view |
| 4 | +> type, every chart type**, and the major **end-to-end capability chains** — |
| 5 | +> built for three audiences at once: **demonstration**, **debugging**, and |
| 6 | +> **verification**. |
| 7 | +
|
| 8 | +Most example apps are intentionally minimal. This one is deliberately |
| 9 | +*exhaustive*. It pairs a coherent business domain (project delivery) with a |
| 10 | +set of synthetic "gallery" objects whose only job is to cover protocol |
| 11 | +variants, and ties the two together with a **coverage manifest** that the test |
| 12 | +suite checks against the protocol's own Zod enums. |
| 13 | + |
| 14 | +## Why it exists |
| 15 | + |
| 16 | +Demonstration and verification pull in opposite directions: |
| 17 | + |
| 18 | +- **Demo** wants a believable, connected app — but a realistic app never |
| 19 | + naturally uses all 49 field types, all 8 view types, or all 38 chart types. |
| 20 | +- **Verify** wants every variant present and *asserted* — which a single |
| 21 | + realistic domain can't provide. |
| 22 | + |
| 23 | +So the showcase splits into two tracks: |
| 24 | + |
| 25 | +| Track | Purpose | Where | |
| 26 | +| :--- | :--- | :--- | |
| 27 | +| **Realistic backbone** | A connected delivery domain with seeded data, so every view renders something real. | `Account → Project → Task`, `Team`, `Category` | |
| 28 | +| **Gallery / specimens** | Synthetic objects & views that exhaust protocol variants. | `Field Zoo`, the Task view gallery, the Chart Gallery | |
| 29 | + |
| 30 | +## Quick start |
| 31 | + |
| 32 | +```bash |
| 33 | +pnpm install |
| 34 | +pnpm --filter @objectstack/spec build # if not already built |
| 35 | + |
| 36 | +# Demonstration — open Studio and click through the gallery |
| 37 | +pnpm dev # → http://localhost:3000/_studio |
| 38 | + |
| 39 | +# Verification — typecheck + coverage test |
| 40 | +pnpm verify |
| 41 | +``` |
| 42 | + |
| 43 | +## What it covers |
| 44 | + |
| 45 | +### Data layer (ObjectQL) |
| 46 | +- **All 49 field types** — `src/objects/field-zoo.object.ts` carries one field |
| 47 | + of every `FieldType`, with the remainder appearing naturally on the backbone |
| 48 | + objects. |
| 49 | +- **Every relationship kind** — `lookup` (project → account, category → self), |
| 50 | + `master_detail` (task → project), self-referencing **hierarchy/tree** |
| 51 | + (`Category.parent`), and **many-to-many** via the |
| 52 | + `showcase_project_membership` junction. |
| 53 | +- **Formulas, validations, and a status state machine** on `Project` and |
| 54 | + `Task`. |
| 55 | + |
| 56 | +### View layer (ObjectUI) |
| 57 | +- **All 8 list-view types** on a single object (`src/views/task.view.ts`): |
| 58 | + grid, kanban, gallery, calendar, timeline, gantt, map, chart. The Task object's |
| 59 | + fields are chosen so one object can back every type. |
| 60 | +- **All 5 form-view types**: simple, tabbed, wizard, split, drawer. |
| 61 | +- **The full chart taxonomy** — `src/dashboards/chart-gallery.dashboard.ts` |
| 62 | + has one widget per chart family (all 38 `ChartType`s). |
| 63 | +- **All 4 report types**: tabular, summary, matrix, joined |
| 64 | + (`src/reports/index.ts`). |
| 65 | +- **The action matrix** — every `ActionType` (script/url/flow/modal/api/form) |
| 66 | + across every `ActionLocation`. |
| 67 | +- **A component-gallery page** placing the standard page components. |
| 68 | + |
| 69 | +### Capability chains (the "complex abilities") |
| 70 | +- **Security** (`src/security/index.ts`): a role hierarchy + a permission set |
| 71 | + that layers object CRUD, **field-level security (FLS)**, and |
| 72 | + **row-level security (RLS)**, plus criteria- and owner-based **sharing rules** |
| 73 | + and an org **policy**. |
| 74 | +- **Automation**: a record-triggered flow → a screen-flow wizard → a multi-step |
| 75 | + **approval** → an outbound **webhook** → a scheduled **job** → an **email** |
| 76 | + template. |
| 77 | +- **AI**: an **agent** wired to a **tool** and a **skill**. |
| 78 | +- **i18n / theming / portals**: `en` + `zh-CN` translations, light + dark |
| 79 | + themes, and an external client portal. |
| 80 | + |
| 81 | +## The coverage manifest — how "confirm" works |
| 82 | + |
| 83 | +`src/coverage.ts` declares what the showcase is supposed to cover and provides |
| 84 | +the collectors the test uses. `test/coverage.test.ts` then **introspects the |
| 85 | +protocol's own enums** (`FieldType`, `ChartTypeSchema`, `ReportType`, |
| 86 | +`ActionType`, `ACTION_LOCATIONS`) and asserts every member appears at least |
| 87 | +once across the registered metadata. |
| 88 | + |
| 89 | +Because the expected sets come from the **spec** — not a hand-maintained list — |
| 90 | +the test fails automatically when the platform gains a new field type, chart |
| 91 | +type, or report type that the showcase hasn't demonstrated yet. That keeps this |
| 92 | +example a **living conformance fixture**, not a static snapshot. (`defineStack` |
| 93 | +itself also runs full schema + cross-reference validation when the config is |
| 94 | +imported, so `pnpm test` proves the whole stack loads cleanly.) |
| 95 | + |
| 96 | +## Directory layout |
| 97 | + |
| 98 | +``` |
| 99 | +app-showcase/ |
| 100 | +├── objectstack.config.ts # defineStack — registers everything |
| 101 | +├── src/ |
| 102 | +│ ├── coverage.ts # coverage manifest + collectors (the soul) |
| 103 | +│ ├── objects/ # field-zoo + backbone + junction + tree |
| 104 | +│ ├── views/ # all 8 list types + all 5 form types |
| 105 | +│ ├── dashboards/ # chart gallery (all 38 chart types) |
| 106 | +│ ├── reports/ # tabular / summary / matrix / joined |
| 107 | +│ ├── actions/ # type × location matrix |
| 108 | +│ ├── pages/ # component gallery |
| 109 | +│ ├── apps/ # navigation linking every surface |
| 110 | +│ ├── security/ # roles + FLS + RLS + sharing + policy |
| 111 | +│ ├── flows/ approvals/ webhooks/ jobs/ emails/ # automation chain |
| 112 | +│ ├── agents/ # agent + tool + skill |
| 113 | +│ ├── themes/ translations/ datasources/ portals/ |
| 114 | +│ └── data/ # seed data sized to feed every view |
| 115 | +└── test/ |
| 116 | + ├── coverage.test.ts # introspects spec enums, asserts coverage |
| 117 | + └── seed.test.ts # stack-loads + breadth smoke test |
| 118 | +``` |
| 119 | + |
| 120 | +## Extending it |
| 121 | + |
| 122 | +When you add a new variant to the platform, the coverage test will go red and |
| 123 | +point at the gap. Add a field/view/widget that uses it, reference it in |
| 124 | +`COVERAGE`, and the test goes green again. |
0 commit comments