diff --git a/backend/locale/en/LC_MESSAGES/django.po b/backend/locale/en/LC_MESSAGES/django.po index ab3f309..4c55457 100644 --- a/backend/locale/en/LC_MESSAGES/django.po +++ b/backend/locale/en/LC_MESSAGES/django.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: tubco-portal\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-03-24 12:58+0000\n" +"POT-Creation-Date: 2026-03-24 13:05+0000\n" "PO-Revision-Date: 2026-03-24 00:00+0000\n" "Language: en\n" "MIME-Version: 1.0\n" @@ -262,6 +262,43 @@ msgstr "deployment, security, and maintenance notes" msgid "Open Developer Handbook" msgstr "Open Developer Handbook" +#: workflows/templates/workflows/handbook.html:67 +#: workflows/templates/workflows/release_checklist.html:36 +msgid "Release" +msgstr "" + +#: workflows/templates/workflows/handbook.html:68 +#: workflows/templates/workflows/release_checklist.html:7 +#: workflows/templates/workflows/release_checklist.html:38 +msgid "Release Checklist" +msgstr "" + +#: workflows/templates/workflows/handbook.html:69 +msgid "" +"Step-by-step release runbook for rebuilds, migrations, translations, static " +"assets, smoke checks, and rollout verification." +msgstr "" + +#: workflows/templates/workflows/handbook.html:71 +msgid "pre-release validation commands" +msgstr "" + +#: workflows/templates/workflows/handbook.html:72 +msgid "translation, static, and migration steps" +msgstr "" + +#: workflows/templates/workflows/handbook.html:73 +msgid "post-release smoke checks" +msgstr "" + +#: workflows/templates/workflows/handbook.html:74 +msgid "rollback and evidence checklist" +msgstr "" + +#: workflows/templates/workflows/handbook.html:77 +msgid "Open Release Checklist" +msgstr "" + #: workflows/templates/workflows/home.html:8 #: workflows/templates/workflows/home.html:469 #: workflows/templates/workflows/requests_dashboard.html:1118 @@ -915,6 +952,167 @@ msgstr "Generate live protocol" msgid "Live-Protokoll öffnen" msgstr "Open live protocol" +#: workflows/templates/workflows/release_checklist.html:39 +#, fuzzy +#| msgid "Back to Home" +msgid "Back to Handbook" +msgstr "Back to home" + +#: workflows/templates/workflows/release_checklist.html:41 +msgid "" +"Single runbook for preparing, validating, and evidencing a safe application " +"release. Use it for both local production-like rollouts and future CI/CD " +"handoffs." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:46 +msgid "1. Pre-release checks" +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:48 +msgid "Confirm git working tree is clean or intentionally scoped." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:49 +msgid "" +"Read the latest Project Wiki and Developer Handbook updates for architecture " +"changes." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:50 +msgid "" +"Check environment changes in .env.example and deployment secrets if " +"integrations changed." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:51 +msgid "" +"If dependencies changed, rebuild web and worker images before validation." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:58 +msgid "2. Validation commands" +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:60 +msgid "Run Django system checks." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:61 +msgid "Run tests or a targeted verification command for the changed area." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:62 +msgid "Compile translations after UI/content changes." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:63 +msgid "If dependencies changed, verify imports do not emit warnings." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:72 +msgid "3. Data and asset steps" +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:74 +msgid "Create and apply migrations if models changed." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:75 +msgid "Run collectstatic if UI assets changed." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:76 +msgid "Generate fresh PDFs if PDF templates or document logic changed." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:77 +msgid "Confirm file outputs appear under backend/media/pdfs/." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:85 +#, fuzzy +#| msgid "Integrationen" +msgid "4. Integration checks" +msgstr "Integrations" + +#: workflows/templates/workflows/release_checklist.html:87 +msgid "Verify the health endpoint returns status ok." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:88 +msgid "Verify MailHog in test mode or SMTP in production mode." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:89 +msgid "Verify Nextcloud upload if synchronization behavior changed." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:90 +msgid "" +"Verify welcome-email scheduling or notification rules if email routing " +"changed." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:97 +msgid "5. Release evidence" +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:99 +msgid "Record which checks were run and their result." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:100 +msgid "Take a snapshot commit before moving to the next change phase." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:101 +msgid "" +"If a release introduces new operations or engineering behavior, update both " +"handbooks." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:102 +msgid "" +"Keep at least one successful onboarding and one offboarding smoke example " +"during major workflow changes." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:107 +msgid "6. Rollback basics" +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:109 +msgid "" +"If rollout fails after code-only changes, redeploy the previous snapshot " +"commit." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:110 +msgid "" +"If rollout includes schema changes, verify backward compatibility before " +"rollback." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:111 +msgid "" +"If integrations fail, switch email mode/test settings conservatively before " +"wider retry." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:112 +msgid "" +"Use logs from web and worker containers to isolate whether the issue is " +"request, task, or integration related." +msgstr "" + +#: workflows/templates/workflows/release_checklist.html:119 +msgid "" +"Project rule: German remains the primary/fallback language. English is " +"secondary. If a release adds new dynamic text, add the German source first " +"and then the English value." +msgstr "" + #: workflows/templates/workflows/requests_dashboard.html:899 msgid "" "Steuert Onboarding- und Offboarding-Prozesse an einem Ort. Die Oberfläche " @@ -1230,45 +1428,45 @@ msgstr "Finish" msgid "Notizen und Freigabe" msgstr "Notes and approval" -#: workflows/views.py:239 +#: workflows/views.py:245 msgid "Sie haben keine Berechtigung für diese Aktion." msgstr "You do not have permission for this action." -#: workflows/views.py:248 +#: workflows/views.py:254 msgid "Keine Einträge ausgewählt." msgstr "No entries selected." -#: workflows/views.py:277 +#: workflows/views.py:283 #, python-format msgid "%(count)s Eintrag/Einträge gelöscht." msgstr "%(count)s entry/entries deleted." -#: workflows/views.py:279 +#: workflows/views.py:285 #, python-format msgid "%(count)s Auswahl(en) konnten nicht verarbeitet werden." msgstr "%(count)s selection(s) could not be processed." -#: workflows/views.py:281 +#: workflows/views.py:287 msgid "Keine passenden Einträge gefunden." msgstr "No matching entries found." -#: workflows/views.py:440 +#: workflows/views.py:446 msgid "Einweisungs- und Übergabeprotokoll wurde erzeugt." msgstr "Introduction and handover protocol was generated." -#: workflows/views.py:457 +#: workflows/views.py:463 msgid "Einweisungsprotokoll aus Live-Status wurde erzeugt." msgstr "Introduction protocol from live status was generated." -#: workflows/views.py:486 +#: workflows/views.py:492 msgid "Einweisung wurde zurückgesetzt." msgstr "Introduction was reset." -#: workflows/views.py:492 +#: workflows/views.py:498 msgid "Einweisung wurde als abgeschlossen gespeichert." msgstr "Introduction was saved as completed." -#: workflows/views.py:497 +#: workflows/views.py:503 msgid "Einweisung wurde als Entwurf gespeichert." msgstr "Introduction was saved as draft." diff --git a/backend/workflows/templates/workflows/developer_handbook.html b/backend/workflows/templates/workflows/developer_handbook.html index 03c508a..ca66e2d 100644 --- a/backend/workflows/templates/workflows/developer_handbook.html +++ b/backend/workflows/templates/workflows/developer_handbook.html @@ -194,6 +194,7 @@ 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.
  • +
  • Use the dedicated Release Checklist page as the final go/no-go runbook before shipping changes.
  • 12) Deployment and Release Checklist

    diff --git a/backend/workflows/templates/workflows/handbook.html b/backend/workflows/templates/workflows/handbook.html index 00efd45..4275378 100644 --- a/backend/workflows/templates/workflows/handbook.html +++ b/backend/workflows/templates/workflows/handbook.html @@ -13,7 +13,7 @@ .top { display: flex; justify-content: space-between; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; } h1 { margin: 0; color: #000078; font-size: 30px; } .sub { margin: 8px 0 18px; color: #5f6f85; max-width: 760px; } - .grid { display: grid; grid-template-columns: repeat(2, minmax(280px, 1fr)); gap: 14px; } + .grid { display: grid; grid-template-columns: repeat(3, minmax(260px, 1fr)); gap: 14px; } .card { border: 1px solid #d7e0ea; border-radius: 14px; background: #fcfdff; padding: 16px; } .eyebrow { display: inline-block; padding: 5px 10px; border-radius: 999px; background: #eef4ff; color: #244a8f; border: 1px solid #d5e2f9; font-size: 12px; font-weight: 700; margin-bottom: 10px; } h2 { margin: 0 0 8px; color: #113a74; } @@ -62,6 +62,20 @@
    {% trans "Open Developer Handbook" %}
    + +
    +
    {% trans "Release" %}
    +

    {% trans "Release Checklist" %}

    +

    {% trans "Step-by-step release runbook for rebuilds, migrations, translations, static assets, smoke checks, and rollout verification." %}

    + +
    + {% trans "Open Release Checklist" %} +
    diff --git a/backend/workflows/templates/workflows/project_wiki.html b/backend/workflows/templates/workflows/project_wiki.html index 229c1e5..585a1b5 100644 --- a/backend/workflows/templates/workflows/project_wiki.html +++ b/backend/workflows/templates/workflows/project_wiki.html @@ -196,6 +196,7 @@
  • Einweisungs- und Übergabeprotokoll: staff-only PDF erzeugen, Neu erzeugen, and PDF öffnen actions directly on onboarding rows in the Requests Dashboard.
  • Einweisung durchführen: staff-only live checklist page opened from onboarding rows, with draft/completed status, notes, progress tracking, and a separate live-status PDF export.
  • Project Wiki: this documentation page.
  • +
  • Release Checklist: dedicated staff-only release runbook for validation, rollout evidence, and rollback basics.
  • 10) Operations Runbook

    diff --git a/backend/workflows/templates/workflows/release_checklist.html b/backend/workflows/templates/workflows/release_checklist.html new file mode 100644 index 0000000..be56c6b --- /dev/null +++ b/backend/workflows/templates/workflows/release_checklist.html @@ -0,0 +1,122 @@ +{% load static i18n %} + + + + + + {% trans "Release Checklist" %} + + + + +
    + +
    +
    {% trans "Release" %}
    +
    +

    {% trans "Release Checklist" %}

    + {% trans "Back to Handbook" %} +
    +

    {% trans "Single runbook for preparing, validating, and evidencing a safe application release. Use it for both local production-like rollouts and future CI/CD handoffs." %}

    +
    + +
    +
    +

    {% trans "1. Pre-release checks" %}

    +
      +
    • {% trans "Confirm git working tree is clean or intentionally scoped." %}
    • +
    • {% trans "Read the latest Project Wiki and Developer Handbook updates for architecture changes." %}
    • +
    • {% trans "Check environment changes in .env.example and deployment secrets if integrations changed." %}
    • +
    • {% trans "If dependencies changed, rebuild web and worker images before validation." %}
    • +
    +
    git status --short
    +docker compose up -d --build web worker
    +
    + +
    +

    {% trans "2. Validation commands" %}

    +
      +
    • {% trans "Run Django system checks." %}
    • +
    • {% trans "Run tests or a targeted verification command for the changed area." %}
    • +
    • {% trans "Compile translations after UI/content changes." %}
    • +
    • {% trans "If dependencies changed, verify imports do not emit warnings." %}
    • +
    +
    docker compose exec -T web python manage.py check
    +docker compose exec -T web python manage.py test
    +make i18n-compile
    +docker compose exec -T web python -c "import requests"
    +
    + +
    +

    {% trans "3. Data and asset steps" %}

    +
      +
    • {% trans "Create and apply migrations if models changed." %}
    • +
    • {% trans "Run collectstatic if UI assets changed." %}
    • +
    • {% trans "Generate fresh PDFs if PDF templates or document logic changed." %}
    • +
    • {% trans "Confirm file outputs appear under backend/media/pdfs/." %}
    • +
    +
    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 collectstatic --noinput
    +
    + +
    +

    {% trans "4. Integration checks" %}

    +
      +
    • {% trans "Verify the health endpoint returns status ok." %}
    • +
    • {% trans "Verify MailHog in test mode or SMTP in production mode." %}
    • +
    • {% trans "Verify Nextcloud upload if synchronization behavior changed." %}
    • +
    • {% trans "Verify welcome-email scheduling or notification rules if email routing changed." %}
    • +
    +
    curl --max-time 8 http://127.0.0.1:8088/healthz/
    +docker compose exec -T web python manage.py run_staging_e2e_check
    +
    + +
    +

    {% trans "5. Release evidence" %}

    +
      +
    • {% trans "Record which checks were run and their result." %}
    • +
    • {% trans "Take a snapshot commit before moving to the next change phase." %}
    • +
    • {% trans "If a release introduces new operations or engineering behavior, update both handbooks." %}
    • +
    • {% trans "Keep at least one successful onboarding and one offboarding smoke example during major workflow changes." %}
    • +
    +
    + +
    +

    {% trans "6. Rollback basics" %}

    +
      +
    • {% trans "If rollout fails after code-only changes, redeploy the previous snapshot commit." %}
    • +
    • {% trans "If rollout includes schema changes, verify backward compatibility before rollback." %}
    • +
    • {% trans "If integrations fail, switch email mode/test settings conservatively before wider retry." %}
    • +
    • {% trans "Use logs from web and worker containers to isolate whether the issue is request, task, or integration related." %}
    • +
    +
    docker compose logs --no-color --tail=200 web
    +docker compose logs --no-color --tail=200 worker
    +
    +
    + +
    {% trans "Project rule: German remains the primary/fallback language. English is secondary. If a release adds new dynamic text, add the German source first and then the English value." %}
    +
    + + diff --git a/backend/workflows/urls.py b/backend/workflows/urls.py index 0c67b31..415d093 100644 --- a/backend/workflows/urls.py +++ b/backend/workflows/urls.py @@ -30,6 +30,7 @@ urlpatterns = [ path('admin-tools/handbook/', views.handbook_page, name='handbook_page'), path('admin-tools/wiki/', views.project_wiki_page, name='project_wiki_page'), path('admin-tools/developer-handbook/', views.developer_handbook_page, name='developer_handbook_page'), + path('admin-tools/release-checklist/', views.release_checklist_page, name='release_checklist_page'), path('admin-tools/form-builder/', views.form_builder_page, name='form_builder_page'), path('admin-tools/form-builder/save-order/', views.form_builder_save_order, name='form_builder_save_order'), path('admin-tools/intro-builder/', views.intro_builder_page, name='intro_builder_page'), diff --git a/backend/workflows/views.py b/backend/workflows/views.py index 4e0a7ab..71417e9 100644 --- a/backend/workflows/views.py +++ b/backend/workflows/views.py @@ -232,6 +232,12 @@ def developer_handbook_page(request): return render(request, 'workflows/developer_handbook.html') +@login_required +@user_passes_test(_is_staff) +def release_checklist_page(request): + return render(request, 'workflows/release_checklist.html') + + @login_required def requests_dashboard(request): if request.method == 'POST':