//! Category and tag models. use chrono::{DateTime, Utc}; use sqlx::FromRow; use super::super::id_types::*; use super::super::validated_types::*; // ── Category models ── /// A project category for discover-page filtering. #[derive(Debug, Clone, FromRow)] #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion pub struct DbCategory { pub id: CategoryId, pub name: String, pub slug: Slug, pub created_at: DateTime, } /// A category with a count of public projects, for discover sidebar facets. #[derive(Debug, Clone, FromRow)] #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion pub struct DbCategoryCount { pub name: String, pub slug: Slug, pub count: i64, } // ── Tag models ── /// A tag in the hierarchical taxonomy. /// /// Tag slugs use dot-notation (`audio.genre.electronic`) and are validated /// by tagtree, not the general `Slug` type. #[derive(Debug, Clone, FromRow)] #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion pub struct DbTag { pub id: TagId, pub name: String, pub slug: String, pub parent_id: Option, pub sort_order: i32, pub created_at: DateTime, pub path: String, } /// A tag attached to an item, with joined tag name/slug for display. #[derive(Debug, Clone, FromRow)] #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion pub struct DbItemTag { pub item_id: ItemId, pub tag_id: TagId, pub is_primary: bool, pub tag_name: String, pub tag_slug: String, } /// Tag with item count, used for discover sidebar facets. #[derive(Debug, Clone, FromRow)] #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion pub struct DbTagCount { pub tag_id: TagId, pub tag_name: String, pub tag_slug: String, pub count: i64, }