//! Unauthenticated, read-only endpoints safe to expose before a user has joined. use axum::Json; use axum::extract::State; use serde::Serialize; use crate::services::config; use crate::state::AppState; #[derive(Serialize)] pub struct PublicEventDto { pub name: String, pub slug: String, /// Whether the comment feature is on (env `COMMENTS_ENABLED`). The frontend hides /// the whole comment UI when false; exposed here so even the pre-auth shell knows. pub comments_enabled: bool, /// Active colour theme. `preset` is an id the frontend maps to a palette (or /// "custom"); `primary`/`accent` are the `#rrggbb` seeds the ramps derive from. /// Resolved as DB-config override → env default. Public so the theme applies on /// the very first (pre-auth) paint without a flash. pub theme_preset: String, pub theme_primary: String, pub theme_accent: String, } /// Public event identity + presentation config, used by the pre-auth join/recover /// screens (which event am I joining, what does it look like). Only non-user-scoped /// fields are exposed, so this is safe without a token. Identity comes straight from /// instance config; the theme is resolved from the runtime `config` table (admin UI) /// falling back to the env-seeded default. pub async fn get_public_event(State(state): State) -> Json { let cache = &state.config_cache; Json(PublicEventDto { name: state.config.event_name.clone(), slug: state.config.event_slug.clone(), comments_enabled: state.config.comments_enabled, theme_preset: config::get_str(cache, "theme_preset", &state.config.default_theme_preset) .await, theme_primary: config::get_str(cache, "theme_primary", &state.config.default_theme_primary) .await, theme_accent: config::get_str(cache, "theme_accent", &state.config.default_theme_accent) .await, }) }