//! HTML page routes, split by domain.
mod blog;
pub(crate) mod dashboard;
mod email_actions;
mod feeds;
pub(crate) mod public;
mod sandbox;
use crate::{AppState, csrf::CsrfRouter};
use axum::Router;
/// Compose the page tree from posture-declared sub-groups and `finalize()` once.
///
/// Every sub-router is a `CsrfRouter`, and `CsrfRouter::merge` only accepts
/// another `CsrfRouter`, so a bare `axum::Router` (which can carry an
/// undeclared mutation route) is a *type error* here, not a silent CSRF bypass.
/// This is the structural resolution of the Run #16/#17 CHRONIC: the old code
/// merged `email_actions`/`sandbox`/`feeds`/`blog` as bare `Router`s, and
/// `email_actions`'s `POST /forgot-password` (plus `sandbox`'s `POST /sandbox`)
/// skipped the envelope. `finalize()` drops the wrapper exactly once, here.
pub fn page_routes() -> Router {
CsrfRouter::new()
.merge(public::public_routes())
.merge(sandbox::sandbox_routes())
.merge(dashboard::dashboard_routes())
.merge(email_actions::email_action_routes())
.merge(feeds::feed_routes())
.merge(blog::blog_routes())
.finalize()
}