Files
qbit-scripting/middleware
james.maesandClaude Sonnet 5.5 034d77b5ac build: make the reactor root the single version source of every module
The release pipeline rewrites <revision> only in the ROOT pom.xml (the pinned legacy calculate_version.sh) and nothing passes -Drevision
(java-verify runs plain `mvn verify` with MAVEN_ARGS only from caller inputs), but every module declared its own <revision>0.1.0-SNAPSHOT</revision>
and did not inherit the root. After an RC rewrite the root would say the RC while the modules still built as the SNAPSHOT, so capture
(target/<artifact>-<root version>.jar) would find no JAR and the publisher (one version per reactor) would reject the reactor.

Standard Maven CI-friendly inheritance: the root takes the modules' own former parent (qbit-build-parent 2.0.0, identical for all four
modules), every module's parent becomes the root (version ${revision}, relativePath ../pom.xml) and the per-module <revision> properties are
removed. Each module's inherited build configuration is unchanged (child -> root -> the same qbit-build-parent); modules still build on their
own through the relative parent. Metadata audit: the root declares Apache-2.0 and base declares it too (unchanged); rdbms, middleware and
github declared no license and inherited qbit-build-parent's AGPL-3.0, so they now state that same license explicitly to keep their published
metadata exactly as before (the repository LICENSE is Apache: whether those three should be Apache is an owner decision, not changed here).
All GAVs, module boundaries, flatten plugin, dependencies, tests and sources are unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 17:23:52 -06:00
..

Scripting middleware

Optional native QQQ UI API extension. The base QBit depends only on core; this artifact supplies authenticated transport and generated OpenAPI, without another source registry or runtime.

GAV: com.kingsrook.qbits:qbit-scripting-middleware:0.1.0-SNAPSHOT. After producing the base QBit, the host calls ScriptingApi.register(qInstance) before middleware startup. The native /version discovery response advertises extension scripting version 1.0.0.

All routes are relative to the host's standard UI API prefix:

Method Path Purpose
POST /qbit/scripting/projects Create a server-marked isolated project; body contains name only
GET /qbit/scripting/projects/{scriptId} Authorized project, recent revisions/builds/publications, available actions
GET /qbit/scripting/projects/{scriptId}/revisions/{revisionId} Immutable source files
POST /qbit/scripting/projects/{scriptId}/drafts Append draft using expected baseRevisionId
POST /qbit/scripting/projects/{scriptId}/imports Explicit exact-commit import through the configured host provider
POST /qbit/scripting/projects/{scriptId}/builds Compile saved revision and declared capabilities
GET /qbit/scripting/projects/{scriptId}/builds/{buildId} Bounded compiler diagnostics
POST /qbit/scripting/projects/{scriptId}/builds/{buildId}/test-context Test compiled artifact with bounded JSON context
POST /qbit/scripting/projects/{scriptId}/builds/{buildId}/publications Publish tested immutable artifact
POST /qbit/scripting/projects/{scriptId}/typings Permission-filtered editor declarations
GET /qbit/scripting/projects/{scriptId}/hooks Authorized host phases and project binding page; optional beforeBindingId cursor
POST /qbit/scripting/projects/{scriptId}/bindings Create an enabled binding pinned to a publication
POST /qbit/scripting/projects/{scriptId}/bindings/{bindingId}/state Explicit boolean enable/disable
POST /qbit/scripting/projects/{scriptId}/builds/{buildId}/test-hook Read-only selected-record event simulation

Current authenticated QQQ session supplies identity; clients cannot supply actors, providers, commands or runtime configuration. Every action rechecks project association and its service permission. Source intake rejects legacy projects and requires the coordinated core isolation guard. This artifact selectively pins reviewed core/RDBMS 4.1.0-isolated-record-files-SNAPSHOT while other QQQ modules remain RC20. Creation and publication use typed core authority; no reflective class-presence gate remains. This local artifact is not a remote release.

Request limit is 3 MiB before JSON decoding, in addition to source, capability, context and worker bounds enforced by the service. Host ingress/Javalin limits should be configured consistently and remain bounded. Source/build/publication histories expose the latest 100 entries each; hook bindings use bounded keyset pages across all project publications, without bundles, signing keys, signatures or provider settings. Responses use the normal QQQ error envelope; unexpected exceptions return generic text. A timeout does not cancel or undo committed work. Refresh history before deciding whether to retry.

The generated fragment is src/main/resources/openapi/qqq-v1/scripting.yaml. From the base QBit directory:

.\mvnw.cmd -B -ntp install
.\mvnw.cmd -B -ntp -f middleware/pom.xml verify
# Intentional schema changes only:
.\mvnw.cmd -B -ntp -f middleware/pom.xml '-Dscripting.openapi.update=true' test

Verification: seven tests, including six actual Javalin HTTP tests for create/save/build/test/publish, hook binding controls, current session/association/legacy denials, injected context rejection, generic source-count refusal, worker failure-detail suppression and committed schema comparison for fourteen routes; full wrapper install passes. No sandbox, production database, deployment or full language-service IDE qualification is implied. The optional GitHub adapter is independently tested with trusted response fixtures.

Hook test bodies contain tableName, event, string recordId and scalar changes only. The server loads prior/current values, validates current permissions and never performs record writes. Binding mutation receipts share the mutation transaction. Worker execution audit commits independently and does not prove business-record commit. Failure responses expose host-owned outcome text, never untrusted worker error details.