snapshot: preserve release checklist documentation

This commit is contained in:
Md Bayazid Bostame
2026-03-24 14:05:47 +01:00
parent f728f7134f
commit 8e2104c306
7 changed files with 355 additions and 12 deletions

View File

@@ -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."

View File

@@ -194,6 +194,7 @@ docker compose exec -T web python manage.py run_staging_e2e_check</code></pre>
<li>Use <code>check</code> after model/view/template changes.</li>
<li>Use targeted shell checks for render validation when changing templates or routes.</li>
<li>Use real PDF generation tests when changing PDF templates or intro/offboarding document logic.</li>
<li>Use the dedicated Release Checklist page as the final go/no-go runbook before shipping changes.</li>
</ul>
<h2 id="deploy">12) Deployment and Release Checklist</h2>

View File

@@ -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 @@
<div class="actions">
<a class="btn btn-secondary" href="/admin-tools/developer-handbook/">{% trans "Open Developer Handbook" %}</a>
</div>
<section class="card">
<div class="eyebrow">{% trans "Release" %}</div>
<h2>{% trans "Release Checklist" %}</h2>
<p>{% trans "Step-by-step release runbook for rebuilds, migrations, translations, static assets, smoke checks, and rollout verification." %}</p>
<ul>
<li>{% trans "pre-release validation commands" %}</li>
<li>{% trans "translation, static, and migration steps" %}</li>
<li>{% trans "post-release smoke checks" %}</li>
<li>{% trans "rollback and evidence checklist" %}</li>
</ul>
<div class="actions">
<a class="btn btn-secondary" href="/admin-tools/release-checklist/">{% trans "Open Release Checklist" %}</a>
</div>
</section>
</div>
</div>

View File

@@ -196,6 +196,7 @@
<li><strong>Einweisungs- und Übergabeprotokoll:</strong> staff-only <code>PDF erzeugen</code>, <code>Neu erzeugen</code>, and <code>PDF öffnen</code> actions directly on onboarding rows in the Requests Dashboard.</li>
<li><strong>Einweisung durchführen:</strong> staff-only live checklist page opened from onboarding rows, with draft/completed status, notes, progress tracking, and a separate live-status PDF export.</li>
<li><strong>Project Wiki:</strong> this documentation page.</li>
<li><strong>Release Checklist:</strong> dedicated staff-only release runbook for validation, rollout evidence, and rollback basics.</li>
</ul>
<h2 id="operations">10) Operations Runbook</h2>

View File

@@ -0,0 +1,122 @@
{% load static i18n %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{% trans "Release Checklist" %}</title>
<link rel="stylesheet" href="{% static 'workflows/css/buttons.css' %}" />
<style>
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 20px; }
.shell { max-width: 1120px; margin: 0 auto; }
.brand-logo { width: 190px; max-width: 100%; height: auto; margin: 0 0 10px; display: block; }
.hero, .panel { background: #fff; border: 1px solid #d7e0ea; border-radius: 16px; box-shadow: 0 20px 40px rgba(17, 58, 116, 0.08); }
.hero { padding: 20px; margin-bottom: 18px; }
.top { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.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; }
h1 { margin: 0; color: #000078; font-size: 30px; }
.sub { margin: 8px 0 0; color: #5f6f85; max-width: 820px; }
.grid { display: grid; grid-template-columns: repeat(2, minmax(320px, 1fr)); gap: 16px; }
.panel { padding: 18px; }
h2 { margin: 0 0 12px; color: #113a74; font-size: 20px; }
ol, ul { margin: 0; padding-left: 20px; }
li { margin: 8px 0; color: #334155; }
.checklist li { list-style: none; position: relative; padding-left: 28px; }
.checklist li::before { content: '\25A1'; position: absolute; left: 0; top: 0; color: #66758c; font-size: 16px; }
pre { margin: 12px 0 0; padding: 14px; border-radius: 12px; background: #f7faff; border: 1px solid #dfe8f4; overflow-x: auto; color: #16345f; }
code { font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; }
.note { margin-top: 16px; padding: 14px 16px; border-radius: 12px; background: #f7faff; border: 1px solid #dfe8f4; color: #355175; }
@media (max-width: 820px) { .grid { grid-template-columns: 1fr; } }
</style>
</head>
<body>
<div class="shell">
<img class="brand-logo" src="{% static 'workflows/img/tubco-logo.svg' %}" alt="TUB/CO Logo" />
<section class="hero">
<div class="eyebrow">{% trans "Release" %}</div>
<div class="top">
<h1>{% trans "Release Checklist" %}</h1>
<a class="btn btn-secondary" href="/admin-tools/handbook/">{% trans "Back to Handbook" %}</a>
</div>
<p class="sub">{% 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." %}</p>
</section>
<div class="grid">
<section class="panel">
<h2>{% trans "1. Pre-release checks" %}</h2>
<ul class="checklist">
<li>{% trans "Confirm git working tree is clean or intentionally scoped." %}</li>
<li>{% trans "Read the latest Project Wiki and Developer Handbook updates for architecture changes." %}</li>
<li>{% trans "Check environment changes in .env.example and deployment secrets if integrations changed." %}</li>
<li>{% trans "If dependencies changed, rebuild web and worker images before validation." %}</li>
</ul>
<pre><code>git status --short
docker compose up -d --build web worker</code></pre>
</section>
<section class="panel">
<h2>{% trans "2. Validation commands" %}</h2>
<ul class="checklist">
<li>{% trans "Run Django system checks." %}</li>
<li>{% trans "Run tests or a targeted verification command for the changed area." %}</li>
<li>{% trans "Compile translations after UI/content changes." %}</li>
<li>{% trans "If dependencies changed, verify imports do not emit warnings." %}</li>
</ul>
<pre><code>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"</code></pre>
</section>
<section class="panel">
<h2>{% trans "3. Data and asset steps" %}</h2>
<ul class="checklist">
<li>{% trans "Create and apply migrations if models changed." %}</li>
<li>{% trans "Run collectstatic if UI assets changed." %}</li>
<li>{% trans "Generate fresh PDFs if PDF templates or document logic changed." %}</li>
<li>{% trans "Confirm file outputs appear under backend/media/pdfs/." %}</li>
</ul>
<pre><code>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</code></pre>
</section>
<section class="panel">
<h2>{% trans "4. Integration checks" %}</h2>
<ul class="checklist">
<li>{% trans "Verify the health endpoint returns status ok." %}</li>
<li>{% trans "Verify MailHog in test mode or SMTP in production mode." %}</li>
<li>{% trans "Verify Nextcloud upload if synchronization behavior changed." %}</li>
<li>{% trans "Verify welcome-email scheduling or notification rules if email routing changed." %}</li>
</ul>
<pre><code>curl --max-time 8 http://127.0.0.1:8088/healthz/
docker compose exec -T web python manage.py run_staging_e2e_check</code></pre>
</section>
<section class="panel">
<h2>{% trans "5. Release evidence" %}</h2>
<ul class="checklist">
<li>{% trans "Record which checks were run and their result." %}</li>
<li>{% trans "Take a snapshot commit before moving to the next change phase." %}</li>
<li>{% trans "If a release introduces new operations or engineering behavior, update both handbooks." %}</li>
<li>{% trans "Keep at least one successful onboarding and one offboarding smoke example during major workflow changes." %}</li>
</ul>
</section>
<section class="panel">
<h2>{% trans "6. Rollback basics" %}</h2>
<ul class="checklist">
<li>{% trans "If rollout fails after code-only changes, redeploy the previous snapshot commit." %}</li>
<li>{% trans "If rollout includes schema changes, verify backward compatibility before rollback." %}</li>
<li>{% trans "If integrations fail, switch email mode/test settings conservatively before wider retry." %}</li>
<li>{% trans "Use logs from web and worker containers to isolate whether the issue is request, task, or integration related." %}</li>
</ul>
<pre><code>docker compose logs --no-color --tail=200 web
docker compose logs --no-color --tail=200 worker</code></pre>
</section>
</div>
<div class="note">{% 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." %}</div>
</div>
</body>
</html>

View File

@@ -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'),

View File

@@ -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':