directlx-claude-config/plans/vast-beaming-goblet.md

5.4 KiB

HiveOps Portal UI Implementation Plan

Overview

Add a Thymeleaf portal UI accessible at mgmt.directlx.dev/portal for managing:

  • Customers (separate from Users/admins)
  • Product Key Licenses linked to customers
  • API Keys for hiveops-agent (with configurable scopes)
  • Global Configuration

Design Decisions

  • Auth: Session-based for portal (separate from JWT API)
  • UI: Bootstrap 5 (via CDN)
  • Customer Model: Separate entity (Users are admins, Customers get licenses)
  • API Key Scope: Full agent operations with configurable permissions

Implementation Phases

Phase 1: Dependencies & Database

1.1 Update pom.xml - Add dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>

1.2 Create migration V3__add_customer_and_apikey_tables.sql:

  • customers table (name, email, company, phone, status, metadata)
  • api_keys table (name, key_prefix, key_hash, scopes, customer_id, status, expires_at)
  • Add customer_id FK to licenses table

Phase 2: Entities & Repositories

2.1 Create entities:

  • Customer.java - name, email, company, phone, address, notes, status (ACTIVE/SUSPENDED/ARCHIVED)
  • ApiKey.java - name, keyPrefix, keyHash, scopes (JSON), status, expiresAt, lastUsedAt

2.2 Update License.java - Add @ManyToOne Customer customer

2.3 Create repositories:

  • CustomerRepository.java - findByUuid, findByEmail, search()
  • ApiKeyRepository.java - findByKeyPrefix, findActiveByKeyPrefix

Phase 3: Services

3.1 Create services:

  • CustomerService.java - CRUD, search, suspend/activate
  • ApiKeyService.java - generate (returns raw key once), validate, revoke
  • PortalLicenseService.java - create license for customer, generate key
  • DashboardService.java - statistics aggregation

API Key format: hiveops_{8-char-prefix}_{32-char-random}

  • Only SHA-256 hash stored; raw key shown once at creation

Phase 4: Security Configuration

4.1 Create ApiKeyAuthenticationFilter.java

  • Process X-API-Key header for agent requests
  • Validate against hashed keys in DB

4.2 Update SecurityConfig.java - Dual filter chains:

// Order 1: API chain (JWT, stateless)
@Bean @Order(1)
SecurityFilterChain apiFilterChain() { ... }

// Order 2: Portal chain (session-based)
@Bean @Order(2)
SecurityFilterChain portalFilterChain() {
    // Form login at /portal/login
    // Session management
    // CSRF enabled
}

Phase 5: Portal Controllers

Create in com.hiveops.mgmt.controller.portal:

Controller Routes Function
PortalDashboardController /portal/, /portal/dashboard, /portal/login Dashboard, login
PortalCustomerController /portal/customers/** Customer CRUD
PortalLicenseController /portal/licenses/** License management
PortalApiKeyController /portal/api-keys/** API key management
PortalSettingsController /portal/settings/** Global settings (admin only)

Phase 6: Templates & Static Resources

Directory structure:

src/main/resources/
├── templates/portal/
│   ├── layout/base.html
│   ├── fragments/ (header, sidebar, footer, alerts, pagination)
│   ├── login.html
│   ├── dashboard.html
│   ├── customers/ (list, form, view)
│   ├── licenses/ (list, form, view)
│   ├── api-keys/ (list, form, created)
│   ├── settings/list.html
│   └── error/ (403, 404, 500)
└── static/portal/
    ├── css/styles.css
    ├── js/portal.js
    └── images/logo.svg

Phase 7: Configuration Updates

Update application.yml:

server:
  servlet:
    context-path: /  # Changed from /api
    session:
      timeout: 30m

spring:
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
    cache: false

Key Files to Modify

File Changes
pom.xml Add Thymeleaf dependencies
application.yml Add Thymeleaf config, change context-path
SecurityConfig.java Dual filter chains for API + Portal
License.java Add customer relationship

New Files to Create

Category Count Files
Migration 1 V3__add_customer_and_apikey_tables.sql
Entities 2 Customer.java, ApiKey.java
Repositories 2 CustomerRepository.java, ApiKeyRepository.java
Services 4 CustomerService, ApiKeyService, PortalLicenseService, DashboardService
Security 2 ApiKeyAuthenticationFilter, ApiKeyAuthentication
Controllers 5 Portal controllers
DTOs 8 Request/Response DTOs
Templates ~20 Thymeleaf HTML templates
Static 3 CSS, JS, images

Verification

  1. Build: ./mvnw clean compile - verify no compilation errors
  2. Database: Run migrations, verify tables created
  3. Login: Access /portal/login, authenticate as admin@hiveops.com
  4. Customer CRUD: Create, view, edit, suspend customers
  5. License Generation: Create license linked to customer, verify key format
  6. API Key Generation: Create API key, verify raw key shown once, test validation
  7. Settings: Edit global settings (admin only)
  8. Existing API: Verify /api/v1/auth/login still works with JWT