85 lines
3.0 KiB
Markdown
85 lines
3.0 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
# Build
|
|
cargo build
|
|
cargo build --release
|
|
|
|
# Run (requires config.toml or APP__ env vars)
|
|
cargo run
|
|
|
|
# Check without building
|
|
cargo check
|
|
|
|
# Run tests
|
|
cargo test
|
|
|
|
# Run a single test
|
|
cargo test <test_name>
|
|
|
|
# Lint
|
|
cargo clippy
|
|
|
|
# Format
|
|
cargo fmt
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Copy `config.example.toml` to `config.toml` and fill in the values. All config fields can be overridden with `APP__` prefixed environment variables using `__` as separator (e.g. `APP__DATABASE__URL`, `APP__S3__BUCKET`).
|
|
|
|
Supports both SQLite (`sqlite://mikebase.db`) and PostgreSQL (`postgresql://user:pass@host/db`) via `sqlx::AnyPool`.
|
|
|
|
## Architecture
|
|
|
|
The app is an Axum HTTP server with shared state (`AppState`) containing two components:
|
|
- **`Database`** (`src/db.rs`): Thin wrapper around `sqlx::AnyPool` supporting SQLite and PostgreSQL. Runs migrations from `migrations/` on startup. All timestamps are stored as ISO 8601 strings (not native DB types) because `sqlx::Any` lacks a blanket chrono `Encode`/`Decode` impl.
|
|
- **`S3Storage`** (`src/storage.rs`): AWS SDK S3 client pointed at a configurable endpoint (Wasabi by default). Images are uploaded under the key `emoji/<filename>` and public URLs are built from the configured `public_url` base.
|
|
|
|
**Data flow for emote creation:** multipart form → upload bytes to S3 → insert row into DB → return `EmoteResponse` JSON.
|
|
|
|
**Models** (`src/models.rs`):
|
|
- `EmoteRow` — raw DB row (timestamps as strings)
|
|
- `EmoteResponse` — JSON API response (timestamps as `DateTime<Utc>`)
|
|
|
|
**Routes** (`src/routes/`):
|
|
- `GET /` — health check
|
|
- `GET /version` — git commit hash and tag (baked in at build time via `build.rs`)
|
|
- `GET /json` — list all emotes
|
|
- `POST /emotes` — create emote (multipart: `name`, `alias?`, `file`)
|
|
- `PUT /emotes/{uuid}` — update emote metadata (JSON: `name?`, `alias?`, `image_key?`)
|
|
- `DELETE /emotes/{uuid}` — delete emote from DB and S3 (S3 delete is best-effort)
|
|
|
|
## Releases
|
|
|
|
Pushing a `v*` tag triggers the Gitea Actions release workflow, which builds a
|
|
Linux binary, uploads it to a Gitea Release, and pushes a Docker image to the
|
|
Gitea container registry.
|
|
|
|
### Cutting a release
|
|
|
|
1. Move the `[Unreleased]` entries in `CHANGELOG.md` to a new versioned section:
|
|
```markdown
|
|
## [0.x.y] - YYYY-MM-DD
|
|
```
|
|
2. Add a new empty `## [Unreleased]` section at the top.
|
|
3. Update the comparison links at the bottom of `CHANGELOG.md`:
|
|
- Change the `[Unreleased]` link to compare the new tag against `HEAD`.
|
|
- Add a new link for the new version comparing it against the previous tag.
|
|
4. Commit: `git commit -m "Release v0.x.y"`
|
|
5. Tag and push:
|
|
```bash
|
|
git tag v0.x.y
|
|
git push origin main v0.x.y
|
|
```
|
|
|
|
### Changelog conventions
|
|
|
|
`CHANGELOG.md` follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
Group entries under: `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`, `Security`.
|
|
Record notable changes in `[Unreleased]` as you make them, not only at release time.
|