Skip to content

Contributing

openwcs-docs-agent edited this page Jun 12, 2026 · 8 revisions

Contributing

Workflow

  • main is protected (the guardMain ruleset blocks direct pushes). Land every change via a feature branch + pull request; squash-merge when CI is green.
  • CI is the gate (GitHub Actions): Java ./gradlew build (Testcontainers tests on Docker), Go adapter build/vet/test, UI build, and OpenAPI validation. The code is authored without a local JVM in some environments, so a green CI run is the source of truth.
  • Contract-first: define/extend the OpenAPI spec (contracts/openapi/) or event schema before implementing.
  • Documentation is automated: the docs agent (.github/workflows/docs-agent.yml) runs once a day (23:00 UTC), reviews the last 24 hours of commits on main, and commits any needed updates to README.md, docs/, and public/ directly to main. Review and adjust the agent's edits if a product capability changed, but you rarely need to write docs from scratch. The GitHub wiki is synced separately after each merge. See docs/DOCS-AGENT.md.

Conventions

  • Java: Java 21 + Spring Boot 3, package org.openwcs.<service>, actuator health probes, the port from Services. PostgreSQL 16 via Flyway (schema-per-service) + JPA/Hibernate 6 with ddl-auto: validate (migrations own the schema), UUID keys, JSONB via @JdbcTypeCode.
  • Persistence: a service writes only its own schema; reference other services' data by UUID (no cross-schema FKs). Publish events via the transactional outbox; consume idempotently.
  • Go adapters: stdlib-first, implement the uniform device contract, expose /healthz + /readyz. Independent Go modules (not part of the Gradle build).
  • UI: React + TypeScript; theme from styling.md tokens.
  • Logging: the audience is an engineer chasing a fault in the per-service daily logs, so each line must make sense in isolation. Decisions and state changes at INFO: what changed, for which business object, and why (the trigger), pairing ids with human-readable codes (SKU code, HU code, location code, order ref) whenever the row at hand carries one. WARN for skipped/degraded/best-effort-failed paths with reason and consequence; DEBUG for per-item detail inside loops; ERROR only where a human must act. SLF4J parameterized messages ({}), no secrets. Applied across all services (inventory, master-data, txlog, slotting, gtp, counting, order-management, allocation, flow-orchestrator, process-engine, integration-host, integration-sap, integration-manhattan, iam, and gateway).

Adding a service

  1. include 'services:<name>' in settings.gradle; add build.gradle, Dockerfile, application.yml (unique port).
  2. Add a gateway route /api/<name>/** and a compose service.
  3. Add the OpenAPI spec under contracts/openapi/.
  4. Update Services, AS-BUILT, and DEVELOPMENT-STATUS.

Tests

Testcontainers (PostgreSQL 16) + JUnit 5 + Mockito + MockMvc. Run ./gradlew build or ./gradlew :services:<name>:test (Docker required).

Screenshot gallery

CI automatically captures one screenshot per UI route into screenshots/ on every merge to main and commits the result back to the repository. The gallery is generated by ui/scripts/screenshots.ts using Playwright + Chromium: it serves the built SPA with vite preview, injects a fake ADMIN session into sessionStorage (the UI only reads JWT claims, so no real Keycloak is needed), and captures each route at 1440×900. There is no backend in CI, so /api/* calls fail gracefully — screens show their empty/loading state, illustrating chrome and layout rather than live data.

The route list is imported from the canonical SCREENS catalog, so the gallery can never drift from the actual routes.

To regenerate locally (from the ui/ directory):

npm run build      # produces ui/dist — required first
npm run screenshots

PNGs land in screenshots/ at the repo root. A README.md gallery index is also written there.

On every UI build, CI uploads the gallery as the ui-screenshots artifact regardless of whether it changed. Only pushes to main commit the regenerated files back to the repo (fork PRs can't push, and per-PR commits would be noise).

Supporting the project

Code contributions are always welcome. If you'd like to support openWCS financially, you can sponsor on Patreon. Tiers run from Backer (individuals and developers) through Sponsor and Business Sponsor to Partner (advisory and roadmap influence for integrators and enterprises). Sponsors at the Sponsor tier and above are credited in SPONSORS.md in the main repository.

Clone this wiki locally