Skip to main content

character_service/
lib.rs

1//! Character service: CRUD over character sheets, in Postgres. Every
2//! request needs a token from the auth service, and only sees its own
3//! campaign's characters.
4
5/// Errors, as responses.
6/// What whoever runs the service asks of it over HTTP.
7pub mod admin;
8pub mod error;
9/// The HTTP routes.
10pub mod routes;
11/// Characters in Postgres.
12pub mod store;
13
14use std::sync::Arc;
15
16use axum::{Extension, Router};
17use edda_auth::server::TokenVerifier;
18use edda_server::{Limits, openapi::Conventions};
19use sqlx::PgPool;
20
21pub use store::CharacterStore;
22
23/// The service's `OpenAPI` description.
24#[derive(utoipa::OpenApi)]
25#[openapi(
26    paths(
27        edda_server::health,
28        edda_server::ready,
29        routes::list,
30        routes::create,
31        routes::fetch,
32        routes::replace,
33        routes::remove,
34        routes::apply_action,
35        routes::set_owners,
36    ),
37    modifiers(&Conventions),
38    tags((name = "characters", description = "Character sheets, and what happens to them in play."))
39)]
40pub struct ApiDoc;
41
42/// What the handlers share.
43#[derive(Clone)]
44pub struct AppState {
45    pub characters: CharacterStore,
46    pub limits: Arc<Limits>,
47}
48
49/// Opens (creating if needed) the database and applies migrations.
50pub async fn connect(database_url: &str) -> Result<PgPool, sqlx::Error> {
51    edda_server::open_database(database_url, &sqlx::migrate!()).await
52}
53
54/// The service, accepting tokens that `verifier` vouches for, within
55/// `limits` (how many characters a campaign may keep).
56pub fn app(pool: PgPool, verifier: TokenVerifier, limits: Limits) -> Router {
57    let ready = edda_server::readiness(pool.clone());
58    let state = AppState {
59        characters: CharacterStore::new(pool),
60        limits: Arc::new(limits),
61    };
62    Router::new()
63        .merge(routes::router())
64        .with_state(state)
65        .layer(Extension(Arc::new(verifier)))
66        .merge(ready)
67}