A privacy-first shared journal where memories are pinned to places on a map. Your stories stay yours until you're ready to share them.
This is a monorepo split into two main pieces:
web/apps/api/— Fastify + Prisma backend that handles authentication, encryption, media storage, and the delayed-reveal logic that keeps posts private until they're unlockedweb/apps/web/— React frontend with the map, journals, and the UI that makes all of this actually work
Both live under web/ because they share a docker-compose setup and general dependencies.
- Sign in with Google, no accounts to manage
- Drop journal entries on a map and see them visually
- Mark posts as private — they stay hidden until one month passes (or you're signed in as the author)
- Add photos, encrypt sensitive data, manage who sees what
- Admins get a platform to manage users, roles, and pricing tiers
cd web
cp .env.example .envvopenssl rand -hex 32Paste this into APP_ENCRYPTION_KEY in your .env.
If you want one-click login:
# Get a Client ID from Google Cloud Console, then set:
GOOGLE_CLIENT_ID=your_client_id_here
VITE_GOOGLE_CLIENT_ID=same_client_id_hereredocker compose up --buildOpen http://localhost:5173 and you're in.
- Backend: Fastify, Prisma, PostgreSQL
- Frontend: React, Vite
- Infrastructure: Docker Compose
- Auth: Google Identity Services, refresh token rotation
- Security: CSRF protection, encrypted payloads, rate limiting
For detailed setup, environment variables, and feature breakdown, check out web/README.md.
The whole thing runs in Docker. If you're working on the API or frontend:
# Rebuild and restart
docker compose up --build
# Check logs
docker compose logs -f api
docker compose logs -f webebDatabase migrations happen automatically on startup via Prisma.