feat: update README with enhanced feature descriptions and API documentation
This commit is contained in:
88
README.md
88
README.md
@@ -1,33 +1,44 @@
|
|||||||
# Movies Diary
|
# Movies Diary
|
||||||
|
|
||||||
A self-hosted, server-side rendered movie logging system. Built in Rust — no JavaScript, no SPA, just HTML forms and an RSS feed. Designed to run as a lightweight widget embedded on a personal site.
|
A self-hosted, server-side rendered movie logging system with a full REST API. Built in Rust — no JavaScript in the HTML interface, just HTML forms and an RSS feed. Designed to run as a lightweight widget embedded on a personal site or as a backend for third-party clients.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Log movies with a TMDB/OMDb ID and a 0–5 rating
|
- Log movies with a TMDB/OMDb ID or manual title/year/director, with a 0–5 rating
|
||||||
- Immutable append-only viewing ledger (tracks re-watches)
|
- Immutable append-only viewing ledger (tracks re-watches)
|
||||||
- Background poster fetching and storage (local filesystem or S3-compatible)
|
- Background poster fetching and storage (local filesystem or S3-compatible)
|
||||||
- RSS/Atom feed for public subscription
|
- RSS/Atom feed for public subscription (global and per-user)
|
||||||
- JWT authentication via cookie (HTML) or Bearer token (REST API)
|
- JWT authentication via cookie (HTML) or Bearer token (REST API)
|
||||||
- Zero JavaScript
|
- ActivityPub federation — follow/unfollow remote users on any compatible server, accept/reject/remove followers, pending follow request management
|
||||||
|
- CSV and JSON diary export (full round-trip: exported files can be re-imported via the TUI bulk import)
|
||||||
|
- REST API v1 (`/api/v1/`) with full feature parity with the HTML interface
|
||||||
|
- OpenAPI documentation at `/docs` (Swagger UI) and `/scalar` (Scalar)
|
||||||
|
- CSRF protection on all HTML form routes (double-submit cookie, defense-in-depth on top of `SameSite=Strict`)
|
||||||
|
- Per-IP rate limiting via token bucket (production-grade, backed by `axum-governor`)
|
||||||
|
- Terminal UI client (`crates/tui`) for logging reviews, bulk CSV import, and diary browsing
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
Hexagonal (Ports & Adapters) with Domain-Driven Design:
|
Hexagonal (Ports & Adapters) with Domain-Driven Design:
|
||||||
|
|
||||||
```
|
```
|
||||||
domain — pure types and trait definitions, no external deps
|
domain — pure types and trait definitions, no external deps
|
||||||
application — use cases / business logic orchestration
|
application — use cases / business logic orchestration
|
||||||
presentation — Axum HTTP router, wires all adapters together
|
presentation — Axum HTTP router, wires all adapters together
|
||||||
adapters/
|
adapters/
|
||||||
auth — JWT issuance and validation (Argon2 passwords)
|
auth — JWT issuance and validation (Argon2 passwords)
|
||||||
sqlite — SQLite repository via sqlx
|
sqlite — SQLite repository via sqlx
|
||||||
metadata — OMDb HTTP client
|
metadata — OMDb HTTP client
|
||||||
poster-fetcher — downloads poster images
|
poster-fetcher — downloads poster images
|
||||||
poster-storage — uploads posters to local filesystem or S3-compatible storage
|
poster-storage — uploads posters to local filesystem or S3-compatible storage
|
||||||
template-askama — Askama HTML rendering
|
template-askama — Askama HTML rendering
|
||||||
rss — RSS/Atom feed generation
|
rss — RSS/Atom feed generation
|
||||||
event-publisher — async event channel for background poster sync
|
export — CSV and JSON diary serialization
|
||||||
|
event-publisher — async event channel for background poster sync
|
||||||
|
activitypub — ActivityPub federation (follow, inbox/outbox, actor)
|
||||||
|
activitypub-base — core ActivityPub types and repository traits
|
||||||
|
doc — OpenAPI spec assembly and Swagger UI / Scalar serving
|
||||||
|
tui — terminal UI client (ratatui)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
@@ -39,7 +50,7 @@ adapters/
|
|||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
A `.env.example` file is provided at the repo root — copy it to `.env` and fill in your values. Key variables:
|
A `.env.example` file is provided at the repo root — copy it to `.env` and fill in your values.
|
||||||
|
|
||||||
```env
|
```env
|
||||||
# Database
|
# Database
|
||||||
@@ -51,6 +62,9 @@ JWT_SECRET=change-me
|
|||||||
# OMDb metadata
|
# OMDb metadata
|
||||||
OMDB_API_KEY=your-key
|
OMDB_API_KEY=your-key
|
||||||
|
|
||||||
|
# Public base URL (used for ActivityPub actor URLs and canonical links)
|
||||||
|
BASE_URL=https://yourdomain.example.com
|
||||||
|
|
||||||
# Poster storage — pick one backend:
|
# Poster storage — pick one backend:
|
||||||
|
|
||||||
# Option A: local filesystem (zero deps)
|
# Option A: local filesystem (zero deps)
|
||||||
@@ -64,9 +78,15 @@ POSTER_STORAGE_PATH=./posters
|
|||||||
# MINIO_REGION=minio
|
# MINIO_REGION=minio
|
||||||
# MINIO_ACCESS_KEY_ID=minioadmin
|
# MINIO_ACCESS_KEY_ID=minioadmin
|
||||||
# MINIO_SECRET_ACCESS_KEY=minioadmin
|
# MINIO_SECRET_ACCESS_KEY=minioadmin
|
||||||
```
|
|
||||||
|
|
||||||
See `.env.example` for optional variables (rate limiting, logging, host/port, etc.).
|
# Optional
|
||||||
|
HOST=0.0.0.0
|
||||||
|
PORT=3000
|
||||||
|
RATE_LIMIT=60 # requests per minute per IP (default: 60)
|
||||||
|
ALLOW_REGISTRATION=true # set to false to disable new sign-ups
|
||||||
|
SECURE_COOKIES=true # set when serving over HTTPS
|
||||||
|
RUST_LOG=presentation=info,tower_http=info
|
||||||
|
```
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
@@ -74,7 +94,24 @@ See `.env.example` for optional variables (rate limiting, logging, host/port, et
|
|||||||
cargo run -p presentation
|
cargo run -p presentation
|
||||||
```
|
```
|
||||||
|
|
||||||
Server listens on `0.0.0.0:3000`.
|
Server listens on `0.0.0.0:3000` by default.
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
All REST endpoints are under `/api/v1/`. Authentication uses `Authorization: Bearer <token>` obtained from `POST /api/v1/auth/login`.
|
||||||
|
|
||||||
|
Interactive API documentation is available at runtime:
|
||||||
|
|
||||||
|
- **Swagger UI** — `http://localhost:3000/docs`
|
||||||
|
- **Scalar** — `http://localhost:3000/scalar`
|
||||||
|
|
||||||
|
## Terminal UI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run -p tui
|
||||||
|
```
|
||||||
|
|
||||||
|
Supports review logging, bulk CSV import (column order matches the export format), and diary browsing with review history.
|
||||||
|
|
||||||
## Test
|
## Test
|
||||||
|
|
||||||
@@ -82,6 +119,19 @@ Server listens on `0.0.0.0:3000`.
|
|||||||
cargo test
|
cargo test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t movies-diary .
|
||||||
|
docker run -p 3000:3000 \
|
||||||
|
-e DATABASE_URL=sqlite:///data/movies.db \
|
||||||
|
-e JWT_SECRET=change-me \
|
||||||
|
-e OMDB_API_KEY=your-key \
|
||||||
|
-e BASE_URL=https://yourdomain.example.com \
|
||||||
|
-v $(pwd)/data:/data \
|
||||||
|
movies-diary
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT License. See [LICENSE](LICENSE).
|
MIT License. See [LICENSE](LICENSE).
|
||||||
|
|||||||
Reference in New Issue
Block a user