130 lines
4.6 KiB
Markdown
130 lines
4.6 KiB
Markdown
# AGENTS.md
|
|
|
|
## Development Commands
|
|
|
|
```bash
|
|
# Dev server — runs tailwindcss watch + dx serve (needs PostgreSQL running)
|
|
make dev
|
|
|
|
# Production build — builds editor, compiles CSS, then dx build --release
|
|
make build
|
|
|
|
# Just CSS
|
|
make css # one-shot
|
|
make css-watch # watch mode
|
|
|
|
# Rust only (no CSS/editor)
|
|
cargo build
|
|
cargo clippy
|
|
cargo test
|
|
dx check # Dioxus type-check
|
|
dx serve # Dev server without Tailwind watch
|
|
```
|
|
|
|
**Command order matters for production**: `make build` internally runs `build-editor` → `tailwindcss` → `dx build --release`. Do not run `dx build --release` alone if you need the editor or CSS.
|
|
|
|
## Prerequisites
|
|
|
|
- Rust 1.95+ with `wasm32-unknown-unknown` target
|
|
- `dx` CLI (`cargo install dioxus-cli`)
|
|
- `tailwindcss` CLI v4 (standalone binary)
|
|
- PostgreSQL running locally
|
|
|
|
## Environment
|
|
|
|
Create `.env` (not committed — see `.env.example`):
|
|
|
|
```
|
|
DATABASE_URL=postgres://postgres:postgres@localhost:5432/yggdrasil
|
|
RUST_LOG=info
|
|
```
|
|
|
|
Run migrations before first dev server start:
|
|
|
|
```bash
|
|
psql $DATABASE_URL -f migrations/001_init.sql
|
|
```
|
|
|
|
## Architecture: Conditional Compilation
|
|
|
|
This is a Dioxus 0.7 fullstack project with **two independent gates**. Getting this wrong is the most common source of compilation errors.
|
|
|
|
| Gate | Applies to | Used for |
|
|
|------|-----------|----------|
|
|
| `#[cfg(feature = "server")]` | Server binary only | Database, env loading, background tasks, server functions body |
|
|
| `#[cfg(target_arch = "wasm32")]` | WASM frontend only | localStorage, DOM APIs, cookie manipulation, web_sys calls |
|
|
|
|
**Critical**: `feature = "server"` and `target_arch = "wasm32"` are **mutually exclusive** at build time, but both default features (`web` + `server`) are enabled in `Cargo.toml`. The `dx` CLI handles feature selection during builds.
|
|
|
|
**Stub pattern**: `src/db/mod.rs` provides a `DummyPool` when the `server` feature is disabled so the crate still compiles for WASM. Do not remove this.
|
|
|
|
**Dead code allowances**: Auth utilities (`password.rs`, `session.rs`) carry `#[allow(dead_code)]` because they are imported by `api/auth.rs` but the compiler sees them as unused in WASM builds where server function bodies are stripped.
|
|
|
|
## Server Functions
|
|
|
|
Server functions live in `src/api/auth.rs` and use the macro:
|
|
|
|
```rust
|
|
#[server(Name, "/api")]
|
|
pub async fn fn_name(...) -> Result<..., ServerFnError>
|
|
```
|
|
|
|
These are callable from both client and server Rust code; Dioxus handles HTTP transport automatically.
|
|
|
|
## Tiptap Editor Subproject
|
|
|
|
The rich-text editor is a separate Vite project in `libs/tiptap-editor/`.
|
|
|
|
- Built as an **IIFE** library exposing `window.TiptapEditor`
|
|
- Output goes to `public/tiptap/`
|
|
- `make build` runs `npm install && vite build` inside `libs/tiptap-editor` and renames the output file
|
|
- The write page (`src/pages/admin/write.rs`) initializes the editor via `js_sys::eval` and polls `window.__tiptap_ready`
|
|
|
|
Do not edit files in `public/tiptap/` directly — they are build artifacts.
|
|
|
|
## Auth & Session
|
|
|
|
- **Registration**: first user becomes `admin`; subsequent registrations are rejected with `"Registration is closed"`.
|
|
- **Login**: sets an **HttpOnly** cookie via `FullstackContext::add_response_header` (server-side).
|
|
- **Session validation**: `get_current_user` reads the `session` cookie from the request headers and queries `sessions` + `users` tables.
|
|
- **Background cleanup**: `tasks::session_cleanup::run_cleanup()` deletes expired sessions every hour on a tokio task.
|
|
|
|
## Database
|
|
|
|
- PostgreSQL via `tokio-postgres` + `deadpool-postgres`
|
|
- Pool is a `LazyLock` global in `src/db/pool.rs`, initialized from `DATABASE_URL`
|
|
- Max pool size: 10
|
|
|
|
## Testing & Verification
|
|
|
|
```bash
|
|
# Standard Rust test suite
|
|
cargo test
|
|
|
|
# Dioxus type-check (catches component/Router issues)
|
|
dx check
|
|
|
|
# Lint
|
|
cargo clippy
|
|
```
|
|
|
|
There are currently no integration tests requiring a database connection.
|
|
|
|
## Build Artifacts to Ignore
|
|
|
|
The following are generated and gitignored:
|
|
|
|
- `public/style.css` — generated by Tailwind
|
|
- `public/tiptap/` — generated by Vite from `libs/tiptap-editor/`
|
|
- `/dist`, `/.dioxus`, `/target`
|
|
- `node_modules` (inside `libs/tiptap-editor/`)
|
|
|
|
## rust-analyzer
|
|
|
|
`rust-analyzer.toml` excludes generated directories (`node_modules`, `public`, `.dioxus`, `.omc`, `dist`). If rust-analyzer shows spurious errors in generated files, check that the exclusion list is respected by your editor.
|
|
|
|
## Notes
|
|
|
|
- `rand` + `getrandom` with `js` feature are required for Argon2 salt generation in WASM builds.
|
|
- The `#[allow(unused_mut, unused_variables)]` on `Write` component is intentional — the `mut` signals are used inside `#[cfg(target_arch = "wasm32")]` blocks that are stripped in server builds.
|