Skip to main content

max / makenotwork

5.0 KB · 129 lines History Blame Raw
1 //! Discover page query models.
2
3 use chrono::{DateTime, Utc};
4 use serde::Serialize;
5 use sqlx::FromRow;
6
7 use super::super::id_types::{CustomLinkId, ItemId, UserId};
8 use super::super::validated_types::{Slug, Username};
9
10 /// A flattened item row returned by the discover/search query.
11 #[derive(Debug, Clone, FromRow)]
12 #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion
13 pub struct DbDiscoverItemRow {
14 /// Item primary key.
15 pub id: ItemId,
16 /// Item title.
17 pub title: String,
18 /// Item description.
19 pub description: Option<String>,
20 /// Price in cents.
21 pub price_cents: i32,
22 /// Content type.
23 pub item_type: super::super::ItemType,
24 /// When the item was created.
25 pub created_at: DateTime<Utc>,
26 /// Creator's username (joined from users).
27 pub username: Username,
28 /// The creator's settlement currency (joined from users). Carried on the row
29 /// because the discover feed mixes creators, so the page has no single
30 /// currency it could apply to every price it renders.
31 pub settlement_currency: crate::currency::SettlementCurrency,
32 /// Parent project title (joined from projects).
33 pub project_title: String,
34 /// Number of completed purchases.
35 pub sales_count: i64,
36 /// Primary tag name (joined from item_tags/tags), or NULL if no primary tag.
37 pub primary_tag_name: Option<String>,
38 /// Whether PWYW pricing is enabled.
39 pub pwyw_enabled: bool,
40 /// Minimum price in cents when PWYW is enabled.
41 pub pwyw_min_cents: Option<i32>,
42 /// Which kind of match this row is: `2` = holds at least one typed word,
43 /// `1` = holds none and is here on character overlap alone. `None` when not
44 /// searching.
45 ///
46 /// Ranks ahead of [`Self::match_score`], and the two scores are not
47 /// comparable across the boundary: tier 2 uses `ts_rank`, tier 1 uses
48 /// per-word trigram. That is safe because the tier is decided by a count,
49 /// not by either score. See [`crate::db::discover::MATCH_TIER_LEXICAL`].
50 pub match_tier: Option<i16>,
51 /// How many of the typed words this row holds, and how many were typed.
52 ///
53 /// Drives the per-row "Matched 3 of 5 words" label. `None` when not
54 /// searching, or on the 1-2 character path where there are no words to
55 /// count. Counted separately from [`Self::match_score`] on purpose: the
56 /// score folds in field weighting, so a row holding every typed word but
57 /// only in its description scores 0.5, and a label derived from it would
58 /// undercount.
59 pub matched_terms: Option<i32>,
60 /// Denominator for [`Self::matched_terms`].
61 pub query_terms: Option<i32>,
62 /// Rank within the row's own tier (set when searching, `None` otherwise).
63 pub match_score: Option<f32>,
64 /// AI disclosure tier, drives the badge / row label on Discover.
65 pub ai_tier: super::super::AiTier,
66 }
67
68 /// A flattened project row returned by the discover projects query.
69 #[derive(Debug, Clone, FromRow)]
70 #[allow(dead_code)] // Fields populated by sqlx query, read during type conversion
71 pub struct DbDiscoverProjectRow {
72 /// Project URL slug.
73 pub slug: Slug,
74 /// Project title.
75 pub title: String,
76 /// Project description.
77 pub description: Option<String>,
78 /// Project category.
79 pub project_type: super::super::ProjectType,
80 /// When the project was created.
81 pub created_at: DateTime<Utc>,
82 /// Creator's username (joined from users).
83 pub username: Username,
84 /// Number of public items in this project.
85 pub item_count: i64,
86 /// Which kind of match this row is. See [`DbDiscoverItemRow::match_tier`].
87 pub match_tier: Option<i16>,
88 /// See [`DbDiscoverItemRow::matched_terms`].
89 pub matched_terms: Option<i32>,
90 /// See [`DbDiscoverItemRow::query_terms`].
91 pub query_terms: Option<i32>,
92 /// Rank within the row's own tier (set when searching, `None` otherwise).
93 pub match_score: Option<f32>,
94 /// Category name (joined from project_categories), or NULL if uncategorized.
95 pub category_name: Option<String>,
96 /// Category slug (joined from project_categories), or NULL if uncategorized.
97 pub category_slug: Option<String>,
98 }
99
100 /// An item_type value paired with the number of matching items.
101 #[derive(Debug, Clone, FromRow)]
102 pub struct DbItemTypeCount {
103 /// The item_type category value.
104 pub category: String,
105 /// Number of matching items of this type.
106 pub count: i64,
107 }
108
109 /// A user-defined external link shown on their profile.
110 #[derive(Debug, Clone, FromRow, Serialize)]
111 pub struct DbCustomLink {
112 /// Database primary key.
113 pub id: CustomLinkId,
114 /// Owning user's ID.
115 pub user_id: UserId,
116 /// Full URL.
117 pub url: String,
118 /// Display title for the link.
119 pub title: String,
120 /// Optional description shown below the title.
121 pub description: Option<String>,
122 /// Position in the user's link list.
123 pub sort_order: i32,
124 /// When the link was created.
125 pub created_at: DateTime<Utc>,
126 /// When the link was last modified.
127 pub updated_at: DateTime<Utc>,
128 }
129