README: distinguish the two cap-5 apps (product SPA vs developer studio) and add current capability screenshots
131
README.md
|
|
@ -27,8 +27,8 @@ This README is a **show, don't tell** index. Skim the three tables, then jump to
|
|||
| 1 | **iframe embed** on any site | required | [§2](#deploy-1--iframe-embed) |
|
||||
| 2 | **Mobile app** (Android / Capacitor) | required | [§2](#deploy-2--mobile-app) |
|
||||
| 3 | **Direct-JS / research dashboard** (props + events + SRI) | required | [§2](#deploy-3--research-dashboard-direct-js) |
|
||||
| 4 | **WordPress** (same artifacts, Custom HTML block) | deferred POC | [§3](#3-cli-commands--installs-per-deploy-method) |
|
||||
| 5 | **Desktop** (Tauri) | deferred POC | [§3](#3-cli-commands--installs-per-deploy-method) |
|
||||
| 4 | **WordPress** (PHP plugin: shortcode + Gutenberg block) | built, not yet shot | [§3](#3-cli-commands--installs-per-deploy-method) |
|
||||
| 5 | **Desktop** (Tauri) | aspirational (no code yet) | [§3](#3-cli-commands--installs-per-deploy-method) |
|
||||
|
||||
### CLI commands + what to install
|
||||
|
||||
|
|
@ -96,7 +96,32 @@ the UPG-100 list plugin. The composite (`upg-100-mfe`) plus its list pages:
|
|||
build. A vertical-tab sidebar groups every plugin by capability (CAP 5 → 1); clicking a row mounts that
|
||||
plugin. This same SPA is the Capacitor mobile-app entry (see deploy 2).
|
||||
|
||||

|
||||
**`plugin-studio` is itself a CAP-5 plugin, AUTO-GENERATED by the Vite build step.** You do not hand-write
|
||||
it — the build discovers every folder in `plugin-designs/`, bundles each, and generates the studio SPA that
|
||||
composes them (a `nested-spa-single-spa` / app-shell tier plugin). Add a plugin-design folder, run the
|
||||
build, and it appears in the studio automatically. (`doxa-maps-spa` is the curated product SPA; `plugin-studio`
|
||||
is the auto-generated gallery of everything built — same cap-5 tier, both built by `bun run build`.)
|
||||
|
||||
**Two shared layouts back the cap-5 tier** (in `library/layouts/`, brand-neutral + reusable by any plugin):
|
||||
- **`VerticalTabsLayout`** — one element visible at a time (the sidebar-tab shell above). Lazy-mounts each
|
||||
tab's element on first open.
|
||||
- **`StackLayout`** — the *opposite*: all elements STACKED top-to-bottom at natural height, so the host page
|
||||
scrolls through them (the doxa-life / nuxtinator page-flow model). Group two elements and embed the pair.
|
||||
|
||||
**The two cap-5 apps, side by side.** They are different products at the same tier and the distinction
|
||||
matters when you embed one: `doxa-maps-spa` is what an END USER gets, `plugin-studio` is what a DEVELOPER
|
||||
reviews. (Captioning a studio shot as the product SPA is a documented mistake — see `/plugin-designer`.)
|
||||
|
||||
*`doxa-maps-spa` — the curated PRODUCT SPA.* Vertical tabs grouped by audience, not by capability:
|
||||
Prayer Mobilization (Big Picture · UPG-100 List · Prayer Progress · Gospel Resources) → Research
|
||||
(Cities & Internet · Research Map) → Experimental. Tab 1 is the cap-4 Big Picture composite.
|
||||
|
||||

|
||||
|
||||
*`plugin-studio` — the AUTO-GENERATED developer gallery.* The same cap-5 tier, but the sidebar groups every
|
||||
built plugin by capability (CAP 5 → 1) so an author can review the whole catalogue after a build.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
|
|
@ -144,18 +169,114 @@ Quick reference:
|
|||
| 1 | **iframe embed** | Bun | `bun install` → `bun run build` → `bun run serve` (or drop `public/doxa-maps/` on any host) |
|
||||
| 2 | **Mobile (Android)** | Bun · Android SDK + `adb` · JDK 17 · Capacitor (devDep) | `bun run phone` |
|
||||
| 3 | **Direct-JS / dashboard** | Bun | `bun run build`, then paste the `<script src> + integrity` snippet from `manifest.json` |
|
||||
| 4 | **WordPress** | Bun | `bun run build`, then paste the iframe/script snippet into a Custom HTML block *(deferred POC)* |
|
||||
| 5 | **Desktop (Tauri)** | Rust + Tauri CLI *(not yet scaffolded)* | *deferred POC* |
|
||||
| 4 | **WordPress** | Bun | `bun run build`, then install the `wordpress/doxa-maps-embed/` PHP plugin (shortcode + Gutenberg block) *(built, not yet shot — plugin written, install never captured live)* |
|
||||
| 5 | **Desktop (Tauri)** | Rust + Tauri CLI *(not yet scaffolded)* | *aspirational — no Tauri code exists yet* |
|
||||
|
||||
Every build writes `public/doxa-maps/manifest.json` — a machine-readable index carrying the ready-to-paste
|
||||
**iframe** and **`<script src>` + SRI** embed snippet for every map.
|
||||
|
||||
---
|
||||
|
||||
## 4. Repository layout (hand-off map)
|
||||
|
||||
Two directories matter to a plugin author: **`library/`** (the shared, high-bar reusable toolkit) and
|
||||
**`plugin-designs/`** (your free zone — one folder per plugin). The build reads `plugin-designs/`, pulls
|
||||
what it needs from `library/`, and emits each plugin to `public/<name>/`.
|
||||
|
||||
### `library/` — the shared reusable toolkit
|
||||
|
||||
Imported by ANY plugin. High blast radius — see [Library governance](#5-library-governance) before editing.
|
||||
|
||||
```
|
||||
library/
|
||||
├── index.js ← the library's public surface (what plugins import)
|
||||
├── ProfileLoader.vue ← the runtime loader that mounts a plugin profile
|
||||
├── layouts/ ← reusable shell layouts (VerticalTabsLayout, app-wrapper-material, pane-wrapper)
|
||||
├── components/ ← reusable Vue components (map controls, search, tables, charts, legends, detail panels)
|
||||
├── composables/ ← reusable logic hooks (useMapData, useMapClustering, useGeocoderSearch, legends/, poster/)
|
||||
├── colors/ ← brand-neutral color scales + registry (prayer-progress, adoption, engagement, religion, language-family)
|
||||
├── constants/ ← shared defaults (map defaults, zoom, poster sizes)
|
||||
├── stores/ ← shared Pinia-style stores (dataStore, mapStore, uiStore)
|
||||
├── i18n/ ← shared translations (index + locales/)
|
||||
├── api/ ← data-source layer (DataSourceManager, source registry, sources.json)
|
||||
├── data/ ← shared static reference data (ISO tables, language-family lookups)
|
||||
├── utils/ ← shared helpers (clustering, MST/network utils, data-source helpers)
|
||||
├── styles/ ← shared style registry
|
||||
└── scripts/ ← shared build/gen scripts (posters, research)
|
||||
```
|
||||
|
||||
### `plugin-designs/` — your free zone (one folder per plugin)
|
||||
|
||||
You write your app HERE. Each folder is its own application; on `bun run build` it compiles to
|
||||
`public/<name>/` and becomes its own deployable custom element (via `defineCustomElement`).
|
||||
|
||||
```
|
||||
plugin-designs/
|
||||
├── template-bundle/ ← copy this to start a new plugin
|
||||
├── doxa-vision-card/ ← CAP 1: single element (one .vue + index.js)
|
||||
│ ├── doxa-vision-card.vue
|
||||
│ └── index.js
|
||||
├── doxa-simple-map/ ← CAP 2: preset element (one root.vue + *.instances.json → many maps)
|
||||
├── doxa-research-map/ ← CAP 3: monolithic multi-view map
|
||||
├── my-upg-100-list/ ← CAP 4: composite element (nests lower-tier elements)
|
||||
├── doxa-maps-spa/ ← CAP 5: app-shell (the full doxa-maps app, one deep-linkable SPA)
|
||||
│ ├── doxa-maps-spa.vue
|
||||
│ ├── doxa-maps-spa.meta.json
|
||||
│ ├── doxa-maps-spa.instances.json
|
||||
│ └── index.js
|
||||
├── research-dashboard/ ← direct-JS dashboard (props/events/SRI; deploy method 3)
|
||||
├── big-picture/ country-posters/ key-cities/ cities-internet/ … ← more example plugins
|
||||
```
|
||||
|
||||
**How a plugin-design works:** create a folder in `plugin-designs/<name>/` (copy `template-bundle/`),
|
||||
write your `.vue` (plus an optional `<name>.meta.json` to declare its type and `<name>.instances.json` for
|
||||
preset rows), and run `bun run build`. The build auto-detects the folder, compiles it into a self-contained
|
||||
element at `public/<name>/`, and adds its embed snippets to `public/doxa-maps/manifest.json`. Your plugin
|
||||
imports shared pieces from `library/` but ships as its own deployable artifact.
|
||||
|
||||
### Deploy honesty ledger
|
||||
|
||||
This README does not over-claim. Per the verified ledger (2026-09-19):
|
||||
|
||||
| Count | State | Methods |
|
||||
|-------|-------|---------|
|
||||
| 2 | **proven live** | iframe embed · direct-JS embed |
|
||||
| 2 | **built, not yet shot** | mobile (Capacitor scaffolded, APK never emitted) · WordPress (`wordpress/doxa-maps-embed/*.php` written, install never captured) |
|
||||
| 1 | **aspirational** | Tauri desktop (no code exists yet) |
|
||||
|
||||
All **5 capabilities** are proven by a built bundle. Only the deploy *methods* carry the two lower states.
|
||||
|
||||
---
|
||||
|
||||
## 5. Library governance
|
||||
|
||||
The two zones above have very different rules. Follow them so one author's change never breaks another's map.
|
||||
|
||||
**`plugin-designs/` = free zone.** Agentically engineer your maps here without asking. A plugin operates as
|
||||
its own application, isolated to its own folder, and builds to its own output — nothing you do here can break
|
||||
another author's plugin.
|
||||
|
||||
**`library/` = HIGH BAR.** It is multi-tenant: reused by many maps and authors. Editing it is a
|
||||
breaking-change risk to everyone. From the canonical anti-pattern
|
||||
(`AP-fill-shared-library-with-non-reusable-components`):
|
||||
|
||||
> Agentically engineer your maps IN plugin-designs — a plugin operates as its own application that builds to
|
||||
> the output folder on the build step. Only contribute to the shared library if you're experienced AND the
|
||||
> component is genuinely reusable + parameterized so OTHER maps (not just yours) can use it. Treat every
|
||||
> library edit as breaking-change-risk to other tenants — a HIGH BAR. Never widen or casually add.
|
||||
|
||||
Why it matters: a non-reusable component in `library/` teaches other agents + future authors that it's OK to
|
||||
follow the anti-pattern, polluting a high-blast-radius surface over time — and any library edit can make a
|
||||
breaking change that breaks other tenants' maps. Keep all map-specific, non-parameterized content in your
|
||||
plugin-design; contribute to `library/` only when it is genuinely reusable and parameterized.
|
||||
|
||||
---
|
||||
|
||||
## More docs
|
||||
|
||||
| Read this | When |
|
||||
|---|---|
|
||||
| **[docs/develop-a-plugin-and-see-it-live.md](./docs/develop-a-plugin-and-see-it-live.md)** | ★ START HERE — the golden path, zero → a plugin live, in 6 steps |
|
||||
| **[docs/README-SECTION-3-cli-commands.md](./docs/README-SECTION-3-cli-commands.md)** | the full per-method CLI + install matrix |
|
||||
| **[docs/why.md](./docs/why.md)** | 2 min — the problem, the idea, one diagram |
|
||||
| **[docs/tutorial.md](./docs/tutorial.md)** | build your first map, step by step |
|
||||
|
|
|
|||
BIN
docs/screenshots/cap-1-single-element.png
Normal file
|
After Width: | Height: | Size: 687 KiB |
BIN
docs/screenshots/cap-2-prop-table.png
Normal file
|
After Width: | Height: | Size: 856 KiB |
BIN
docs/screenshots/cap-3-monolithic.png
Normal file
|
After Width: | Height: | Size: 610 KiB |
BIN
docs/screenshots/cap-4-nested-element-spa.png
Normal file
|
After Width: | Height: | Size: 527 KiB |
BIN
docs/screenshots/cap-5-nested-spa.png
Normal file
|
After Width: | Height: | Size: 510 KiB |
BIN
docs/screenshots/map-cities-internet.png
Normal file
|
After Width: | Height: | Size: 257 KiB |
BIN
docs/screenshots/map-gospel-resources.png
Normal file
|
After Width: | Height: | Size: 262 KiB |