Skip to content

Add ConfigSpec, PreferenceSpec, and RoleSpec typed classes#538

Merged
lbwexler merged 6 commits intodevelopfrom
ensure-required-spec-classes
Apr 27, 2026
Merged

Add ConfigSpec, PreferenceSpec, and RoleSpec typed classes#538
lbwexler merged 6 commits intodevelopfrom
ensure-required-spec-classes

Conversation

@amcclain
Copy link
Copy Markdown
Member

@amcclain amcclain commented Apr 8, 2026

Summary

  • Add ConfigSpec, PreferenceSpec, and RoleSpec typed classes with @MapConstructor for use with ensureRequiredConfigsCreated(), ensureRequiredPrefsCreated(), and ensureRequiredRolesCreated(), replacing untyped Map arguments with classes that provide IDE autocomplete and compile-time validation.
  • Previous Map-based signatures remain as deprecated overloads targeted for removal in v40.
  • Fix the legacy note/notes field name mismatch in the preference API — PreferenceSpec uses the correct notes (plural) matching the Preference domain. The deprecated overload maps singular note for backward compat.
  • Add v40 removal target to the previously un-targeted @Access annotation deprecation.
  • Convert all internal hoist-core callers (BootStrap, DefaultMonitorDefinitionService, DefaultRoleService) to use the new spec classes.

Companion Toolbox PR: xh/toolbox#838

Test plan

  • Build hoist-core: ./gradlew assemble
  • Run Toolbox without adopting spec classes — confirm configs/prefs seed with deprecation warning
  • Run Toolbox with companion PR — confirm configs/prefs seed without warning
  • Verify Admin Console config, preference, and role editors still load and function correctly

🤖 Generated with Claude Opus 4.6

Replace untyped Map arguments in ensureRequiredConfigsCreated(), ensureRequiredPrefsCreated(), and ensureRequiredRolesCreated() with typed spec classes that provide IDE autocomplete and compile-time validation. Previous Map-based signatures remain as deprecated overloads targeted for removal in v40.

Also fixes the legacy note/notes field name mismatch in the preference API — PreferenceSpec uses the correct `notes` (plural) matching the Preference domain, with the deprecated overload mapping singular `note` for backward compat.

Adds v40 removal target to the previously un-targeted @access deprecation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@amcclain
Copy link
Copy Markdown
Member Author

amcclain commented Apr 8, 2026

Hi @lbwexler - "real" Anselm here - had Claude do this after remembering we made that nice change for bootstrapping status monitors, wanted to get the same benefits and bwds-compat in place for more common configs and prefs.

Opened as draft as I have not yet reviewed the code myself - I did look over the plan carefully and adjust it, and this seems likely to land in a clean state. I will post any updates when I have a chance to look over it myself, or if you are motivated to do so at any point...

@amcclain
Copy link
Copy Markdown
Member Author

FYI — once this lands, the Bootstrap Required Resources section of docs/coding-conventions.md should be updated to use the new ConfigSpec / PreferenceSpec / RoleSpec classes. The current section shows the deprecated Map-based literal syntax in its ensureRequired*Created examples.

Reconciles the typed-config expansion shipped on develop (#545) with the new ConfigSpec/PreferenceSpec/RoleSpec API on this branch.

Adds `typedClass` field to `ConfigSpec` so the typed-config registration shipped on develop can flow through the new typed API. `ConfigService.ensureRequiredConfigsCreated(List<ConfigSpec>)` now performs the typed-class registration + drift-check that develop added to the Map overload, keeping a single registration path for both the new and deprecated signatures. The deprecated `Map<String, Map>` overload continues to forward through `ConfigSpec` and inherits the typed-class wiring for free.

BootStrap was reconciled to keep develop's tracing-aware init structure (`configService.initialize`, `traceService.startServerLoadSpan`, hoistInit span) while expressing every config + pref entry through the new typed `ConfigSpec`/`PreferenceSpec` literals — including the `typedClass:` references for all 12 newly typed framework configs and the `xhTraceConfig` shape change from develop (drop `alwaysSampleErrors`, add `jdbcTracingEnabled`).

Moves the ConfigSpec/PreferenceSpec/RoleSpec changelog entry from the now-released v38 section to the v39.0-SNAPSHOT section, and notes `ConfigSpec.typedClass` as the supported entry point. Updates docs/configuration.md typed-config example to use `new ConfigSpec(...)` rather than the deprecated Map literal.

🤖 Generated with Claude Opus 4.7 (1M context)
…Class doc

Bumps the removal target on the deprecated `ensureRequiredConfigsCreated(Map)` and `ensureRequiredPrefsCreated(Map)` overloads from v40 to v42, giving downstream apps more runway. Also condenses the `ConfigSpec.typedClass` Groovydoc to a one-line pointer to docs/configuration.md rather than restating the full feature description.

🤖 Generated with Claude Opus 4.7 (1M context)
Comment thread grails-app/services/io/xh/hoist/config/ConfigService.groovy
@lbwexler lbwexler marked this pull request as ready for review April 27, 2026 23:23
@lbwexler lbwexler merged commit 10b1f11 into develop Apr 27, 2026
7 checks passed
@lbwexler lbwexler deleted the ensure-required-spec-classes branch April 27, 2026 23:26
lbwexler added a commit to xh/toolbox that referenced this pull request Apr 27, 2026
## Summary

- Convert `ensureRequiredConfigsCreated()` and
`ensureRequiredPrefsCreated()` calls in BootStrap from untyped Map
literals to typed `ConfigSpec` and `PreferenceSpec` classes introduced
in hoist-core.
- Adopt corrected `notes` (plural) field name on `PreferenceSpec`,
fixing the legacy `note` mismatch.

Companion hoist-core PR: xh/hoist-core#538

## Test plan
- [ ] Run Toolbox with companion hoist-core branch — confirm
configs/prefs seed without deprecation warnings
- [ ] Verify Admin Console config and preference editors still load and
function correctly

🤖 Generated with Claude Opus 4.6

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: lbwexler <lbwexler@xh.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants