(** The web tier: routing, authentication, sessions, and CSRF. Functorized over the repository so tests drive it with an in-memory store while production uses SQLite. *) module Make (R : Hito_app.Repository.S) (_ : Hito_app.Password_hash.S) : sig type t val make : repo:R.t -> ?now:(unit -> Recovery.timestamp) -> ?registration_open:bool -> unit -> t (** [registration_open] exposes the public [/register] routes and the sign-in page's Register link. Defaults to [false]: the deployment runs on pre-seeded accounts until public sign-up returns. *) val routes : t -> Dream.route list (** The route table. Session and CSRF middleware are applied per handler. Wrap with {!Dream.sql_sessions} or {!Dream.memory_sessions} and a secret at the top level. *) val error_handler : Dream.error_handler (** Renders a branded page for every failure Dream routes here, including unmatched paths and [5xx] responses. Pass to {!Dream.run} [~error_handler]. It leaks no server-supplied string. *) end