# CurseTechnique Codebase Walkthrough This document is a practical map of the app, aimed at learning-oriented Rust reading. ## 1. High-level architecture The app uses a lightweight 4-layer layout: 1. `src/main.rs` - startup and route wiring 2. `src/handlers.rs` - HTTP handlers and input validation 3. `src/db.rs` - SQLite queries and data structs 4. `src/views.rs` - HTML rendering (server-side string rendering) The goal is to keep each file focused and easy to read without adding extra frameworks. ## 2. Request flow (end-to-end) Example: open `GET /day/2026-02-07` 1. Route is defined in `src/main.rs` and points to `handlers::show_day_entries`. 2. `show_day_entries` in `src/handlers.rs` validates the date path param. 3. It calls `db::fetch_day_entries` in `src/db.rs` to load rows from SQLite. 4. It passes those rows to `views::render_day_page` in `src/views.rs`. 5. The rendered HTML is returned to the browser. Example: submit add-entry form `POST /day/{date}/add` 1. Route points to `handlers::create_entry`. 2. Handler validates date and form fields (`name`, `calories`). 3. Handler calls `db::insert_entry`. 4. Handler redirects back to `/day/{date}`. ## 3. File-by-file reading guide ## `src/main.rs` Read this file first. It is intentionally small. - Creates data directory and opens SQLite DB. - Calls DB init/seed helpers. - Builds Axum router. - Starts Tokio TCP listener. If you ever wonder "where is this endpoint connected?", this file is the source of truth. ## `src/handlers.rs` This is the HTTP boundary. Core concepts here: - `AppState` holds shared DB connection behind `Arc>`. - Each handler receives typed route/form data. - Handlers do three steps: 1. Validate input 2. Call DB function 3. Return HTML or redirect Useful helper functions: - `validate_date` ensures `YYYY-MM-DD` format. - `parse_entry_form_fields` validates `name` + `calories`. - `month_bounds` computes first/next month boundaries. ## `src/db.rs` This file contains all SQL. Data structs: - `FoodEntry` represents one row. - `DaySummary` represents aggregated values for calendar cards. Functions are split by intent: - Setup: `init_db`, `seed_db_if_empty` - Reads: `fetch_month_summaries`, `fetch_day_entries` - Writes: `insert_entry`, `update_entry`, `delete_entry` If behavior looks wrong (totals, filtering, ordering), start debugging here. ## `src/views.rs` This file builds HTML strings for SSR. - `render_calendar_page` renders `/`. - `render_day_page` renders `/day/{date}`. - Small helpers reduce clutter: - `render_day_card` - `render_entry_rows` - `entry_count_label` - `escape_html` Important: `escape_html` is used when rendering user-provided food names. ## 4. Key Rust patterns used - `Result` for explicit error handling. - `?` operator to propagate errors. - `Arc>` for shared mutable state across async handlers. - Simple structs over tuple-heavy values for readability (`DaySummary`). - Module organization (`mod db; mod handlers; mod views;`) to keep files focused. ## 5. How to add a feature safely Use this checklist: 1. Add/adjust SQL function in `db.rs`. 2. Add or update handler logic in `handlers.rs`. 3. Update route wiring in `main.rs` if endpoint path changes. 4. Update HTML output/forms in `views.rs`. 5. Run: - `cargo fmt` - `cargo check` ## 6. Suggested beginner exercises 1. Add a "notes" text column to food entries. 2. Show count of entries in the day header. 3. Add confirmation step on delete (simple query param or separate page). 4. Add a helper in handlers to prevent editing future dates. These exercises touch all 4 layers and are great practice for understanding the whole flow.