# vibe_erp vibe_erp is an ERP/EBC framework for the printing industry, sold worldwide and deployed self-hosted-first. It is not an ERP application: it is the substrate on which any printing shop's workflows, forms, roles, and rules can be assembled by configuration and plug-ins instead of by forking the core. The reference business under `raw/` is one example customer, used as an executable acceptance test, never as the spec. ## Why a framework, not an app Printing shops differ in process, terminology, paperwork, and order of operations. An app that hard-codes one shop's workflow becomes a fork farm the moment a second customer signs up. vibe_erp follows the **Clean Core** philosophy borrowed from SAP S/4HANA: the core stays generic and upgrade-safe, and every customer-specific concept lives in metadata rows or plug-ins. The core never knows what a "plate" or a "press" is — those concepts are introduced by a plug-in. Upgrading the core does not touch the customer's extensions. ## Architecture in one picture ``` ┌──────────────────────────────────────────────────────────────────────┐ │ Customer's network │ │ │ │ Browser (React SPA) ─┐ │ │ AI agent (MCP, v1.1)─┼─► Reverse proxy ──► vibe_erp backend (1 image)│ │ 3rd-party system ─┘ │ │ │ │ │ │ Inside the image (one Spring Boot process): │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ HTTP layer (REST + OpenAPI + MCP) │ │ │ │ ├─────────────────────────────────────┤ │ │ │ │ Public Plug-in API (api.v1.*) │◄──┤ loaded from │ │ │ — the only stable contract │ │ ./plugins/*.jar │ │ ├─────────────────────────────────────┤ │ via PF4J │ │ │ Core PBCs (modular monolith): │ │ │ │ │ identity · catalog · partners · │ │ │ │ │ inventory · warehousing · │ │ │ │ │ orders-sales · orders-purchase · │ │ │ │ │ production · quality · finance │ │ │ │ ├─────────────────────────────────────┤ │ │ │ │ Cross-cutting: │ │ │ │ │ • Flowable (workflows-as-data) │ │ │ │ │ • Metadata store (Doctype-style) │ │ │ │ │ • i18n (ICU MessageFormat) │ │ │ │ │ • Reporting (JasperReports) │ │ │ │ │ • Job scheduler (Quartz) │ │ │ │ │ • Audit, security, events │ │ │ │ └─────────────────────────────────────┘ │ │ │ ▼ │ │ PostgreSQL (mandatory) │ │ File store (local or S3) │ └──────────────────────────────────────────────────────────────────────┘ Optional sidecars for larger deployments (off by default): • Keycloak (OIDC) • Redis (cache + queue) • OpenSearch (search) • SMTP relay ``` The full architecture lives at [`docs/superpowers/specs/2026-04-07-vibe-erp-architecture-design.md`](docs/superpowers/specs/2026-04-07-vibe-erp-architecture-design.md). ## Stack - Kotlin on the JVM, Spring Boot, single fat-JAR / single Docker image - PostgreSQL (the only mandatory external dependency) - Embedded Flowable (BPMN 2.0) for workflows-as-data - PF4J + Spring Boot child contexts for plug-in classloader isolation - ICU4J + Spring `MessageSource` for i18n - JasperReports for reporting - React + TypeScript SPA for the web client ## Repository layout ``` vibe-erp/ ├── api/ │ └── api-v1/ ← THE CONTRACT (semver, published to Maven Central) ├── platform/ ← Framework runtime (internal) ├── pbc/ ← Core PBCs (one Gradle subproject each) ├── reference-customer/ │ └── plugin-printing-shop/ ← Reference plug-in, built and CI-tested, not loaded by default ├── web/ ← React + TypeScript SPA ├── docs/ ← Framework documentation └── distribution/ ← Bootable assembly: fat JAR + Docker image ``` ## Building ```bash # Build everything (compiles all JVM modules + the web SPA, runs 356 unit tests) ./gradlew build # Bring up Postgres + the reference plug-in JAR docker compose up -d db ./gradlew :reference-customer:plugin-printing-shop:installToDev # Boot the framework against it ./gradlew :distribution:bootRun ``` The bootstrap admin password is printed to the application logs on first boot. ## Running the end-to-end demo 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. ```bash docker compose up -d db ./gradlew :distribution:bootRun open http://localhost:8080 ``` Then: 1. Log in as `admin` — the password is in the bootRun log, under `vibe_erp bootstrap admin created`. 2. The dashboard shows every PBC populated with seeded rows. Click through **Items**, **Partners**, **Locations**, **Stock Balances** — each page is live against Postgres. 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`. 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. 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. 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. 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. ## Status **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. | | | |---|---| | JVM modules | 24 Kotlin subprojects + `:web` | | Unit tests | 356, all green | | Real PBCs | 10 of 10 | | Cross-cutting services live | 12 | | Plug-ins serving HTTP | 1 (reference printing-shop — 8 endpoints, own DB schema, metadata, i18n, TaskHandlers, JobHandler, BPMN, reports, file storage) | | Web SPA | Served by Spring Boot at `/` — login, dashboard, 14 pages, live ship/receive/confirm verbs, shop-floor dashboard | | Production-ready | **No** — OIDC, MCP server, JSON Schema form renderer, GL-level finance, and richer per-PBC verbs are still pending | 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). ## Documentation - [Documentation index](docs/index.md) - [Architecture overview](docs/architecture/overview.md) - [Plug-in API overview](docs/plugin-api/overview.md) - [Plug-in author getting started](docs/plugin-author/getting-started.md) - [Workflow authoring guide](docs/workflow-authoring/guide.md) - [Form authoring guide](docs/form-authoring/guide.md) - [i18n guide](docs/i18n/guide.md) - [Customer onboarding guide](docs/customer-onboarding/guide.md) ## License Apache License 2.0. See [`LICENSE`](LICENSE).