Skip to main content

max / makenotwork

2.8 KB · 89 lines History Blame Raw
1 //! Category and tag models.
2
3 use chrono::{DateTime, Utc};
4 use sqlx::FromRow;
5
6 use super::super::id_types::{CategoryId, ItemId, TagId};
7 use super::super::validated_types::Slug;
8
9 // ── Category models ──
10
11 /// A project category for discover-page filtering.
12 #[derive(Debug, Clone, FromRow)]
13 #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion
14 pub struct DbCategory {
15 pub id: CategoryId,
16 pub name: String,
17 pub slug: Slug,
18 pub created_at: DateTime<Utc>,
19 }
20
21 /// A category with a count of public projects, for discover sidebar facets.
22 #[derive(Debug, Clone, FromRow)]
23 #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion
24 pub struct DbCategoryCount {
25 pub name: String,
26 pub slug: Slug,
27 pub count: i64,
28 }
29
30 // ── Tag models ──
31
32 /// A tag in the hierarchical taxonomy.
33 ///
34 /// Tag slugs use dot-notation (`audio.genre.electronic`) and are validated
35 /// by tagtree, not the general `Slug` type.
36 #[derive(Debug, Clone, FromRow)]
37 #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion
38 pub struct DbTag {
39 pub id: TagId,
40 pub name: String,
41 pub slug: String,
42 pub parent_id: Option<TagId>,
43 pub sort_order: i32,
44 pub created_at: DateTime<Utc>,
45 pub path: String,
46 }
47
48 /// A tag attached to an item, with joined tag name/slug for display.
49 #[derive(Debug, Clone, FromRow)]
50 #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion
51 pub struct DbItemTag {
52 pub item_id: ItemId,
53 pub tag_id: TagId,
54 pub is_primary: bool,
55 pub tag_name: String,
56 pub tag_slug: String,
57 }
58
59 /// Tag with item count, used for discover sidebar facets.
60 #[derive(Debug, Clone, FromRow)]
61 #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion
62 pub struct DbTagCount {
63 pub tag_id: TagId,
64 pub tag_name: String,
65 pub tag_slug: String,
66 pub count: i64,
67 }
68
69 /// One rung of the discover sidebar's tag drill-down: an immediate child of the
70 /// browse cursor, with the number of matching items anywhere in its subtree.
71 ///
72 /// `count` is a subtree total, not a direct-assignment total, because the
73 /// drill-down's promise is "pick this and you get that many". Items are only
74 /// ever tagged with depth-3+ leaves, so a category's direct count is always
75 /// zero and would render a sidebar full of noise.
76 #[derive(Debug, Clone, FromRow)]
77 pub struct DbTagChild {
78 pub tag_id: TagId,
79 pub tag_name: String,
80 pub tag_slug: String,
81 pub count: i64,
82 /// True once this tag is deep enough to be assigned to an item, and
83 /// therefore to act as a filter rather than only as a navigation rung.
84 pub assignable: bool,
85 /// True when this tag has children of its own, so the UI knows whether
86 /// selecting it should also offer to drill further.
87 pub has_children: bool,
88 }
89