1pub mod admin;
10pub mod error;
11mod export;
12pub mod routes;
14pub mod store;
15pub mod texts;
16
17use std::sync::Arc;
18
19use axum::{Extension, Router};
20use edda_auth::server::TokenVerifier;
21use edda_server::{Limits, openapi::Conventions};
22use sqlx::PgPool;
23
24pub use store::MonsterStore;
25
26#[derive(utoipa::OpenApi)]
28#[openapi(
29 paths(
30 edda_server::health,
31 edda_server::ready,
32 routes::list,
33 routes::create,
34 routes::fetch,
35 routes::replace,
36 routes::remove,
37 routes::spells::list,
38 routes::spells::create,
39 routes::spells::fetch,
40 routes::spells::replace,
41 routes::spells::remove,
42 routes::conditions::list,
43 routes::conditions::create,
44 routes::conditions::fetch,
45 routes::conditions::replace,
46 routes::conditions::remove,
47 ),
48 modifiers(&Conventions),
49 tags(
50 (name = "monsters", description = "Stat blocks: the shared library of the campaign's edition, and the campaign's own. Only DM devices change them."),
51 (name = "spells", description = "The text of spells, shared and the campaign's own, like monsters."),
52 (name = "conditions", description = "The text of conditions, shared and the campaign's own, like monsters."),
53 )
54)]
55pub struct ApiDoc;
56
57pub async fn connect(database_url: &str) -> Result<PgPool, sqlx::Error> {
59 edda_server::open_database(database_url, &sqlx::migrate!()).await
60}
61
62pub fn app(pool: PgPool, verifier: TokenVerifier, limits: Limits) -> Router {
66 let ready = edda_server::readiness(pool.clone());
67 Router::new()
68 .merge(routes::router())
69 .with_state(MonsterStore::new(pool))
70 .layer(Extension(Arc::new(verifier)))
71 .layer(Extension(Arc::new(limits)))
72 .merge(ready)
73}