kumwe/app

Kumwe App 2.0

Maintainers

Package info

github.com/kumwe/app

Documentation

Type:project

pkg:composer/kumwe/app

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 3

Open Issues: 1

dev-master 2026-08-19 19:15 UTC

README

Kumwe is a modern CMS, built with disciplined engineering and AI acceleration. It is two platforms behind one set of rules: a content-management system — managed pages, media, nested menus, and governed publishing workflows in a graphical administrator — and a business application platform — a typed business definition and record runtime with policies, approvals, reports, and an isolated client portal. Both halves run through the same application services, so what the browser allows, the REST API, CLI, MCP tools, workers, and scheduler allow, and what one refuses, the others refuse too.

  • Content, media, and navigation are managed records with revisions, workflow states, and audit trails.
  • Business definitions declare typed entities, relationships, views, actions, and safe formulas; the runtime generates the administrator and portal surfaces, the REST contract, and the CLI/MCP tools.
  • The interface is presented in the language a request resolves to, and an operator changes the wording their people read — relabelling "Client" as "Patient" or "Learner" — from a screen, per message and without a deployment.
  • Extensions install through a signed pipeline into a compiled, verified runtime — plugins, components, templates, languages, and message catalogues, without rebuilding the application image.
  • Automation is durable: database-backed queues, leases, bounded retries, and recurring schedules.

Entry points: AGENTS.md for contributors, the coding standard, demo profiles, workers and scheduler, and the full documentation index.

Quick start: the full demonstration

Docker Engine with Compose v2 is the shortest path. The copied environment selects the documentation site and the Vast Development Method (VDM) business dataset by default, and database:migrate installs both.

git clone https://github.com/kumwe/app.git
cd cms
cp .env.example .env
docker compose run --rm app composer install --no-interaction --prefer-dist
docker compose run --rm app php bin/kumwe database:migrate
docker compose up -d --wait
curl --fail http://localhost:8080/health/ready

The app container runs as user ${KUMWE_UID:-1000}:${KUMWE_GID:-1000} over the mounted checkout. If your host user is not UID 1000, export matching identifiers before the first compose command so the checkout stays writable from inside the container:

export KUMWE_UID="$(id -u)" KUMWE_GID="$(id -g)"

Create the owner account, then complete the demonstration — sign-ins and example extensions — with one command. Passwords never travel as arguments; they arrive in files only you can read. Paths passed to the container must be container-visible, which is why the flags below use the /app prefix (the checkout is mounted there):

install -m 0600 /dev/null .admin-password
# Put a password of at least 12 characters in .admin-password.
docker compose run --rm app php bin/kumwe user:create-admin \
  --email=owner@example.com \
  --name="Site owner" \
  --password-file=/app/.admin-password
docker compose run --rm app php bin/kumwe demo:install \
  --admin-email=owner@example.com \
  --admin-password-file=/app/.admin-password \
  --credentials-file=/app/storage/private/demo-access-credentials.json
rm .admin-password

demo:install provisions the VDM demonstration cast — five staff accounts and six portal client organizations with nine members — and installs the shipped example extensions (announcements, asset-inspection, audit-listener, and the horizon-theme site theme, which installs as selectable and is never activated for you). Each new account receives a generated password written exactly twice: to the command output and to the owner-only credentials file, which lands on the host at storage/private/demo-access-credentials.json.

Re-running the command is safe: existing accounts and installed examples are confirmed, no password is re-issued, and the credentials file is only created on a run that actually generated a new password — otherwise the command reports that existing sign-ins remain valid and touches nothing.

Sign in at http://localhost:8080/administrator with the owner or a staff account, and at http://localhost:8080/portal with a portal member. The site content and business records were already installed by database:migrate; the getting-started guide continues from here.

Without Docker

The same flow runs on host PHP 8.5 with MariaDB (or MySQL/PostgreSQL) and Redis reachable from the process. Point DB_HOST and REDIS_HOST in .env at your services (for example 127.0.0.1), then:

composer install
cp .env.example .env   # edit DB_HOST and REDIS_HOST first
php bin/kumwe database:migrate
sh tools/development-server.sh   # serves http://localhost:8080

Run the same user:create-admin and demo:install commands with host-absolute paths — for example --admin-password-file="$PWD/.admin-password" and --credentials-file="$PWD/storage/private/demo-access-credentials.json". The password and credentials file rules are identical: absolute paths, regular files, no group or other permission bits. Composer-project and release-ZIP installations follow the production install guide instead; bin/kumwe-install walks the same steps interactively.

Starting clean

For an empty installation, choose the blank datasets in .env before the first migration:

KUMWE_SITE_CONTENT_PROFILE=blank
KUMWE_BUSINESS_PROFILE=none

Then run the same database:migrate and create the first administrator with user:create-admin as above. Each dataset's choice is frozen independently when its first reconciliation begins; later migration runs refuse a different value rather than switching profiles, so decide before the first migrate. With none selected, demo:install skips the demonstration cast cleanly and can still install the example extensions if you want them. See demo profiles for the selector contract.

Running it

The development Compose stack runs three services: app (the PHP built-in server behind a dedicated asset router, plus a watcher that keeps the extension runtime verified), database (MariaDB by default; MySQL and PostgreSQL are supported), and redis. docker compose up -d --wait returns only once /health/ready answers. KUMWE_HTTP_PORT in .env moves the published port.

Background work is real infrastructure, not an afterthought. Queued report exports are completed by a worker on the exports queue — without one they stay queued forever:

php bin/kumwe queue:work --queue=default --sleep-ms=1000
php bin/kumwe queue:work --queue=exports --sleep-ms=1000
php bin/kumwe schedule:run --loop

Production Compose runs the web, PHP-FPM, one-shot migrate, database, and Redis services, and starts the same worker and scheduler commands as dedicated services:

docker compose -f compose.production.yaml --profile automation up -d worker scheduler

Workers and scheduler covers queues, schedules, and operating rules; operations covers deployment, backup, and upgrades.

Testing

composer qa

That is the merge gate. Its parts run individually:

composer architecture:policy   # layer and dependency policy
composer cs                    # PSR-12 layout, 120-character lines
composer analyse               # PHPStan at level max
composer docs:api              # documentation-block completeness
composer openapi:check         # the compiled REST contract is current
composer translation:check     # the compiled message catalogues are current
composer translation:strings   # no template carries user-facing text inline
composer assets:direction      # no stylesheet pins a rule to one writing direction
composer test:unit             # unit suite
composer test:integration      # integration suite (needs the database)

The browser suite runs against the started stack:

npm ci
npm run check
npm run build
npm run test:browser

Every supported engine — MariaDB, MySQL 8.4, PostgreSQL 17 — runs the same services and migrations; select one per installation with DB_DRIVER and KUMWE_DATABASE_IMAGE and re-run the same suites. Development and testing documents the local and CI contracts; CONTRIBUTING.md and AGENTS.md describe the workflow.

Contributing and extending

  • Read AGENTS.md first; the coding standard is normative for every contributor, human or automated.
  • Scaffold an extension with php bin/kumwe extension:scaffold and build against extensions and templates; everything installs through the signed pipeline.
  • Demonstration data is packaged as versioned demo profiles. Build a site, then turn it into a shareable, installable profile with php bin/kumwe demo:export-profile — forks ship their own demonstrations by dropping a profile beside the released ones.
  • Report problems and propose changes on GitHub issues and discussions.

Supported runtime

Layer Supported choice
PHP 8.5
Database MariaDB current LTS (default), MySQL 8.4 LTS, PostgreSQL 17
Persistence Doctrine DBAL 4 with one portable schema and repository boundary
Redis Current Redis 8 image line for cache, locks, rate limits, and coordination
Web nginx and PHP-FPM release images

The machine-readable API contract is api/openapi/kumwe-v1.json. Run php bin/kumwe list from an installed release for the CLI command index.

License

Copyright (C) 2022–2026 Vast Development Method.

Kumwe is licensed under the GNU General Public License version 2.0; see LICENSE.