QBit Document Generation

Version 1.0. Published to the KOF22 Gitea Maven registry (com.kingsrook.qbits). Requires QQQ Core 4.1.0-RC.22; the bridges need Record Files 0.1.0-RC.1 and Scripting 1.0.0. See status.

Start with current status and build prerequisites and known issues. These documents supersede older release-readiness statements below.

foundation/ owns metadata, revisions, requests and audit contracts. renderer/ contains rendering and vendored corresponding source. bridges/ contains optional integrations. The root Maven reactor lists all modules.

Java 21 implementation of user-defined document metadata and generation coordination. Built against public QQQ 4.1.0-RC.21. This is a development snapshot, not a qualified production 1.0 renderer.

The QBit owns document types, stock, table bindings, template drafts, immutable published revisions, named asset-version references, batch pins and generation requests. It does not own retained file bytes, a scripting engine, a printer queue, or a generic workflow framework.

Implemented

  • Native, visible document_generation_* tables. Direct writes are denied; validated Java services own changes. Draft HTML/PDF and ZPL fields carry QQQ CODE_EDITOR metadata.
  • User-defined types, table/output bindings and exact physical stock in micrometres, margins and DPI. Source and manifest sizes are bounded.
  • Separate draft saves and publication. Publication requires isolated source validation, plus published-script validation when a context script is configured. Revisions copy stock and pin immutable asset/script identities.
  • Authorized single-record and bounded synchronous batch generation. Batch revision and selection hashes persist across repeated calls, and partial failures remain explicit.
  • Matching durable retained-file receipts and strict audit callbacks before success or printing. Request tables contain receipt/provenance fields, never document bytes or context bodies.
  • Reprint through current retained-version authorization, without rerendering. Queue acceptance is reported as QUEUED, never as physical printing.
  • Stable request keys prevent blind duplicate execution. Incomplete work requires reconciliation; this implementation does not claim exactly-once processing.
  • Native definition/source editing, display-name renames for types, stock and templates, immutable retained previews and optimistic draft/publication forms in a Document Generation workspace. See authoring.
  • Durable generation-owned queue/items, independent strict audit, bounded admission/cursors and conservative recovery. Native source record/batch/status/download/reprint processes call the same services. See queue.
  • Explicit opt-in adapter to existing core Jobs with cooperative checkpoints; no additional scheduler. See Jobs for verification state and host requirements.

Host integration

Install metadata with DocumentGenerationQBitProducer.withQBitConfig(config).produce(instance). Configure a backend through DocumentGenerationQBitConfig.withBackendName(...). Registration never runs DDL automatically. Apply DocumentGenerationSchema.mysqlScript(config) through host migration tooling for native MySQL 8.4. postgresScript(config) generates the same tables for the native QQQ PostgreSQL 17 backend (and the file-H2 fixture); the PostgreSQL publication, audit and queue suites pass against postgres:17 with QQQ 4.1.0-RC.21 (see Verification), but, as with MySQL, that does not qualify a production deployment. See MySQL qualification for required current engine/settings, metadata mappings and deployment boundaries.

Use DocumentDefinitionService for types, stock, bindings, assets, drafts and publication. Use DocumentGenerationService.generate, generateBatch and reprint for operational work. Permissions are separate document-generation.view, .configure, .publish, .generate and .print; each generation/print additionally enforces current source-record access.

The host supplies these typed contracts from GenerationPorts:

Port Required behavior
ContextExecution Validate a published immutable build and run it in the shared isolated scripting service; broker QQQ access under the initiating actor.
IsolatedRenderer Authorize assets, validate sources and render in a qualified isolated worker. Enforce time/memory/network/input limits and output/ZPL policies before returning.
RetainedOutputIntake Idempotently retain exact bytes plus source association, return matching hash/length and a committed receipt; reauthorize immutable versions for reprint.
PrintDispatch Reauthorize retained version and destination and submit idempotently to existing printing; return a queue job ID.
Audit Independently commit deduplicated generation/print outcomes before returning; throw on failure. This is not core's best-effort AuditAction.
AssetSelection Search and resolve currently authorized, released immutable image/font versions; obtain hash/media/length from the owner, never from a browser claim.

Every default provider fails closed. No adapter calls the trusted in-process rendering proof. Template source is never evaluated by this QBit's JVM code. Optional bridges/scripting, bridges/renderer and bridges/record-files artifacts implement public integration boundaries without dependency cycles. The renderer bridge has a fail-closed production constructor (runsc, pinned digest) and, for trusted local development only, an explicit cold Java transport (TrustedLocalDockerExchange) and an optional warm single-use pool; both are non-production, never automatic fallbacks, and documented in bridges/renderer. The supported durable storage is native MySQL 8.4, native PostgreSQL 17 and synchronous file H2. The host worker/renderer configuration is operator-owned and unqualified until a deployment supplies matching external evidence. Printing integration and the latest owner download extension are tracked separately. A callback alone does not establish production durability or isolation: its implementation and deployment must meet the contract and pass integration tests.

Context contains bounded immutable JSON-like data, including the authorized selected record. A script may add context objects but cannot replace that reserved original record. Credentials, QQQ sessions, raw host objects and lazy entities are rejected. Source-record permissions are checked before context preparation, before rendering, before intake and before printing. Asset access is rechecked by the isolated renderer adapter, and retained-version access by retained/printing adapters.

Known boundaries before release

Native table/record processes and source-editor forms are implemented through standard QQQ metadata. Results include record navigation and download/preview metadata consumed by generic frontend components. Authenticated delivery requires verified bytes and a completed owner receipt before preview. There is no visual designer. Final integrated browser workflow acceptance, a qualified worker deployment, production storage/restore and printing integration remain release work. Service-only fields cannot be edited through unrestricted generic CRUD. Domain actions use validated services.

The original generateBatch API remains synchronous; GenerationQueue provides separate durable queued selections. Native publication locks and compares the draft fingerprint after isolated validation, then commits the immutable revision and active pointer atomically. Publication rejects ambient and split-backend transactions; memory is a volatile test fixture only. Request states and external side effects do not share one transaction. Generation rejects ambient caller transactions. Known retained versions can be reconciled without rerendering. Unknown intake outcomes and abandoned invocations require owner evidence and a trusted termination provider; they are never automatically recycled into untouched work.

The definition permission model is application-wide: configuration grants cover all definitions. Requests require source access; batches are visible only to their initiating actor. Counts and aggregates on request/batch tables are denied because post-query parent filtering cannot make those totals safe. Private queue context/lease fields cannot be queried, sorted, joined or used as unique keys through enforced native actions. Per-tenant template authoring scopes and efficient SQL-level parent filtering need explicit qualification. Explicit retained-owner authority supports archived exact-version history and operational access; without that port the live-source policy remains. See retained authority.

Production gates still include volume/retained-storage restore; isolated compiler/renderer containment; physical barcode/printer acceptance; user-defined filename/output options; complete host browser workflows; and dependency/license checks. Standalone renderer catalog 9 offers 71 explicit barcode IDs (finite, not universal; see renderer/BARCODES.md). Its trusted warm-engine benchmark is documented in renderer/PERFORMANCE.md and does not establish sandbox/end-to-end capacity. Strict ledger/queue durability accepts synchronous file-H2 and explicitly qualified native MySQL 8.4 and PostgreSQL 17; unsupported backends and metadata/settings drift fail closed.

Modules

Directory Artifact Notes
foundation com.kingsrook.qbits:qbit-document-generation Metadata, services, ports and schema. Depends on QQQ core only (RDBMS optional).
renderer/vendor/openhtml-1.1.105-qqq-p1 com.kingsrook.thirdparty:openhtmltopdf-pdfbox:<family revision> (upstream 1.1.105 + QQQ patch p1) LGPL-2.1-or-later patched OpenHTML (one file differs from upstream 1.1.105), built from the tracked source with its notices; the renderer depends on it.
renderer com.kingsrook.qbits:qbit-document-renderer Standalone isolated renderer CLI/image source; no QQQ dependency.
bridges/renderer qbit-document-generation-renderer IsolatedRenderer port implementation for the renderer.
bridges/remote-renderer remote-renderer-parent -> qqq-remote-renderer-transport, qbit-document-generation-remote-renderer Remote renderer service and adapter.
bridges/record-files, bridges/printing, bridges/scripting qbit-document-generation-record-files, -printing, -scripting Bridges to sibling QBits (Record Files, released Printing 1.0.0, Scripting).

The root pom.xml is an aggregator only and lists every module, so one build produces every GAV. Each module keeps its own dependency boundary. Build a subset with ./mvnw -pl <module> -am install (for example -pl renderer -am builds the patched OpenHTML module first); a module also builds alone with mvn -f <module>/pom.xml install once its dependencies are installed. All modules share one ${revision} (default 0.1.0-SNAPSHOT; releases set -Drevision=<version>), and flatten-maven-plugin publishes self-contained POMs.

Verification

Run ./mvnw verify (.\mvnw.cmd verify on Windows) at the repository root. The foundation's tests include disposable MySQL 8.4 and PostgreSQL suites started with Testcontainers, so Docker access is required. They verify publication concurrency/commit/rollback, physical pooled-connection restoration, mapping/settings drift refusal, bounded lock contention, current-authorized context selection and immutable pins, audit/receipt failures, restart and incomplete results. They do not qualify production storage, hostile workers or physical printer output.

The build enforces Checkstyle plus 85% instruction/90% class coverage in the foundation, and holds the renderer (94% instructions, 91% lines) and its bridge (85% instructions, 82% lines) to their measured baselines; the new packages and classes named in each pom.xml must reach 100% line coverage. Bounded mutation campaigns over the scene parser and the host printer gate run in the test phase; see docs/security/fuzzing.md. The published qbit-build-parent POMs leave ${revision} in their own version, which causes a Maven parent-resolution warning despite a successful build. That upstream publication issue remains open; it is neither suppressed nor patched.

Maven publication

Library POMs are flattened (ossrh mode) so an installed POM carries resolved versions and needs no -Drevision. Dependencies on the sibling QBits are properties (qbit-record-files.version, qbit-scripting.version, qbit-printing.version) so the owners' released versions can be set in one place.

Corresponding source and licenses

renderer/vendor carries the hash-pinned corresponding-source archives next to their patches and build scripts: zint-2.16.0.tar.gz (GPL/BSD/MIT notices in LICENSE.zint, MIT-ZINGL.txt) and openhtml-1.1.105-qqq-p1/openhtmltopdf-pdfbox-1.1.105-qqq-p1-complete-source.zip (LGPL-2.1-or-later). inputs.sha256 files pin them; openhtml-1.1.105-qqq-p1/verify-module-source.sh proves the Maven module's pom.xml and src/ are byte-identical to the archive. Release artifacts and images must ship these notices and sources, not just a URL.

S
Description
No description provided
Readme
8.8 MiB
0 Stars 2 Watchers 0 Forks
Languages
Java 51.1%
Zimpl 48.7%
HTML 0.1%
Dockerfile 0.1%