Skip to content

Comments

feat: admin UI with auth, CRUD operations, and upload#231

Merged
fank merged 24 commits intomainfrom
worktree-admin-ui
Feb 24, 2026
Merged

feat: admin UI with auth, CRUD operations, and upload#231
fank merged 24 commits intomainfrom
worktree-admin-ui

Conversation

@fank
Copy link
Member

@fank fank commented Feb 23, 2026

Summary

  • Add secret-based cookie authentication for admin access (login with server secret, receive session cookie)
  • Add admin CRUD endpoints: edit operation metadata, delete operations with file cleanup, retry failed conversions
  • Add frontend admin UI: login/logout in header, edit modal, delete confirmation, retry button, drag-and-drop upload zone
  • Add cookie-based auth fallback for uploads (admin UI users don't need the secret form field)
  • UI polish: admin action buttons, edit modal, and delete dialog matched to design spec
  • Refactor: extract dialog components into dialogs.tsx with co-located dialogs.module.css
  • Refactor: replace all hardcoded colors in admin styles with CSS variables from variables.css

New API Endpoints

Method Path Auth Purpose
POST /api/v1/auth/login None Login with server secret
GET /api/v1/auth/me None Check auth status
POST /api/v1/auth/logout Cookie Destroy session
PATCH /api/v1/operations/:id Cookie Edit metadata (name, tag, date)
DELETE /api/v1/operations/:id Cookie Delete operation + files
POST /api/v1/operations/:id/retry Cookie Retry failed conversion

Test plan

  • Go tests pass (go test ./internal/server/...)
  • TypeScript compiles (tsc --noEmit)
  • Integration test covers full admin flow (login → edit → delete → logout → 401)
  • Visual comparison of edit modal, delete dialog, and admin action buttons against design artifact
  • All 49 mission-selector tests pass after refactor

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @fank, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the application by introducing a robust administrative interface. It provides secure access to manage operations through a new authentication system and enables critical data management functionalities like editing, deleting, and retrying conversions. The accompanying frontend UI streamlines these administrative tasks, improving overall usability and control over the application's data.

Highlights

  • Admin Authentication: Implemented secret-based cookie authentication for admin access, allowing login with a server secret and receiving a session cookie. This includes new API endpoints for login, checking authentication status, and logout, protected by an requireAdmin Echo middleware.
  • Admin CRUD Operations: Added backend API endpoints and corresponding handlers for administrative tasks: editing operation metadata (name, tag, date), deleting operations with associated file cleanup, and retrying failed conversions. The operation repository was extended with UpdateOperation and Delete methods.
  • Frontend Admin UI: Developed a comprehensive frontend admin user interface using SolidJS, featuring login/logout functionality in the header, modals for editing operation details, confirmation for deleting operations, a retry button for failed conversions, and a drag-and-drop upload zone for new recordings.
  • Cookie-based Upload Fallback: Introduced a cookie-based authentication fallback for uploads, enabling authenticated admin UI users to upload files without needing to provide the server secret explicitly in the form field.
Changelog
  • internal/server/handler.go
    • Added sessions field to the Handler struct to manage user sessions.
    • Initialized SessionStore with Admin.SessionTTL during handler creation.
    • Registered new API routes for authentication (login, me, logout) and admin operations (edit, delete, retry) with requireAdmin middleware.
    • Implemented cookie-based authentication fallback for the StoreOperation handler, allowing uploads with a valid session cookie.
  • internal/server/handler_admin.go
    • Added new file handler_admin.go to encapsulate admin-specific HTTP handlers.
    • Implemented EditOperation handler to update mission name, tag, and date.
    • Implemented RetryConversion handler to reset failed operations to pending status and remove partial output files.
    • Implemented DeleteOperation handler to remove operation records from the database and clean up associated data files.
  • internal/server/handler_admin_test.go
    • Added new file handler_admin_test.go for testing admin handlers.
    • Included unit tests for EditOperation, DeleteOperation, and RetryConversion.
    • Provided an end-to-end integration test (TestAdminFlow_LoginEditDelete) covering the full admin workflow: login, auth check, edit, delete, logout, and unauthorized access after logout.
  • internal/server/handler_auth.go
    • Added new file handler_auth.go for authentication-related HTTP handlers.
    • Defined sessionCookieName constant for the session cookie.
    • Implemented Login handler to validate the server secret and create a session cookie.
    • Implemented GetMe handler to return the current authentication status.
    • Implemented Logout handler to destroy the session and clear the session cookie.
    • Created requireAdmin middleware to enforce valid session cookie authentication for protected routes.
  • internal/server/handler_auth_test.go
    • Added new file handler_auth_test.go for testing authentication handlers.
    • Included unit tests for successful login, incorrect secret handling, authenticated and unauthenticated GetMe requests, and logout functionality.
  • internal/server/handler_test.go
    • Added TestStoreOperation_CookieAuth to verify that uploads succeed with a valid session cookie and fail with an invalid cookie or no authentication.
  • internal/server/operation.go
    • Added Delete method to RepoOperation to remove an operation record by ID.
    • Added UpdateOperation method to RepoOperation to modify the mission name, tag, and date of an operation.
  • internal/server/operation_test.go
    • Added tests for the new UpdateOperation method to ensure correct metadata updates.
    • Added tests for the new Delete method, including successful deletion and handling of not-found cases.
  • internal/server/session.go
    • Added new file session.go to define an in-memory SessionStore.
    • Implemented Create method to generate new session tokens with an expiry.
    • Implemented Valid method to check if a token is active and not expired.
    • Implemented Destroy method to remove a session token.
  • internal/server/session_test.go
    • Added new file session_test.go for testing the SessionStore functionality.
    • Included tests for session creation, validation, destruction, and expiry.
  • internal/server/setting.go
    • Added Admin struct to Setting to hold admin-related configurations.
    • Included SessionTTL field within the Admin struct for session duration.
    • Set a default value for admin.sessionTTL and bound it to environment variables.
  • internal/server/setting_test.go
    • Added tests for Admin.SessionTTL configuration, verifying custom and default values are parsed correctly.
  • setting.json.example
    • Added a new admin section with a sessionTTL field to the example configuration file.
  • ui/src/App.tsx
    • Imported AuthProvider from useAuth.
    • Wrapped the main application content (props.children) with AuthProvider to provide authentication context globally.
  • ui/src/data/api-client.ts
    • Added AuthState interface to represent authentication status.
    • Implemented login method to authenticate with the server secret.
    • Implemented getMe method to retrieve the current authentication status.
    • Implemented logout method to destroy the server session.
    • Added editOperation method to update operation metadata.
    • Added deleteOperation method to remove an operation.
    • Added retryConversion method to re-queue failed conversions.
    • Added uploadOperation method to handle file uploads.
  • ui/src/hooks/useAuth.tsx
    • Added new file useAuth.tsx to create a SolidJS authentication context.
    • Defined Auth interface for authentication state and actions.
    • Implemented AuthProvider to manage authentication state, check session on mount, and provide login/logout functions.
    • Created useAuth hook for components to easily access authentication context.
  • ui/src/pages/mission-selector/DetailSidebar.tsx
    • Updated DetailSidebar props to include isAdmin, onEdit, onDelete, and onRetry callbacks.
    • Added a new 'Admin Actions' section to the sidebar, conditionally displayed based on isAdmin prop.
    • Included buttons for 'Edit', 'Delete', and 'Retry' (for failed operations) within the admin actions section.
  • ui/src/pages/mission-selector/MissionSelector.module.css
    • Added new CSS classes for admin area styling, including badges, icons, and sign-in buttons.
    • Introduced styles for modal overlays, cards, titles, inputs, errors, and action buttons (cancel, submit, danger).
    • Defined specific styles for the 'Admin actions in sidebar' section, including action buttons.
    • Created styles for the 'Edit modal' form fields, labels, readonly displays, and tag groups.
    • Added styles for the 'Delete confirm' warning and info messages.
    • Implemented styles for the 'Upload zone', including drag-over effects and upload progress display.
  • ui/src/pages/mission-selector/MissionSelector.tsx
    • Imported useAuth hook and batch utility.
    • Added state variables for login modal visibility, login errors, upload visibility, editing/deleting operations, and drag-and-drop status.
    • Integrated authenticated, login, and logout from useAuth.
    • Implemented refreshOperations to reload data after admin actions.
    • Added handleEditSave, handleDeleteConfirm, handleRetry functions to interact with the API.
    • Implemented handleUpload, handleFileSelect, handleDrop, handleDragOver, and handleDragLeave for file upload functionality.
    • Updated the header to display admin login/logout and upload controls based on authentication status.
    • Added a conditional 'Upload Zone' component for drag-and-drop file uploads.
    • Integrated isAdmin, onEdit, onDelete, and onRetry props into DetailSidebar.
    • Introduced LoginModal, EditModal, and DeleteConfirm components, displayed conditionally based on application state.
  • ui/src/pages/mission-selector/icons.tsx
    • Added new SVG icons for Lock, Shield, Upload, LogOut, Edit, Trash, and RefreshCw to be used in the admin UI.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive admin interface with secret-based cookie authentication, CRUD operations for mission metadata, and a drag-and-drop upload zone. The backend implementation includes an in-memory session store and protected API endpoints. Overall, the code is well-structured and follows Go and SolidJS best practices. My feedback focuses on improving security by adding the Secure flag to session cookies, enhancing reliability by checking I/O errors during file operations, and optimizing performance by removing redundant database queries in the edit handler.

fank added 4 commits February 23, 2026 23:01
- Edit button: grey → blue (background, border, text color)
- Label: "ADMIN" → "ADMIN ACTIONS" with tighter spacing
- Admin section: add border-top separator and proper padding
- Header with edit icon, title, and close button
- Compact read-only info bar (ID, Map, Format, Status)
- Tag + Date fields with proper button selection styles
- Footer with border separator, Cancel and Save Changes buttons
- Centered layout with warning triangle icon
- Mission name and metadata prominently displayed
- Detailed warning about file removal
- Delete Recording button with trash icon and red gradient
- Add Secure flag to session cookie (auto-detect TLS)
- Remove redundant DB fetch in EditOperation, update in-memory instead
- Log file cleanup errors in DeleteOperation instead of silently ignoring
- Wrap MissionSelector tests with AuthProvider to fix 30 test failures
@github-actions
Copy link

github-actions bot commented Feb 23, 2026

Coverage Report for ui

Status Category Percentage Covered / Total
🔵 Lines 77.95%
⬆️ +1.53%
2808 / 3602
🔵 Statements 74.54%
⬆️ +1.84%
3623 / 4860
🔵 Functions 74.38%
⬆️ +1.90%
970 / 1304
🔵 Branches 64.87%
⬆️ +0.61%
1265 / 1950
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
ui/src/App.tsx 100%
🟰 ±0%
50%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
ui/src/data/api-client.ts 81.81%
⬆️ +9.94%
85.36%
⬆️ +7.10%
95.65%
⬆️ +3.35%
81.05%
⬆️ +11.05%
149-151, 175-179, 226-262
ui/src/hooks/useAuth.tsx 96.66% 83.33% 100% 96.66% 29
ui/src/pages/mission-selector/DetailSidebar.tsx 45.34%
⬆️ +5.88%
37.5%
⬆️ +2.32%
53.68%
⬆️ +4.85%
48.27%
⬆️ +5.42%
89-96, 150-179
ui/src/pages/mission-selector/MissionSelector.tsx 84.75%
⬆️ +2.69%
72.72%
⬇️ -0.83%
80.76%
⬆️ +2.06%
90.29%
⬆️ +0.61%
658, 88-99, 127, 128, 154-155, 249-252, 256-257, 261, 273-275, 296-297, 299-300, 308, 315-318, 441, 471, 472-473, 475-476, 514, 619-620, 631
ui/src/pages/mission-selector/dialogs.tsx 97.67% 73.33% 96.77% 100% 33, 117, 142
ui/src/pages/mission-selector/icons.tsx 89.28%
⬆️ +5.07%
100%
🟰 ±0%
88.88%
⬆️ +5.55%
89.28%
⬆️ +5.07%
6, 12, 14
Generated in workflow #115 for commit dac6bc2 by the Vitest Coverage Report Action

fank added 8 commits February 23, 2026 23:26
…ariables

Move EditModal and DeleteConfirm into dialogs.tsx and replace all
hardcoded color values in admin styles with existing CSS variables.
Move edit modal and delete confirm CSS classes from
MissionSelector.module.css into dialogs.module.css to follow the
existing convention of one CSS module per component file.
- api-client: 14 tests for login, getMe, logout, editOperation,
  deleteOperation, retryConversion, uploadOperation
- dialogs: 8 tests for EditModal and DeleteConfirm rendering and
  interaction
- useAuth: 6 tests for AuthProvider mount, login, logout, and
  context guard
Cover error branches: bad ID, not-found, not-in-failed-state for
admin handlers; bad request body for login. Raises server package
coverage from 84.1% to 85.2%.
Switch from HttpOnly cookie-based sessions (in-memory SessionStore) to
stateless JWT authentication using HMAC-SHA256 (golang-jwt/jwt/v5). The
server secret doubles as the signing key. Tokens are returned in the
login response body, stored in-memory on the frontend, and sent via
Authorization: Bearer header.
Add tests for authentication UI, login modal flows, edit/delete/retry
operations, upload zone, drag events, and keyboard shortcuts.
@github-actions
Copy link

Merging this branch will increase overall coverage

Impacted Packages Coverage Δ 🤖
github.com/OCAP2/web/internal/server 86.15% (+0.49%) 👍

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/OCAP2/web/internal/server/handler.go 83.60% (+0.82%) 189 (+9) 158 (+9) 31 👍
github.com/OCAP2/web/internal/server/handler_admin.go 85.19% (+85.19%) 54 (+54) 46 (+46) 8 (+8) 🌟
github.com/OCAP2/web/internal/server/handler_auth.go 95.65% (+95.65%) 23 (+23) 22 (+22) 1 (+1) 🌟
github.com/OCAP2/web/internal/server/jwt.go 88.89% (+88.89%) 9 (+9) 8 (+8) 1 (+1) 🌟
github.com/OCAP2/web/internal/server/operation.go 77.90% (+0.25%) 181 (+11) 141 (+9) 40 (+2) 👍
github.com/OCAP2/web/internal/server/setting.go 93.33% (+0.15%) 45 (+1) 42 (+1) 3 👍

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

Changed unit test files

  • github.com/OCAP2/web/internal/server/handler_admin_test.go
  • github.com/OCAP2/web/internal/server/handler_auth_test.go
  • github.com/OCAP2/web/internal/server/handler_test.go
  • github.com/OCAP2/web/internal/server/jwt_test.go
  • github.com/OCAP2/web/internal/server/operation_test.go
  • github.com/OCAP2/web/internal/server/setting_test.go

@fank fank merged commit cf764ad into main Feb 24, 2026
3 checks passed
@fank fank deleted the worktree-admin-ui branch February 24, 2026 09:12
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