feat: gallery + generic blueprint viewer, add Grid blueprint
Refactor the List-specific screen into a data-driven, reusable viewer: - generic Blueprint type + shared LoadState machine + registry - vue-router: / (gallery) and /b/:slug (illustration) - BlueprintViewer renders any blueprint; specimens stay bespoke - add Grid blueprint (6 functions incl. Position) + GridSpecimen
This commit is contained in:
70
DESIGN.md
Normal file
70
DESIGN.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Design — `blueprints`
|
||||
|
||||
Decisions for building `blueprints` out from a single List illustration into a
|
||||
gallery of many. Terminology: see [CONTEXT.md](CONTEXT.md).
|
||||
|
||||
## D1 · Content sourcing: hand-authored typed data + bespoke specimen
|
||||
|
||||
Each blueprint is a **typed TS data module** (`src/data/<name>Blueprint.ts`),
|
||||
transcribed by hand from its ontology README, paired with a **bespoke Specimen**
|
||||
component. The generic **Viewer** renders everything else (Readout, composition map,
|
||||
state machine) from that data.
|
||||
|
||||
- **Why not parse the ontology at build time?** The Specimen must be hand-built for
|
||||
every blueprint regardless (the ontology only provides an ASCII sketch), so parsing
|
||||
would automate only the cheap, structured text — at the cost of fragile
|
||||
markdown/mermaid parsing and a build-time coupling to the ontology repo's exact
|
||||
format. Not worth it.
|
||||
- **Source of truth** stays the `blueprint-ontology` repo; the data modules are a
|
||||
faithful transcription, cited in each module's header.
|
||||
|
||||
Structural split this implies:
|
||||
|
||||
| Part | Generic (data-driven) | Bespoke (per blueprint) |
|
||||
| ---------------------------------- | ------------------------------------ | ----------------------------------- |
|
||||
| Chrome (title block, tabs, legend) | ✓ | |
|
||||
| Readout (dossier per function) | ✓ | |
|
||||
| Composition map | ✓ (from `extends` + `composes` data) | |
|
||||
| State machine | ✓ (from nodes/edges data) | |
|
||||
| Specimen | | ✓ component slotted into the Viewer |
|
||||
|
||||
## D2 · Routing: vue-router, URL per blueprint
|
||||
|
||||
Add `vue-router`. Routes: `/` → Gallery, `/b/:slug` → the blueprint's illustration
|
||||
(e.g. `/b/list`). Deep-linkable and shareable; browser back/forward works. The nginx
|
||||
SPA fallback (`try_files … /index.html`) already serves client routes, so no server
|
||||
change is needed. A blueprint registry (`src/data/blueprints.ts`) maps `slug →
|
||||
{ data module, specimen component, meta }` and is the single source both the router
|
||||
and the Gallery read from.
|
||||
|
||||
## D3 · Gallery: illustrated-only, grows over time
|
||||
|
||||
The Gallery lists **only** blueprints that have an illustration; it grows as we add
|
||||
them. No greyed "planned" cards. Rationale: keeps the landing clean and truthful, and
|
||||
avoids maintaining metadata for 45 not-yet-built entries. A blueprint appears in the
|
||||
Gallery precisely when it is registered in `src/data/blueprints.ts`.
|
||||
|
||||
## D4 · Build-out slice #1: foundation + Grid
|
||||
|
||||
**Foundation (refactor, no UX change to List):**
|
||||
|
||||
- `pnpm add vue-router`; `App.vue` → thin shell with a header (link home) + `<RouterView/>`.
|
||||
- `src/views/GalleryView.vue` (`/`) — cards from the registry.
|
||||
- `src/views/BlueprintView.vue` (`/b/:slug`) — resolves the registry entry, renders the Viewer.
|
||||
- `src/components/BlueprintViewer.vue` — the **generic Viewer**, generalized from the
|
||||
current List-specific `App.vue`: title block, legend, function tabs + full view,
|
||||
two panes, optional composition map + state machine, footer. Props: a `Blueprint`
|
||||
object + the blueprint's Specimen component (injected via `<component :is>`).
|
||||
- Generic `Blueprint` type in `src/data/blueprint.ts` (signature, functions,
|
||||
coreInvariants, optional composition, optional stateMachine, meta). `listBlueprint.ts`
|
||||
conforms to it. Specimens move to `src/specimens/`.
|
||||
- `src/data/blueprints.ts` — registry: `slug → { meta, blueprint, specimen }`.
|
||||
|
||||
**Content:** `gridBlueprint.ts` + `src/specimens/GridSpecimen.vue` (2D tile grid).
|
||||
|
||||
**Ships:** Gallery listing List + Grid; `/b/list` (same UX, refactored) and `/b/grid`.
|
||||
|
||||
**Gates before push:** `pnpm build` clean · `pnpm lint` · `pnpm fmt`; then commit → push
|
||||
(auto-deploys) → verify `https://blueprints.apoena.dev`.
|
||||
|
||||
Subsequent slices add one blueprint each (Table, Feed, …).
|
||||
Reference in New Issue
Block a user