diff --git a/README.md b/README.md index 83564c1..18138c8 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,14 @@ A self-hosted microblogging server with full ActivityPub federation. Write short - JWT authentication (Bearer token) with API key support for third-party clients - OpenAPI documentation at `/docs` (Swagger UI) and `/scalar` (Scalar) - Full-text search over thoughts and users via PostgreSQL trigram indexes -- Top friends — pin up to 5 users as highlighted contacts +- **Profile fields** — up to 4 custom key/value fields (Website, Pronouns, etc.), federated as AP `PropertyValue` attachment +- **Custom CSS** — per-user stylesheet applied to their profile page +- **Visibility levels** — public, followers-only, unlisted, and direct posts +- **Content warnings** — optional CW label and sensitive flag on posts +- **Feed controls** — sort by newest, oldest, most liked, most boosted, or most discussed; filter to originals only, replies only, local only, or hide sensitive +- **Popular tags** — trending hashtag discovery +- Top friends — pin up to 8 users as highlighted contacts +- Account migration — set `alsoKnownAs` for Fediverse actor moves - Home feed, public feed, and per-user thought timelines - Rate limiting and registration control @@ -108,7 +115,7 @@ Copy `.env.example` to `.env` and fill in your values. | Variable | Default | Description | |---|---|---| | `HOST` | `0.0.0.0` | Interface to bind | -| `PORT` | `3000` | Port to listen on | +| `PORT` | `8000` | Port to listen on | | `NATS_URL` | — | NATS connection string. If unset, a no-op publisher is used and events are not delivered to the worker | | `CORS_ORIGINS` | `*` | Comma-separated allowed origins for CORS, e.g. `https://app.example.com` | | `RATE_LIMIT` | disabled | Max requests per minute per IP | @@ -201,18 +208,7 @@ Interactive API documentation is available at runtime: ## Frontend -The Next.js frontend lives in `thoughts-frontend/`. It requires two environment variables: - -```env -NEXT_PUBLIC_API_URL=http://localhost:8000 # client-side requests -NEXT_PUBLIC_SERVER_SIDE_API_URL=http://localhost:8000 # SSR requests -``` - -```bash -cd thoughts-frontend -bun install -bun run dev # http://localhost:3000 -``` +The Next.js frontend lives in `thoughts-frontend/`. See [Frontend environment](#frontend-environment) for required env vars, or follow the [local development](#local-development-recommended) steps above. ## Docker @@ -270,7 +266,7 @@ Services: Contributions are welcome. A few guidelines: -- **Run tests before opening a PR.** At minimum: `cargo test -p application` (no database needed). For adapter changes: `cargo test --workspace` with a live database. +- **Run tests before opening a PR.** At minimum: `make test-unit` (no database needed). For adapter changes: `make test-integration` with a live database. `make check` runs the full suite (fmt + clippy + tests). - **Keep the hexagonal boundary.** `domain` and `application` must not import any adapter crate. Use `&dyn Port` traits for all I/O. - **No ORM.** The project uses raw `sqlx`. Keep it that way. - **ActivityPub changes** — test against a live Mastodon instance if possible, or use the AP debug logs (`RUST_ENV=development`). diff --git a/crates/bootstrap/src/config.rs b/crates/bootstrap/src/config.rs index 8991cf1..d96d49e 100644 --- a/crates/bootstrap/src/config.rs +++ b/crates/bootstrap/src/config.rs @@ -31,12 +31,12 @@ impl Config { Self { database_url: std::env::var("DATABASE_URL").expect("DATABASE_URL is required"), jwt_secret: std::env::var("JWT_SECRET").expect("JWT_SECRET is required"), - base_url: std::env::var("BASE_URL").unwrap_or_else(|_| "http://localhost:3000".into()), + base_url: std::env::var("BASE_URL").unwrap_or_else(|_| "http://localhost:8000".into()), nats_url: std::env::var("NATS_URL").ok(), port: std::env::var("PORT") .ok() .and_then(|p| p.parse().ok()) - .unwrap_or(3000), + .unwrap_or(8000), allow_registration: std::env::var("ALLOW_REGISTRATION") .map(|v| v == "true") .unwrap_or(true),