124 lines
3.6 KiB
Markdown
124 lines
3.6 KiB
Markdown
# 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<Mutex<Connection>>`.
|
|
- 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<T, E>` for explicit error handling.
|
|
- `?` operator to propagate errors.
|
|
- `Arc<Mutex<_>>` 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.
|