Files
movies-diary/CONTRIBUTING.md
Gabriel Kaszewski 70b3ca0f5c
Some checks failed
CI / Check / Test (push) Failing after 47s
refactor: split domain models, move presentation logic out of app layer
Split domain/models/mod.rs (630 lines) into focused files:
movie.rs, review.rs, user.rs, stats.rs, enrichment.rs, feed.rs.

Move URL/date formatting from application use cases to
presentation mappers — use cases now return raw domain data.

Delete watchlist/get_page.rs (was pure presentation logic),
replace with presentation/mappers/watchlist.rs.

Document signature conventions in CONTRIBUTING.md.
2026-06-09 02:29:11 +02:00

3.4 KiB

Contributing

Thanks for your interest in Movies Diary! This is a personal project but contributions are welcome — bug fixes, new features, docs improvements, or picking up the deprecated TUI.

Getting started

  1. Fork and clone the repo
  2. Copy .env.example to .env and fill in at least JWT_SECRET and OMDB_API_KEY
  3. Install Rust (stable, 2024 edition) and Bun (for the SPA)
  4. Run the backend and worker:
cargo run -p presentation   # HTTP server on :3000
cargo run -p worker          # event worker (separate terminal)
  1. Run the SPA dev server:
cd spa && bun install && bun run dev

Before submitting a PR

make           # runs fmt-check + clippy + test

Or individually:

cargo fmt --check
cargo clippy -- -D warnings
cargo test
cd spa && bunx tsc --noEmit

All four must pass. PRs with clippy warnings or failing tests won't be merged.

Architecture

The project follows hexagonal (ports & adapters) architecture. See architecture.mmd for the full diagram.

Key rules:

  • Presentation handlers never touch repositories directly — all domain logic goes through use cases in the application crate
  • Application use cases return raw domain data — URL formatting, date display, and view model assembly belong in presentation mappers (presentation/src/mappers/)
  • Use cases called from presentation handlers take &AppContext. Functions called from adapter event handlers take individual Arc<dyn Trait> params to keep adapter dependencies explicit
domain         → pure types, traits (ports), zero deps
application    → use cases, orchestration
presentation   → Axum handlers, routes, OpenAPI
worker         → event consumer, background jobs
adapters/*     → implements domain ports (sqlite, postgres, AP, etc.)
spa/           → React SPA (TanStack Router + shadcn/ui)

Adding a new feature

  1. Domain first — models in domain/src/models/, ports in ports.rs, events in events.rs
  2. Adapters — implement ports in both sqlite and postgres adapters, add migration
  3. Application — use cases in application/src/<domain>/, wire into context.rs
  4. API types — DTOs in api-types/src/
  5. Presentation — handler file in handlers/<domain>.rs, routes in routes.rs
  6. SPA — API client in spa/src/lib/api/, hook in spa/src/hooks/, components
  7. Classic HTML — Askama template + CSS in static/style.css

Database adapters

Both SQLite and PostgreSQL are supported. If you add a migration or repository, implement it for both. The postgres adapter uses $1, $2 params and TIMESTAMPTZ; SQLite uses ? and text datetimes.

Federation (ActivityPub)

Federation is feature-gated (#[cfg(feature = "federation")]). If your feature should federate, add domain events, handle them in activitypub/src/event_handler.rs, and create an AP object + inbound handler.

Code style

  • No comments unless the why is non-obvious
  • Concise commit messages
  • One feature per PR — don't bundle unrelated changes
  • Follow existing patterns (check a similar feature for reference)

Areas seeking help

  • TUI (crates/tui) — deprecated, needs a maintainer to bring it up to feature parity
  • Tests — the domain and application crates have 400+ unit tests; integration tests for the presentation layer are welcome
  • Docs — API usage examples, deployment guides