Fix release blockers and deployment build
deploy / deploy (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-21 21:22:29 +02:00
parent b8091e59bd
commit a4eced8be5
64 changed files with 1011 additions and 675 deletions
+45 -21
View File
@@ -26,7 +26,7 @@ SNAPSHOT_VERSION = "1.0.0"
def _coerce_json_value(value: Any) -> Any:
if isinstance(value, (date,)):
if isinstance(value, date):
return value.isoformat()
if isinstance(value, Decimal):
return float(value)
@@ -85,7 +85,17 @@ def _latest_score_snapshot(job: JobPosting, user) -> dict[str, Any] | None:
run = (
ScoreRun.objects.filter(job=job, profile=profile)
.order_by("-created_at")
.only("score", "recommendation", "confidence", "components", "positives", "concerns", "hard_exclusions", "evidence", "profile_version")
.only(
"score",
"recommendation",
"confidence",
"components",
"positives",
"concerns",
"hard_exclusions",
"evidence",
"profile_version",
)
.first()
)
if not run:
@@ -121,7 +131,9 @@ def _build_application_snapshot_payload(application: Application) -> dict[str, A
}
def _record_timeline_event(*, application: Application, user, event_type: str, metadata: dict[str, Any] | None = None) -> ApplicationTimelineEvent:
def _record_timeline_event(
*, application: Application, user, event_type: str, metadata: dict[str, Any] | None = None
) -> ApplicationTimelineEvent:
payload: dict[str, Any] = {}
if metadata:
payload.update({key: value for key, value in metadata.items() if value is not None})
@@ -243,8 +255,11 @@ def track_application_changes(
)
events += 1
if (_normalize_str(previous.get("contact_name")) != _normalize_str(current.get("contact_name"))) or (
_normalize_str(previous.get("contact_email")) != _normalize_str(current.get("contact_email"))
if (
_normalize_str(previous.get("contact_name")) != _normalize_str(current.get("contact_name"))
) or (
_normalize_str(previous.get("contact_email"))
!= _normalize_str(current.get("contact_email"))
):
_record_timeline_event(
application=application,
@@ -266,16 +281,14 @@ def build_print_html(application: Application) -> str:
safe_rows = []
for row in timeline_rows:
safe_rows.append(
(
f"<tr>"
f"<td>{escape(row['timestamp'])}</td>"
f"<td>{escape(row['type'])}</td>"
f"<td>{escape(row['actor'])}</td>"
f"<td>{escape(row['from'])}</td>"
f"<td>{escape(row['to'])}</td>"
f"<td>{escape(row['note'])}</td>"
"</tr>"
)
f"<tr>"
f"<td>{escape(row['timestamp'])}</td>"
f"<td>{escape(row['type'])}</td>"
f"<td>{escape(row['actor'])}</td>"
f"<td>{escape(row['from'])}</td>"
f"<td>{escape(row['to'])}</td>"
f"<td>{escape(row['note'])}</td>"
"</tr>"
)
source_rows = []
@@ -284,20 +297,26 @@ def build_print_html(application: Application) -> str:
source_url = escape(str(source.get("url", "")))
source_rows.append(f"<li>{source_name}: {source_url}</li>")
source_section = "".join(source_rows) if source_rows else "<li>Niet beschikbaar</li>"
frozen_at = (
application.snapshot.get("frozen_at", "") if isinstance(application.snapshot, dict) else ""
)
snapshot_json = json.dumps(snapshot, indent=2, ensure_ascii=False, sort_keys=True)
return (
"<!doctype html><html><head><meta charset='utf-8'>"
"<title>Sollicitatiedossier</title><style>body{font-family:Arial,sans-serif;margin:24px}"
"table{border-collapse:collapse;width:100%}th,td{border:1px solid #ddd;padding:8px;text-align:left}"
"table{border-collapse:collapse;width:100%}"
"th,td{border:1px solid #ddd;padding:8px;text-align:left}"
"th{background:#f2f2f2} </style></head><body>"
f"<h1>{escape(job.original_title)}</h1>"
f"<p>Vacature: {escape(job.canonical_url)}</p>"
f"<p>Status: {escape(application.get_status_display())}</p>"
f"<p>Geslaagd op: {escape(str(application.snapshot.get('frozen_at') if isinstance(application.snapshot, dict) else ''))}</p>"
f"<p>Geslaagd op: {escape(str(frozen_at))}</p>"
f"<h2>Bronnen</h2><ul>{source_section}</ul>"
f"<h2>Timeline</h2><table><thead><tr><th>Tijd</th><th>Type</th><th>Actor</th><th>Van</th><th>Naar</th><th>Notitie</th></tr></thead><tbody>"
"<h2>Timeline</h2><table><thead><tr><th>Tijd</th><th>Type</th>"
"<th>Actor</th><th>Van</th><th>Naar</th><th>Notitie</th></tr></thead><tbody>"
f"{''.join(safe_rows)}</tbody></table>"
f"<h2>Snapshot</h2><pre>{escape(json.dumps(snapshot, indent=2, ensure_ascii=False, sort_keys=True))}</pre>"
f"<h2>Snapshot</h2><pre>{escape(snapshot_json)}</pre>"
"</body></html>"
)
@@ -315,7 +334,9 @@ def build_application_export(application: Application) -> tuple[bytes, str]:
"snapshot_version": SNAPSHOT_VERSION,
"exported_at": timezone.now().isoformat(),
"applied_at": application.applied_at.isoformat() if application.applied_at else None,
"follow_up_date": application.follow_up_date.isoformat() if application.follow_up_date else None,
"follow_up_date": application.follow_up_date.isoformat()
if application.follow_up_date
else None,
},
"snapshot": _coerce_json_value(application.snapshot),
"timeline": _timeline_dict_rows(application),
@@ -332,7 +353,10 @@ def build_application_export(application: Application) -> tuple[bytes, str]:
content_buffer = io.BytesIO()
with zipfile.ZipFile(content_buffer, "w", compression=zipfile.ZIP_DEFLATED) as zf:
zf.writestr("application.json", json.dumps(_coerce_json_value(payload), indent=2, ensure_ascii=False, sort_keys=True))
zf.writestr(
"application.json",
json.dumps(_coerce_json_value(payload), indent=2, ensure_ascii=False, sort_keys=True),
)
zf.writestr("timeline.csv", timeline_buffer.getvalue())
zf.writestr("application_print.html", build_print_html(application))