# 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: ```xml org.springframework.boot spring-boot-starter-thymeleaf org.thymeleaf.extras thymeleaf-extras-springsecurity6 ``` **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: ```java // 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`:** ```yaml 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