--setup-only creates just the realm, service client, OIDC client, and
sponsor attribute — no demo users, groups, or memberships. Ideal for
production Keycloak setup.
--base-uri sets the OIDC redirect URIs and web origins to the given
app URL instead of localhost. Also updates URIs on existing clients.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Connector lines between steps were green for skipped checks, making it
look like the chain succeeded even with no connection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The global axios instance defaults to application/json, which prevents
FormData from being sent correctly. Other file uploads already set the
header explicitly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
funding_doc_number is now only returned through the billing endpoints
after password verification. Previously it leaked via GET /api/projects
and GET /api/projects/{key} to any authenticated user.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New CostCenter model with CSV upload and manual add support
- Pipe-delimited CSV parsing extracts Cost Center and Code Name columns
- Upload preview shows which projects will lose their cost center
- Manual entries preserved across CSV re-uploads
- Fuzzy search combobox replaces text inputs on project form and billing page
- Cost center manager added to admin settings under Billing section
- Billing page: filter out archived projects, gate funding doc behind password
- Widen cost_center column from VARCHAR(10) to VARCHAR(50)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend now returns an empty billing array when password is not verified,
preventing data exposure via developer tools. Frontend no longer renders
the table at all when locked — only the password card is shown.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Exports a CSV of all licenses with name, vendor, part number, cost,
purchase date, and expiration date. Generated client-side from the
already-fetched license data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New GET /api/projects/<key>/members/export endpoint returns a CSV with
name, email, sponsor_status, sponsor_project, last_login_at,
unsponsored_since, and days_until_deletion. Export button added to the
Users Associated with Project table toolbar on the project detail page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ensures each cert file ends with a newline before concatenation so PEM
markers never run together, and strips blank lines for libpq/OpenSSL
compatibility. Supports .crt, .pem, and .cert file extensions from the
configmap.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Billing page now requires a shared password (separate from KC auth) to view any
data. Financial columns (Total, Spent, Available) populated from pipe-delimited
CSV uploads, parsed and stored encrypted (Fernet) in a new billing_data table.
Unmatched funding docs stored for auto-populate when projects get assigned matching
numbers. Admins set/reset the billing password from the Settings page with audit
logging and a gov-only access warning.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Funding document is now a text field (funding_doc_number) on the Project model
instead of a separate file-upload model. Both cost_center and funding_doc_number
are inline-editable on the billing page via PATCH /api/billing/<id>. Removed
FundingDocument model and all file upload/download/delete endpoints.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New billing domain: backend blueprint with Swagger-documented CRUD endpoints for
funding documents (one per project), FundingDocument model, billing_required
decorator checking VELA-mgmt-billing group membership. Frontend billing page with
DataTable (key, name, cost center, funding document upload/download/delete),
BillingRoute guard, hasBillingAccess in auth context. KC seed creates
VELA-mgmt-billing child group and adds Bill Billings (bill@bills.com) as a
billing-only test user.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds flasgger dependency and initializes Swagger UI behind @login_required.
All ~100 API endpoints across 9 blueprints now have OpenAPI docstrings
covering parameters, request bodies, and response schemas.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Link to user detail page as an alternative to releasing sponsorship,
so admins can transfer sponsorship to another project instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add vela_or_admin_required decorator that gates access to hardcoded
admin or users with any VELA group membership. Applied to all cert,
license, and downtime API routes. Frontend sidebar hides these sections
and routes redirect non-VELA users to the dashboard.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract schema migrations, KC sync, and seed data to migrate.py;
run as Helm init container before pods start
- Guard seed data behind SEED_DATA=true env var (off by default)
- Add Config.validate_production() — fail loudly if SECRET_KEY,
FERNET_KEY, or DATABASE_URL are missing/insecure in production
- Add /api/auth/ready endpoint with SELECT 1 DB check for readiness probe
- Make CORS origins configurable via CORS_ORIGINS env var
- Fix duplicate downtime reminders with SELECT FOR UPDATE SKIP LOCKED
- Add --access-logfile and --graceful-timeout to gunicorn
- Add SSL_CERT_FILE env var in Helm for Authlib/httpx CA cert support
- Slim run.py to app creation + background workers only
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove hardcoded .limit(3) on expiring licenses/certs query so all
expiring items are returned
- Increase scroll container to max-h-[220px] to show ~3 items with
partial 4th visible as scroll hint
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add PKCS#7 (P7B/P7C) parsing support for cert import
- Allow adding/updating private keys on existing certs via PUT endpoint
- Add drag-and-drop file reading on private key textarea in cert form
- Truncate long issuer names in certs table column (max 200px)
- Fix certs table not refreshing after create/import/update/delete
- Add .p7b/.p7c to import dialog accepted file extensions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cleanup_completed() imported timedelta but not datetime or timezone,
causing 'name datetime is not defined' on every cleanup cycle.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Init container concatenates all .crt files from the ConfigMap into a
single bundle, supporting multiple CA certificates without requiring
users to pre-bundle them.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
User detail page shows expandable accordion rows with permission
pills (e.g. mgmt-write, bitbucket-read) per project, scoped to
viewer access. "Manage" link directs to project groups tab.
Group member add/remove routes now write UserPermission rows
immediately (DB-first pattern), matching the rest of the codebase.
KC sync does full delete+rebuild per project to eliminate orphaned
and duplicate rows. Startup dedup migration cleans existing data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
License form shows seat/device count when type is Per Seat or Per
Device. Release sponsorship button now shows a confirmation dialog
warning that the user will be disabled in Keycloak and their account
deleted after the configurable unsponsored deletion period.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Daily email reminders for unresolved downtime entries with configurable
time and max days via admin settings (background worker thread)
- Downtime form: enclave, scope, and planned/unplanned now required
- Audit log resolves entity names from details when entities are deleted
instead of showing "Deleted (ID: X)"
- Projects list: agency and service columns with faceted filters
- All data tables: "All" option in rows-per-page dropdown
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Count badges next to Users, Licenses, and Certificates titles now
reflect the filtered row count from TanStack Table, updating live
with search and faceted filters. Added onFilteredCountChange callback
to the shared DataTable component.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Users list gets a disable/enable button per row (admin-only).
Licenses and certs lists get archive/unarchive buttons per row
(VELA write/admin only). All use confirmation dialogs and existing
backend endpoints with proper permission gating.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Projects card shows red "Unverified" pill linking to filtered project
list with new Verified column and faceted filter. License and cert
cards show amber "Expiring" pills alongside existing red "Expired"
pills. Added amber badge color to StatCard.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces hardcoded 30-day verification window with a configurable
setting (default 90 days). Changes to any settings are now audit
logged with from/to values.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Full audit log page (VELA-only) with search, filters, and pagination
- Sidebar nav item gated on global_role (VELA users)
- User detail "Add to Project" now supports multi-select with checkboxes
- Status banner system: admin-configurable messages in topbar with
info/warning/critical types, cycling, dismiss, and expand for long text
- Banner management UI in admin settings page
- Fix table overflow in audit log with min-w-0 on app shell
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>