Onyscribe Admin: Initialer Stand

Admin-Plattform für die Tenants von Onyscribe: Editor mit Live-Vorschau (echter Core in Sandbox), Versionen, KI-Agent (Cortecs),
OIDC-Abgleich über die Login-Developer-API, Deploy-Engine (Mittwald, gesperrt ohne DEPLOY_LIVE, Freigabe pro Tenant),
Core-Vertrag (Schema/Manifest), Core-Releases mit Kompatibilitätsprüfung, Canary-Rollout und Rollback, Zustandsabgleich.
Runbook: docs/RUNBOOK_PARALLELTEST.md

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
RubenRWU
2026-10-15 15:30:26 +02:00
commit 7d8c226da2
89 changed files with 13975 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
/* Default PDF stylesheet. Rendered through Jinja, so colour tokens like
colors.accent (in double curly braces) from the tenant config are available.
Copy this file into a tenant folder and edit freely to give a customer a
completely individual PDF design. */
@page {
size: A4;
margin: 26mm 22mm 24mm 22mm;
@top-left {
content: element(runHdrText);
vertical-align: bottom;
}
@top-right {
content: element(runHdrLogo);
vertical-align: bottom;
}
@bottom-left {
content: element(runFtr);
vertical-align: top;
}
@bottom-right {
content: "Seite " counter(page, decimal-leading-zero) " / " counter(pages, decimal-leading-zero);
vertical-align: top;
font-size: 7.5pt;
font-style: italic;
color: {{ colors.text_3 }};
}
}
body {
font-family: "Noto Sans", "DejaVu Sans", Arial, sans-serif;
font-size: 9.8pt;
color: #000000;
margin: 0;
}
/* ── running header / footer ── */
.run-hdr-text {
position: running(runHdrText);
font-style: italic;
font-size: 9pt;
color: {{ colors.text_2 }};
}
.run-hdr-logo {
position: running(runHdrLogo);
height: 12mm;
}
.run-ftr {
position: running(runFtr);
font-size: 7pt;
line-height: 1.4;
color: {{ colors.text_2 }};
}
/* ── optional document title (tenant sets doc_title) ── */
.doc-title {
color: {{ colors.accent_dark }};
font-size: 16pt;
font-weight: 700;
margin: 0 0 3mm 0;
}
/* ── metadata block ── */
.meta {
width: 100%;
border-collapse: collapse;
margin: 2mm 0 6mm 0;
}
.meta-left { width: 50%; vertical-align: top; padding: 0; }
.meta-right { width: 50%; vertical-align: top; text-align: right; padding: 0; }
.meta-label {
color: {{ colors.accent }};
font-style: italic;
font-size: 11pt;
margin-bottom: 1.8mm;
}
.meta-sublabel {
color: {{ colors.accent }};
font-weight: 700;
font-size: 9.5pt;
margin: 3mm 0 1mm 0;
}
.meta-val {
font-size: 10.2pt;
line-height: 1.45;
}
/* ── content sections ── */
.proto-section { margin-bottom: 3.5mm; }
.section-bar {
background: {{ colors.accent_light }};
color: {{ colors.accent_dark }};
font-size: 10pt;
font-weight: 700;
padding: 1.8mm 2.5mm;
margin: 0 0 2.5mm 0;
break-after: avoid;
}
.para {
margin: 0 0 1.8mm 6mm;
line-height: 1.5;
}
.bullets {
margin: 0 0 1.8mm 0;
padding-left: 10mm;
list-style: disc;
}
.bullets li {
margin: 0 0 0.8mm 0;
line-height: 1.5;
}

View File

@@ -0,0 +1,59 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Gesprächsprotokoll {{ terminart }} – {{ project_display }}</title>
</head>
<body>
{# ── running header/footer: pulled into the @page margin boxes by the CSS ── #}
<div class="run-hdr-text">{{ terminart }} &nbsp;|&nbsp; Gesprächsprotokoll</div>
{% if logo_data_uri %}<img class="run-hdr-logo" src="{{ logo_data_uri }}" alt="{{ tenant.name }}">{% endif %}
<div class="run-ftr">
<div>Gesprächsprotokoll · {{ terminart }} · {{ date_de }} · {{ project_display }}</div>
<div>Erstellt durch: {{ office.name }}{% if office.subtitle %} {{ office.subtitle }}{% endif %}{% if office.tel %} • {{ office.tel }}{% endif %}{% if office.email %} • {{ office.email }}{% endif %}</div>
<div>{{ footer_note }}</div>
</div>
{% if doc_title %}<h1 class="doc-title">{{ doc_title }}</h1>{% endif %}
{# ── metadata: two columns (Projekt / Erstellt durch) ── #}
<table class="meta">
<tr>
<td class="meta-left">
<div class="meta-label">{{ projekt_label }}</div>
{% for line in projekt %}<div class="meta-val">{{ line }}</div>{% endfor %}
{% if kontakt %}
<div class="meta-sublabel">Ansprechpartner Kunde</div>
{% for line in kontakt %}<div class="meta-val">{{ line }}</div>{% endfor %}
{% endif %}
</td>
<td class="meta-right">
<div class="meta-label">Erstellt durch</div>
{% if office.name %}<div class="meta-val">{{ office.name }}{% if office.subtitle %} {{ office.subtitle }}{% endif %}</div>{% endif %}
{% for line in (office.address or "").splitlines() %}<div class="meta-val">{{ line }}</div>{% endfor %}
{% if office.tel %}<div class="meta-val">{{ office.tel }}</div>{% endif %}
{% if office.email %}<div class="meta-val">{{ office.email }}</div>{% endif %}
{% if office.website %}<div class="meta-val">{{ office.website }}</div>{% endif %}
</td>
</tr>
</table>
{# ── content sections ── #}
{% for section in sections %}
<section class="proto-section">
<h2 class="section-bar">{{ section.heading }}</h2>
{% for block in section.blocks %}
{% if block.type == 'paragraph' %}
<p class="para">{{ block.text }}</p>
{% elif block.type == 'list' %}
<ul class="bullets">
{% for item in block['items'] %}<li>{{ item }}</li>{% endfor %}
</ul>
{% endif %}
{% endfor %}
</section>
{% endfor %}
</body>
</html>