Member-facing cinema planner for discovering showtimes and following a personal selection of theaters. Built with Express.js, React, and PostgreSQL, fully containerized with Docker.
Provenance: Movie Planner is a permanently diverged project derived from the allo-scrapper codebase. The inherited history is preserved up to the
allo-scrapper-importboundary tag; see ADR 0008 for the fork and permanent-divergence decision.
Version:
0.0.0-development(pre-release). The first planned release is0.1.0and is deferred until the independence cleanup (issue #3) is complete.
- Automated scraping of theater showtimes from the source website, via a standalone scraper microservice consuming a Redis job queue.
- Scraper resilience with automatic HTTP 429 detection and graceful shutdown.
- RESTful API built with Express.js and TypeScript.
- React SPA (Vite) with a member-facing homepage driven by a personal selection of theaters.
- Real-time progress via Server-Sent Events (SSE) for live scraping updates.
- Weekly reports for tracking theater programs and identifying new releases.
- White-label branding — site name, logo, colors, fonts, footer — via the
admin panel, with
Movie Planneras the canonical default and reset value. - Role-based access control with granular, permission-based role management.
- JWT authentication with rotating refresh tokens and CSRF protection.
- Member accounts — self-registration by email, verification, member selection, member submission of new theaters (see CONTEXT.md).
- Rate limiting per endpoint type, dynamically configurable via the admin panel.
- Prometheus metrics at the authenticated
/metricsendpoint.
┌─────────────────┐
│ React SPA │ Port 80 (container) / 5173 (host dev)
│ (Vite + TS) │
└────────┬────────┘
│ HTTP API / SSE
▼
┌─────────────────┐ Redis pub/sub ┌───────────────────┐
│ Express API │◄───────────────────►│ Scraper │
│ (TypeScript) │ scrape:jobs queue │ Microservice │
│ API + frontend │────────────────────►│ (consumer + cron) │
│ only — no │ │ │
│ scraping code │ │ SQL │
└────────┬────────┘ └────────┬──────────┘
│ SQL │ SQL
└──────────────────┬────────────────────┘
▼
┌─────────────────────────┐
│ PostgreSQL Port 5432 │
│ theaters / movies / │
│ showtimes / reports │
└─────────────────────────┘
┌─────────────────────────┐
│ Redis (mandatory) │ Job queue + progress pub/sub
└─────────────────────────┘
The API publishes scrape jobs to Redis; the scraper microservice consumes them, fetches the source site, and writes results directly to PostgreSQL. Progress flows back to the client via Redis pub/sub → SSE. Redis is mandatory.
See CONTEXT.md for the domain glossary and the architecture reference for system design.
- Docker and Docker Compose
- Node.js 24 (only for the host-application path)
- Ports 3000, 5432, 6379 available
openssl(forJWT_SECRETgeneration)
Copy .env.example to .env and fill in the two mandatory secrets. The server
refuses to start without them:
JWT_SECRET— minimum 32 characters. Generate withopenssl rand -base64 64.POSTGRES_PASSWORD— any non-empty value.
git clone https://github.com/PhBassin/movie-planner.git
cd movie-planner
cp .env.example .env
# Fill in POSTGRES_PASSWORD and JWT_SECRET in .env
npm run dev # docker compose up --buildRuns PostgreSQL and Redis in Docker; the client, server, and scraper run on the host under Node 24.
git clone https://github.com/PhBassin/movie-planner.git
cd movie-planner
cp .env.example .env
# Fill in POSTGRES_PASSWORD and JWT_SECRET in .env
npm install --legacy-peer-deps
npm run dev:infra # starts Postgres + Redis in Docker
# In separate terminals:
npm run server:dev # API on http://localhost:3000
npm run client:dev # UI on http://localhost:5173
npm run scraper:dev # scraper microservice (consumer + cron)On a fresh database, the server bootstrap creates the admin user with a
securely generated random password and logs it once to stdout. There is no
static default admin password — copy the logged password on first start, then
change it immediately via the admin panel.
See the setup guide and database initialization reference for details.
- Quick Start
- Installation
- Configuration
- Development guides — setup, testing, contributing, CI
- API reference
- Database schema and migrations
- Architecture
- Troubleshooting
- Domain glossary (CONTEXT.md)
- Architecture Decision Records
Contributions are welcome. See CONTRIBUTING.
Workflow:
- Open or pick a GitHub issue.
- Branch from
main(the default and only long-lived branch):<type>/<issue#>-<desc>. - Write tests first; keep type-checks and tests green.
- Use Conventional Commit subjects (
feat:,fix:, etc.). - Open a PR against
mainreferencing the issue.
Releases are produced by manual dispatch of the Prepare Release workflow with
a target version; merging the generated release/X.Y.Z PR creates the tag and
the GitHub Release. See CI/CD guide and
CONTRIBUTING for details.
For AI coding agents working in this repository, see AGENTS.md.
MIT — see LICENSE.
- Issues: GitHub Issues
- Discussions: GitHub Discussions