directlx-claude-config/plans/squishy-sauteeing-donut.md

3.2 KiB

Plan: Thymeleaf UI for Dynamic API Server

Context

The app is currently REST-only. The user wants a browser-accessible UI covering:

  • Generate API key
  • List/view all keys
  • Revoke a key
  • Test dynamic endpoints

Since the app is stateless (no sessions), the UI controller will call the service layer directly (bypassing REST auth), with UI paths made public in SecurityConfiguration.


Files to Create/Modify

1. pom.xml — Add dependencies

  • spring-boot-starter-thymeleaf
  • bootstrap (WebJar, 5.3.x)
  • webjars-locator-lite (auto-resolves WebJar versions in templates)

2. SecurityConfiguration.java — Add public UI paths

Add /ui/** to the permit-all list so browser requests don't need an X-API-Key header.

3. ApiKeyService.java — Add listAllKeys() method

Returns List<ApiKey> via apiKeyRepository.findAll() (already available from JpaRepository).

4. UiController.java (new) — com/dynamicapi/controller/UiController.java

Mapped to /ui/**. Injects ApiKeyService and DynamicApiConfigLoader directly.

Endpoints:

  • GET /ui/index.html (generate key form)
  • POST /ui/generate → calls apiKeyService.generateApiKey(), redirects to index with result
  • GET /ui/keyskeys.html (list all keys)
  • POST /ui/revoke/{key} → calls apiKeyService.revokeApiKey(), redirects to keys page
  • GET /ui/testtest.html (test endpoint form, loads endpoint list)
  • POST /ui/test → makes RestTemplate call to selected endpoint, returns result to test.html

5. Templates (new) — src/main/resources/templates/

fragments/layout.html — Bootstrap 5 base layout with navbar (links: Home, API Keys, Test Endpoints)

index.html — API Key generation

  • Form: clientName (required), description (optional) → POST /ui/generate
  • On success: shows generated key in a highlighted alert box with copy button (JS)
  • On error: shows validation/duplicate error message

keys.html — Key management table

  • Table columns: Client Name, Key (masked, last 8 chars shown), Created At, Last Used, Status (Active/Revoked), Actions
  • Revoke button → POST /ui/revoke/{key} (only shown for active keys)
  • Flash message on successful revoke

test.html — Endpoint tester

  • Dropdown: select from registered dynamic endpoints (path + method)
  • Input: API Key (required to call protected endpoints)
  • Submit → POST /ui/test → displays JSON response in <pre> block

Implementation Notes

  • Use Bootstrap 5 via WebJar (no CDN required)
  • Thymeleaf fragment includes for navbar (th:replace)
  • Flash attributes (RedirectAttributes) for post-redirect-get pattern on generate/revoke
  • RestTemplate in UiController for the endpoint tester (reuse existing pattern from DynamicApiController)
  • The endpoint tester calls http://localhost:8080/api/dynamic/{path} with the user-supplied API key

Verification

  1. mvn spring-boot:run compiles and starts cleanly
  2. GET http://localhost:8080/api/ui/ — renders generate key form
  3. Submit form → key displayed on page
  4. GET http://localhost:8080/api/ui/keys — lists all keys
  5. Revoke a key → table reflects revoked status
  6. GET http://localhost:8080/api/ui/test — dropdown shows all dynamic endpoints, submit returns JSON response