# AGENTS.md

## Cursor Cloud specific instructions

### Architecture
Rust library crate (`athena-auth`) with a **`server` binary** (`cargo run --bin server --features server`) using Axum 0.8 + PostgreSQL 16. Static files are served at **`/admin/`** (interactive API docs: **`/admin/docs.html`**; optional bootstrap **`GET /admin/api-config.json`** uses `BASE_URL`, **`DOCS_API_ORIGIN`**, and `AUTH_BASE_PATH`). Workspace members: `crates/core`, `crates/api`, `crates/derive`.

### Prerequisites
- **Rust**: ≥ 1.93.1 (edition 2024). Use `rustup update stable`.
- **Docker**: Required for PostgreSQL. The nested Docker-in-Docker environment needs `fuse-overlayfs` and `iptables-legacy` configured (see daemon.json and update-alternatives).
- **libssl-dev / pkg-config**: Required for Rust crypto crate compilation.

### Running Services
1. **PostgreSQL**: `docker compose up -d postgres` (from repo root). Healthcheck is configured; wait for healthy before starting the app.
2. **athena-auth API**: `cargo run --bin server --features server` from repo root (listens on `HOST`/`PORT`, default `0.0.0.0:3000`). Requires `.env` — copy from `.env.example` and set `DATABASE_URL` (e.g. `postgresql://postgres:postgres@localhost:5432/athena_auth`), `JWT_SECRET` (at least 32 characters), and optionally `BASE_URL`, `AUTH_BASE_PATH`, `TRUSTED_ORIGINS`, and Passkey-related variables (see `.env.example`).

### Lint / Test / Build
- `cargo fmt --check` — formatting (note: existing code has formatting diffs)
- `cargo clippy` — lints
- `cargo test` — Rust unit/integration suites in `src/tests` and `tests/`
- `cargo test --test compat_endpoint_tests -- --nocapture` — entry point for split compatibility suites (see `compat-tests/README.md`)
- `cargo build` — dev build
- `cargo build --bin server --features server` — HTTP server binary

### athena_rs UUID/Timestamp Gotcha
The `athena_rs` library returns PostgreSQL UUID and TIMESTAMPTZ columns as the literal string `"<binary>"`. All SELECT queries must cast these columns to text (e.g. `id::text as id`, `created_at::text as created_at`). Helper functions in `src/utils/db.rs` handle parsing the resulting text back into `Uuid` and `DateTime<Utc>`. PostgreSQL text-format timestamps use the format `%Y-%m-%d %H:%M:%S%.f%#z` (space separator, short timezone offset), not RFC 3339.

## Learned User Preferences
- For Rust in Cursor/VS Code, moving a fully qualified path into a top-level `use` is rust-analyzer's "Replace qualified path with use" quick fix (caret on the path, then Ctrl+.); it is not applied automatically on save by `organizeImports` or `source.fixAll.rust-analyzer`.

## Learned Workspace Facts
- The repo’s `.vscode/settings.json` turns on Rust format-on-save, `source.organizeImports`, `source.fixAll.rust-analyzer`, and `rust-analyzer.completion.autoimport.enable` for smoother imports.
- Curl and HTTP samples under `examples/` target Better Auth–style routes under the configured auth base path (default `/api/auth` via helpers like `ATHENA_AUTH_BASE`); prefer `better-auth.yaml`, compat tests, and plugin registrations over root `openapi.yaml` when paths disagree.
