Skip to content

feat(admin): Settings + Diagnostics field-rename to admin-ui shape#18

Merged
jlc488 merged 1 commit into
mainfrom
feat/diagnostics-settings-rename
May 27, 2026
Merged

feat(admin): Settings + Diagnostics field-rename to admin-ui shape#18
jlc488 merged 1 commit into
mainfrom
feat/diagnostics-settings-rename

Conversation

@jlc488

@jlc488 jlc488 commented May 27, 2026

Copy link
Copy Markdown
Contributor

Last PR in the admin-ui ↔ backend contract-gap series (after #14 menus, #15 audit-logs, #16 policies, #17 tenants). Both endpoints reshaped — no schema or service changes, just JSON-key renames + a richer menu-visibility response.

Summary

GET /admin/api/v1/settings

Rewritten to the admin UI's AdminSettings shape:

{
  "jwt":     { "issuer": "...", "ttlSeconds": 28800, "secretMasked": "***" },
  "tenant":  { "resolver": "FIXED" },
  "identity":{ "lockoutThreshold": 5, "lockoutDurationSeconds": 900 },
  "audit":   { "enabled": true, "asyncQueueCapacity": 1024 },
  "menu":    { "cacheTtlSeconds": 300 },
  "raw":     { "devslab.kit.foo.bar": "value", "...": "..." }
}
  • Durations are exposed as integer seconds (parsed from ISO-8601 via Duration.parse). Defaults applied on missing/malformed values.
  • JWT secret rendered as "***" under secretMasked — never the raw value.
  • raw dumps every devslab.* key the Environment can enumerate (sorted for stable diffs in the UI). Keys containing secret / password / token are masked.
  • Still implemented against Environment (not DevslabKitProperties) so this module avoids depending on devslab-kit-autoconfigure — keeps the dep graph acyclic.

POST /admin/api/v1/diagnostics/permission-check

  • Response: allowedhasPermission, userPermissionCodesmatchedVia.
  • matchedVia surfaces the single matched code today; the "which role / which group granted it" breakdown is queued as a follow-up once the access SPI exposes that detail.

GET /admin/api/v1/diagnostics/menu-visibility

  • Response is now a { "items": [...] } wrapper instead of the raw MenuTree (which would have serialised as { "roots": [...] }).
  • Each node carries a visible flag (true if the user has the required permission, or the node has no permission gate) instead of pre-pruning hidden nodes. The admin UI uses the flag to render greyed-out items for parent / sibling context.
  • New records: MenuVisibilityResponse, MenuVisibilityItem.

Test plan

  • ./gradlew build green (55 tasks, all tests pass — no schema migration in this PR, no service touched)
  • Manual: hit /admin/api/v1/settings and confirm every devslab.* property appears under raw with identity.jwt.secret masked; exercise Diagnostics permission-check + menu-visibility with a partially-permitted user

Series wrap

This closes the seven open contract gaps between the admin UI's src/api/*.ts and the backend:

# Gap PR
Menus tree endpoint, get-by-id, icon column, field rename #14
Audit logs paging, filters, outcome/ip/userAgent, field rename #15
Policies PolicyDescriptor list, nested test body, XACML PERMIT #16
Tenants TenantStatus enum, status endpoint, optional mode #17
Settings + Diagnostics field rename + richer menu-visibility this PR

The Users / Roles / Permissions / Groups endpoints already matched their src/api/*.ts wrappers and didn't need any change. Once these five PRs merge alongside the admin-ui stack, the UI should light up end-to-end against a running sample-app.

Honest follow-ups queued (not in this PR)

  • PermissionCheckResponse.matchedVia returning the actual grant path (which role, which group) — needs an access-SPI extension.
  • Promote outcome / ip / userAgent to first-class AuditEvent fields so publishers don't have to use the metadata map (currently the publisher-side workaround documented in feat(audit-logs): paging + filters + outcome/ip/userAgent + field rename #15).
  • Promote reason / matchedRules on Policy.evaluate to a richer PolicyEvaluation decision object (documented in feat(policies): PolicyDescriptor + nested test body + XACML PERMIT #16).
  • asyncQueueCapacity / cacheTtlSeconds properties currently expose defaults only — they're not wired to actual behaviour yet. Wire them up when the audit publisher / menu cache need the knob.

Last PR in the contract-gap series. Closes the two remaining cosmetic
mismatches between the admin UI and the backend — both pure JSON-key
renames, no schema or service changes.

Settings (GET /admin/api/v1/settings)
------------------------------------
Rewritten to the admin UI's AdminSettings shape:

  {
    jwt:     { issuer, ttlSeconds, secretMasked },
    tenant:  { resolver },
    identity:{ lockoutThreshold, lockoutDurationSeconds },
    audit:   { enabled, asyncQueueCapacity },
    menu:    { cacheTtlSeconds },
    raw:     { "devslab.kit.foo.bar": "value", ... }
  }

- Durations exposed as integer seconds (ttlSeconds /
  lockoutDurationSeconds / cacheTtlSeconds) parsed from ISO-8601
  strings via Duration.parse — defaults applied on missing or
  malformed values (28800s JWT TTL, 900s lockout, 300s menu cache).
- JWT secret rendered as "***" under secretMasked, never the raw
  value.
- `raw` dumps every devslab.* key the Environment can enumerate
  (sorted for stable diffs) with secrets / passwords / tokens
  masked.
- Still reads via org.springframework.core.env.Environment so this
  module avoids depending on devslab-kit-autoconfigure (no
  circular dep).

Diagnostics — permission-check
------------------------------
- Response field rename: `allowed` -> `hasPermission`,
  `userPermissionCodes` -> `matchedVia`.
- matchedVia surfaces the single matched code today; the
  "which role / which group granted it" breakdown is queued as a
  follow-up once the access SPI exposes that detail.

Diagnostics — menu-visibility
-----------------------------
- Response is now a `{items: [...]}` wrapper instead of a raw
  MenuTree (which would have serialized as `{roots: [...]}`).
- Each node carries a `visible` flag (true if the user has the
  required permission or the node has none) instead of pre-pruning
  hidden nodes. The admin UI uses the flag to render greyed-out
  items for parent / sibling context.
- New records: MenuVisibilityResponse, MenuVisibilityItem.
@jlc488
jlc488 merged commit fc15f72 into main May 27, 2026
1 check passed
@jlc488
jlc488 deleted the feat/diagnostics-settings-rename branch May 30, 2026 06:37
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.

1 participant