xConfess is a monorepo for an anonymous confession platform built with NestJS, Next.js 16, PostgreSQL, Redis-backed queues, WebSockets, and Soroban smart contracts on Stellar.
xconfess-backend: API, auth, moderation, notifications, data export, and Stellar integrationxconfess-frontend: App Router UI, cookie-backed auth/session handling, proxy routes, and admin surfacesxconfess-contracts: Soroban Rust workspace for confession anchoring, tipping, and reputation-related contractscompose.yaml: local Postgres and Redis stack for development
- anonymous confession feed and composer
- reactions, comments, and private messaging
- admin moderation, reports, analytics, and user management
- privacy settings, notifications, and profile flows
- Stellar anchoring, tipping, and contract invocation tooling
- audit logging and data export
- The frontend does not use NextAuth.
- Auth is cookie/session based, with a dev-only bypass flag:
NEXT_PUBLIC_DEV_BYPASS_AUTH=true. - The frontend talks to the backend through App Router proxy routes and
credentials: "include". - Redis is required for queue-backed features such as notifications and export jobs.
- Some export and Stellar workflows are still being hardened; see the open issues for the current backlog.
Follow these steps from a fresh clone to get the full stack running.
- Node.js >= 18 and npm >= 9
- Docker (for Postgres and Redis)
- Rust +
cargo(only needed if working on contracts; seedocs/SOROBAN_SETUP.md)
For most contributors, this is the fastest path:
npm install
cp xconfess-backend/.env.example xconfess-backend/.env
cp xconfess-frontend/.env.example xconfess-frontend/.env.local
npm run dev:services
npm run dev:check
npm run devnpm run dev:check is intentionally part of the default startup path. It verifies that local environment files exist and that Postgres and Redis are reachable before NestJS starts. If infrastructure is down, it fails quickly with the exact command to run instead of printing long TypeORM connection retries.
On Windows, Docker Desktop must be open and using Linux containers. If Docker prints an error similar to open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specified, start Docker Desktop, wait for the engine to finish booting, then rerun:
npm run dev:services
npm run dev:checknpm installcompose.yaml provides a Postgres 16 instance on localhost:55432 and a Redis 7 instance on localhost:6379.
npm run dev:servicesVerify both containers are healthy before continuing:
docker compose -f compose.yaml psSecurity reminder: Never commit
.envor.env.localfiles. Always commit only the.env.exampletemplate files (which contain no real secrets). Do not paste real secret values into issues, PR descriptions, or comments.
Backend - copy the sample and fill in the values marked change-me:
cp xconfess-backend/.env.example xconfess-backend/.envRequired keys to set before first boot (everything else has safe defaults):
| Key | Purpose |
|---|---|
JWT_SECRET |
Signs auth tokens; use any long random string locally |
APP_SECRET |
App-level HMAC secret; use any long random string locally |
CONFESSION_ENCRYPTION_KEY |
64-character hex string used to encrypt confession content |
ENCRYPTION_CURRENT_KEY_VERSION |
Active envelope-encryption key version, usually v1 locally |
ENCRYPTION_MASTER_KEY_v1 |
64-character hex master key for envelope encryption |
STELLAR_SERVER_SECRET |
Stellar keypair secret for on-chain operations (testnet only) |
TYPEORM_LOGGING |
Set to true only when debugging SQL; default is quiet local startup |
Mail (MAIL_HOST, MAIL_USER, MAIL_PASSWORD) and Stellar contract IDs are pre-filled with testnet values in the example file and can be left as-is for local development. Leave STELLAR_FEATURES_ENABLED=false (default) to boot without enforcing every contract ID; set it to true only when you need full on-chain anchoring and tipping.
Frontend - copy the sample (no secrets required for basic local use):
cp xconfess-frontend/.env.example xconfess-frontend/.env.localThe example file points API URLs at http://localhost:5000/api, WebSockets at ws://localhost:5000, and the frontend at http://localhost:3000; it is ready to use without changes. The frontend URL resolver also accepts http://localhost:5000 and appends /api automatically, which keeps older local .env.local files working. If you want to skip the auth flow during UI development, add:
NEXT_PUBLIC_DEV_BYPASS_AUTH=true
Populate the database with demo confessions, users, reactions, comments, and reports for testing:
npm run seedThe seed script is idempotent — re-running it will not duplicate data. It creates:
- 5 users (1 admin, 4 regular; password:
password123) - 20 confessions across 5 categories
- 50 reactions, 20 comments, 3 reports, 1 pending notification
Stellar anchoring is stubbed when STELLAR_FEATURES_ENABLED=false (default).
Environment safety: Never commit
.envor.env.localfiles. Only commit the.env.exampletemplates. When sharing logs or asking for help in issues and PRs, redact all secrets, tokens, and private keys before pasting.
npm run dev:check
npm run devThis starts the backend and frontend concurrently. Once both are ready:
| Service | URL |
|---|---|
| Frontend | http://localhost:3000 |
| Backend API | http://localhost:5000 |
| Health (live) | http://localhost:5000/api/health/live |
| Health (ready) | http://localhost:5000/api/health/ready |
| Postgres | localhost:55432 |
| Redis | localhost:6379 |
See Health Endpoint Quick Reference for details on liveness vs readiness probes, Kubernetes config examples, and response formats.
| Symptom | Cause | Fix |
|---|---|---|
ERR Postgres localhost:55432 from npm run dev:check |
Postgres container is not running or Docker Desktop is not ready | Run npm run dev:services, then npm run dev:check |
ERR Redis localhost:6379 from npm run dev:check |
Redis container is not running or Docker Desktop is not ready | Run npm run dev:services, then npm run dev:check |
dockerDesktopLinuxEngine pipe error on Windows |
Docker Desktop is closed, still starting, or not using Linux containers | Open Docker Desktop, switch to Linux containers if needed, then rerun npm run dev:services |
| Backend config validation error | Required backend env vars are missing | Copy xconfess-backend/.env.example to xconfess-backend/.env |
Frontend proxy requests return 503 |
Backend is not running or BACKEND_API_URL/NEXT_PUBLIC_API_URL is wrong |
Start the backend and confirm http://localhost:5000/api/health/live |
Browser reports _next/static 404s, text/plain MIME errors, or sw.js Failed to fetch |
A stale service worker is controlling the local dev tab | Close all localhost:3000 tabs, reopen the app, and hard refresh once. Dev mode now unregisters xConfess service workers automatically |
| Very verbose SQL logs | TYPEORM_LOGGING=true |
Set TYPEORM_LOGGING=false in xconfess-backend/.env |
# Backend only
npm run dev:backend
# Frontend only
npm run dev:frontend# Backend unit tests
npm run backend:test
# Backend e2e tests (requires running stack)
npm run backend:test:e2e
# Frontend tests
npm run frontend:test
# Backend + Soroban contract tests (from monorepo root)
npm testRoot npm test runs backend unit tests, then contract tests via npm run contract:test. Use it when you want the same contract coverage as CI without running the full npm run ci pipeline.
For backend directories that are intentionally test-light, such as migrations, type definitions, and DTOs, see the backend testing notes.
Rust commands for xconfess-contracts must be run with that directory as the working directory (or use the root npm run contract:* scripts, which delegate there automatically).
cd xconfess-contracts
# Format
cargo fmt --all
# Lint (clippy, warnings as errors — mirrors CI)
cargo clippy --workspace --all-targets --all-features -- -D warnings
# Tests
cargo test --workspaceEquivalent from the monorepo root (no cd required):
npm run contract:fmt
npm run contract:lint
npm run contract:testSee xconfess-contracts/README.md for release builds, integration tests, and deployment.
npm run backend:build
npm run frontend:build
npm run contract:buildnpm run backend:lint
npm run frontend:lint
npm run contract:lintnpm run ciThis runs ci:backend, ci:frontend, and ci:contract in sequence — build, lint, and test for each package.
xConfess participates in Stellar Wave. Check the open issues for work tagged Stellar Wave, then coordinate before opening a PR.
Before opening a PR, read the small PR policy. Keep each PR focused on one issue, include tests for code changes, and screenshots for UI changes.
When your PR is ready for review, include a concise summary, validation results, screenshots for UI changes, and any known limitations.
When reporting bugs, see Attaching Logs to Issues and PRs for redaction guidelines.
- Account Recovery Guide — What to do if you connect the wrong wallet or network
- Contributor Guide — Local setup, branch hygiene, PR expectations, and validation commands
xconfess-backend/README.mdxconfess-frontend/README.mdxconfess-contracts/README.mddocs/message-e2e-encryption.md— E2E private messaging protocol