//! Database read queries, projection structs and SQL. use chrono::{DateTime, Utc}; use mt_core::types::{ BanType, ChatPolicy, CommunityRole, CommunityState, ModAction, SortColumn, SortOrder, }; use sqlx::PgPool; use uuid::Uuid; /// A community resource loaded by id but not yet proven to belong to a caller's /// community scope (the ultra-fuzz C1 invariant). /// /// The inner value is private, so [`Unscoped::in_community`] is the only way to /// reach it and the community check cannot be skipped. Why the invariant exists /// and what it replaced is in `src/routes/scope.rs`, which is the canonical /// account; do not restate it here. pub struct Unscoped { inner: T, community_id: Uuid, } impl Unscoped { /// Wrap a freshly-loaded resource together with the community it lives in. pub fn new(inner: T, community_id: Uuid) -> Self { Self { inner, community_id, } } /// Yield the resource only if it belongs to `expected_community`; `None` /// otherwise (the id names a resource in a different community, which to a /// scoped URL is indistinguishable from "not found"). pub fn in_community(self, expected_community: Uuid) -> Option { (self.community_id == expected_community).then_some(self.inner) } /// Unwrap without a community check. This is the deliberate escape hatch for /// callers that have no URL slug to scope against, the trusted internal /// server-to-server API. It is on `clippy.toml`'s `disallowed-methods` so a /// normal handler cannot reach for it by accident; the one sanctioned call /// site (`src/routes/internal.rs`) carries a local `#[allow]`. Anything /// reached via `/p/{slug}/…` must use [`Unscoped::in_community`] instead. pub fn into_inner_unchecked(self) -> T { self.inner } } mod admin; mod category; mod chat; mod community; mod endorsement; mod footnote; mod image; mod link_preview; mod member; mod mention; mod moderation; mod post; mod search; mod tag; mod thread; mod tracked_thread; mod user; pub use admin::*; pub use category::*; pub use chat::*; pub use community::*; pub use endorsement::*; pub use footnote::*; pub use image::*; pub use link_preview::*; pub use member::*; pub use mention::*; pub use moderation::*; pub use post::*; pub use search::*; pub use tag::*; pub use thread::*; pub use tracked_thread::*; pub use user::*; // Explicit re-exports so clippy.toml disallowed-methods paths resolve // (path-based lints do not follow glob re-exports). pub use post::get_post_for_edit; pub use thread::get_thread_with_breadcrumb;