Commit 873998629c05736ac583b38745059a58105ac3a8

Authored by zichun
1 parent 0add76bd

docs(progress+readme): pin SPA commit + document the runnable demo

Updates the "at a glance" row to v0.29.0-SNAPSHOT + fc62d6d7,
bumps the Phase 6 R1 row to DONE with the commit ref and an
overview of what landed (Gradle wrapper, SpaController, security
reordering, bundled fat-jar, 16 pages), and rewrites the
"How to run" section to walk the click-through demo instead of
just curl. README's status table updated to reflect 10/10 PBCs
+ 356 tests + SPA status; building section now mentions that
`./gradlew build` compiles the SPA too.

No code changes.
Showing 2 changed files with 73 additions and 22 deletions
PROGRESS.md
... ... @@ -10,11 +10,11 @@
10 10  
11 11 | | |
12 12 |---|---|
13   -| **Latest version** | v0.28.0-SNAPSHOT (pbc-production v3 + shop-floor dashboard + OpenAPI / Swagger UI with 15 grouped specs + plug-in endpoints visible in spec + real buildInfo) |
14   -| **Latest commit** | `dfd01ff feat(plugins+bootstrap): plug-in endpoints visible in OpenAPI spec` |
  13 +| **Latest version** | v0.29.0-SNAPSHOT (R1 Web SPA bootstrap + demo seed — click-through end-to-end buy-sell loop from the browser) |
  14 +| **Latest commit** | `0add76b ci(docker): install nodejs+npm in build stage for :web SPA build` |
15 15 | **Repo** | https://github.com/reporkey/vibe-erp |
16   -| **Modules** | 24 |
17   -| **Unit tests** | 355, all green |
  16 +| **Modules** | 24 JVM subprojects + `:web` SPA |
  17 +| **Unit tests** | 356, all green |
18 18 | **Real PBCs implemented** | **10 of 10** (pbc-identity, pbc-catalog, pbc-partners, pbc-inventory, pbc-warehousing, pbc-orders-sales, pbc-orders-purchase, pbc-finance, pbc-production, pbc-quality) — P5.x row of the implementation plan complete at minimal v1 scope |
19 19 | **End-to-end smoke runs** | An SO confirmed with 2 lines auto-spawns 2 draft work orders via `SalesOrderConfirmedSubscriber`; completing one credits the finished-good stock via `PRODUCTION_RECEIPT`, cancelling the other flips its status, and a manual WO can still be created with no source SO. All in one run: 6 outbox rows DISPATCHED across `orders_sales.SalesOrder` and `production.WorkOrder` topics; pbc-finance still writes its AR row for the underlying SO; the `inventory__stock_movement` ledger carries the production receipt tagged `WO:<code>`. First PBC that REACTS to another PBC's events by creating new business state (not just derived reporting state). |
20 20 | **Plug-ins serving HTTP** | 1 (reference printing-shop, 7 endpoints + own DB schema + own metadata + own i18n bundles) |
... ... @@ -92,10 +92,10 @@ That target breaks down into roughly 30 work units across 8 phases. About **22 a
92 92  
93 93 | # | Unit | Status |
94 94 |---|---|---|
95   -| R1 | Vite + React + TS bootstrap, login flow, OpenAPI client | 🔜 Pending |
96   -| R2 | Identity screens | 🔜 Pending |
  95 +| R1 | Vite + React + TS bootstrap, login flow, typed REST client | ✅ DONE — `fc62d6d` — new `:web` Gradle subproject wraps Vite/React 18/TypeScript/Tailwind 3.4 via Exec tasks; `:distribution` consumes the dist via an outgoing/incoming Gradle configuration and stages it into `classpath:/static/` so a single fat-jar serves both API and SPA. Hand-written typed fetch client over `/api/v1/**` (211 KB JS gzipped, no codegen toolchain). AuthContext stores the JWT in localStorage with a 401 handler. `SpaController` forwards every known SPA route prefix to `/index.html` so React Router deep links work on hard refresh. `SecurityConfiguration` reordered: `/api/**` stays `.authenticated()` before the SPA permitAll rules so the "API is always authenticated" invariant holds even with the SPA bundled in the same image. Dockerfile build stage adds `apk add nodejs npm` so `./gradlew :distribution:bootJar` produces a self-contained image with the SPA inside. End-to-end smoke verified on fresh Postgres: log in, walk SO DRAFT → CONFIRMED → SHIPPED, watch stock balances drop + AR journal entry settle — all in a real browser. |
  96 +| R2 | Identity screens (user admin, role admin) | 🔜 Pending |
97 97 | R3 | Customize / metadata UIs | 🔜 Pending |
98   -| R4 | Per-PBC list/detail/create/edit screens | 🔜 Pending |
  98 +| R4 | Per-PBC create/edit screens (list/detail are live in R1) | 🔜 Pending — list + detail pages for all 10 PBCs landed in R1 along with the ship/receive/confirm/cancel action verbs on the order + work-order detail pages. Create/edit forms and richer per-PBC screens (BOM editor, routing editor) will follow when a real consumer asks for them. |
99 99  
100 100 ### Phase 7 — Reference printing-shop plug-in
101 101  
... ... @@ -175,30 +175,59 @@ This is **real**: a JAR file dropped into a directory, loaded by the framework,
175 175 - **MCP server.** The architecture leaves room for it; the implementation is v1.1.
176 176 - **Mobile.** v2.
177 177  
178   -## How to run what exists today
  178 +## How to run the end-to-end demo
179 179  
180 180 ```bash
181   -# Bring up Postgres + the plug-in JAR (in background)
  181 +# Bring up Postgres + stage the reference plug-in JAR
182 182 docker compose up -d db
183 183 ./gradlew :reference-customer:plugin-printing-shop:installToDev
184 184  
185   -# Boot the framework against it
  185 +# Boot the framework (serves both the REST API and the React SPA
  186 +# from the same fat-jar on http://localhost:8080)
186 187 ./gradlew :distribution:bootRun
187 188  
  189 +# Open the browser:
  190 +open http://localhost:8080
  191 +```
  192 +
  193 +The dev profile opts in to the one-shot `DemoSeedRunner` which
  194 +populates a starter dataset on first boot (5 items, 2 warehouses
  195 +with opening stock, 4 partners, one open sales order, one open
  196 +purchase order, all prefixed `DEMO-`). The bootstrap admin
  197 +password is printed to the boot log.
  198 +
  199 +Walk the demo:
  200 +
  201 +1. Log in as `admin` (password from the boot log).
  202 +2. **Sales Orders → DEMO-SO-0001** → **Confirm** → watch the
  203 + `AR POSTED` row appear in the on-page journal-entry panel.
  204 +3. Pick `DEMO-WH-FG` → **Ship** → order flips to `SHIPPED`, stock
  205 + balances drop, the journal entry settles to `AR SETTLED`, and
  206 + the `SALES_SHIPMENT` rows appear in the inventory movements
  207 + panel. All from one button click.
  208 +4. **Purchase Orders → DEMO-PO-0001** → **Confirm** → **Receive**
  209 + into `DEMO-WH-RAW` for the mirror-image flow.
  210 +5. **Shop Floor** polls every 5 seconds; create or start a work
  211 + order and watch it appear with a progress bar.
  212 +
  213 +Or for the API-only version:
  214 +
  215 +```bash
188 216 # In another shell:
189 217 curl -s localhost:8080/api/v1/_meta/info
190 218 curl -s localhost:8080/api/v1/_meta/metadata | jq
191 219  
192   -# Read the bootstrap admin password from the boot logs, then:
193 220 ACCESS=$(curl -s -H 'Content-Type: application/json' \
194 221 -X POST localhost:8080/api/v1/auth/login \
195 222 -d '{"username":"admin","password":"<from-logs>"}' | jq -r .accessToken)
196 223  
197   -curl -s -H "Authorization: Bearer $ACCESS" localhost:8080/api/v1/identity/users
198   -curl -s -H "Authorization: Bearer $ACCESS" localhost:8080/api/v1/catalog/uoms
  224 +curl -s -H "Authorization: Bearer $ACCESS" localhost:8080/api/v1/catalog/items
  225 +curl -s -H "Authorization: Bearer $ACCESS" localhost:8080/api/v1/orders/sales-orders
199 226 curl -s -H "Authorization: Bearer $ACCESS" localhost:8080/api/v1/plugins/printing-shop/plates
200 227 ```
201 228  
  229 +OpenAPI spec at [`/v3/api-docs`](http://localhost:8080/v3/api-docs) and Swagger UI at [`/swagger-ui/index.html`](http://localhost:8080/swagger-ui/index.html).
  230 +
202 231 ## Module map
203 232  
204 233 ```
... ...
README.md
... ... @@ -77,7 +77,7 @@ vibe-erp/
77 77 ## Building
78 78  
79 79 ```bash
80   -# Build everything (compiles 18 modules, runs 230 unit tests)
  80 +# Build everything (compiles all JVM modules + the web SPA, runs 356 unit tests)
81 81 ./gradlew build
82 82  
83 83 # Bring up Postgres + the reference plug-in JAR
... ... @@ -88,20 +88,42 @@ docker compose up -d db
88 88 ./gradlew :distribution:bootRun
89 89 ```
90 90  
91   -The bootstrap admin password is printed to the application logs on first boot. After login, REST endpoints are live under `/api/v1/identity/users`, `/api/v1/catalog/uoms`, `/api/v1/catalog/items`, `/api/v1/partners/partners`, `/api/v1/plugins/printing-shop/*`, and the public introspection endpoint at `/api/v1/_meta/metadata`.
  91 +The bootstrap admin password is printed to the application logs on first boot.
  92 +
  93 +## Running the end-to-end demo
  94 +
  95 +The dev profile opts in to a one-shot `DemoSeedRunner` that stages a starter dataset on first boot (5 items, 2 warehouses with opening stock, 4 partners, one open sales order, one open purchase order — everything prefixed `DEMO-`). Combined with the React SPA served out of the same fat-jar, that's enough to click through the entire buy-sell loop in the browser.
  96 +
  97 +```bash
  98 +docker compose up -d db
  99 +./gradlew :distribution:bootRun
  100 +open http://localhost:8080
  101 +```
  102 +
  103 +Then:
  104 +
  105 +1. Log in as `admin` — the password is in the bootRun log, under `vibe_erp bootstrap admin created`.
  106 +2. The dashboard shows every PBC populated with seeded rows. Click through **Items**, **Partners**, **Locations**, **Stock Balances** — each page is live against Postgres.
  107 +3. Click **Sales Orders → DEMO-SO-0001**. The order is in `DRAFT`; click **Confirm**. The `Journal entries` panel on the same page shows an `AR POSTED` row appear, created reactively by `pbc-finance` from the `SalesOrderConfirmedEvent`.
  108 +4. Pick `DEMO-WH-FG` as the shipping location and click **Ship**. The order flips to `SHIPPED`, the `Inventory movements` panel shows the `SALES_SHIPMENT` ledger rows, and the journal entry settles to `AR SETTLED`. Navigate to **Stock Balances** and confirm the two finished-good rows dropped by the shipped quantity.
  109 +5. Do the mirror-image flow on **Purchase Orders → DEMO-PO-0001** (Confirm → Receive into `DEMO-WH-RAW`). Stock grows, an `AP` row posts and settles, and another ledger row appears.
  110 +6. **Shop Floor** renders any `IN_PROGRESS` work order with a live progress bar; create one via **Work Orders** or via the workflow engine and watch it update every 5 seconds.
  111 +
  112 +REST endpoints are live under `/api/v1/**` for every PBC (see `/v3/api-docs` or the Swagger UI at `/swagger-ui/index.html` for the full catalog). The SPA uses them directly — no separate backend server is needed.
92 113  
93 114 ## Status
94 115  
95   -**Current stage: foundation complete; Tier 1 customization live; business surface area growing.** All eight cross-cutting platform services are live and verified end-to-end against a real Postgres: auth (JWT + Argon2id + bootstrap admin), plug-in HTTP endpoints, plug-in linter (ASM bytecode scan), plug-in-owned DB schemas + typed SQL, event bus + transactional outbox, the metadata seeder + custom-field validator, and the ICU4J translator with per-plug-in locale chain. The Tier 1 customization story works end-to-end: a YAML declaration adds a typed custom field to an existing entity, the framework's `ExtJsonValidator` enforces it on every save, and the SPA-facing `GET /api/v1/_meta/metadata/custom-fields/{entityName}` endpoint serves the runtime view to the form builder.
  116 +**Current stage: end-to-end runnable demo.** All 10 core PBCs are live against real Postgres, the full buy-sell-make loop is wired via cross-PBC events, every cross-cutting platform service (auth + authorization + plug-in HTTP + linter + Liquibase + metadata + i18n + events/outbox + JasperReports + FileStorage + Quartz + embedded Flowable) is running, and the **R1 React SPA** is served out of the same fat-jar with a seeded starter dataset so the entire buy-sell-make loop can be walked in a browser on first boot.
96 117  
97 118 | | |
98 119 |---|---|
99   -| Modules | 18 |
100   -| Unit tests | 230, all green |
101   -| Real PBCs | 8 of 10 |
102   -| Cross-cutting services live | 9 |
103   -| Plug-ins serving HTTP | 1 (reference printing-shop) |
104   -| Production-ready | **No** — workflow engine, forms, web SPA, more PBCs all still pending |
  120 +| JVM modules | 24 Kotlin subprojects + `:web` |
  121 +| Unit tests | 356, all green |
  122 +| Real PBCs | 10 of 10 |
  123 +| Cross-cutting services live | 12 |
  124 +| Plug-ins serving HTTP | 1 (reference printing-shop — 8 endpoints, own DB schema, metadata, i18n, TaskHandlers, JobHandler, BPMN, reports, file storage) |
  125 +| Web SPA | Served by Spring Boot at `/` — login, dashboard, 14 pages, live ship/receive/confirm verbs, shop-floor dashboard |
  126 +| Production-ready | **No** — OIDC, MCP server, JSON Schema form renderer, GL-level finance, and richer per-PBC verbs are still pending |
105 127  
106 128 For the full feature inventory, completed work, and next-priority list, see [`PROGRESS.md`](PROGRESS.md). For the detailed roadmap, see [`docs/superpowers/specs/2026-04-07-vibe-erp-implementation-plan.md`](docs/superpowers/specs/2026-04-07-vibe-erp-implementation-plan.md).
107 129  
... ...