Problem
Provider identities are displayed throughout the UI using the raw `type/host` compound key stored in the database. For default providers this looks redundant and slightly silly:
- SCM identity badges on the Users list, User Detail, and Profile pages show `github/github.com` instead of `github`
- Permission tables show the same compound key in the provider column
- Add-identity and add-permission dropdowns already use `host` only (inconsistency)
- API URL paths require a `/` → `@` encoding hack in `api.ts` because the compound key breaks Spring Security URL routing
The user-configured `name` (the YAML config key — e.g. `github`, `internal`, `corp-gitlab`) is unique by construction (it is a top-level map key under `providers:`), meaningful to the specific deployment, and more stable than `type/host` (survives hostname migration without changing operator-visible names).
Decision
Use `name` as the canonical provider FK in the database. #75 (live provider hot-swap) has been closed as wontfix — providers are config/operator-driven only and require a process restart to change. This makes `name` stable by construction: there is a single source of truth (YAML config), no JDBC-sourced providers to collide with, and no live-reload requirement that could orphan FK data mid-run.
Current state
Six database tables store `type/host` as a string FK in a `provider VARCHAR(100)` column:
- `user_scm_identities` (PK includes `provider`)
- `repo_permissions`
- `access_rules`
- `push_records`
- `fetch_records`
- `scm_token_cache` (PK includes `provider`)
`GitProxyProvider.getProviderId()` currently returns `{type}/{host}` and is the source of every stored value.
Implementation
-
One-off data fixup script — since this project is pre-1.0.0 beta, a formal DB migration is not used for data changes (migrations are DDL-only until 1.0.0). Provide a SQL script with `UPDATE` statements to rename existing `type/host` values to `name` across all six tables. Operators run this once before deploying the new version.
-
`GitProxyProvider.getProviderId()` — change to return `name` instead of `type/host`.
-
`ProviderInfo.id` (REST API response) — already equals `getProviderId()`, so this follows automatically. Verify no other callers construct the compound key manually.
-
Remove the `/` → `@` URL encoding hack in `api.ts` and the corresponding `replace('@', '/')` decode in `ProfileController` and any other backend endpoints. Provider names are safe in URL path segments.
-
Startup orphan check — on boot, warn if any `provider` column values in the DB do not match a currently configured provider name. Gives operators a clear signal if a YAML rename has left FK data dangling.
-
UI badge cleanup — with `id` now equalling `name`, the raw value displayed in badges is already human-readable. Verify all badge render sites and remove any workarounds.
Out of scope
Problem
Provider identities are displayed throughout the UI using the raw `type/host` compound key stored in the database. For default providers this looks redundant and slightly silly:
The user-configured `name` (the YAML config key — e.g. `github`, `internal`, `corp-gitlab`) is unique by construction (it is a top-level map key under `providers:`), meaningful to the specific deployment, and more stable than `type/host` (survives hostname migration without changing operator-visible names).
Decision
Use `name` as the canonical provider FK in the database. #75 (live provider hot-swap) has been closed as wontfix — providers are config/operator-driven only and require a process restart to change. This makes `name` stable by construction: there is a single source of truth (YAML config), no JDBC-sourced providers to collide with, and no live-reload requirement that could orphan FK data mid-run.
Current state
Six database tables store `type/host` as a string FK in a `provider VARCHAR(100)` column:
`GitProxyProvider.getProviderId()` currently returns `{type}/{host}` and is the source of every stored value.
Implementation
One-off data fixup script — since this project is pre-1.0.0 beta, a formal DB migration is not used for data changes (migrations are DDL-only until 1.0.0). Provide a SQL script with `UPDATE` statements to rename existing `type/host` values to `name` across all six tables. Operators run this once before deploying the new version.
`GitProxyProvider.getProviderId()` — change to return `name` instead of `type/host`.
`ProviderInfo.id` (REST API response) — already equals `getProviderId()`, so this follows automatically. Verify no other callers construct the compound key manually.
Remove the `/` → `@` URL encoding hack in `api.ts` and the corresponding `replace('@', '/')` decode in `ProfileController` and any other backend endpoints. Provider names are safe in URL path segments.
Startup orphan check — on boot, warn if any `provider` column values in the DB do not match a currently configured provider name. Gives operators a clear signal if a YAML rename has left FK data dangling.
UI badge cleanup — with `id` now equalling `name`, the raw value displayed in badges is already human-readable. Verify all badge render sites and remove any workarounds.
Out of scope