https://github.com/charlieroth/capsule
Read later web service
https://github.com/charlieroth/capsule
Last synced: 10 months ago
JSON representation
Read later web service
- Host: GitHub
- URL: https://github.com/charlieroth/capsule
- Owner: charlieroth
- License: mit
- Created: 2025-08-19T11:23:46.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-08-29T06:32:59.000Z (11 months ago)
- Last Synced: 2025-09-22T13:02:28.463Z (10 months ago)
- Language: Rust
- Size: 228 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 26
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# capsule
[](https://github.com/charlieroth/capsule/actions/workflows/ci.yml)
A pragmatic "read later" service built in Rust to explore production-grade web service patterns:
- Authentication
- Background jobs
- Full‑text search
- Observability
- Robust operations
## Features (Planned / In Progress)
- REST API with generated OpenAPI docs (axum + utoipa)
- User authentication (argon2 password hashes + JWT)
- Background fetch & extract pipeline (reqwest + scraper)
- Full‑text search (tantivy)
- Structured logging & tracing (tracing) + metrics (future Prometheus endpoint)
- Database persistence (PostgreSQL via sqlx; async, compile‑time checked queries when `make prepare` is run)
- Schema documentation / ERD via SchemaSpy (`make erd` -> `./erd/index.html`)
## Architecture Overview
High-level flow:
1. Client creates an item (URL + metadata)
2. A background task fetches & normalizes HTML, stores text content
3. Indexer updates tantivy with (title + site + tags + text)
4. Search endpoint returns ranked results with snippets
## Repository Layout
```
src/
bin/
api.rs # HTTP server entrypoint
migrate.rs # One-shot migration runner (used in Docker / local)
lib.rs # (future) shared library code
migrations/ # sqlx migrations (*.up.sql / *.down.sql)
Makefile # Developer workflow commands
Dockerfile # Multi-stage container build (api + migrate)
docker-compose.yml# Postgres + migrate + api + schemaspy services
scripts/db-health.sh # Wait/health checks for Postgres
erd/ # Generated SchemaSpy output (HTML + diagrams)
docs/PROJECT.md # Vision, roadmap, non-functional goals
```
## Quick Start (Local Dev)
Pre-requisites:
- Rust (see `rust-toolchain.toml`)
- Docker (for Postgres + ERD generation)
- Run `make install-tools`
Steps:
```bash
# 1. Start Postgres
make db-up
# 2. Run migrations
make db-migrate
# 3. Launch the API (defaults to 0.0.0.0:8080 via Config)
make dev
# 4. Hit the root endpoint
curl -s localhost:8080/
```
Expected response: `Hello from capsule!`
Tear down:
```bash
make db-down
```
Full reset (drops volume):
```bash
make db-reset
```
## Configuration
`Config::from_env()` (see `config/mod.rs`) loads environment variables. Key variable:
- `DATABASE_URL` (required for API & migrations) e.g. `postgres://capsule:capsule_password@localhost:5432/capsule_dev`
Additional configuration knobs (future): bind address, logging level, JWT secrets, rate limits.
## Database & Migrations
Migrations live in `migrations/` and are executed by either:
- `make db-migrate` (sqlx-cli) OR
- The `capsule-migrate` binary (used in `docker-compose.yml` as the `migrate` service)
Generate / update sqlx offline metadata (speeds up compile-time query checking):
```bash
make prepare
```
Check database health:
```bash
make db-health # exit 0 if healthy
make db-wait # block until healthy (used in CI / scripts)
```
Open a psql-like shell (requires `pgcli` installed):
```bash
make pgcli
```
## Schema / ERD Docs
Generate ERD & HTML docs (writes into `./erd`):
```bash
make erd
open erd/index.html # macOS
```
## Docker / Compose
Build & run everything (Postgres + migrations + API):
```bash
docker compose up --build api
```
Services:
- `postgres` (port 5432)
- `migrate` (runs once; executes migrations then exits)
- `api` (exposes port 8080)
- `schemaspy` (on-demand ERD generation: `make erd`)
Environment is baked with `DATABASE_URL` pointing at the compose network host.
## Makefile Cheat Sheet
| Target | Purpose |
| ------------ | -------------------------------- |
| `dev` | Run API locally (debug) |
| `fmt` | Format sources |
| `lint` | Clippy (deny warnings) |
| `test` | Run tests |
| `audit` | Security audit (cargo-audit) |
| `deny` | Dependency policy (cargo-deny) |
| `check` | fmt + lint + test + audit + deny |
| `db-up` | Start Postgres via Docker |
| `db-down` | Stop Postgres |
| `db-migrate` | Apply migrations |
| `db-reset` | Drop volume & reinit DB |
| `db-health` | Health probe (fast) |
| `db-wait` | Wait until healthy |
| `db-logs` | Tail Postgres logs |
| `prepare` | sqlx offline metadata |
| `erd` | Generate ERD docs |
Install tooling once:
```bash
make install-tools
```
## Testing Strategy (Planned)
- Unit tests for parsing, auth, extraction
- Integration tests exercising HTTP routes & DB side-effects
- Property tests (URL normalization; idempotent job enqueue)
- Fuzzing extractor inputs
Run tests:
```bash
make test
```