Creates the admin API router. JWT and dev mode are mutually exclusive (enforced by the caller). - **JWT mode** (`Some`): Only `/health`, `/entities/delete`, and `/users/delete` are available. The token's `email` claim is resolved to a HASH user actor for provenance tracking. - **Dev mode** (`None`, requires `--unsafe-allow-dev-authentication`): All endpoints are available. The `X-Authenticated-U
(
store_pool: PostgresStorePool,
jwt_validator: Option<Arc<JwtValidator>>,
external_services: ExternalServicesConfig,
)
| 93 | /// destructive endpoints (`/snapshot`, `/accounts`, `/data-types`, `/property-types`, |
| 94 | /// `/entity-types`) are registered in this mode only. |
| 95 | pub fn routes( |
| 96 | store_pool: PostgresStorePool, |
| 97 | jwt_validator: Option<Arc<JwtValidator>>, |
| 98 | external_services: ExternalServicesConfig, |
| 99 | ) -> Router { |
| 100 | let public = Router::new().route("/health", get(async || "Healthy")); |
| 101 | |
| 102 | let mut protected = Router::new() |
| 103 | .route("/entities/delete", post(delete_entities)) |
| 104 | .route("/users/delete", post(delete_user)); |
| 105 | |
| 106 | if let Some(validator) = jwt_validator { |
| 107 | protected = protected.layer(Extension(validator)); |
| 108 | } else { |
| 109 | protected = protected |
| 110 | .route("/snapshot", post(restore_snapshot)) |
| 111 | .route("/accounts", delete(delete_accounts)) |
| 112 | .route("/data-types", delete(delete_data_types)) |
| 113 | .route("/property-types", delete(delete_property_types)) |
| 114 | .route("/entity-types", delete(delete_entity_types)); |
| 115 | } |
| 116 | |
| 117 | public |
| 118 | .merge(protected) |
| 119 | .fallback(|| async { |
| 120 | status_to_response(Status::<()>::new( |
| 121 | StatusCode::NotFound, |
| 122 | Some("endpoint not found".to_owned()), |
| 123 | vec![], |
| 124 | )) |
| 125 | }) |
| 126 | .layer(http_tracing_layer::HttpTracingLayer) |
| 127 | .layer(Extension(Arc::new(store_pool))) |
| 128 | .layer(Extension(Arc::new(external_services))) |
| 129 | .layer(Extension(Arc::new(reqwest::Client::new()))) |
| 130 | } |
| 131 | |
| 132 | #[derive(Debug, derive_more::Display, derive_more::Error)] |
| 133 | enum AdminActorError { |
no test coverage detected