Skip to main content

max / makenotwork

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