Real-time multi-user issue tracker for Test Fests. Left pane: submit issues. Right pane: live list of issues from everyone. Auth via Entra ID (SSO), data in Postgres, real-time via Socket.IO, optional Jira integration.
- Real-time updates across all connected users in a room
- Entra ID (Azure AD) OIDC login required to submit
- Rooms: Created by a Groupier; members join and report issues
- Groupier can tag issues (duplicate, as-designed, low-priority)
- Issues with duplicate/as-designed fade visually
- Upload images with each issue (5MB max, images only, validated)
- Comprehensive file upload security (MIME type validation, size limits)
- “Send to Jira” button (requires Jira config)
- Node.js, Express, Socket.IO
- Postgres (schema auto-migrates on startup)
- Passport + openid-client for Entra ID
- Multer for uploads
To deploy to Heroku:
- Create a Heroku App: Run
heroku create test-fest-tracker. - Add Postgres: Run
heroku addons:create heroku-postgresql:essential-0. - Configure Env Vars: Set
ENTRA_ISSUER,ENTRA_CLIENT_ID,ENTRA_CLIENT_SECRET, etc., usingheroku config:set. - Deploy: Run
git push heroku main.
For detailed instructions, see docs/DEPLOYMENT_CHECKLIST.md.
- Prerequisites (local dev)
- Node.js 20+
- Postgres 13+ with psql CLI
- Install dependencies
npm install- Create
.envfrom the template values below
PORT=3000
SESSION_SECRET=please_change_me
DATABASE_URL=postgres://username:password@localhost:5432/test_fest_tracker
# Entra ID OIDC
# Use https://login.microsoftonline.com/<tenant-id>/v2.0
ENTRA_ISSUER=
ENTRA_CLIENT_ID=
ENTRA_CLIENT_SECRET=
# (Optional) Defaults to https://testfestdotdev-dff5671c87e3.herokuapp.com/auth/callback
# ENTRA_REDIRECT_URI=http://localhost:3000/auth/callback
# Comma-separated list of emails with Groupier powers (creator is groupier by default)
GROUPIER_EMAILS=
# Tag list editable here
TAGS=duplicate,as-designed,low-priority
# Jira (optional)
JIRA_BASE_URL=
JIRA_EMAIL=
JIRA_API_TOKEN=
JIRA_PROJECT_KEY=
JIRA_ISSUE_TYPE=Bug
- Provision local database (optional but recommended for first run)
# create the database if it does not exist
createdb test_fest_tracker || true
# apply schema (uses testfest schema, not public)
psql "$DATABASE_URL" -f db/schema.sql- Run in development mode (Nodemon)
npm run devOpen http://localhost:3000.
Interactive API documentation is available via Swagger UI at:
http://localhost:3000/api-docs
The documentation includes:
- Complete endpoint reference for all REST API routes
- Request/response schemas and examples
- Authentication details
- Interactive API testing interface
For more details, see docs/API_DOCUMENTATION.md.
- Create an app registration in Azure Entra ID (Azure AD)
- Add a Web redirect URI:
http://localhost:3000/auth/callback - Configure client secret and set
ENTRA_CLIENT_SECRET - Set
ENTRA_ISSUERtohttps://login.microsoftonline.com/<tenant-id>/v2.0 - Grant basic scopes (openid, profile, email). The app only requires standard OIDC claims
If you see “OIDC not configured” on login, ensure ENTRA_ISSUER, ENTRA_CLIENT_ID, and ENTRA_CLIENT_SECRET are set in .env.
You can pre-provision the DB with the SQL file to use a dedicated schema testfest (instead of public):
psql "$DATABASE_URL" -f db/schema.sqlAt runtime, the app will also create the schema/tables if they don’t exist, and sets search_path to testfest,public. You can override the schema via env var DB_SCHEMA.
- File uploads are stored under
uploads/and served via/uploads/<file> - Session store is Postgres via
connect-pg-simple - Schema is created on startup if missing
Some read-heavy endpoints support short TTL caching.
- Enable: set
CACHE_ENABLED=true - Redis: set
REDIS_URL(orREDISCLOUD_URL) - TTL:
CACHE_TTL_SECONDS(default varies by endpoint)
If you're using docker-compose.yml (which includes a redis service), set:
REDIS_URL=redis://redis:6379
Build locally:
docker build -t test-fest-tracker:local .
docker run --env-file .env -p 3000:3000 test-fest-tracker:localThe UI in public/ can be built and optimized for production:
npm run build:uiThis outputs dist/. When NODE_ENV=production and dist/index.html exists, server.js serves the built UI automatically.