添加 AGENTS.md 项目开发指南文档

This commit is contained in:
xfy 2026-06-01 16:55:19 +08:00
parent a58e0f4e3b
commit e48253c6f7

129
AGENTS.md Normal file
View File

@ -0,0 +1,129 @@
# 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.