Engineering runbook for development, deployment, maintenance, and extension of the TUBCO Onboarding & Offboarding Portal.
1) Overview
This handbook is for developers and maintainers. It documents the actual engineering workflow of the standalone product repository.
- Repository:
tubco-onboarding-offboarding-portal
- Main stack: Django + Celery + PostgreSQL + Redis + MailHog
- Runtime mode: Docker Compose for local development and staging-style operation
2) Repository Structure
/backend/config/: Django settings, WSGI, URL config
/backend/workflows/: application logic, views, models, tasks, templates, static assets
/backend/media/templates/: PDF HTML templates and letterhead source files
/backend/media/pdfs/: generated PDF outputs on host volume
/backend/locale/: translation catalogs
/docker-compose.yml: local runtime orchestration
/Makefile: repeatable translation commands
/.github/workflows/i18n.yml: translation compile validation in CI
3) Local Development Workflow
Start
cd /Users/bostame/Documents/tubco-onboarding-offboarding-portal
docker compose up -d --build
Main URLs
- App:
http://127.0.0.1:8088/
- MailHog:
http://127.0.0.1:8025/
- Health check:
http://127.0.0.1:8088/healthz/
Bootstrap users
- Admin:
admin_test / admin12345
- User:
user_test / user12345
4) Docker Operations
docker compose up -d --build
docker compose restart web
docker compose restart worker
docker compose logs --no-color --tail=120 web
docker compose logs --no-color --tail=120 worker
docker compose down
docker compose down -v
The source code is bind-mounted into the container. Most template/view/static changes only require a web restart, not a full rebuild. Image changes such as system packages require docker compose up -d --build.
5) Database and Migrations
docker compose exec -T web python manage.py makemigrations
docker compose exec -T web python manage.py migrate
docker compose exec -T web python manage.py check
- Never edit or remove historical migrations casually.
- When adding fields to builder-driven models, preserve fallback behavior for existing rows.
- Fresh boot sequence runs migrations automatically in
entrypoint-web.sh.
6) Translation Workflow
Standard Django i18n path
make i18n-update-en
make i18n-compile
Equivalent raw commands:
docker compose exec -T web django-admin makemessages -l en
docker compose exec -T web django-admin compilemessages
gettext is installed in the Docker image.
- Do not use custom ad hoc
.mo compilation anymore.
- Phase 1 bilingual support covers fixed UI, including the main admin-tool labels/buttons.
- Phase 2 covers builder-driven labels and checklist items with explicit German and English fields.
- Email phase covers
NotificationTemplate, NotificationRule, and the welcome-email settings UI with explicit DE/EN subject/body fields.
- Request records now persist
preferred_language so workflow emails can render in the submitter's active UI language with German fallback.
preferred_language is normalized in model save() and also has a DB default of de, so alternate creation paths cannot insert null values.
7) PDF Pipeline
- PDF generation is HTML-to-PDF using
xhtml2pdf.
- Letterhead overlay is applied from
templates.pdf.
- Main logic lives in
backend/workflows/tasks.py.
- Fixed PDF labels/headings are rendered from task-level DE/EN text dictionaries, not hard-coded directly in request processing logic.
- PDF language follows the normalized request
preferred_language, with German fallback.
- Key templates:
onboarding_template.html
offboarding_template.html
onboarding_intro_template.html
onboarding_intro_session_pdf.html
xhtml2pdf is sensitive to layout complexity. Keep print templates conservative and verify every structural change with a real generated PDF.
8) Email Pipeline
- Notification defaults are defined in
DEFAULT_NOTIFICATION_TEMPLATES in tasks.py.
- Admin-configured overrides live in
NotificationTemplate and NotificationRule.
- Both models now support explicit DE/EN content fields. Prefer filling both languages in the frontend integrations UI instead of embedding mixed-language copy into a single template.
- Welcome-email configuration under Admin Apps has the same DE/EN split and follows the same runtime language selection.
- The request objects passed into email tasks always carry a normalized
preferred_language value.
- Mail sending uses Celery tasks and supports test mode redirection.
- MailHog is the local verification path when test mode is active.
9) Nextcloud Integration
- Configured from Admin Apps → Integrations.
- Upload logic lives in
backend/workflows/services.py.
- Feature can be globally toggled without changing environment variables.
- Failures should degrade gracefully and not block request persistence.
10) Builder Architecture
Form Builder
- Model:
FormFieldConfig + FormOption
- Controls field order, visibility, required flags, option sets, and bilingual label/help-text overrides
Intro Builder
- Model:
IntroChecklistItem
- Controls additional checklist items used by intro PDF and live intro checklist
- Now supports bilingual DE/EN labels
Dynamic content should use explicit DE/EN fields with German fallback, not machine translation at runtime.
11) Testing and Validation
docker compose exec -T web python manage.py check
docker compose exec -T web python manage.py test
docker compose exec -T web python manage.py run_staging_e2e_check
- Use
check after model/view/template changes.
- Use targeted shell checks for render validation when changing templates or routes.
- Use real PDF generation tests when changing PDF templates or intro/offboarding document logic.
12) Deployment and Release Checklist
- Run
manage.py check
- Run tests or targeted verification
- Run translation compile step
- Generate at least one onboarding/offboarding PDF if PDF templates changed
- Verify MailHog or SMTP path if email behavior changed
- Verify Nextcloud upload if integration behavior changed
- Update Project Wiki and Developer Handbook if architecture/workflow changed
- Take a snapshot commit before major next-phase work
13) Troubleshooting
- Page looks stale: restart
web and hard-refresh browser
- Second request hangs: inspect web logs and verify health endpoint
- PDF looks unchanged: regenerate the PDF; browser may cache old file names unless the path changes
- Language switch not visible: verify translation catalog compiled and restart web
- Mail not visible: check MailHog on port
8025 and test/production mode toggle
- Nextcloud sync unclear: verify config in Integrations page and inspect service logs
14) Security and Maintenance Notes
- Containers run as non-root
app user.
- Keep secrets in
.env, not in tracked files.
- Avoid destructive git operations in a dirty repo.
- Prefer standard framework workflows over custom one-off maintenance scripts.
- When adding new features, document them in both the Project Wiki and this handbook if they change engineering workflow.