pdf-quiz-generator/ADMIN.md
Daniel affd2fc116 Add admin guide, document CLI commands, consolidate account into settings
- Add list-docs, fix-stuck-docs, reprocess-doc CLI commands
- Create ADMIN.md with deployment, CLI, database, and troubleshooting docs
- Add HIBP warning to Settings page password change
- Remove separate Account nav link (already in Settings)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 20:39:58 +02:00

5.4 KiB

PedsHub — Admin Guide

Deployment

# Start everything
docker compose up -d

# Rebuild after code changes (restart alone won't pick up changes)
docker compose build --no-cache backend celery frontend
docker compose up -d backend celery frontend --force-recreate

# View logs
docker compose logs backend --tail=50
docker compose logs celery --tail=50
docker compose logs frontend --tail=50

CLI Management Tool

All commands run inside the backend container:

docker compose exec backend python -m app.cli <command>

User Management

# List all users
docker compose exec backend python -m app.cli list-users

# Reset a user's password
docker compose exec backend python -m app.cli reset-password user@example.com newpassword

# Change user role (admin / moderator / user)
docker compose exec backend python -m app.cli set-role user@example.com moderator

# Force-verify a user's email (skip email confirmation)
docker compose exec backend python -m app.cli verify-email user@example.com

# Delete a user (interactive confirmation)
docker compose exec backend python -m app.cli delete-user user@example.com

# Export users to CSV
docker compose exec backend python -m app.cli export-users > users.csv

Documents

# List all documents with status
docker compose exec backend python -m app.cli list-docs

# Fix documents stuck in 'processing' (>30 min)
docker compose exec backend python -m app.cli fix-stuck-docs

# Requeue a specific document for processing
docker compose exec backend python -m app.cli reprocess-doc 32

Why documents get stuck: If the Celery worker restarts while processing a PDF, the task is lost and the document stays at "processing" forever. fix-stuck-docs resets these to "ready" so they can be reprocessed.

Courses & Quizzes

# List all courses
docker compose exec backend python -m app.cli list-courses

# List quizzes (active only)
docker compose exec backend python -m app.cli list-quizzes

# List all quizzes including deleted
docker compose exec backend python -m app.cli list-quizzes --all

Maintenance

# Platform statistics
docker compose exec backend python -m app.cli stats

# Clean up orphaned Redis keys (quiz progress with no expiry)
docker compose exec backend python -m app.cli cleanup-redis

Database

Direct Access

docker compose exec postgres psql -U pedquiz -d pedquiz

Backups

Automated daily backups run via the db-backup service (prodrigestivill/postgres-backup-local). Retention: 14 daily, 4 weekly, 6 monthly. Stored in ./backups/.

# Check backup status
docker compose logs db-backup --tail=10

# List backups
ls -la backups/

# Manual backup
docker compose exec postgres pg_dump -U pedquiz pedquiz > manual-backup.sql

# Restore from backup
cat backups/daily/pedquiz-YYYYMMDD-HHMMSS.sql.gz | gunzip | \
  docker compose exec -T postgres psql -U pedquiz -d pedquiz

User Roles

Role Capabilities
user Take quizzes, study flashcards, enroll in courses, create quizzes from question bank
moderator All user abilities + create courses, upload PDFs, manage documents
admin All moderator abilities + admin dashboard, user management, model config, system settings

Common Issues

Document stuck in "processing"

docker compose exec backend python -m app.cli fix-stuck-docs

Cause: Celery worker restarted mid-task. The fix resets status to "ready".

DDL race condition on startup

One or two backend workers may fail on startup with Application startup failed. This is normal — multiple uvicorn workers race to run ALTER TABLE migrations, and losers get a deadlock error. The surviving workers handle all traffic. Check with:

docker compose logs backend --tail=10 | grep "startup complete"

Celery task not running

# Check Celery is connected
docker compose logs celery --tail=5

# Check if tasks are registered
docker compose exec celery celery -A app.tasks inspect registered

# Check active tasks (don't restart if tasks are running!)
docker compose exec celery celery -A app.tasks inspect active

Password reset without email

docker compose exec backend python -m app.cli reset-password user@example.com newpassword

User can't log in (unverified email)

docker compose exec backend python -m app.cli verify-email user@example.com

Environment

Key settings in backend/.env:

Variable Purpose
APP_URL Base URL for email links (e.g. https://pedshub.com)
SECRET_KEY JWT signing key — change in production
MAIL_FROM Sender email for verification/reset emails
LITELLM_API_BASE LiteLLM proxy URL for AI features
LITELLM_API_KEY API key for LiteLLM proxy
TURNSTILE_SITE_KEY / TURNSTILE_SECRET_KEY Cloudflare Turnstile bot protection
BBB_SERVER_URL / BBB_SECRET BigBlueButton integration for live sessions

Security Notes

  • Passwords are hashed with bcrypt (one-way, irreversible)
  • Registration checks passwords against Have I Been Pwned breach database (warns, doesn't block)
  • Only the first 5 characters of the SHA-1 hash are sent to HIBP (k-anonymity)
  • JWT tokens auto-refresh via sliding expiration (12h age or <1h remaining)
  • Rate limiting on login (10 attempts per IP per 15 min) via Redis
  • Email verification required for new accounts