feat(validation): add editing versioning revalidation and aligned reports

This commit is contained in:
Schubert Ferenc 2026-07-11 10:26:18 +02:00
parent f73a24df13
commit 302e542fda
28 changed files with 2691 additions and 406 deletions

View file

@ -0,0 +1,201 @@
@page {
size: A4;
margin: 24mm 16mm 22mm 16mm;
@top-left {
content: "Validation Suite";
color: #4F6A74;
font-size: 9pt;
font-weight: 700;
}
@top-right {
content: string(report-number);
color: #6B7C85;
font-size: 9pt;
}
@bottom-left {
content: "Schubamed";
color: #6B7C85;
font-size: 8pt;
}
@bottom-right {
content: "Seite " counter(page) " von " counter(pages);
color: #6B7C85;
font-size: 8pt;
}
}
@page:first {
margin: 20mm 16mm 18mm 16mm;
@top-left { content: ""; }
@top-right { content: ""; }
}
* {
box-sizing: border-box;
}
html {
color: #2E3B40;
font-family: Inter, Arial, sans-serif;
font-size: 10.5pt;
line-height: 1.45;
}
body {
margin: 0;
}
.report-meta {
string-set: report-number attr(data-report-number);
}
.cover-page {
min-height: 245mm;
display: flex;
flex-direction: column;
justify-content: center;
page-break-after: always;
}
.cover-kicker {
color: #6C8A96;
font-size: 11pt;
font-weight: 700;
letter-spacing: .08em;
margin-bottom: 14mm;
text-transform: uppercase;
}
h1 {
color: #2E3B40;
font-size: 34pt;
line-height: 1.05;
margin: 0 0 8mm 0;
}
.cover-subtitle {
color: #4F6A74;
font-size: 16pt;
margin: 0 0 18mm 0;
}
.signature-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16mm;
margin-top: 18mm;
}
.signature-grid div {
border-top: 1px solid #6B7C85;
color: #6B7C85;
padding-top: 3mm;
}
.chapter {
break-before: page;
}
h2 {
border-bottom: 1px solid #E6EAEA;
color: #2E3B40;
font-size: 18pt;
margin: 0 0 8mm 0;
padding-bottom: 4mm;
}
h3 {
color: #4F6A74;
font-size: 12pt;
margin: 8mm 0 3mm 0;
}
.definition-list {
display: block;
margin: 0;
}
.definition-row {
border-bottom: 1px solid #E6EAEA;
display: grid;
grid-template-columns: 42mm 1fr;
gap: 6mm;
padding: 2.5mm 0;
}
dt {
color: #6B7C85;
font-weight: 700;
}
dd {
margin: 0;
}
.data-table {
border-collapse: collapse;
margin-top: 4mm;
table-layout: fixed;
width: 100%;
}
.data-table th {
background: #F7F8F8;
color: #4F6A74;
font-size: 8.5pt;
font-weight: 700;
text-align: left;
}
.data-table th,
.data-table td {
border: 1px solid #E6EAEA;
padding: 2.4mm;
vertical-align: top;
word-wrap: break-word;
}
.data-table.compact {
font-size: 8.5pt;
}
.toc-list {
counter-reset: toc;
list-style: none;
margin: 0;
padding: 0;
}
.toc-list li {
border-bottom: 1px solid #E6EAEA;
padding: 3mm 0;
}
.toc-list a {
color: #2E3B40;
text-decoration: none;
}
@media screen {
body {
background: #F7F8F8;
padding: 24px;
}
.report-document {
background: #FFFFFF;
box-shadow: 0 14px 40px rgba(46, 59, 64, 0.08);
margin: 0 auto;
max-width: 960px;
padding: 48px;
}
.cover-page {
min-height: auto;
}
.chapter {
break-before: auto;
margin-top: 48px;
}
}

View file

@ -0,0 +1,28 @@
from __future__ import annotations
from pathlib import Path
from app.modules.orion.context import ReportContext
from app.modules.orion.html import text
def render_document(context: ReportContext, chapters: list[str]) -> str:
css = (Path(__file__).resolve().parent / "report.css").read_text(encoding="utf-8")
title = f"Validierungsbericht {context.validation.report_number}"
chapter_markup = "\n".join(chapters)
return f"""<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{text(title)}</title>
<style>{css}</style>
</head>
<body>
<article class="report-document">
<div class="report-meta" data-report-number="{text(context.validation.report_number)}"></div>
{chapter_markup}
</article>
</body>
</html>"""