commit a302bcc59be3eba6eb778914c481cbfd46d0611a
parent d3796200d8d6a96e32c6b83e50321db7ebfb7161
Author: Silas Brack <silasbrack@gmail.com>
Date: Sat, 13 Jun 2026 13:30:46 +0200
refactor: flatten db module into database.rs
StoryWithMeta and CommentWithMeta now live in database.rs alongside
the types they wrap. Removed the unnecessary src/db/ directory.
One module for all database types and queries.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
8 files changed, 97 insertions(+), 96 deletions(-)
diff --git a/src/database.rs b/src/database.rs
@@ -101,6 +101,98 @@ pub struct StoryMeta {
}
// ==========================================================================
+// View types (for templates)
+// ==========================================================================
+
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+pub struct StoryWithMeta {
+ pub id: i64,
+ pub url: Option<String>,
+ pub title: String,
+ pub text: String,
+ pub domain: Option<String>,
+ pub score: i64,
+ pub comment_count: i64,
+ pub published: String,
+ pub created_by: Option<String>,
+ pub tags: Vec<Category>,
+ pub author_username: Option<String>,
+ pub time_ago: String,
+ pub user_voted: bool,
+ pub rank: usize,
+}
+
+impl StoryWithMeta {
+ pub fn from_story(
+ story: Story,
+ tags: Vec<Category>,
+ author_username: Option<String>,
+ time_ago: String,
+ user_voted: bool,
+ rank: usize,
+ ) -> Self {
+ Self {
+ id: story.id,
+ url: story.url,
+ title: story.title,
+ text: story.text,
+ domain: story.domain,
+ score: story.score,
+ comment_count: story.comment_count,
+ published: story.published,
+ created_by: story.created_by,
+ tags,
+ author_username,
+ time_ago,
+ user_voted,
+ rank,
+ }
+ }
+}
+
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+pub struct CommentWithMeta {
+ pub id: i64,
+ pub story_id: i64,
+ pub parent_id: Option<i64>,
+ pub path: String,
+ pub depth: i64,
+ pub indent_px: i64,
+ pub text: String,
+ pub score: i64,
+ pub created_at: String,
+ pub created_by: String,
+ pub author_username: Option<String>,
+ pub time_ago: String,
+ pub user_voted: bool,
+}
+
+impl CommentWithMeta {
+ pub fn from_comment(
+ comment: Comment,
+ author_username: Option<String>,
+ time_ago: String,
+ user_voted: bool,
+ ) -> Self {
+ Self {
+ id: comment.id,
+ story_id: comment.story_id,
+ parent_id: comment.parent_id,
+ path: comment.path.clone(),
+ depth: comment.depth,
+ indent_px: comment.depth * 20,
+ text: comment.text,
+ score: comment.score,
+ created_at: comment.created_at,
+ created_by: comment.created_by,
+ author_username,
+ time_ago,
+ user_voted,
+ }
+ }
+}
+
+// ==========================================================================
// Database
// ==========================================================================
diff --git a/src/db/mod.rs b/src/db/mod.rs
@@ -1,90 +0,0 @@
-// Re-export types from database module
-pub use crate::database::{Category, Comment, Story, UserProfile};
-
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
-pub struct StoryWithMeta {
- pub id: i64,
- pub url: Option<String>,
- pub title: String,
- pub text: String,
- pub domain: Option<String>,
- pub score: i64,
- pub comment_count: i64,
- pub published: String,
- pub created_by: Option<String>,
- pub tags: Vec<Category>,
- pub author_username: Option<String>,
- pub time_ago: String,
- pub user_voted: bool,
- pub rank: usize,
-}
-
-impl StoryWithMeta {
- pub fn from_story(
- story: Story,
- tags: Vec<Category>,
- author_username: Option<String>,
- time_ago: String,
- user_voted: bool,
- rank: usize,
- ) -> Self {
- Self {
- id: story.id,
- url: story.url,
- title: story.title,
- text: story.text,
- domain: story.domain,
- score: story.score,
- comment_count: story.comment_count,
- published: story.published,
- created_by: story.created_by,
- tags,
- author_username,
- time_ago,
- user_voted,
- rank,
- }
- }
-}
-
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
-pub struct CommentWithMeta {
- pub id: i64,
- pub story_id: i64,
- pub parent_id: Option<i64>,
- pub path: String,
- pub depth: i64,
- pub indent_px: i64, // Pre-computed: depth * 20
- pub text: String,
- pub score: i64,
- pub created_at: String,
- pub created_by: String,
- pub author_username: Option<String>,
- pub time_ago: String,
- pub user_voted: bool,
-}
-
-impl CommentWithMeta {
- pub fn from_comment(
- comment: Comment,
- author_username: Option<String>,
- time_ago: String,
- user_voted: bool,
- ) -> Self {
- Self {
- id: comment.id,
- story_id: comment.story_id,
- parent_id: comment.parent_id,
- path: comment.path.clone(),
- depth: comment.depth,
- indent_px: comment.depth * 20,
- text: comment.text,
- score: comment.score,
- created_at: comment.created_at,
- created_by: comment.created_by,
- author_username,
- time_ago,
- user_voted,
- }
- }
-}
diff --git a/src/handlers/feed.rs b/src/handlers/feed.rs
@@ -6,7 +6,7 @@ use axum::{
use axum_extra::extract::cookie::CookieJar;
use serde::Deserialize;
-use crate::db::{Category, StoryWithMeta};
+use crate::database::{Category, StoryWithMeta};
use crate::database::{self, TARGET_TYPE_STORY};
use crate::error::AppError;
use crate::handlers::auth::get_user_id_from_cookies;
diff --git a/src/handlers/story.rs b/src/handlers/story.rs
@@ -9,7 +9,7 @@ use axum::{
use axum_extra::extract::cookie::CookieJar;
use serde::Deserialize;
-use crate::db::{CommentWithMeta, StoryWithMeta};
+use crate::database::{CommentWithMeta, StoryWithMeta};
use crate::database::{self, TARGET_TYPE_COMMENT, TARGET_TYPE_STORY};
use crate::error::AppError;
use crate::handlers::auth::get_user_id_from_cookies;
diff --git a/src/handlers/tag.rs b/src/handlers/tag.rs
@@ -6,7 +6,7 @@ use axum::{
use axum_extra::extract::cookie::CookieJar;
use serde::Deserialize;
-use crate::db::{Category, StoryWithMeta};
+use crate::database::{Category, StoryWithMeta};
use crate::database::{self, TARGET_TYPE_STORY};
use crate::error::AppError;
use crate::handlers::auth::get_user_id_from_cookies;
diff --git a/src/handlers/user.rs b/src/handlers/user.rs
@@ -6,7 +6,7 @@ use axum::{
use axum_extra::extract::cookie::CookieJar;
use serde::Deserialize;
-use crate::db::{CommentWithMeta, StoryWithMeta, UserProfile};
+use crate::database::{CommentWithMeta, StoryWithMeta, UserProfile};
use crate::database::{self, TARGET_TYPE_STORY};
use crate::error::AppError;
use crate::handlers::auth::get_user_id_from_cookies;
diff --git a/src/main.rs b/src/main.rs
@@ -1,7 +1,6 @@
mod auth;
mod config;
mod database;
-mod db;
mod error;
mod handlers;
mod migrations;
diff --git a/src/templates.rs b/src/templates.rs
@@ -1,6 +1,6 @@
use askama::Template;
-use crate::db::{Category, CommentWithMeta, StoryWithMeta, UserProfile};
+use crate::database::{Category, CommentWithMeta, StoryWithMeta, UserProfile};
use crate::database::SearchResult;
#[derive(Template)]