Commit Graph

161 Commits

Author SHA1 Message Date
220d0587d5 Add --setup-only and --base-uri flags to seed-keycloak script
--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>
2026-04-01 14:46:21 -07:00
bce35c6035 Fix Keycloak diagnostics showing green connectors when not connected
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>
2026-04-01 14:41:26 -07:00
5a70b62182 Shrink cost center settings table to show ~3 rows
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:33:24 -07:00
852686d123 Add delete all cost centers button on settings page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:32:21 -07:00
125f097df3 Fix cost center CSV upload by setting multipart/form-data header
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>
2026-04-01 14:28:19 -07:00
Scott Hatlen (CTR)
a1f54f4775 debug csv 2026-04-01 12:48:56 -07:00
805591a21c Remove funding_doc_number from project API responses
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>
2026-04-01 11:50:15 -07:00
98c200e774 Remove duplicate lines in notes and clean up Round 8 entries
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:45:23 -07:00
93d114f3e7 Fix CA cert handling: use Secret, normalize line endings, pull busybox from registry
- Switch caCert volume source from ConfigMap to Secret (avoids base64 issues)
- Strip \r carriage returns in init container to fix psycopg2 PEM parsing
- Add busyboxImage helper so init containers pull from imageRegistry when set
- Unify backend/frontend init container cert bundling scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:41:35 -07:00
175f4159be Add cost center management with CSV upload and fuzzy search combobox
- 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>
2026-04-01 11:25:11 -07:00
Scott Hatlen (CTR)
38da4481e7 cost center name 2026-04-01 10:39:13 -07:00
Scott Hatlen (CTR)
448ecdef69 new todos 2026-04-01 10:37:30 -07:00
18e1215bc7 make project keys clickable links on billing page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:48:08 -07:00
7a0fa3172a Revert "fix billing page to not send or render data until password is verified"
This reverts commit b1a7770f64.
2026-03-31 20:41:14 -07:00
b1a7770f64 fix billing page to not send or render data until password is verified
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>
2026-03-31 20:39:58 -07:00
afb8f13613 updated notes 2026-03-31 14:39:45 -07:00
4581e7f13f add Generate Report button to licenses page
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>
2026-03-31 14:34:40 -07:00
596d2ee449 add Export CSV button for project members sponsorship table
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>
2026-03-31 14:32:15 -07:00
81b898246f fix CA cert bundle init container to handle all cert extensions and newlines
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>
2026-03-31 14:27:28 -07:00
120a8e1955 add encrypted financial data from CSV uploads and password-gated billing page
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>
2026-03-31 14:18:07 -07:00
8c122d2685 replace funding document file with editable funding doc number and cost center fields
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>
2026-03-31 13:27:35 -07:00
Scott Hatlen (CTR)
fc69dbc7c3 more notes todo 2026-03-31 12:03:45 -07:00
28f7777437 add Billing page with funding document management gated by VELA-mgmt-billing KC group
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>
2026-03-31 09:24:29 -07:00
598517071a add Swagger docstrings to settings and keycloak admin routes
Covers all 29 endpoints: expiry thresholds, all settings, agency/service
map, banner, downtime applications, SMTP, KC diagnostics, sync, queue,
and sync error management.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 19:02:21 -07:00
f750e8c7a5 add Flasgger API docs with Swagger UI at /apidocs
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>
2026-03-30 16:02:56 -07:00
Scott Hatlen (CTR)
b6f10cf012 we want to build and push, but no need for helm commands 2026-03-27 14:32:41 -07:00
89950b917f add government employee recommendation under PM field in project form
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:28:50 -07:00
d95f071af0 add switch-project hint to release sponsorship dialog
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>
2026-03-27 11:24:05 -07:00
b65b9c328f restrict certs, licenses, and downtime to VELA/admin users
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>
2026-03-27 11:23:28 -07:00
eea1d1c3df removing the externalsecret reference 2026-03-27 11:10:53 -07:00
a30046b550 production readiness: init container, seed guard, safety checks, and fixes
- 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>
2026-03-27 11:09:31 -07:00
ab61f63e58 remove SQLite fallback, require PostgreSQL everywhere
- Remove sqlite DATABASE_URL from Dockerfile, docker-compose.yml, and
  Helm configmap; add Postgres service to base docker-compose
- Remove SQLite persistence PVC, usePostgres helper, and conditional
  volume/strategy logic from Helm chart
- Remove dual-dialect branches in run.py (keep Postgres-only SQL)
- Remove SQLite backup endpoint and frontend button
- Add Postgres container to dev.sh alongside Keycloak
- Update config.py default to postgresql://
- Update .env.example files, README, CLAUDE.md, and notes
- Tests remain on in-memory SQLite for speed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 10:46:32 -07:00
358d8d5dcc fix dashboard expiring items: remove limit(3) and add scrollable overflow
- 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>
2026-03-27 10:34:40 -07:00
Scott Hatlen (CTR)
fa2981aeaa more work todo 2026-03-27 10:25:42 -07:00
Scott Hatlen (CTR)
d32b0b5fbd env var for container tool 2026-03-27 09:54:36 -07:00
df8a8233bc add PKCS7 import, private key editing, drag-and-drop, and cert table fixes
- 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>
2026-03-27 09:23:36 -07:00
Scott Hatlen (CTR)
304810babe round 7 2026-03-26 13:46:58 -07:00
b4846f8655 done 2026-03-25 16:09:36 -07:00
e708391658 fix missing datetime import in KC queue cleanup
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>
2026-03-25 16:07:44 -07:00
201f2116a5 change CA cert from single-key Secret to multi-entry ConfigMap
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>
2026-03-25 16:07:41 -07:00
45321873f3 add per-project permissions on user detail, fix KC sync consistency
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>
2026-03-25 16:03:47 -07:00
a2ad513d63 add license quantity field and sponsorship release warning dialog
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>
2026-03-25 15:13:18 -07:00
70b1d25b31 add downtime reminders, required fields, audit name fix, project filters, show-all rows
- 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>
2026-03-25 15:05:13 -07:00
b60d03ea14 add dynamic filtered count pills to list page titles
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>
2026-03-25 14:31:55 -07:00
a86e816d96 add row-level actions: disable user, archive licenses/certs
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>
2026-03-25 14:23:21 -07:00
d15bd88fee add dashboard pills for unverified projects, expiring licenses/certs
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>
2026-03-25 14:04:16 -07:00
d88a48b08e add configurable verification interval with audit logging
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>
2026-03-25 13:47:38 -07:00
Scott Hatlen (CTR)
88da8e1414 one more 2026-03-25 13:11:20 -07:00
Scott Hatlen (CTR)
bf8cf1c899 round 6 2026-03-25 11:28:08 -07:00
dca541be61 add audit log page, multi-select project assignment, and status banner
- 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>
2026-03-24 16:48:35 -07:00