fix(custom-fields): reject over-long STRING values and reload help after publication #61

Merged
james.maes merged 1 commits from fix/custom-field-length-and-help-20261106 into develop 2026-11-06 15:32:04 +00:00
Owner

What Forge observed

GG Forge runs Collaboration from source 8f348daf and has been carrying two local patches:

  1. A bounded STRING custom field (maxLength set on the definition) accepted writes longer than its maximum. QQQ's default ValueTooLongBehavior is PASS_THROUGH, and CustomFieldsProvider set maxLength without a behavior, so the over-long value went through unchecked.
  2. Help content stored in helpContent for a section created by publishing a custom-field definition (for example table:document;section:customFields) did not appear until restart: the runtime metadata overlay created the section after startup help loading had already run.

The fix

  • CustomFieldsProvider.field: a STRING field with a maxLength carries ValueTooLongBehavior.ERROR, so the write is rejected with a field error and the stored value is preserved.
  • FeatureSettingsCustomizer.refresh: after RuntimeMetaDataOverlay.refresh (immediately, or inside the after-commit callback of the originating transaction) call QInstanceHelpContentManager.reloadHelpContent(instance) so persisted help binds to the newly created sections and fields.
  • CHANGELOG entries under Unreleased / Fixed.

Both APIs exist in the pinned qqq-bom-pom 4.1.0-RC.15. Adaptation from the carried patch: inline fully-qualified names were replaced with imports; no logic changes.

Test evidence

Two regressions in CustomFieldsTest:

  • publishedStringRejectsValuesBeyondItsMaximumLength: a 5-character bound accepts valid, rejects too long with errors, and the persisted value is still valid.
  • publishedSectionReceivesStoredHelp: a helpContent row keyed to table:document;section:customFields is present on the section after publishing a definition.

./mvnw verify on this branch (Windows, JDK 21, no Docker needed by any suite): Checkstyle clean, Tests run: 164, Failures: 0, Errors: 0, Skipped: 0, JaCoCo All coverage checks have been met, BUILD SUCCESS. CustomFieldsTest ran 10 tests including both new ones.

Carried locally by GG Forge as collaboration-custom-fields.patch (supersedes collaboration-field-length.patch). Once released, Forge can drop the 0.1.0-forge.8f348daf324d-* development builds for this fix.

🤖 Generated with Claude Code

## What Forge observed GG Forge runs Collaboration from source `8f348daf` and has been carrying two local patches: 1. A bounded STRING custom field (`maxLength` set on the definition) accepted writes longer than its maximum. QQQ's default `ValueTooLongBehavior` is `PASS_THROUGH`, and `CustomFieldsProvider` set `maxLength` without a behavior, so the over-long value went through unchecked. 2. Help content stored in `helpContent` for a section created by publishing a custom-field definition (for example `table:document;section:customFields`) did not appear until restart: the runtime metadata overlay created the section after startup help loading had already run. ## The fix - `CustomFieldsProvider.field`: a STRING field with a `maxLength` carries `ValueTooLongBehavior.ERROR`, so the write is rejected with a field error and the stored value is preserved. - `FeatureSettingsCustomizer.refresh`: after `RuntimeMetaDataOverlay.refresh` (immediately, or inside the after-commit callback of the originating transaction) call `QInstanceHelpContentManager.reloadHelpContent(instance)` so persisted help binds to the newly created sections and fields. - CHANGELOG entries under Unreleased / Fixed. Both APIs exist in the pinned `qqq-bom-pom 4.1.0-RC.15`. Adaptation from the carried patch: inline fully-qualified names were replaced with imports; no logic changes. ## Test evidence Two regressions in `CustomFieldsTest`: - `publishedStringRejectsValuesBeyondItsMaximumLength`: a 5-character bound accepts `valid`, rejects `too long` with errors, and the persisted value is still `valid`. - `publishedSectionReceivesStoredHelp`: a `helpContent` row keyed to `table:document;section:customFields` is present on the section after publishing a definition. `./mvnw verify` on this branch (Windows, JDK 21, no Docker needed by any suite): Checkstyle clean, `Tests run: 164, Failures: 0, Errors: 0, Skipped: 0`, JaCoCo `All coverage checks have been met`, BUILD SUCCESS. `CustomFieldsTest` ran 10 tests including both new ones. Carried locally by GG Forge as `collaboration-custom-fields.patch` (supersedes `collaboration-field-length.patch`). Once released, Forge can drop the `0.1.0-forge.8f348daf324d-*` development builds for this fix. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
james.maes added 1 commit 2026-11-06 14:40:18 +00:00
fix(custom-fields): reject over-long STRING values and reload help after publication
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (pull_request) Successful in 7s
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 6s
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 6s
maven / build (push) Successful in 5m44s
build / maven (push) Successful in 5m44s
ef625ca300
Bounded STRING custom fields now carry QQQ's native ValueTooLongBehavior.ERROR,
so a write longer than maxLength is rejected with a field error and the stored
value is preserved. The QQQ default is PASS_THROUGH, which let over-long values
through unchecked.

After the runtime metadata overlay refreshes (immediately, or in the after-commit
callback of the originating transaction), persisted help content is reloaded so
sections and fields created by publishing a definition receive their stored
helpContent rows without a restart.

Two CustomFieldsTest regressions cover invalid-write preservation and stored
help on a newly published section. Carried locally by GG Forge as
collaboration-custom-fields.patch (supersedes collaboration-field-length.patch).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
james.maes merged commit 483dc271fe into develop 2026-11-06 15:32:03 +00:00
Sign in to join this conversation.