Compare commits

...

15 Commits

Author SHA1 Message Date
Claude
94b539ed24
feat(ai-act-kompass): include training register in JSON backup (schema v3)
Some checks failed
security-scan / secret-scan (push) Failing after 5s
The training register incl. scan attachments and checksums is now part
of the backup export/import — the Art. 4 evidence chain survives device
moves. Older backups (v1/v2) remain importable.

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 11:37:14 +00:00
Claude
dc09999472
feat(ai-act-kompass): verified evidence chain for the AI literacy test
- Manual participant entry for paper tests: name + correct answers →
  register entry with source 'paper' (app runs are tagged 'app')
- Scan upload per register entry: marked paper sheets (image/PDF,
  max 1 MB) stored locally as data URL and anchored with a SHA-256
  checksum of the original file; view scan in-app, checksum shown
- Document verification: certificate and training register printouts
  carry a SHA-256 checksum footer over the document content — a
  presented printout can be re-verified against the tool; certificate
  additionally references its register entry ID (evidence chain
  certificate ↔ register ↔ scan)
- Register printout extended with source, evidence checksum and ID
  columns; record deletion with confirmation warning
- UI labels in all nine languages; 73 tests green

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 11:35:58 +00:00
Claude
c35318a240
feat(ai-act-kompass): answer key now includes the questions themselves
The answer key is self-contained for markers: each entry shows the
question text, the correct answer spelled out (letter + wording) and
the explanation — no need to hold the test sheet next to it.
Test updated accordingly (72 green).

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 11:32:19 +00:00
Claude
ca58f1738f
feat(ai-act-kompass): printable training materials (paper test, answer key, handout)
- Paper version of the AI literacy test: name/date/department fields,
  12 questions with tick boxes (A/B/C), marking line and signature
  block — for employees without computer access; contains no answers
- Answer key for markers: correct letter plus explanation per question,
  pass threshold noted
- Training handout: the 12 core rules (question + explanation) as
  Art. 4 training material to distribute before the test
- All printable with company letterhead via the existing print/PDF
  pipeline and downloadable; buttons in the quiz view under 'Print
  training materials'; UI labels in all nine languages (document body
  DE/EN with EN fallback, full localization follows the content pack)
- 3 new tests (72 total)

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 11:29:14 +00:00
Claude
efdc60fe84
feat(ai-act-kompass): quiz question bank in all nine languages
All 12 AI literacy test questions (question, 3 options, explanation —
540 strings) translated to FR/IT/ES/PL/CS/SK/RO with official EU AI
Act terminology and locale-appropriate GDPR abbreviations (RGPD/RODO/
GDPR); light humour of the distractor answers preserved.

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 11:18:59 +00:00
Claude
21946a157f
feat(ai-act-kompass): AI literacy test (Art. 4) with certificate and training register
- Simple 12-question basics quiz ('for dummies'): how AI works,
  hallucinations, confidential data, human oversight, chatbot
  disclosure (Art. 50), prohibited practices (Art. 5), high-risk
  (Annex III), GDPR, internal incident reporting (Art. 73), shadow AI
  approval, content marking, the Art. 4 duty itself — 3 options each,
  pass threshold 70%
- Evaluation view with per-question explanations (learning effect),
  pass/fail stamp badge
- Printable certificate (letterhead) as Art. 4 evidence: name, date,
  score, topics covered, signature lines — files into the existing
  training plan documentation
- Local training register (localStorage): every run recorded (name,
  date, score, status), printable as continuous Art. 4 evidence
  register; cleared with all-data delete
- New nav entry; UI strings in all nine languages; question bank
  currently DE/EN (translations for the other seven languages follow
  in the next commit)
- 6 new tests (69 total)

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 11:09:55 +00:00
Claude
3a08392669
feat(ai-act-kompass): calendar reminders via iCalendar (.ics) export
- New RFC 5545 generator: all future obligation deadlines (per system)
  plus upcoming AI Act application dates as all-day events, each with
  two DISPLAY alarms (30 and 7 days ahead), stable UIDs for
  re-import/update, proper escaping and 75-octet line folding, CRLF
- Export button in the tasks view downloads ai-act-fristen-<date>.ics
  (text/calendar) — opens in Outlook, Apple Calendar, Google Calendar,
  Thunderbird on phone and desktop; no server involved (local-first)
- Event titles and descriptions localized via the active content pack
  (all nine languages); button and hint translated in all dictionaries
- 5 new tests: calendar frame, future-only filter, stable UIDs, alarm
  count, escaping/folding, localized summaries (63 total)

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 11:02:28 +00:00
Claude
9b25985281
feat(ai-act-kompass): Polish, Czech, Slovak and Romanian — nine full languages
Complete translations (UI, content pack, obligations catalogue,
national modules, classification reasons, document strings, Annex IV
sections incl. new FR/IT/ES section translations, procurement spec,
conformity declaration, all 10 template documents) for pl/cs/sk/ro,
using the official terminology of the respective language versions of
Regulation (EU) 2024/1689 (e.g. podmiot stosujący, zavádějící subjekt,
nasadzujúci subjekt, implementator). Locale architecture extended to
nine languages with EN fallback reserved for future additions;
language switcher, browser detection, locale-aware date formats
(dots for de/pl/cs/sk/ro), localized Annex IV title; language hints
updated; dictionary-completeness and real-translation tests now cover
all seven non-DE/EN locales (58 tests green).

Note: pl/cs/sk/ro legal texts are machine-drafted against official
terminology — native legal review recommended before market launch.

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 10:30:00 +00:00
Claude
935fa8849e
feat(ai-act-kompass): complete FR/IT/ES legal-content translations
Every user-visible text is now fully available in all five languages
(DE/EN/FR/IT/ES) — no English fallback remains in the product:
- Content pack: AI definition criteria, prohibited practices, Annex III
  areas, transparency triggers, deadlines (36 entries)
- Obligations catalogue: all 26 EU obligations (title + description)
- National modules: all 6 countries incl. authority descriptions
- Classification reasons (classify engine)
- Document strings, risk/role/status labels, disclaimers, Annex IV
- Procurement spec (12 requirements, DOIT/DEVE/DEBE priorities) and
  EU declaration of conformity (numbering-preserving field prefill)
- All 10 template documents (works council, employee info, FRIA,
  incident report, AI policy, training plan, works agreement,
  reporting policy, approval request, audit checklist)
Official terminology of the FR/IT/ES language versions of Regulation
(EU) 2024/1689 (e.g. hypertrucages/ultrafalsificaciones, contrôle
humain, alfabetizzazione in materia di IA); German statute names
(BetrVG, HinSchG, KI-MIG) kept as proper nouns.
Language hints updated; tests now assert real translations instead of
EN fallback (58 tests green).

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 10:16:12 +00:00
Claude
08968a85a1
feat(ai-act-kompass): FR/IT/ES locales, EN fallback architecture, PWA install support
- Full UI dictionaries for French, Italian and Spanish (all views,
  wizard, legal gate, templates); browser-language auto-detection
  extended to all five locales
- Fallback architecture: LText now carries optional fr/it/es entries;
  regulatory legal texts (content pack, classify reasons, document
  strings) fall back to English until legal translations land —
  clearly stated in the language setting
- Locale-aware date formatting (DE dots, FR/IT/ES slashes, EN ISO)
- PWA: web app manifest, network-first service worker with offline
  cache fallback, generated icons (512/192/apple-touch) — installable
  on phone home screen and macOS dock
- 2 new tests incl. dictionary-completeness check for FR/IT/ES
  (58 total)

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 10:05:28 +00:00
Claude
45c8c9557d
feat(ai-act-kompass): internal process documents (reporting policy, approval, audit)
- Internal reporting & escalation policy: internal reporting duty for
  AI incidents with 24h/48h internal deadlines, three escalation
  levels, incident register, whistleblower protection note — feeds the
  statutory Art. 73 report
- AI system approval request form: internal gate against shadow AI
  with risk pre-screening and decision block
- Internal AI compliance audit checklist: periodic self-review
  (inventory/shadow IT, classifications, trainings, logs, incidents,
  provider documents, works agreements, country-module changes) with
  sign-off
- All bilingual (DE/EN), letterhead-printable; 4 new tests (56 total)

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 09:50:23 +00:00
Claude
2ec13165c8
feat(ai-act-kompass): internal and external regulatory templates (works council etc.)
- Company-wide templates view: internal AI policy (framework), AI
  literacy training plan & record (Art. 4) listing inventory systems,
  works agreement on AI (Sec. 87(1) No. 6 / Sec. 90 BetrVG draft)
- System-specific forms in detail view (role/risk/country gated):
  works council information letter (Sec. 90 BetrVG, DE module),
  employee information on AI use (Art. 26(7) / Law 132/2025),
  FRIA working template (Art. 27), serious incident report form
  (Art. 73 incl. 15/10/2-day deadlines)
- All templates bilingual (DE/EN), letterhead-printable, placeholder-
  based drafts with legal disclaimer
- 8 new tests (52 total)

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 09:23:04 +00:00
Claude
cd31274738
feat(ai-act-kompass): i18n, national modules, task checklist, legal gate, new documents
- Full i18n (DE/EN): UI, rules engine, content pack and generated
  documents; language switcher, browser-language default, architecture
  extensible to further EU languages via localized source texts
- National country modules (opt-in per company profile): DE (KI-MIG/
  BNetzA supervision, works council co-determination Sec. 87 BetrVG,
  GDPR/BDSG), AT (RTR AI service desk), IT (Law 132/2025: employer info
  duty, deepfake criminal liability, sector decrees), ES (AESIA,
  sandbox RD 817/2023), FR (CNIL guidance), NL (algorithm register);
  merged into obligation derivation, checklists and documents
- New EU obligations: corrective actions (Art. 20/21), authorised
  representative (Art. 22), EU database registration for public-body
  deployers (Art. 49(3)), post-market monitoring (Art. 72), serious
  incident reporting (Art. 73), GDPR DPIA (Art. 35 GDPR / 26(9))
- New documents: AI procurement requirements specification (MUST/SHOULD
  matrix for vendors) and EU declaration of conformity draft (Annex V)
- Cross-system checkable task list (due now / upcoming / done) with
  progress bar, one-tap toggling, per-system links
- Legal safety: first-run acknowledgement gate (working aid, no legal
  services), legal notice panel in settings, result-screen disclaimer,
  disclaimers on every document
- Responsive layout for phone/tablet (top-bar nav, scrollable tables,
  larger tap targets)
- 12 new tests (44 total): EN pack parity, national merge, checklist
  grouping, new document generators

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 09:18:07 +00:00
Claude
06574c5cfd
feat(ai-act-kompass): anti-AI print design and company personalization
- Full redesign: paper tone, serif typography, hairlines, rectangular
  stamp badges, mono labels — technical print look instead of SaaS style,
  no gradients/shadows/emoji
- Company profile settings (name, address, contact person, email, phone,
  website, logo upload as local data URL) persisted in localStorage and
  included in JSON backup (schema v2, v1 imports still supported)
- Print/PDF output via letterhead print view (window.print): logo,
  company name and contact data in header, contact line in footer;
  applies to risk report, action plan, Annex IV skeleton and inventory
- Company block also embedded in generated Markdown headers
- Minimal auditable Markdown renderer (no external parser), HTML-escaped
- 8 new tests (32 total)

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 09:18:07 +00:00
Claude
fb2da0db00
feat: add AI-Act-Kompass — standalone EU AI Act compliance toolkit for SMEs
Local-first React/Vite app (no cloud, no telemetry, localStorage only):
- Assessment wizard classifying AI systems per AI Act systematics
  (Art. 3 definition, Art. 5 prohibitions, Art. 6/Annex I+III high-risk
  incl. Art. 6(3) exception and profiling bar, Art. 50 transparency, GPAI)
- Role-specific obligation checklists (provider/deployer/importer/distributor)
  with legal basis, deadlines and implementation status
- Document generator: risk report, action plan, Annex IV skeleton (Markdown)
- AI inventory with export, deadline overview incl. Digital Omnibus shift
- Versioned regulatory content pack modeled as data for future update feed
- Engine fully unit-tested (24 tests), TS strict, static build

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
2026-07-04 08:03:16 +00:00
64 changed files with 15163 additions and 0 deletions

3
.gitignore vendored
View File

@ -34,3 +34,6 @@ docker-compose.override.yml
app/.next/
dist/
*.local
# TS incremental build
*.tsbuildinfo

42
ai-act-kompass/README.md Normal file
View File

@ -0,0 +1,42 @@
# AI-Act-Kompass
**Standalone EU-AI-Act-Compliance-Toolkit für europäische Unternehmen (KMU-Fokus).** Local-first: keine Cloud, keine Telemetrie, keine Datenübertragung — alle Daten bleiben im Browser des Nutzers (localStorage, mit JSON-Export/-Import). Mehrsprachig (DE/EN, erweiterbar), responsiv für Handy, Tablet und Desktop.
> ⚠️ Strukturierte Arbeitshilfe auf Basis der Verordnung (EU) 2024/1689 — **keine Rechtsberatung** und keine Rechtsdienstleistung i. S. d. RDG. Beim ersten Start bestätigungspflichtiger rechtlicher Hinweis; Disclaimer in App und allen Dokumenten.
## Was es kann
- **Bewertungs-Wizard**: erfasst ein KI-System und klassifiziert es automatisch nach der Systematik des AI Act — KI-Definition (Art. 3 Nr. 1) → verbotene Praktiken (Art. 5) → Hochrisiko (Art. 6, Annex I/III, inkl. Ausnahme Art. 6 Abs. 3 und Profiling-Sperre) → Transparenzpflichten (Art. 50) → minimales Risiko. GPAI-Pflichten (Art. 53 ff.) werden separat geflaggt.
- **Aufgaben & Fristen**: systemübergreifende, abhakbare Pflichtenliste („Jetzt fällig / Kommt auf Sie zu / Erledigt") mit Fortschrittsanzeige — mobiltauglich.
- **KI-Inventar**: alle Systeme des Unternehmens mit Risikoklasse, Rolle und Verantwortlichen — exportierbar als Markdown (AI Asset Register).
- **Pflichten-Checklisten**: rollenspezifisch (Anbieter/Betreiber/Einführer/Händler) abgeleitete EU-Pflichten (Art. 473) mit Rechtsgrundlage, Geltungsfrist und Umsetzungsstatus.
- **Länder-Module** (zuschaltbar): nationale Zusatzanforderungen für DE (KI-MIG/BNetzA, § 87 BetrVG, DSGVO/BDSG), AT (RTR-KI-Servicestelle), IT (Legge 132/2025: Arbeitgeber-Info, Deepfake-Strafnormen, Sektorregeln), ES (AESIA, Sandbox RD 817/2023), FR (CNIL), NL (Algorithmenregister). Bei grenzüberschreitender Zusammenarbeit mehrere Länder aktivieren.
- **Dokumenten-Generator** (Markdown + Druck/PDF mit Firmen-Briefkopf): Risikobericht, Maßnahmenplan, Annex-IV-Grundgerüst, **Lastenheft KI-Beschaffung** (AI-Act-Anforderungen an Anbieter, MUSS/SOLL) und **EU-Konformitätserklärung** (Entwurf nach Art. 47/Annex V).
- **Vorlagen & Vordrucke** (zweisprachig, druckbar): unternehmensweit **KI-Richtlinie**, **Schulungsplan/Nachweis KI-Kompetenz** (Art. 4) und **Betriebsvereinbarung KI** (§ 87/§ 90 BetrVG); systembezogen **Betriebsrats-Information** (§ 90 BetrVG), **Mitarbeiterinformation** (Art. 26 Abs. 7 / Legge 132), **FRIA-Arbeitsvorlage** (Art. 27) und **Vorfallmeldung** (Art. 73 mit Fristen).
- **Firmenprofil**: Logo, Name, Kontaktdaten — erscheinen in Briefkopf und Fußzeile aller gedruckten Dokumente.
- **Fristen-Übersicht**: alle Geltungsfristen des AI Act inkl. der Digital-Omnibus-Verschiebung (Annex III → 02.12.2027).
## Architektur
| Schicht | Inhalt |
|---|---|
| `src/engine/` | Reine, getestete Regel-Engine: `classify`, `deriveObligations`, Dokumenten-Generatoren. Kein DOM, keine Seiteneffekte. |
| `src/content/` | Versionierter regulatorischer **Content-Pack** (Verbote, Annex-III-Bereiche, Pflichten, Fristen) als Daten — vorbereitet für einen späteren signierten Update-Feed. |
| `src/store/` | localStorage-Persistenz + Export/Import (JSON). |
| `src/ui/` | React-UI (Dashboard, Wizard, Detailansicht, Einstellungen), Deutsch. |
Kein Backend, kein Build-Server nötig — `dist/` ist eine statische Site und läuft von Datei-Share, Intranet oder localhost.
## Entwicklung
```bash
npm install
npm run dev # Dev-Server
npm test # Engine-Tests (Vitest)
npm run typecheck # TS strict
npm run build # Statischer Build nach dist/
```
## Geschäftsmodell (geplant)
Standalone-App + Abo für den **Regulatory-Content-Feed**: Die App gehört dem Kunden und läuft lokal; das Abo liefert aktualisierte Regelinhalte (delegierte Rechtsakte, harmonisierte Normen, Fristenänderungen), Templates und Norm-Mappings. Synergie mit `@shieldx/core`: Art.-15-Pflicht (Robustheit/Cybersicherheit gegen Prompt Injection & Co.) verweist direkt auf ShieldX als technische Umsetzung.

17
ai-act-kompass/index.html Normal file
View File

@ -0,0 +1,17 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="AI-Act-Kompass — EU AI Act Compliance-Toolkit für KMU. Local-first, keine Cloud." />
<meta name="theme-color" content="#14120e" />
<link rel="manifest" href="./manifest.webmanifest" />
<link rel="icon" type="image/png" href="./icon-192.png" />
<link rel="apple-touch-icon" href="./apple-touch-icon.png" />
<title>AI-Act-Kompass</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

2135
ai-act-kompass/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
{
"name": "@shieldx/ai-act-kompass",
"version": "0.1.0",
"private": true,
"description": "AI-Act-Kompass — Standalone EU AI Act Compliance-Toolkit für KMU. Local-first, keine Cloud, keine Datenübertragung.",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview",
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.4",
"typescript": "^5.6.3",
"vite": "^5.4.11",
"vitest": "^2.1.8"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,14 @@
{
"name": "AI-Act-Kompass",
"short_name": "AI-Act-Kompass",
"description": "EU AI Act Compliance-Toolkit für KMU — local-first, mehrsprachig, keine Cloud.",
"start_url": "./",
"scope": "./",
"display": "standalone",
"background_color": "#f4f1ea",
"theme_color": "#14120e",
"icons": [
{ "src": "icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
]
}

View File

@ -0,0 +1,46 @@
/*
* Service Worker des AI-Act-Kompass.
* Strategie: Network-first mit Cache-Fallback die App bleibt offline
* nutzbar (Handy/Mac), lädt aber online immer die aktuelle Version.
* Es werden ausschließlich eigene (same-origin) GET-Antworten gecacht.
*/
const CACHE = 'ai-act-kompass-v1';
self.addEventListener('install', () => {
self.skipWaiting();
});
self.addEventListener('activate', (event) => {
event.waitUntil(
caches
.keys()
.then((keys) => Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k))))
.then(() => self.clients.claim()),
);
});
self.addEventListener('fetch', (event) => {
const { request } = event;
if (request.method !== 'GET' || new URL(request.url).origin !== location.origin) {
return;
}
event.respondWith(
caches.open(CACHE).then(async (cache) => {
try {
const fresh = await fetch(request);
if (fresh.ok) {
cache.put(request, fresh.clone());
}
return fresh;
} catch (err) {
const cached = await cache.match(request, { ignoreSearch: true });
if (cached) return cached;
if (request.mode === 'navigate') {
const shell = await cache.match('./index.html');
if (shell) return shell;
}
throw err;
}
}),
);
});

View File

@ -0,0 +1,101 @@
import type {
ContentItem,
ContentPack,
Deadline,
NationalPack,
Obligation,
} from '../engine/types';
import { resolveText } from '../i18n/types';
import type { Locale, LText } from '../i18n/types';
import {
AI_DEFINITION_CRITERIA,
ANNEX_III_CATEGORIES,
DEADLINES,
PROHIBITED_PRACTICES,
TRANSPARENCY_TRIGGERS,
} from './packCore';
import { NATIONAL_PACKS } from './packNational';
import { OBLIGATIONS } from './packObligations';
import type { ContentItemSrc, DeadlineSrc, NationalPackSrc, ObligationSrc } from './sourceTypes';
/**
* Regulatorischer Content-Pack v2026.07.
*
* Kodifiziert den Stand der Verordnung (EU) 2024/1689 (AI Act) inkl. der
* durch das Digital-Omnibus-Paket verschobenen Annex-III-Fristen sowie
* nationale Zusatzmodule (DE, AT, IT, ES, FR, NL). Quelltexte sind
* lokalisiert (DE/EN) und werden hier je Sprache aufgelöst vorbereitet
* für einen späteren signierten Update-Feed.
*
* WICHTIG: Inhalte sind eine strukturierte Arbeitshilfe, keine Rechtsberatung.
*/
const VERSION = '2026.07.1';
const RELEASED_AT = '2026-07-04';
const LEGAL_BASIS: LText = {
de: 'Verordnung (EU) 2024/1689 (AI Act) + nationale Module, Stand Juli 2026',
en: 'Regulation (EU) 2024/1689 (AI Act) + national modules, as of July 2026',
};
function resolveItem(src: ContentItemSrc, locale: Locale): ContentItem {
return {
id: src.id,
label: resolveText(src.label, locale),
legalRef: src.legalRef,
...(src.hint ? { hint: resolveText(src.hint, locale) } : {}),
};
}
function resolveObligation(src: ObligationSrc, locale: Locale): Obligation {
return {
id: src.id,
title: resolveText(src.title, locale),
articles: src.articles,
description: resolveText(src.description, locale),
deadline: src.deadline,
roles: src.roles,
riskClasses: src.riskClasses,
};
}
function resolveDeadline(src: DeadlineSrc, locale: Locale): Deadline {
return {
id: src.id,
date: src.date,
label: resolveText(src.label, locale),
description: resolveText(src.description, locale),
};
}
function resolveNational(src: NationalPackSrc, locale: Locale): NationalPack {
return {
code: src.code,
country: resolveText(src.country, locale),
authority: resolveText(src.authority, locale),
items: src.items.map((i) => resolveObligation(i, locale)),
};
}
/**
* Liefert den Content-Pack in der gewünschten Sprache.
*
* @param locale - Zielsprache (de/en)
* @returns Vollständig aufgelöster Content-Pack
*/
export function getContentPack(locale: Locale): ContentPack {
return {
version: VERSION,
releasedAt: RELEASED_AT,
legalBasis: resolveText(LEGAL_BASIS, locale),
aiDefinitionCriteria: AI_DEFINITION_CRITERIA.map((i) => resolveItem(i, locale)),
prohibitedPractices: PROHIBITED_PRACTICES.map((i) => resolveItem(i, locale)),
annexIIICategories: ANNEX_III_CATEGORIES.map((i) => resolveItem(i, locale)),
transparencyTriggers: TRANSPARENCY_TRIGGERS.map((i) => resolveItem(i, locale)),
obligations: OBLIGATIONS.map((o) => resolveObligation(o, locale)),
deadlines: DEADLINES.map((d) => resolveDeadline(d, locale)),
national: NATIONAL_PACKS.map((n) => resolveNational(n, locale)),
};
}
/** Deutscher Content-Pack (Kompatibilitäts-Export, u. a. für Tests). */
export const CONTENT_PACK: ContentPack = getContentPack('de');

View File

@ -0,0 +1,529 @@
import type { ContentItemSrc, DeadlineSrc } from './sourceTypes';
/** Kriterien der KI-Definition (Art. 3 Nr. 1). */
export const AI_DEFINITION_CRITERIA: readonly ContentItemSrc[] = [
{
id: 'def-autonomy',
label: {
de: 'Das System arbeitet mit einem gewissen Grad an Autonomie (nicht rein regelbasiert deterministisch durch den Nutzer gesteuert).',
en: 'The system operates with a degree of autonomy (not purely rule-based and deterministically controlled by the user).',
fr: 'Le système fonctionne avec un certain degré dautonomie (il nest pas purement fondé sur des règles et contrôlé de manière déterministe par lutilisateur).',
it: 'Il sistema opera con un certo grado di autonomia (non è puramente basato su regole e controllato in modo deterministico dallutente).',
es: 'El sistema funciona con un cierto grado de autonomía (no está puramente basado en reglas ni controlado de forma determinista por el usuario).',
pl: 'System działa z pewnym poziomem autonomii (nie jest czysto oparty na regułach i deterministycznie sterowany przez użytkownika).',
cs: 'Systém funguje s určitou úrovní autonomie (není čistě založen na pravidlech a deterministicky řízen uživatelem).',
sk: 'Systém funguje s určitou úrovňou autonómie (nie je čisto založený na pravidlách a deterministicky riadený používateľom).',
ro: 'Sistemul funcționează cu un anumit nivel de autonomie (nu este pur bazat pe reguli și controlat în mod determinist de utilizator).',
},
legalRef: 'Art. 3 Nr. 1',
},
{
id: 'def-inference',
label: {
de: 'Das System leitet aus Eingaben ab, wie Ausgaben (Vorhersagen, Inhalte, Empfehlungen, Entscheidungen) erzeugt werden.',
en: 'The system infers from inputs how to generate outputs (predictions, content, recommendations, decisions).',
fr: 'Le système déduit, à partir des entrées quil reçoit, la manière de générer des sorties (prédictions, contenus, recommandations, décisions).',
it: 'Il sistema deduce dagli input come generare output (previsioni, contenuti, raccomandazioni, decisioni).',
es: 'El sistema infiere de la información de entrada cómo generar resultados de salida (predicciones, contenidos, recomendaciones, decisiones).',
pl: 'System wnioskuje na podstawie otrzymanych danych wejściowych, jak generować wyniki (predykcje, treści, zalecenia, decyzje).',
cs: 'Systém z obdržených vstupů odvozuje, jak generovat výstupy (predikce, obsah, doporučení, rozhodnutí).',
sk: 'Systém zo vstupov, ktoré dostáva, odvodzuje, ako generovať výstupy (predpovede, obsah, odporúčania, rozhodnutia).',
ro: 'Sistemul deduce, din datele de intrare pe care le primește, modul de a genera rezultate (previziuni, conținuturi, recomandări, decizii).',
},
legalRef: 'Art. 3 Nr. 1',
},
{
id: 'def-influence',
label: {
de: 'Die Ausgaben können physische oder virtuelle Umgebungen beeinflussen.',
en: 'The outputs can influence physical or virtual environments.',
fr: 'Les sorties peuvent influencer les environnements physiques ou virtuels.',
it: 'Gli output possono influenzare ambienti fisici o virtuali.',
es: 'Los resultados de salida pueden influir en entornos físicos o virtuales.',
pl: 'Wyniki mogą wywierać wpływ na środowiska fizyczne lub wirtualne.',
cs: 'Výstupy mohou ovlivňovat fyzická nebo virtuální prostředí.',
sk: 'Výstupy môžu ovplyvňovať fyzické alebo virtuálne prostredia.',
ro: 'Rezultatele pot influența medii fizice sau virtuale.',
},
legalRef: 'Art. 3 Nr. 1',
},
];
/** Verbotene Praktiken (Art. 5). */
export const PROHIBITED_PRACTICES: readonly ContentItemSrc[] = [
{
id: 'proh-manipulation',
label: {
de: 'Unterschwellige oder gezielt manipulative Techniken, die Verhalten wesentlich verändern und erheblichen Schaden verursachen (können).',
en: 'Subliminal or purposefully manipulative techniques that materially distort behaviour and cause (or are likely to cause) significant harm.',
fr: 'Techniques subliminales ou délibérément manipulatrices qui altèrent substantiellement le comportement et causent (ou sont susceptibles de causer) un préjudice important.',
it: 'Tecniche subliminali o volutamente manipolative che alterano sostanzialmente il comportamento e causano (o possono causare) un danno significativo.',
es: 'Técnicas subliminales o deliberadamente manipuladoras que alteran sustancialmente el comportamiento y causan (o pueden causar) un perjuicio considerable.',
pl: 'Techniki podprogowe lub celowo manipulacyjne, które dokonują znaczącej zmiany zachowania i wyrządzają (lub mogą wyrządzić) poważną szkodę.',
cs: 'Podprahové nebo záměrně manipulativní techniky, které podstatně narušují chování a způsobují (nebo mohou způsobit) významnou újmu.',
sk: 'Podprahové alebo zámerne manipulatívne techniky, ktoré podstatne narúšajú správanie a spôsobujú (alebo môžu spôsobiť) značnú ujmu.',
ro: 'Tehnici subliminale sau intenționat manipulatoare care denaturează în mod semnificativ comportamentul și cauzează (sau pot cauza) prejudicii semnificative.',
},
legalRef: 'Art. 5 Abs. 1 lit. a',
},
{
id: 'proh-vulnerability',
label: {
de: 'Ausnutzung von Schwächen aufgrund von Alter, Behinderung oder sozialer/wirtschaftlicher Lage mit erheblichem Schadensrisiko.',
en: 'Exploitation of vulnerabilities due to age, disability or social/economic situation with a significant risk of harm.',
fr: 'Exploitation des vulnérabilités dues à lâge, au handicap ou à la situation sociale ou économique, avec un risque important de préjudice.',
it: 'Sfruttamento delle vulnerabilità dovute alletà, alla disabilità o alla situazione sociale o economica, con un rischio significativo di danno.',
es: 'Explotación de vulnerabilidades derivadas de la edad, la discapacidad o la situación social o económica, con un riesgo considerable de perjuicio.',
pl: 'Wykorzystywanie słabości ze względu na wiek, niepełnosprawność lub sytuację społeczną lub ekonomiczną, ze znacznym ryzykiem poważnej szkody.',
cs: 'Zneužívání zranitelnosti v důsledku věku, zdravotního postižení nebo sociální či ekonomické situace s významným rizikem újmy.',
sk: 'Zneužívanie zraniteľností v dôsledku veku, zdravotného postihnutia alebo sociálnej či ekonomickej situácie so značným rizikom ujmy.',
ro: 'Exploatarea vulnerabilităților legate de vârstă, dizabilitate sau de situația socială ori economică, cu un risc semnificativ de prejudiciu.',
},
legalRef: 'Art. 5 Abs. 1 lit. b',
},
{
id: 'proh-social-scoring',
label: {
de: 'Social Scoring: Bewertung von Personen anhand ihres Sozialverhaltens mit ungerechtfertigter Schlechterstellung.',
en: 'Social scoring: evaluating persons based on social behaviour leading to unjustified detrimental treatment.',
fr: 'Notation sociale : évaluation des personnes sur la base de leur comportement social entraînant un traitement défavorable injustifié.',
it: 'Punteggio sociale (social scoring): valutazione delle persone sulla base del loro comportamento sociale con un trattamento pregiudizievole ingiustificato.',
es: 'Puntuación ciudadana (social scoring): evaluación de personas en función de su comportamiento social que da lugar a un trato perjudicial injustificado.',
pl: 'Scoring społeczny: ocena osób na podstawie ich zachowania społecznego prowadząca do nieuzasadnionego niekorzystnego traktowania.',
cs: 'Sociální skórování (social scoring): hodnocení osob na základě jejich sociálního chování vedoucí k neodůvodněnému znevýhodňujícímu zacházení.',
sk: 'Sociálne bodovanie (social scoring): hodnotenie osôb na základe ich sociálneho správania vedúce k neodôvodnenému znevýhodňujúcemu zaobchádzaniu.',
ro: 'Punctajul social (social scoring): evaluarea persoanelor pe baza comportamentului lor social, care conduce la un tratament defavorabil nejustificat.',
},
legalRef: 'Art. 5 Abs. 1 lit. c',
},
{
id: 'proh-predictive-policing',
label: {
de: 'Risikobewertung von Straftaten allein auf Basis von Profiling oder Persönlichkeitsmerkmalen.',
en: 'Assessing the risk of criminal offences based solely on profiling or personality traits.',
fr: 'Évaluation du risque dinfractions pénales fondée uniquement sur le profilage ou des traits de personnalité.',
it: 'Valutazione del rischio di reati basata unicamente sulla profilazione o su tratti della personalità.',
es: 'Evaluación del riesgo de comisión de delitos basada únicamente en la elaboración de perfiles o en rasgos de personalidad.',
pl: 'Ocena ryzyka popełnienia przestępstwa wyłącznie na podstawie profilowania lub cech osobowości.',
cs: 'Posuzování rizika spáchání trestných činů výhradně na základě profilování nebo osobnostních rysů.',
sk: 'Posudzovanie rizika spáchania trestných činov výlučne na základe profilovania alebo osobnostných čŕt.',
ro: 'Evaluarea riscului de săvârșire a unor infracțiuni exclusiv pe baza creării de profiluri sau a trăsăturilor de personalitate.',
},
legalRef: 'Art. 5 Abs. 1 lit. d',
},
{
id: 'proh-face-scraping',
label: {
de: 'Ungezieltes Auslesen (Scraping) von Gesichtsbildern aus Internet oder Überwachungskameras zum Aufbau von Gesichtsdatenbanken.',
en: 'Untargeted scraping of facial images from the internet or CCTV to build facial recognition databases.',
fr: 'Moissonnage non ciblé dimages faciales provenant dinternet ou de la vidéosurveillance afin de constituer des bases de données de reconnaissance faciale.',
it: 'Scraping non mirato di immagini facciali da internet o da telecamere a circuito chiuso per creare banche dati di riconoscimento facciale.',
es: 'Extracción no selectiva de imágenes faciales de internet o de circuitos cerrados de televisión para crear bases de datos de reconocimiento facial.',
pl: 'Nieukierunkowane pozyskiwanie (scraping) wizerunków twarzy z internetu lub nagrań z telewizji przemysłowej w celu tworzenia baz danych służących rozpoznawaniu twarzy.',
cs: 'Necílené vytěžování (scraping) zobrazení obličeje z internetu nebo kamerových záznamů za účelem vytváření databází rozpoznávání obličeje.',
sk: 'Necielené získavanie (scraping) podôb tváre z internetu alebo zo záznamov kamerových systémov na vytváranie databáz na rozpoznávanie tváre.',
ro: 'Extragerea nedirecționată (scraping) a imaginilor faciale de pe internet sau din înregistrări CCTV pentru a crea baze de date de recunoaștere facială.',
},
legalRef: 'Art. 5 Abs. 1 lit. e',
},
{
id: 'proh-emotion-workplace',
label: {
de: 'Emotionserkennung am Arbeitsplatz oder in Bildungseinrichtungen (außer aus medizinischen oder Sicherheitsgründen).',
en: 'Emotion recognition in the workplace or educational institutions (except for medical or safety reasons).',
fr: 'Reconnaissance des émotions sur le lieu de travail ou dans les établissements denseignement (sauf pour des raisons médicales ou de sécurité).',
it: 'Riconoscimento delle emozioni sul luogo di lavoro o negli istituti di istruzione (salvo per motivi medici o di sicurezza).',
es: 'Reconocimiento de emociones en el lugar de trabajo o en los centros educativos (salvo por motivos médicos o de seguridad).',
pl: 'Rozpoznawanie emocji w miejscu pracy lub w instytucjach edukacyjnych (z wyjątkiem względów medycznych lub bezpieczeństwa).',
cs: 'Rozpoznávání emocí na pracovišti nebo ve vzdělávacích institucích (s výjimkou zdravotních nebo bezpečnostních důvodů).',
sk: 'Rozpoznávanie emócií na pracovisku alebo vo vzdelávacích inštitúciách (s výnimkou zdravotných alebo bezpečnostných dôvodov).',
ro: 'Recunoașterea emoțiilor la locul de muncă sau în instituțiile de învățământ (cu excepția motivelor medicale sau de siguranță).',
},
legalRef: 'Art. 5 Abs. 1 lit. f',
},
{
id: 'proh-biometric-categorisation',
label: {
de: 'Biometrische Kategorisierung zur Ableitung sensibler Merkmale (z. B. Ethnie, politische Meinung, sexuelle Orientierung).',
en: 'Biometric categorisation to infer sensitive attributes (e.g. ethnicity, political opinion, sexual orientation).',
fr: 'Catégorisation biométrique visant à déduire des attributs sensibles (p. ex. origine ethnique, opinions politiques, orientation sexuelle).',
it: 'Categorizzazione biometrica per dedurre attributi sensibili (ad es. etnia, opinioni politiche, orientamento sessuale).',
es: 'Categorización biométrica para inferir atributos sensibles (p. ej. etnia, opiniones políticas, orientación sexual).',
pl: 'Kategoryzacja biometryczna w celu wywnioskowania wrażliwych cech (np. pochodzenia etnicznego, poglądów politycznych, orientacji seksualnej).',
cs: 'Biometrická kategorizace za účelem odvození citlivých atributů (např. etnického původu, politických názorů, sexuální orientace).',
sk: 'Biometrická kategorizácia na odvodenie citlivých atribútov (napr. etnického pôvodu, politických názorov, sexuálnej orientácie).',
ro: 'Clasificarea biometrică pentru a deduce atribute sensibile (de ex. originea etnică, opiniile politice, orientarea sexuală).',
},
legalRef: 'Art. 5 Abs. 1 lit. g',
},
{
id: 'proh-rbi',
label: {
de: 'Biometrische Echtzeit-Fernidentifizierung in öffentlich zugänglichen Räumen zu Strafverfolgungszwecken (enge Ausnahmen).',
en: 'Real-time remote biometric identification in publicly accessible spaces for law enforcement (narrow exceptions).',
fr: 'Identification biométrique à distance en temps réel dans des espaces accessibles au public à des fins répressives (exceptions étroites).',
it: 'Identificazione biometrica remota in tempo reale in spazi accessibili al pubblico a fini di attività di contrasto (eccezioni limitate).',
es: 'Identificación biométrica remota en tiempo real en espacios de acceso público con fines de garantía del cumplimiento del Derecho (excepciones limitadas).',
pl: 'Zdalna identyfikacja biometryczna w czasie rzeczywistym w przestrzeni publicznej do celów ścigania przestępstw (wąskie wyjątki).',
cs: 'Biometrická identifikace na dálku v reálném čase na veřejně přístupných místech pro účely vymáhání práva (úzké výjimky).',
sk: 'Diaľková biometrická identifikácia v reálnom čase vo verejne prístupných priestoroch na účely presadzovania práva (úzke výnimky).',
ro: 'Identificarea biometrică la distanță în timp real în spații accesibile publicului în scopul asigurării respectării legii (excepții restrânse).',
},
legalRef: 'Art. 5 Abs. 1 lit. h',
},
];
/** Hochrisiko-Bereiche nach Annex III. */
export const ANNEX_III_CATEGORIES: readonly ContentItemSrc[] = [
{
id: 'a3-biometrics',
label: {
de: 'Biometrie: Fernidentifizierung, biometrische Kategorisierung, Emotionserkennung (soweit nicht verboten).',
en: 'Biometrics: remote identification, biometric categorisation, emotion recognition (where not prohibited).',
fr: 'Biométrie : identification à distance, catégorisation biométrique, reconnaissance des émotions (dans la mesure où elles ne sont pas interdites).',
it: 'Biometria: identificazione remota, categorizzazione biometrica, riconoscimento delle emozioni (ove non vietati).',
es: 'Biometría: identificación remota, categorización biométrica, reconocimiento de emociones (cuando no estén prohibidos).',
pl: 'Biometria: zdalna identyfikacja, kategoryzacja biometryczna, rozpoznawanie emocji (o ile nie są zakazane).',
cs: 'Biometrika: identifikace na dálku, biometrická kategorizace, rozpoznávání emocí (pokud nejsou zakázány).',
sk: 'Biometria: diaľková identifikácia, biometrická kategorizácia, rozpoznávanie emócií (pokiaľ nie sú zakázané).',
ro: 'Biometrie: identificare la distanță, clasificare biometrică, recunoașterea emoțiilor (în măsura în care nu sunt interzise).',
},
legalRef: 'Annex III Nr. 1',
},
{
id: 'a3-critical-infra',
label: {
de: 'Sicherheitskomponenten kritischer Infrastruktur (Verkehr, Wasser, Gas, Wärme, Strom, digitale Infrastruktur).',
en: 'Safety components of critical infrastructure (traffic, water, gas, heating, electricity, digital infrastructure).',
fr: 'Composants de sécurité des infrastructures critiques (trafic, eau, gaz, chauffage, électricité, infrastructure numérique).',
it: 'Componenti di sicurezza delle infrastrutture critiche (traffico, acqua, gas, riscaldamento, elettricità, infrastrutture digitali).',
es: 'Componentes de seguridad de infraestructuras críticas (tráfico, agua, gas, calefacción, electricidad, infraestructura digital).',
pl: 'Elementy bezpieczeństwa infrastruktury krytycznej (ruch drogowy, woda, gaz, ciepło, energia elektryczna, infrastruktura cyfrowa).',
cs: 'Bezpečnostní komponenty kritické infrastruktury (doprava, voda, plyn, vytápění, elektřina, digitální infrastruktura).',
sk: 'Bezpečnostné komponenty kritickej infraštruktúry (doprava, voda, plyn, vykurovanie, elektrina, digitálna infraštruktúra).',
ro: 'Componente de siguranță ale infrastructurii critice (trafic, apă, gaze, încălzire, energie electrică, infrastructură digitală).',
},
legalRef: 'Annex III Nr. 2',
},
{
id: 'a3-education',
label: {
de: 'Bildung: Zulassung, Bewertung von Lernergebnissen, Prüfungsüberwachung.',
en: 'Education: admission, evaluation of learning outcomes, exam proctoring.',
fr: 'Éducation : admission, évaluation des acquis dapprentissage, surveillance des examens.',
it: 'Istruzione: ammissione, valutazione dei risultati dellapprendimento, sorveglianza degli esami.',
es: 'Educación: admisión, evaluación de los resultados del aprendizaje, supervisión de exámenes.',
pl: 'Edukacja: przyjmowanie kandydatów, ocena efektów uczenia się, nadzorowanie egzaminów.',
cs: 'Vzdělávání: přijímání, hodnocení výsledků učení, dohled při zkouškách.',
sk: 'Vzdelávanie: prijímanie, hodnotenie výsledkov vzdelávania, dozor pri skúškach.',
ro: 'Educație: admitere, evaluarea rezultatelor învățării, supravegherea examenelor.',
},
legalRef: 'Annex III Nr. 3',
},
{
id: 'a3-employment',
label: {
de: 'Beschäftigung: Recruiting/Bewerberauswahl, Beförderung/Kündigung, Aufgabenzuweisung, Leistungsüberwachung.',
en: 'Employment: recruiting/candidate selection, promotion/termination, task allocation, performance monitoring.',
fr: 'Emploi : recrutement/sélection des candidats, promotion/licenciement, attribution des tâches, suivi des performances.',
it: 'Occupazione: assunzione/selezione dei candidati, promozione/licenziamento, assegnazione dei compiti, monitoraggio delle prestazioni.',
es: 'Empleo: contratación/selección de candidatos, promoción/despido, asignación de tareas, supervisión del rendimiento.',
pl: 'Zatrudnienie: rekrutacja/selekcja kandydatów, awans/rozwiązanie stosunku pracy, przydział zadań, monitorowanie wyników pracy.',
cs: 'Zaměstnávání: nábor/výběr uchazečů, povýšení/ukončení pracovního poměru, přidělování úkolů, sledování výkonnosti.',
sk: 'Zamestnanosť: nábor/výber uchádzačov, povýšenie/skončenie pracovného pomeru, prideľovanie úloh, monitorovanie výkonnosti.',
ro: 'Ocuparea forței de muncă: recrutare/selecția candidaților, promovare/încetarea raporturilor de muncă, repartizarea sarcinilor, monitorizarea performanței.',
},
legalRef: 'Annex III Nr. 4',
hint: {
de: 'Häufigster KMU-Fall: KI-gestütztes Bewerber-Screening.',
en: 'Most common SME case: AI-supported applicant screening.',
fr: 'Cas de PME le plus fréquent : présélection des candidats assistée par IA.',
it: 'Caso PMI più frequente: screening dei candidati assistito dallIA.',
es: 'Caso más frecuente en las pymes: preselección de candidatos asistida por IA.',
pl: 'Najczęstszy przypadek w MŚP: wstępna selekcja kandydatów wspierana przez AI.',
cs: 'Nejčastější případ u malých a středních podniků: předvýběr uchazečů podporovaný AI.',
sk: 'Najčastejší prípad v MSP: predvýber uchádzačov podporovaný AI.',
ro: 'Cel mai frecvent caz în IMM-uri: preselecția candidaților asistată de IA.',
},
},
{
id: 'a3-essential-services',
label: {
de: 'Wesentliche Dienste: Kreditwürdigkeitsprüfung, Risiko-Pricing bei Lebens-/Krankenversicherung, Notruf-Triage, Sozialleistungen.',
en: 'Essential services: credit scoring, risk pricing in life/health insurance, emergency call triage, public benefits.',
fr: 'Services essentiels : évaluation de la solvabilité, tarification des risques en assurance-vie/maladie, triage des appels durgence, prestations sociales.',
it: 'Servizi essenziali: valutazione del merito creditizio, tariffazione dei rischi nelle assicurazioni sulla vita/malattia, triage delle chiamate di emergenza, prestazioni sociali.',
es: 'Servicios esenciales: evaluación de la solvencia crediticia, fijación de precios de riesgo en seguros de vida/enfermedad, triaje de llamadas de emergencia, prestaciones públicas.',
pl: 'Usługi podstawowe: ocena zdolności kredytowej, taryfikacja ryzyka w ubezpieczeniach na życie i ubezpieczeniach zdrowotnych, triaż zgłoszeń alarmowych, świadczenia publiczne.',
cs: 'Základní služby: hodnocení úvěruschopnosti, stanovení cen rizik v životním/zdravotním pojištění, třídění tísňových volání, veřejné dávky.',
sk: 'Základné služby: hodnotenie úverovej bonity, stanovovanie cien rizík v životnom/zdravotnom poistení, triedenie tiesňových volaní, verejné dávky.',
ro: 'Servicii esențiale: evaluarea bonității, stabilirea prețurilor de risc în asigurările de viață/de sănătate, triajul apelurilor de urgență, prestații publice.',
},
legalRef: 'Annex III Nr. 5',
},
{
id: 'a3-law-enforcement',
label: {
de: 'Strafverfolgung (Beweismittelbewertung, Rückfallrisiko u. a.).',
en: 'Law enforcement (evidence evaluation, recidivism risk, etc.).',
fr: 'Répression (évaluation des éléments de preuve, risque de récidive, etc.).',
it: 'Attività di contrasto (valutazione delle prove, rischio di recidiva, ecc.).',
es: 'Garantía del cumplimiento del Derecho (evaluación de pruebas, riesgo de reincidencia, etc.).',
pl: 'Ściganie przestępstw (ocena dowodów, ryzyko recydywy itd.).',
cs: 'Vymáhání práva (hodnocení důkazů, riziko recidivy atd.).',
sk: 'Presadzovanie práva (hodnotenie dôkazov, riziko recidívy atď.).',
ro: 'Asigurarea respectării legii (evaluarea probelor, riscul de recidivă etc.).',
},
legalRef: 'Annex III Nr. 6',
},
{
id: 'a3-migration',
label: {
de: 'Migration, Asyl, Grenzkontrolle.',
en: 'Migration, asylum, border control.',
fr: 'Migration, asile, contrôle aux frontières.',
it: 'Migrazione, asilo, controllo delle frontiere.',
es: 'Migración, asilo, control fronterizo.',
pl: 'Migracja, azyl, kontrola graniczna.',
cs: 'Migrace, azyl, ochrana hranic.',
sk: 'Migrácia, azyl, kontrola hraníc.',
ro: 'Migrație, azil, controlul frontierelor.',
},
legalRef: 'Annex III Nr. 7',
},
{
id: 'a3-justice',
label: {
de: 'Rechtspflege und demokratische Prozesse (Unterstützung richterlicher Entscheidungen, Wahlbeeinflussung).',
en: 'Administration of justice and democratic processes (supporting judicial decisions, influencing elections).',
fr: 'Administration de la justice et processus démocratiques (aide aux décisions judiciaires, influence sur les élections).',
it: 'Amministrazione della giustizia e processi democratici (supporto alle decisioni giudiziarie, influenza sulle elezioni).',
es: 'Administración de justicia y procesos democráticos (apoyo a las decisiones judiciales, influencia en las elecciones).',
pl: 'Sprawowanie wymiaru sprawiedliwości i procesy demokratyczne (wspieranie decyzji sądowych, wpływanie na wybory).',
cs: 'Výkon spravedlnosti a demokratické procesy (podpora soudních rozhodnutí, ovlivňování voleb).',
sk: 'Výkon spravodlivosti a demokratické procesy (podpora súdnych rozhodnutí, ovplyvňovanie volieb).',
ro: 'Administrarea justiției și procesele democratice (sprijinirea deciziilor judiciare, influențarea alegerilor).',
},
legalRef: 'Annex III Nr. 8',
},
];
/** Auslöser der Transparenzpflichten (Art. 50). */
export const TRANSPARENCY_TRIGGERS: readonly ContentItemSrc[] = [
{
id: 'tr-chatbot',
label: {
de: 'Das System interagiert direkt mit Menschen (z. B. Chatbot, Voicebot).',
en: 'The system interacts directly with humans (e.g. chatbot, voicebot).',
fr: 'Le système interagit directement avec des personnes (p. ex. chatbot, voicebot).',
it: 'Il sistema interagisce direttamente con le persone (ad es. chatbot, voicebot).',
es: 'El sistema interactúa directamente con personas (p. ej. chatbot, voicebot).',
pl: 'System wchodzi w bezpośrednią interakcję z ludźmi (np. chatbot, voicebot).',
cs: 'Systém přímo komunikuje s lidmi (např. chatbot, voicebot).',
sk: 'Systém priamo interaguje s ľuďmi (napr. chatbot, voicebot).',
ro: 'Sistemul interacționează direct cu persoane (de ex. chatbot, voicebot).',
},
legalRef: 'Art. 50 Abs. 1',
hint: {
de: 'Nutzer müssen erkennen können, dass sie mit KI interagieren.',
en: 'Users must be able to recognise that they are interacting with AI.',
fr: 'Les utilisateurs doivent pouvoir reconnaître quils interagissent avec une IA.',
it: 'Gli utenti devono poter riconoscere che stanno interagendo con unIA.',
es: 'Los usuarios deben poder reconocer que están interactuando con una IA.',
pl: 'Użytkownicy muszą być w stanie rozpoznać, że wchodzą w interakcję z AI.',
cs: 'Uživatelé musí být schopni rozpoznat, že komunikují s AI.',
sk: 'Používatelia musia byť schopní rozpoznať, že interagujú s AI.',
ro: 'Utilizatorii trebuie să poată recunoaște că interacționează cu o IA.',
},
},
{
id: 'tr-synthetic-content',
label: {
de: 'Das System erzeugt synthetische Audio-, Bild-, Video- oder Textinhalte.',
en: 'The system generates synthetic audio, image, video or text content.',
fr: 'Le système génère des contenus synthétiques audio, image, vidéo ou texte.',
it: 'Il sistema genera contenuti sintetici audio, immagine, video o testo.',
es: 'El sistema genera contenidos sintéticos de audio, imagen, vídeo o texto.',
pl: 'System generuje syntetyczne treści dźwiękowe, graficzne, wideo lub tekstowe.',
cs: 'Systém generuje syntetický zvukový, obrazový, video nebo textový obsah.',
sk: 'Systém generuje syntetický zvukový, obrazový, video alebo textový obsah.',
ro: 'Sistemul generează conținut sintetic audio, imagine, video sau text.',
},
legalRef: 'Art. 50 Abs. 2',
hint: {
de: 'Maschinenlesbare Kennzeichnung der Ausgaben erforderlich.',
en: 'Machine-readable marking of outputs is required.',
fr: 'Un marquage lisible par machine des sorties est requis.',
it: 'È richiesta la marcatura leggibile meccanicamente degli output.',
es: 'Se requiere el marcado legible por máquina de los resultados de salida.',
pl: 'Wymagane jest oznaczanie wyników w formacie nadającym się do odczytu maszynowego.',
cs: 'Je vyžadováno strojově čitelné označení výstupů.',
sk: 'Vyžaduje sa strojovo čitateľné označenie výstupov.',
ro: 'Este necesară marcarea rezultatelor într-un format care poate fi citit automat.',
},
},
{
id: 'tr-emotion',
label: {
de: 'Emotionserkennung oder biometrische Kategorisierung wird eingesetzt (soweit erlaubt).',
en: 'Emotion recognition or biometric categorisation is used (where permitted).',
fr: 'La reconnaissance des émotions ou la catégorisation biométrique est utilisée (dans la mesure où elle est autorisée).',
it: 'Viene utilizzato il riconoscimento delle emozioni o la categorizzazione biometrica (ove consentito).',
es: 'Se utiliza el reconocimiento de emociones o la categorización biométrica (cuando esté permitido).',
pl: 'Stosowane jest rozpoznawanie emocji lub kategoryzacja biometryczna (o ile jest to dozwolone).',
cs: 'Je používáno rozpoznávání emocí nebo biometrická kategorizace (pokud je to povoleno).',
sk: 'Používa sa rozpoznávanie emócií alebo biometrická kategorizácia (pokiaľ je to povolené).',
ro: 'Se utilizează recunoașterea emoțiilor sau clasificarea biometrică (în măsura în care este permisă).',
},
legalRef: 'Art. 50 Abs. 3',
},
{
id: 'tr-deepfake',
label: {
de: 'Das System erzeugt oder manipuliert Deepfakes (Bild/Audio/Video realer Personen, Orte oder Ereignisse).',
en: 'The system generates or manipulates deepfakes (image/audio/video of real persons, places or events).',
fr: 'Le système génère ou manipule des hypertrucages (deep fakes) (image/audio/vidéo de personnes, lieux ou événements réels).',
it: 'Il sistema genera o manipola deep fake (immagini/audio/video di persone, luoghi o eventi reali).',
es: 'El sistema genera o manipula ultrafalsificaciones (deepfakes) (imagen/audio/vídeo de personas, lugares o acontecimientos reales).',
pl: 'System generuje treści typu deepfake lub nimi manipuluje (obrazy/dźwięk/wideo rzeczywistych osób, miejsc lub wydarzeń).',
cs: 'Systém generuje obsah typu deep fake nebo s ním manipuluje (obraz/zvuk/video skutečných osob, míst nebo událostí).',
sk: 'Systém generuje obsah typu deep fake alebo s ním manipuluje (obraz/zvuk/video skutočných osôb, miest alebo udalostí).',
ro: 'Sistemul generează sau manipulează deepfake-uri (imagini/audio/video ale unor persoane, locuri sau evenimente reale).',
},
legalRef: 'Art. 50 Abs. 4',
},
];
/** Geltungsfristen des AI Act. */
export const DEADLINES: readonly DeadlineSrc[] = [
{
id: 'dl-prohibitions',
date: '2025-02-02',
label: {
de: 'Verbote & KI-Kompetenz',
en: 'Prohibitions & AI literacy',
fr: 'Interdictions & maîtrise de lIA',
it: 'Divieti & alfabetizzazione in materia di IA',
es: 'Prohibiciones & alfabetización en materia de IA',
pl: 'Zakazy & kompetencje w zakresie AI',
cs: 'Zákazy & gramotnost v oblasti AI',
sk: 'Zákazy & gramotnosť v oblasti AI',
ro: 'Interdicții & alfabetizare în domeniul IA',
},
description: {
de: 'Verbotene Praktiken (Art. 5) und KI-Kompetenzpflicht (Art. 4) gelten. Bereits in Kraft.',
en: 'Prohibited practices (Art. 5) and AI literacy duty (Art. 4) apply. Already in force.',
fr: 'Les pratiques interdites (art. 5) et lobligation de maîtrise de lIA (art. 4) sappliquent. Déjà en vigueur.',
it: 'Si applicano le pratiche vietate (art. 5) e lobbligo di alfabetizzazione in materia di IA (art. 4). Già in vigore.',
es: 'Las prácticas prohibidas (art. 5) y la obligación de alfabetización en materia de IA (art. 4) son aplicables. Ya en vigor.',
pl: 'Obowiązują zakazane praktyki (art. 5) i obowiązek zapewnienia kompetencji w zakresie AI (art. 4). Już w mocy.',
cs: 'Uplatňují se zakázané praktiky (čl. 5) a povinnost gramotnosti v oblasti AI (čl. 4). Již v platnosti.',
sk: 'Uplatňujú sa zakázané praktiky (čl. 5) a povinnosť gramotnosti v oblasti AI (čl. 4). Už v platnosti.',
ro: 'Se aplică practicile interzise (art. 5) și obligația de alfabetizare în domeniul IA (art. 4). Deja în vigoare.',
},
},
{
id: 'dl-gpai',
date: '2025-08-02',
label: {
de: 'GPAI-Pflichten',
en: 'GPAI obligations',
fr: 'Obligations GPAI',
it: 'Obblighi GPAI',
es: 'Obligaciones GPAI',
pl: 'Obowiązki GPAI',
cs: 'Povinnosti GPAI',
sk: 'Povinnosti GPAI',
ro: 'Obligații GPAI',
},
description: {
de: 'Pflichten für Anbieter von GPAI-Modellen (Art. 53 ff.) gelten. Bereits in Kraft.',
en: 'Obligations for providers of GPAI models (Art. 53 et seq.) apply. Already in force.',
fr: 'Les obligations des fournisseurs de modèles dIA à usage général (art. 53 et suivants) sappliquent. Déjà en vigueur.',
it: 'Si applicano gli obblighi per i fornitori di modelli di IA per finalità generali (art. 53 e segg.). Già in vigore.',
es: 'Son aplicables las obligaciones de los proveedores de modelos de IA de uso general (art. 53 y ss.). Ya en vigor.',
pl: 'Obowiązują obowiązki dostawców modeli AI ogólnego przeznaczenia (art. 53 i nast.). Już w mocy.',
cs: 'Uplatňují se povinnosti poskytovatelů obecných modelů AI (čl. 53 a násl.). Již v platnosti.',
sk: 'Uplatňujú sa povinnosti poskytovateľov modelov AI na všeobecné účely (čl. 53 a nasl.). Už v platnosti.',
ro: 'Se aplică obligațiile furnizorilor de modele de IA de uz general (art. 53 și urm.). Deja în vigoare.',
},
},
{
id: 'dl-general',
date: '2026-08-02',
label: {
de: 'Allgemeine Geltung',
en: 'General application',
fr: 'Application générale',
it: 'Applicazione generale',
es: 'Aplicación general',
pl: 'Ogólne stosowanie',
cs: 'Obecná použitelnost',
sk: 'Všeobecná uplatniteľnosť',
ro: 'Aplicare generală',
},
description: {
de: 'Transparenzpflichten (Art. 50), Sanktionsregime und Governance-Struktur gelten.',
en: 'Transparency obligations (Art. 50), penalty regime and governance structure apply.',
fr: 'Les obligations de transparence (art. 50), le régime de sanctions et la structure de gouvernance sappliquent.',
it: 'Si applicano gli obblighi di trasparenza (art. 50), il regime sanzionatorio e la struttura di governance.',
es: 'Son aplicables las obligaciones de transparencia (art. 50), el régimen sancionador y la estructura de gobernanza.',
pl: 'Obowiązują obowiązki w zakresie przejrzystości (art. 50), system kar i struktura zarządzania.',
cs: 'Uplatňují se povinnosti transparentnosti (čl. 50), sankční režim a struktura správy.',
sk: 'Uplatňujú sa povinnosti transparentnosti (čl. 50), sankčný režim a štruktúra správy a riadenia.',
ro: 'Se aplică obligațiile de transparență (art. 50), regimul sancțiunilor și structura de guvernanță.',
},
},
{
id: 'dl-annex3',
date: '2027-12-02',
label: {
de: 'Hochrisiko (Annex III)',
en: 'High-risk (Annex III)',
fr: 'Haut risque (annexe III)',
it: 'Alto rischio (allegato III)',
es: 'Alto riesgo (anexo III)',
pl: 'Wysokie ryzyko (załącznik III)',
cs: 'Vysoké riziko (příloha III)',
sk: 'Vysoké riziko (príloha III)',
ro: 'Grad ridicat de risc (anexa III)',
},
description: {
de: 'Pflichten für Annex-III-Hochrisiko-Systeme gelten (durch Digital Omnibus von Aug 2026 verschoben).',
en: 'Obligations for Annex III high-risk systems apply (postponed from Aug 2026 by the Digital Omnibus).',
fr: 'Les obligations relatives aux systèmes dIA à haut risque de lannexe III sappliquent (reportées daoût 2026 par le Digital Omnibus).',
it: 'Si applicano gli obblighi per i sistemi di IA ad alto rischio dellallegato III (rinviati da agosto 2026 dal Digital Omnibus).',
es: 'Son aplicables las obligaciones para los sistemas de IA de alto riesgo del anexo III (aplazadas desde agosto de 2026 por el Digital Omnibus).',
pl: 'Obowiązują obowiązki dotyczące systemów AI wysokiego ryzyka z załącznika III (przesunięte z sierpnia 2026 r. przez Digital Omnibus).',
cs: 'Uplatňují se povinnosti pro vysoce rizikové systémy AI podle přílohy III (odloženo ze srpna 2026 balíčkem Digital Omnibus).',
sk: 'Uplatňujú sa povinnosti pre vysokorizikové systémy AI podľa prílohy III (odložené z augusta 2026 balíkom Digital Omnibus).',
ro: 'Se aplică obligațiile pentru sistemele de IA cu grad ridicat de risc din anexa III (amânate din august 2026 prin Digital Omnibus).',
},
},
{
id: 'dl-annex1',
date: '2028-08-02',
label: {
de: 'Hochrisiko (Annex I)',
en: 'High-risk (Annex I)',
fr: 'Haut risque (annexe I)',
it: 'Alto rischio (allegato I)',
es: 'Alto riesgo (anexo I)',
pl: 'Wysokie ryzyko (załącznik I)',
cs: 'Vysoké riziko (příloha I)',
sk: 'Vysoké riziko (príloha I)',
ro: 'Grad ridicat de risc (anexa I)',
},
description: {
de: 'Pflichten für KI als Sicherheitsbauteil regulierter Produkte (Annex I) gelten.',
en: 'Obligations for AI as a safety component of regulated products (Annex I) apply.',
fr: 'Les obligations relatives à lIA en tant que composant de sécurité de produits réglementés (annexe I) sappliquent.',
it: 'Si applicano gli obblighi per lIA come componente di sicurezza di prodotti regolamentati (allegato I).',
es: 'Son aplicables las obligaciones para la IA como componente de seguridad de productos regulados (anexo I).',
pl: 'Obowiązują obowiązki dotyczące AI jako elementu bezpieczeństwa produktów regulowanych (załącznik I).',
cs: 'Uplatňují se povinnosti pro AI jako bezpečnostní komponentu regulovaných produktů (příloha I).',
sk: 'Uplatňujú sa povinnosti pre AI ako bezpečnostný komponent regulovaných výrobkov (príloha I).',
ro: 'Se aplică obligațiile pentru IA drept componentă de siguranță a produselor reglementate (anexa I).',
},
},
];

View File

@ -0,0 +1,492 @@
import type { NationalPackSrc } from './sourceTypes';
/**
* Nationale Zusatzanforderungen der EU-Mitgliedstaaten (Stand Juli 2026).
*
* Der AI Act ist eine Verordnung und gilt unmittelbar die Mitgliedstaaten
* regeln aber Aufsicht, Sanktionen und teils zusätzliche Pflichten national.
* Diese Module sind zuschaltbar und werden mit dem Content-Pack gepflegt.
*/
export const NATIONAL_PACKS: readonly NationalPackSrc[] = [
{
code: 'DE',
country: {
de: 'Deutschland',
en: 'Germany',
fr: 'Allemagne',
it: 'Germania',
es: 'Alemania',
pl: 'Niemcy',
cs: 'Německo',
sk: 'Nemecko',
ro: 'Germania',
},
authority: {
de: 'Bundesnetzagentur (BNetzA) — Marktüberwachung, KI-Marktüberwachungskammer (UKIM), KoKIVO-Service-Desk',
en: 'Federal Network Agency (BNetzA) — market surveillance, AI Market Surveillance Chamber (UKIM), KoKIVO service desk',
fr: 'Bundesnetzagentur (BNetzA) — surveillance du marché, chambre de surveillance du marché de lIA (UKIM), guichet de service KoKIVO',
it: 'Bundesnetzagentur (BNetzA) — vigilanza del mercato, camera di vigilanza del mercato dellIA (UKIM), service desk KoKIVO',
es: 'Bundesnetzagentur (BNetzA) — vigilancia del mercado, cámara de vigilancia del mercado de IA (UKIM), servicio de atención KoKIVO',
pl: 'Bundesnetzagentur (BNetzA) — nadzór rynku, izba nadzoru rynku AI (UKIM), punkt obsługi KoKIVO',
cs: 'Bundesnetzagentur (BNetzA) — dozor nad trhem, komora pro dozor nad trhem AI (UKIM), servisní místo KoKIVO',
sk: 'Bundesnetzagentur (BNetzA) — dohľad nad trhom, komora pre dohľad nad trhom AI (UKIM), servisné miesto KoKIVO',
ro: 'Bundesnetzagentur (BNetzA) — supravegherea pieței, camera de supraveghere a pieței AI (UKIM), biroul de asistență KoKIVO',
},
items: [
{
id: 'de-kimig-authority',
title: {
de: 'Zuständigkeit und Meldewege nach KI-MIG kennen',
en: 'Know competences and reporting channels under the German AI Act implementation law',
fr: 'Connaître les compétences et les voies de signalement prévues par le KI-MIG',
it: 'Conoscere le competenze e i canali di segnalazione previsti dal KI-MIG',
es: 'Conocer las competencias y los canales de notificación conforme al KI-MIG',
pl: 'Znać właściwości organów i ścieżki zgłoszeń zgodnie z KI-MIG',
cs: 'Znát příslušnosti a ohlašovací kanály podle KI-MIG',
sk: 'Poznať príslušnosti a ohlasovacie kanály podľa KI-MIG',
ro: 'Cunoașterea competențelor și a canalelor de raportare conform KI-MIG',
},
articles: 'KI-MIG (2026)',
description: {
de: 'Das deutsche Durchführungsgesetz benennt die Bundesnetzagentur als zentrale Marktüberwachungs- und Anlaufstelle (KoKIVO als Service-Desk). Meldungen (z. B. Art. 73) laufen über die BNetzA; sektorale Behörden (z. B. BaFin) bleiben teils zuständig.',
en: 'The German implementation law designates the Federal Network Agency as central market surveillance body and contact point (KoKIVO service desk). Reports (e.g. Art. 73) go to BNetzA; sectoral authorities (e.g. BaFin) partly remain competent.',
fr: 'La loi dapplication allemande désigne la Bundesnetzagentur comme autorité centrale de surveillance du marché et point de contact (KoKIVO comme guichet de service). Les signalements (p. ex. art. 73) passent par la BNetzA ; certaines autorités sectorielles (p. ex. la BaFin) restent en partie compétentes.',
it: 'La legge tedesca di attuazione designa la Bundesnetzagentur come autorità centrale di vigilanza del mercato e punto di contatto (KoKIVO come service desk). Le segnalazioni (ad es. art. 73) passano per la BNetzA; le autorità settoriali (ad es. BaFin) restano in parte competenti.',
es: 'La ley alemana de aplicación designa a la Bundesnetzagentur como autoridad central de vigilancia del mercado y punto de contacto (KoKIVO como servicio de atención). Las notificaciones (p. ej., art. 73) se tramitan a través de la BNetzA; las autoridades sectoriales (p. ej., BaFin) siguen siendo parcialmente competentes.',
pl: 'Niemiecka ustawa wykonawcza wyznacza Bundesnetzagentur jako centralny organ nadzoru rynku i punkt kontaktowy (KoKIVO jako punkt obsługi). Zgłoszenia (np. art. 73) kierowane są do BNetzA; organy sektorowe (np. BaFin) pozostają częściowo właściwe.',
cs: 'Německý prováděcí zákon určuje Bundesnetzagentur jako ústřední orgán dozoru nad trhem a kontaktní místo (KoKIVO jako servisní místo). Hlášení (např. čl. 73) směřují na BNetzA; sektorové orgány (např. BaFin) zůstávají zčásti příslušné.',
sk: 'Nemecký vykonávací zákon určuje Bundesnetzagentur ako ústredný orgán dohľadu nad trhom a kontaktné miesto (KoKIVO ako servisné miesto). Hlásenia (napr. čl. 73) smerujú na BNetzA; sektorové orgány (napr. BaFin) zostávajú čiastočne príslušné.',
ro: 'Legea germană de punere în aplicare desemnează Bundesnetzagentur ca autoritate centrală de supraveghere a pieței și punct de contact (KoKIVO ca birou de asistență). Rapoartele (de ex. art. 73) se transmit către BNetzA; autoritățile sectoriale (de ex. BaFin) rămân parțial competente.',
},
deadline: '2026-08-02',
roles: ['provider', 'deployer', 'importer', 'distributor'],
riskClasses: ['high', 'limited'],
},
{
id: 'de-betrvg',
title: {
de: 'Mitbestimmung des Betriebsrats bei KI am Arbeitsplatz',
en: 'Works council co-determination for AI at the workplace',
fr: 'Codétermination du comité dentreprise pour lIA sur le lieu de travail',
it: 'Codeterminazione del consiglio aziendale per lIA sul posto di lavoro',
es: 'Cogestión del comité de empresa en el uso de IA en el lugar de trabajo',
pl: 'Współdecydowanie rady zakładowej przy stosowaniu AI w miejscu pracy',
cs: 'Spolurozhodování podnikové rady při využívání AI na pracovišti',
sk: 'Spolurozhodovanie zamestnaneckej rady pri využívaní AI na pracovisku',
ro: 'Codecizia consiliului de întreprindere privind AI la locul de muncă',
},
articles: '§ 87 Abs. 1 Nr. 6, § 90 BetrVG',
description: {
de: 'Kann das System Verhalten oder Leistung von Beschäftigten überwachen, besteht ein Mitbestimmungsrecht des Betriebsrats; bei Planung von KI-Einsatz ist der Betriebsrat frühzeitig zu unterrichten (§ 90). Betriebsvereinbarung empfohlen.',
en: 'If the system can monitor employee behaviour or performance, the works council has a co-determination right; it must be informed early when AI use is planned (Sec. 90). A works agreement is recommended.',
fr: 'Si le système peut surveiller le comportement ou les performances des salariés, le comité dentreprise dispose dun droit de codétermination ; il doit être informé en amont lorsquune utilisation de lIA est planifiée (§ 90). Un accord dentreprise est recommandé.',
it: 'Se il sistema può monitorare il comportamento o le prestazioni dei dipendenti, il consiglio aziendale ha un diritto di codeterminazione; in caso di pianificazione delluso dellIA deve essere informato tempestivamente (§ 90). Si raccomanda un accordo aziendale.',
es: 'Si el sistema puede supervisar el comportamiento o el rendimiento de los empleados, el comité de empresa tiene un derecho de cogestión; debe ser informado con antelación cuando se planifique el uso de IA (§ 90). Se recomienda un acuerdo de empresa.',
pl: 'Jeżeli system może monitorować zachowanie lub wydajność pracowników, radzie zakładowej przysługuje prawo współdecydowania; przy planowaniu wykorzystania AI radę zakładową należy poinformować z wyprzedzeniem (§ 90). Zalecane jest porozumienie zakładowe.',
cs: 'Pokud systém může sledovat chování nebo výkon zaměstnanců, má podniková rada právo spolurozhodování; při plánování nasazení AI musí být podniková rada včas informována (§ 90). Doporučuje se podniková dohoda.',
sk: 'Ak systém môže sledovať správanie alebo výkon zamestnancov, zamestnanecká rada má právo spolurozhodovania; pri plánovaní nasadenia AI treba zamestnaneckú radu včas informovať (§ 90). Odporúča sa podniková dohoda.',
ro: 'Dacă sistemul poate monitoriza comportamentul sau performanța angajaților, consiliul de întreprindere are un drept de codecizie; la planificarea utilizării AI, consiliul de întreprindere trebuie informat din timp (§ 90). Se recomandă un acord de întreprindere.',
},
deadline: '2025-02-02',
roles: ['deployer'],
riskClasses: ['high', 'limited'],
},
{
id: 'de-dsgvo-bdsg',
title: {
de: 'DSGVO/BDSG-Konformität der KI-Datenverarbeitung sicherstellen',
en: 'Ensure GDPR/BDSG conformity of AI data processing',
fr: 'Garantir la conformité RGPD/BDSG du traitement de données par lIA',
it: 'Garantire la conformità GDPR/BDSG del trattamento dei dati da parte dellIA',
es: 'Garantizar la conformidad del tratamiento de datos de la IA con el RGPD/BDSG',
pl: 'Zapewnić zgodność przetwarzania danych przez AI z RODO/BDSG',
cs: 'Zajistit soulad zpracování dat AI s GDPR/BDSG',
sk: 'Zabezpečiť súlad spracúvania údajov AI s GDPR/BDSG',
ro: 'Asigurarea conformității prelucrării datelor de către AI cu RGPD/BDSG',
},
articles: 'DSGVO, BDSG',
description: {
de: 'Rechtsgrundlage der Verarbeitung, Informationspflichten, Betroffenenrechte und ggf. § 26 BDSG (Beschäftigtendaten) prüfen; Datenschutzbeauftragten einbinden.',
en: 'Check legal basis of processing, information duties, data subject rights and, where relevant, Sec. 26 BDSG (employee data); involve the data protection officer.',
fr: 'Vérifier la base juridique du traitement, les obligations dinformation, les droits des personnes concernées et, le cas échéant, le § 26 BDSG (données des salariés) ; associer le délégué à la protection des données.',
it: 'Verificare la base giuridica del trattamento, gli obblighi di informazione, i diritti degli interessati e, se pertinente, il § 26 BDSG (dati dei dipendenti); coinvolgere il responsabile della protezione dei dati.',
es: 'Comprobar la base jurídica del tratamiento, los deberes de información, los derechos de los interesados y, en su caso, el § 26 BDSG (datos de los empleados); implicar al delegado de protección de datos.',
pl: 'Zweryfikować podstawę prawną przetwarzania, obowiązki informacyjne, prawa osób, których dane dotyczą, oraz w razie potrzeby § 26 BDSG (dane pracowników); zaangażować inspektora ochrony danych.',
cs: 'Ověřit právní základ zpracování, informační povinnosti, práva subjektů údajů a případně § 26 BDSG (údaje zaměstnanců); zapojit pověřence pro ochranu osobních údajů.',
sk: 'Overiť právny základ spracúvania, informačné povinnosti, práva dotknutých osôb a prípadne § 26 BDSG (údaje zamestnancov); zapojiť zodpovednú osobu za ochranu údajov.',
ro: 'Trebuie verificate temeiul juridic al prelucrării, obligațiile de informare, drepturile persoanelor vizate și, dacă este cazul, § 26 BDSG (datele angajaților); responsabilul cu protecția datelor trebuie implicat.',
},
deadline: '2025-02-02',
roles: ['provider', 'deployer'],
riskClasses: ['high', 'limited', 'minimal'],
},
],
},
{
code: 'AT',
country: {
de: 'Österreich',
en: 'Austria',
fr: 'Autriche',
it: 'Austria',
es: 'Austria',
pl: 'Austria',
cs: 'Rakousko',
sk: 'Rakúsko',
ro: 'Austria',
},
authority: {
de: 'KI-Servicestelle bei der RTR (Rundfunk und Telekom Regulierungs-GmbH); Marktüberwachungsstruktur in Umsetzung',
en: 'AI service desk at RTR (Austrian Regulatory Authority for Broadcasting and Telecommunications); market surveillance structure being implemented',
fr: 'Guichet de service IA auprès de la RTR (Rundfunk und Telekom Regulierungs-GmbH) ; structure de surveillance du marché en cours de mise en place',
it: 'Sportello di servizio per lIA presso la RTR (Rundfunk und Telekom Regulierungs-GmbH); struttura di vigilanza del mercato in fase di attuazione',
es: 'Oficina de servicio de IA en la RTR (Rundfunk und Telekom Regulierungs-GmbH); estructura de vigilancia del mercado en fase de implantación',
pl: 'Punkt obsługi AI przy RTR (Rundfunk und Telekom Regulierungs-GmbH); struktura nadzoru rynku w trakcie wdrażania',
cs: 'Servisní místo pro AI při RTR (Rundfunk und Telekom Regulierungs-GmbH); struktura dozoru nad trhem se zavádí',
sk: 'Servisné miesto pre AI pri RTR (Rundfunk und Telekom Regulierungs-GmbH); štruktúra dohľadu nad trhom sa zavádza',
ro: 'Birou de asistență AI pe lângă RTR (Rundfunk und Telekom Regulierungs-GmbH); structura de supraveghere a pieței în curs de implementare',
},
items: [
{
id: 'at-servicestelle',
title: {
de: 'KI-Servicestelle als Anlaufstelle nutzen, nationale Umsetzung beobachten',
en: 'Use the AI service desk as contact point, monitor national implementation',
fr: 'Utiliser le guichet de service IA comme point de contact et suivre la mise en œuvre nationale',
it: 'Utilizzare lo sportello di servizio per lIA come punto di contatto e monitorare lattuazione nazionale',
es: 'Utilizar la oficina de servicio de IA como punto de contacto y seguir la aplicación nacional',
pl: 'Korzystać z punktu obsługi AI jako punktu kontaktowego i śledzić krajowe wdrażanie',
cs: 'Využívat servisní místo pro AI jako kontaktní místo a sledovat národní provádění',
sk: 'Využívať servisné miesto pre AI ako kontaktné miesto a sledovať národnú implementáciu',
ro: 'Utilizarea biroului de asistență AI ca punct de contact și monitorizarea implementării naționale',
},
articles: 'RTR KI-Servicestelle',
description: {
de: 'Österreich hat bei der RTR eine KI-Servicestelle für Unternehmen eingerichtet; das nationale Begleitgesetz mit endgültiger Behördenstruktur und Sanktionen ist zu beobachten.',
en: 'Austria has set up an AI service desk at RTR for companies; the national implementing act with the final authority structure and penalties should be monitored.',
fr: 'LAutriche a mis en place auprès de la RTR un guichet de service IA pour les entreprises ; la loi daccompagnement nationale, avec la structure définitive des autorités et les sanctions, reste à suivre.',
it: 'LAustria ha istituito presso la RTR uno sportello di servizio per lIA destinato alle imprese; va monitorata la legge nazionale di accompagnamento con la struttura definitiva delle autorità e le sanzioni.',
es: 'Austria ha creado en la RTR una oficina de servicio de IA para empresas; conviene seguir la ley nacional de acompañamiento con la estructura definitiva de autoridades y las sanciones.',
pl: 'Austria utworzyła przy RTR punkt obsługi AI dla przedsiębiorstw; należy śledzić krajową ustawę towarzyszącą z ostateczną strukturą organów i sankcjami.',
cs: 'Rakousko zřídilo při RTR servisní místo pro AI určené podnikům; je třeba sledovat národní doprovodný zákon s konečnou strukturou orgánů a sankcemi.',
sk: 'Rakúsko zriadilo pri RTR servisné miesto pre AI určené podnikom; treba sledovať národný sprievodný zákon s konečnou štruktúrou orgánov a sankciami.',
ro: 'Austria a înființat pe lângă RTR un birou de asistență AI pentru întreprinderi; legea națională de însoțire, cu structura definitivă a autorităților și sancțiunile, trebuie monitorizată.',
},
deadline: '2026-08-02',
roles: ['provider', 'deployer'],
riskClasses: ['high', 'limited'],
},
],
},
{
code: 'IT',
country: {
de: 'Italien',
en: 'Italy',
fr: 'Italie',
it: 'Italia',
es: 'Italia',
pl: 'Włochy',
cs: 'Itálie',
sk: 'Taliansko',
ro: 'Italia',
},
authority: {
de: 'AgID (Agentur für digitales Italien) und ACN (Nationale Cybersicherheitsagentur)',
en: 'AgID (Agency for Digital Italy) and ACN (National Cybersecurity Agency)',
fr: 'AgID (Agence pour lItalie numérique) et ACN (Agence nationale de cybersécurité)',
it: 'AgID (Agenzia per lItalia digitale) e ACN (Agenzia per la cybersicurezza nazionale)',
es: 'AgID (Agencia para la Italia Digital) y ACN (Agencia Nacional de Ciberseguridad)',
pl: 'AgID (Agencja ds. Cyfrowych Włoch) i ACN (Krajowa Agencja Cyberbezpieczeństwa)',
cs: 'AgID (Agentura pro digitální Itálii) a ACN (Národní agentura pro kybernetickou bezpečnost)',
sk: 'AgID (Agentúra pre digitálne Taliansko) a ACN (Národná agentúra pre kybernetickú bezpečnosť)',
ro: 'AgID (Agenția pentru Italia Digitală) și ACN (Agenția Națională pentru Securitate Cibernetică)',
},
items: [
{
id: 'it-l132-workers',
title: {
de: 'Beschäftigte über KI-Einsatz informieren (Legge 132/2025)',
en: 'Inform employees about AI use (Law 132/2025)',
fr: 'Informer les salariés de lutilisation de lIA (Legge 132/2025)',
it: 'Informare i lavoratori sulluso dellIA (Legge 132/2025)',
es: 'Informar a los empleados sobre el uso de IA (Legge 132/2025)',
pl: 'Informować pracowników o wykorzystaniu AI (Legge 132/2025)',
cs: 'Informovat zaměstnance o využívání AI (Legge 132/2025)',
sk: 'Informovať zamestnancov o využívaní AI (Legge 132/2025)',
ro: 'Informarea angajaților cu privire la utilizarea AI (Legge 132/2025)',
},
articles: 'Legge 132/2025',
description: {
de: 'Italiens nationales KI-Gesetz verpflichtet Arbeitgeber, Beschäftigte über den Einsatz von KI in Entscheidungsprozessen zu informieren — unabhängig von der Risikoklasse des Systems.',
en: 'Italys national AI law obliges employers to inform employees about the use of AI in decision-making processes — regardless of the systems risk class.',
fr: 'La loi nationale italienne sur lIA oblige les employeurs à informer les salariés de lutilisation de lIA dans les processus décisionnels — indépendamment de la classe de risque du système.',
it: 'La legge nazionale italiana sullIA obbliga i datori di lavoro a informare i lavoratori sulluso dellIA nei processi decisionali — indipendentemente dalla classe di rischio del sistema.',
es: 'La ley nacional italiana de IA obliga a los empleadores a informar a los empleados sobre el uso de IA en los procesos de decisión, con independencia de la clase de riesgo del sistema.',
pl: 'Włoska krajowa ustawa o AI zobowiązuje pracodawców do informowania pracowników o wykorzystaniu AI w procesach decyzyjnych — niezależnie od klasy ryzyka systemu.',
cs: 'Italský národní zákon o AI ukládá zaměstnavatelům povinnost informovat zaměstnance o využívání AI v rozhodovacích procesech — bez ohledu na rizikovou třídu systému.',
sk: 'Taliansky národný zákon o AI ukladá zamestnávateľom povinnosť informovať zamestnancov o využívaní AI v rozhodovacích procesoch — bez ohľadu na rizikovú triedu systému.',
ro: 'Legea națională italiană privind AI obligă angajatorii să informeze angajații cu privire la utilizarea AI în procesele decizionale — indiferent de clasa de risc a sistemului.',
},
deadline: '2025-10-10',
roles: ['deployer'],
riskClasses: ['high', 'limited', 'minimal'],
},
{
id: 'it-l132-deepfake',
title: {
de: 'Strafbarkeit rechtswidriger Deepfakes beachten',
en: 'Note criminal liability for unlawful deepfakes',
fr: 'Tenir compte de la répression pénale des deepfakes illicites',
it: 'Tenere conto della rilevanza penale dei deepfake illeciti',
es: 'Tener en cuenta la responsabilidad penal por deepfakes ilícitos',
pl: 'Uwzględnić odpowiedzialność karną za bezprawne deepfakei',
cs: 'Zohlednit trestní odpovědnost za protiprávní deepfaky',
sk: 'Zohľadniť trestnú zodpovednosť za protiprávne deepfaky',
ro: 'Luarea în considerare a răspunderii penale pentru deepfake-urile ilegale',
},
articles: 'Legge 132/2025',
description: {
de: 'Die rechtswidrige Verbreitung schädigender Deepfakes ist in Italien strafbewehrt (bis zu 5 Jahre Freiheitsstrafe). Kennzeichnungs- und Freigabeprozesse für generierte Inhalte einrichten.',
en: 'Unlawful dissemination of harmful deepfakes is a criminal offence in Italy (up to 5 years imprisonment). Set up labelling and approval processes for generated content.',
fr: 'La diffusion illicite de deepfakes préjudiciables est pénalement sanctionnée en Italie (jusquà 5 ans demprisonnement). Mettre en place des processus de marquage et de validation des contenus générés.',
it: 'La diffusione illecita di deepfake dannosi è penalmente sanzionata in Italia (fino a 5 anni di reclusione). Predisporre processi di etichettatura e approvazione dei contenuti generati.',
es: 'La difusión ilícita de deepfakes dañinos está penalmente sancionada en Italia (hasta 5 años de prisión). Establecer procesos de etiquetado y aprobación de los contenidos generados.',
pl: 'Bezprawne rozpowszechnianie szkodliwych deepfakeów jest we Włoszech zagrożone karą (do 5 lat pozbawienia wolności). Wdrożyć procesy oznaczania i zatwierdzania generowanych treści.',
cs: 'Protiprávní šíření škodlivých deepfaků je v Itálii trestné (až 5 let odnětí svobody). Zavést procesy označování a schvalování generovaného obsahu.',
sk: 'Protiprávne šírenie škodlivých deepfakov je v Taliansku trestné (až 5 rokov odňatia slobody). Zaviesť procesy označovania a schvaľovania generovaného obsahu.',
ro: 'Difuzarea ilegală de deepfake-uri dăunătoare este sancționată penal în Italia (până la 5 ani de închisoare). Instituiți procese de etichetare și aprobare a conținutului generat.',
},
deadline: '2025-10-10',
roles: ['provider', 'deployer'],
riskClasses: ['high', 'limited'],
},
{
id: 'it-l132-sector',
title: {
de: 'Sektorregeln (Gesundheit, Justiz, Arbeit) und Durchführungsdekrete beobachten',
en: 'Monitor sector rules (health, justice, labour) and implementing decrees',
fr: 'Suivre les règles sectorielles (santé, justice, travail) et les décrets dapplication',
it: 'Monitorare le regole settoriali (sanità, giustizia, lavoro) e i decreti attuativi',
es: 'Seguir las normas sectoriales (sanidad, justicia, trabajo) y los decretos de desarrollo',
pl: 'Śledzić przepisy sektorowe (zdrowie, wymiar sprawiedliwości, praca) i dekrety wykonawcze',
cs: 'Sledovat sektorová pravidla (zdravotnictví, justice, práce) a prováděcí dekrety',
sk: 'Sledovať sektorové pravidlá (zdravotníctvo, justícia, práca) a vykonávacie dekréty',
ro: 'Monitorizarea normelor sectoriale (sănătate, justiție, muncă) și a decretelor de aplicare',
},
articles: 'Legge 132/2025',
description: {
de: 'Das Gesetz enthält Sonderregeln u. a. für Gesundheitswesen und Justiz; Durchführungsdekrete (inkl. Sanktionsregime) werden bis Ende 2026 erwartet.',
en: 'The law contains special rules for healthcare and justice, among others; implementing decrees (incl. penalty regime) are expected by the end of 2026.',
fr: 'La loi contient des règles particulières, notamment pour la santé et la justice ; les décrets dapplication (y compris le régime de sanctions) sont attendus dici fin 2026.',
it: 'La legge contiene regole speciali, tra laltro per la sanità e la giustizia; i decreti attuativi (incluso il regime sanzionatorio) sono attesi entro la fine del 2026.',
es: 'La ley contiene normas especiales, entre otras, para la sanidad y la justicia; los decretos de desarrollo (incluido el régimen sancionador) se esperan para finales de 2026.',
pl: 'Ustawa zawiera przepisy szczególne m.in. dla ochrony zdrowia i wymiaru sprawiedliwości; dekrety wykonawcze (w tym system sankcji) są oczekiwane do końca 2026 r.',
cs: 'Zákon obsahuje zvláštní pravidla mj. pro zdravotnictví a justici; prováděcí dekrety (včetně sankčního režimu) se očekávají do konce roku 2026.',
sk: 'Zákon obsahuje osobitné pravidlá o. i. pre zdravotníctvo a justíciu; vykonávacie dekréty (vrátane sankčného režimu) sa očakávajú do konca roka 2026.',
ro: 'Legea conține norme speciale, printre altele, pentru sănătate și justiție; decretele de aplicare (inclusiv regimul sancțiunilor) sunt așteptate până la sfârșitul anului 2026.',
},
deadline: '2026-10-10',
roles: ['provider', 'deployer'],
riskClasses: ['high'],
},
],
},
{
code: 'ES',
country: {
de: 'Spanien',
en: 'Spain',
fr: 'Espagne',
it: 'Spagna',
es: 'España',
pl: 'Hiszpania',
cs: 'Španělsko',
sk: 'Španielsko',
ro: 'Spania',
},
authority: {
de: 'AESIA (Agencia Española de Supervisión de la Inteligencia Artificial)',
en: 'AESIA (Spanish Agency for the Supervision of Artificial Intelligence)',
fr: 'AESIA (Agencia Española de Supervisión de la Inteligencia Artificial — agence espagnole de supervision de lintelligence artificielle)',
it: 'AESIA (Agencia Española de Supervisión de la Inteligencia Artificial — agenzia spagnola di supervisione dellintelligenza artificiale)',
es: 'AESIA (Agencia Española de Supervisión de la Inteligencia Artificial)',
pl: 'AESIA (Agencia Española de Supervisión de la Inteligencia Artificial — hiszpańska agencja nadzoru nad sztuczną inteligencją)',
cs: 'AESIA (Agencia Española de Supervisión de la Inteligencia Artificial — španělská agentura pro dohled nad umělou inteligencí)',
sk: 'AESIA (Agencia Española de Supervisión de la Inteligencia Artificial — španielska agentúra pre dohľad nad umelou inteligenciou)',
ro: 'AESIA (Agencia Española de Supervisión de la Inteligencia Artificial — agenția spaniolă de supraveghere a inteligenței artificiale)',
},
items: [
{
id: 'es-aesia',
title: {
de: 'AESIA-Aufsicht und spanisches Sanktionsgesetz beachten',
en: 'Note AESIA supervision and the Spanish sanctions bill',
fr: 'Tenir compte de la surveillance par lAESIA et du projet de loi espagnol sur les sanctions',
it: 'Tenere conto della vigilanza dellAESIA e del disegno di legge spagnolo sulle sanzioni',
es: 'Tener en cuenta la supervisión de AESIA y el anteproyecto de ley español de sanciones',
pl: 'Uwzględnić nadzór AESIA i hiszpański projekt ustawy o sankcjach',
cs: 'Zohlednit dohled AESIA a španělský návrh zákona o sankcích',
sk: 'Zohľadniť dohľad AESIA a španielsky návrh zákona o sankciách',
ro: 'Luarea în considerare a supravegherii AESIA și a proiectului de lege spaniol privind sancțiunile',
},
articles: 'AESIA; Anteproyecto de Ley de gobernanza de la IA',
description: {
de: 'Spanien hat mit AESIA als erstes EU-Land eine eigene KI-Aufsichtsbehörde; ein nationales Gesetz zu Sanktionen und Governance ist im Verfahren. AESIA ist zentrale Anlauf- und Meldestelle.',
en: 'Spain was the first EU country with a dedicated AI supervisory agency (AESIA); a national law on sanctions and governance is in the legislative process. AESIA is the central contact and reporting point.',
fr: 'LEspagne a été le premier pays de lUE doté dune autorité de surveillance de lIA dédiée (AESIA) ; une loi nationale sur les sanctions et la gouvernance est en cours dadoption. LAESIA est le point de contact et de signalement central.',
it: 'La Spagna è stata il primo paese dellUE con unautorità di vigilanza dedicata allIA (AESIA); una legge nazionale su sanzioni e governance è in corso di approvazione. LAESIA è il punto centrale di contatto e di segnalazione.',
es: 'España fue el primer país de la UE con una autoridad de supervisión de IA propia (AESIA); una ley nacional sobre sanciones y gobernanza está en tramitación. AESIA es el punto central de contacto y notificación.',
pl: 'Hiszpania jako pierwszy kraj UE utworzyła własny organ nadzoru nad AI (AESIA); krajowa ustawa o sankcjach i zarządzaniu jest w toku procedury legislacyjnej. AESIA jest centralnym punktem kontaktowym i zgłoszeniowym.',
cs: 'Španělsko jako první země EU zřídilo vlastní dozorový orgán pro AI (AESIA); národní zákon o sankcích a správě je v legislativním procesu. AESIA je ústředním kontaktním a ohlašovacím místem.',
sk: 'Španielsko ako prvá krajina EÚ zriadilo vlastný orgán dohľadu nad AI (AESIA); národný zákon o sankciách a správe je v legislatívnom procese. AESIA je ústredným kontaktným a ohlasovacím miestom.',
ro: 'Spania a fost prima țară din UE cu o autoritate proprie de supraveghere a AI (AESIA); o lege națională privind sancțiunile și guvernanța se află în procedură legislativă. AESIA este punctul central de contact și de raportare.',
},
deadline: '2026-08-02',
roles: ['provider', 'deployer', 'importer', 'distributor'],
riskClasses: ['high', 'limited'],
},
{
id: 'es-sandbox',
title: {
de: 'Regulatorischen Sandbox-Zugang prüfen (RD 817/2023)',
en: 'Consider regulatory sandbox access (RD 817/2023)',
fr: 'Examiner laccès au bac à sable réglementaire (RD 817/2023)',
it: 'Valutare laccesso alla sandbox regolamentare (RD 817/2023)',
es: 'Valorar el acceso al sandbox regulatorio (RD 817/2023)',
pl: 'Rozważyć dostęp do piaskownicy regulacyjnej (RD 817/2023)',
cs: 'Zvážit přístup do regulatorního sandboxu (RD 817/2023)',
sk: 'Zvážiť prístup do regulačného sandboxu (RD 817/2023)',
ro: 'Evaluarea accesului la sandbox-ul de reglementare (RD 817/2023)',
},
articles: 'Real Decreto 817/2023',
description: {
de: 'Spanien betreibt eine KI-Regulierungs-Sandbox für Hochrisiko-Systeme — für Anbieter eine Möglichkeit, Konformität unter Behördenbegleitung zu erproben.',
en: 'Spain operates an AI regulatory sandbox for high-risk systems — an opportunity for providers to test conformity under regulatory guidance.',
fr: 'LEspagne exploite un bac à sable réglementaire pour lIA destiné aux systèmes à haut risque — une occasion pour les fournisseurs de tester la conformité avec laccompagnement des autorités.',
it: 'La Spagna gestisce una sandbox regolamentare per lIA destinata ai sistemi ad alto rischio — unopportunità per i fornitori di sperimentare la conformità con laccompagnamento delle autorità.',
es: 'España opera un sandbox regulatorio de IA para sistemas de alto riesgo: una oportunidad para que los proveedores prueben la conformidad con acompañamiento de las autoridades.',
pl: 'Hiszpania prowadzi piaskownicę regulacyjną AI dla systemów wysokiego ryzyka — dla dostawców to możliwość przetestowania zgodności pod opieką organów.',
cs: 'Španělsko provozuje regulatorní sandbox pro AI určený vysoce rizikovým systémům — pro poskytovatele příležitost otestovat shodu za doprovodu úřadů.',
sk: 'Španielsko prevádzkuje regulačný sandbox pre AI určený vysokorizikovým systémom — pre poskytovateľov príležitosť otestovať zhodu za sprievodu úradov.',
ro: 'Spania operează un sandbox de reglementare pentru AI destinat sistemelor cu risc ridicat — o oportunitate pentru furnizori de a testa conformitatea sub îndrumarea autorităților.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
],
},
{
code: 'FR',
country: {
de: 'Frankreich',
en: 'France',
fr: 'France',
it: 'Francia',
es: 'Francia',
pl: 'Francja',
cs: 'Francie',
sk: 'Francúzsko',
ro: 'Franța',
},
authority: {
de: 'Mehrbehördenmodell; CNIL federführend für KI mit Personenbezug, DGCCRF u. a. für Marktüberwachung',
en: 'Multi-authority model; CNIL leads on AI involving personal data, DGCCRF and others for market surveillance',
fr: 'Modèle multi-autorités ; la CNIL est chef de file pour lIA impliquant des données personnelles, la DGCCRF et dautres autorités assurent la surveillance du marché',
it: 'Modello multi-autorità; la CNIL guida per lIA che coinvolge dati personali, la DGCCRF e altre autorità per la vigilanza del mercato',
es: 'Modelo de múltiples autoridades; la CNIL lidera en materia de IA con datos personales, la DGCCRF y otras se encargan de la vigilancia del mercado',
pl: 'Model wieloorganowy; CNIL wiodąca dla AI przetwarzającej dane osobowe, DGCCRF i inne organy odpowiadają za nadzór rynku',
cs: 'Model více orgánů; CNIL má vedoucí úlohu pro AI zpracovávající osobní údaje, DGCCRF a další orgány zajišťují dozor nad trhem',
sk: 'Model viacerých orgánov; CNIL má vedúcu úlohu pre AI spracúvajúcu osobné údaje, DGCCRF a ďalšie orgány zabezpečujú dohľad nad trhom',
ro: 'Model cu autorități multiple; CNIL coordonează pentru AI care implică date cu caracter personal, DGCCRF și alte autorități asigură supravegherea pieței',
},
items: [
{
id: 'fr-cnil',
title: {
de: 'CNIL-Empfehlungen zu KI und DSGVO umsetzen',
en: 'Implement CNIL recommendations on AI and GDPR',
fr: 'Mettre en œuvre les recommandations de la CNIL sur lIA et le RGPD',
it: 'Attuare le raccomandazioni della CNIL su IA e GDPR',
es: 'Aplicar las recomendaciones de la CNIL sobre IA y RGPD',
pl: 'Wdrożyć zalecenia CNIL dotyczące AI i RODO',
cs: 'Provést doporučení CNIL k AI a GDPR',
sk: 'Implementovať odporúčania CNIL k AI a GDPR',
ro: 'Punerea în aplicare a recomandărilor CNIL privind AI și RGPD',
},
articles: 'CNIL — Recommandations IA',
description: {
de: 'Die CNIL hat detaillierte Leitlinien zur DSGVO-konformen Entwicklung und Nutzung von KI veröffentlicht (Rechtsgrundlagen, Trainingsdaten, Betroffenenrechte); bei Personenbezug maßgeblich.',
en: 'The CNIL has published detailed guidance on GDPR-compliant development and use of AI (legal bases, training data, data subject rights); authoritative where personal data is involved.',
fr: 'La CNIL a publié des lignes directrices détaillées sur le développement et lutilisation de lIA conformes au RGPD (bases juridiques, données dentraînement, droits des personnes concernées) ; elles font référence dès que des données personnelles sont en jeu.',
it: 'La CNIL ha pubblicato linee guida dettagliate sullo sviluppo e sulluso dellIA conformi al GDPR (basi giuridiche, dati di addestramento, diritti degli interessati); determinanti in presenza di dati personali.',
es: 'La CNIL ha publicado directrices detalladas sobre el desarrollo y uso de IA conformes con el RGPD (bases jurídicas, datos de entrenamiento, derechos de los interesados); son determinantes cuando hay datos personales implicados.',
pl: 'CNIL opublikowała szczegółowe wytyczne dotyczące zgodnego z RODO rozwoju i wykorzystania AI (podstawy prawne, dane treningowe, prawa osób, których dane dotyczą); miarodajne, gdy przetwarzane są dane osobowe.',
cs: 'CNIL zveřejnila podrobné pokyny k vývoji a využívání AI v souladu s GDPR (právní základy, trénovací data, práva subjektů údajů); směrodatné, jsou-li dotčeny osobní údaje.',
sk: 'CNIL zverejnila podrobné usmernenia k vývoju a využívaniu AI v súlade s GDPR (právne základy, trénovacie dáta, práva dotknutých osôb); smerodajné, ak ide o osobné údaje.',
ro: 'CNIL a publicat orientări detaliate privind dezvoltarea și utilizarea AI în conformitate cu RGPD (temeiuri juridice, date de antrenament, drepturile persoanelor vizate); de referință atunci când sunt implicate date cu caracter personal.',
},
deadline: '2025-02-02',
roles: ['provider', 'deployer'],
riskClasses: ['high', 'limited', 'minimal'],
},
],
},
{
code: 'NL',
country: {
de: 'Niederlande',
en: 'Netherlands',
fr: 'Pays-Bas',
it: 'Paesi Bassi',
es: 'Países Bajos',
pl: 'Niderlandy',
cs: 'Nizozemsko',
sk: 'Holandsko',
ro: 'Țările de Jos',
},
authority: {
de: 'Autoriteit Persoonsgegevens (AP) — Koordination Algorithmen-Aufsicht (DCA); RDI für technische Marktüberwachung',
en: 'Dutch Data Protection Authority (AP) — algorithm oversight coordination (DCA); RDI for technical market surveillance',
fr: 'Autoriteit Persoonsgegevens (AP) — coordination de la surveillance des algorithmes (DCA) ; RDI pour la surveillance technique du marché',
it: 'Autoriteit Persoonsgegevens (AP) — coordinamento della vigilanza sugli algoritmi (DCA); RDI per la vigilanza tecnica del mercato',
es: 'Autoriteit Persoonsgegevens (AP) — coordinación de la supervisión de algoritmos (DCA); RDI para la vigilancia técnica del mercado',
pl: 'Autoriteit Persoonsgegevens (AP) — koordynacja nadzoru nad algorytmami (DCA); RDI ds. technicznego nadzoru rynku',
cs: 'Autoriteit Persoonsgegevens (AP) — koordinace dohledu nad algoritmy (DCA); RDI pro technický dozor nad trhem',
sk: 'Autoriteit Persoonsgegevens (AP) — koordinácia dohľadu nad algoritmami (DCA); RDI pre technický dohľad nad trhom',
ro: 'Autoriteit Persoonsgegevens (AP) — coordonarea supravegherii algoritmilor (DCA); RDI pentru supravegherea tehnică a pieței',
},
items: [
{
id: 'nl-algo-register',
title: {
de: 'Algorithmenregister für öffentliche Stellen pflegen',
en: 'Maintain the algorithm register for public bodies',
fr: 'Tenir le registre des algorithmes pour les organismes publics',
it: 'Tenere il registro degli algoritmi per gli enti pubblici',
es: 'Mantener el registro de algoritmos para los organismos públicos',
pl: 'Prowadzić rejestr algorytmów dla podmiotów publicznych',
cs: 'Vést registr algoritmů pro veřejné subjekty',
sk: 'Viesť register algoritmov pre verejné subjekty',
ro: 'Menținerea registrului algoritmilor pentru organismele publice',
},
articles: 'Algoritmeregister (verplicht für Behörden)',
description: {
de: 'Niederländische Behörden müssen eingesetzte (wirkungsrelevante) Algorithmen und KI-Systeme im öffentlichen Algorithmenregister dokumentieren; private Auftragnehmer öffentlicher Stellen sind mittelbar betroffen.',
en: 'Dutch public authorities must document deployed (impact-relevant) algorithms and AI systems in the public algorithm register; private contractors of public bodies are indirectly affected.',
fr: 'Les autorités publiques néerlandaises doivent documenter les algorithmes et systèmes dIA déployés (ayant un impact significatif) dans le registre public des algorithmes ; les prestataires privés dorganismes publics sont indirectement concernés.',
it: 'Le autorità pubbliche olandesi devono documentare gli algoritmi e i sistemi di IA impiegati (rilevanti per limpatto) nel registro pubblico degli algoritmi; i contraenti privati degli enti pubblici sono indirettamente interessati.',
es: 'Las autoridades públicas neerlandesas deben documentar los algoritmos y sistemas de IA utilizados (con impacto relevante) en el registro público de algoritmos; los contratistas privados de organismos públicos se ven indirectamente afectados.',
pl: 'Niderlandzkie organy publiczne muszą dokumentować stosowane (istotne pod względem oddziaływania) algorytmy i systemy AI w publicznym rejestrze algorytmów; prywatni wykonawcy zleceń podmiotów publicznych są pośrednio objęci tym obowiązkiem.',
cs: 'Nizozemské veřejné orgány musí dokumentovat nasazené (z hlediska dopadu relevantní) algoritmy a systémy AI ve veřejném registru algoritmů; soukromí dodavatelé veřejných subjektů jsou dotčeni nepřímo.',
sk: 'Holandské verejné orgány musia dokumentovať nasadené (z hľadiska dopadu relevantné) algoritmy a systémy AI vo verejnom registri algoritmov; súkromní dodávatelia verejných subjektov sú dotknutí nepriamo.',
ro: 'Autoritățile publice neerlandeze trebuie să documenteze algoritmii și sistemele AI utilizate (relevante ca impact) în registrul public al algoritmilor; contractanții privați ai organismelor publice sunt vizați indirect.',
},
deadline: '2025-02-02',
roles: ['deployer'],
riskClasses: ['high', 'limited'],
},
],
},
];

View File

@ -0,0 +1,765 @@
import type { ObligationSrc } from './sourceTypes';
/** EU-weite Pflichten aus dem AI Act (rollen- und risikoklassenspezifisch). */
export const OBLIGATIONS: readonly ObligationSrc[] = [
// ── Alle Risikoklassen / alle Rollen ──────────────────────────────
{
id: 'ob-ai-literacy',
title: {
de: 'KI-Kompetenz des Personals sicherstellen',
en: 'Ensure AI literacy of staff',
fr: 'Garantir la maîtrise de lIA du personnel',
it: 'Garantire lalfabetizzazione in materia di IA del personale',
es: 'Garantizar la alfabetización en materia de IA del personal',
pl: 'Zapewnić kompetencje personelu w zakresie AI',
cs: 'Zajistit gramotnost personálu v oblasti AI',
sk: 'Zabezpečiť gramotnosť personálu v oblasti AI',
ro: 'Asigurarea alfabetizării personalului în domeniul IA',
},
articles: 'Art. 4',
description: {
de: 'Mitarbeitende, die KI-Systeme betreiben oder nutzen, müssen über ausreichende KI-Kompetenz verfügen (Schulungen, Richtlinien). Gilt seit 2. Februar 2025 für alle Anbieter und Betreiber.',
en: 'Staff operating or using AI systems must have sufficient AI literacy (training, policies). Applies since 2 February 2025 to all providers and deployers.',
fr: 'Le personnel qui exploite ou utilise des systèmes dIA doit disposer dune maîtrise de lIA suffisante (formations, lignes directrices). Sapplique depuis le 2 février 2025 à tous les fournisseurs et déployeurs.',
it: 'Il personale che gestisce o utilizza sistemi di IA deve possedere unadeguata alfabetizzazione in materia di IA (formazione, linee guida). Si applica dal 2 febbraio 2025 a tutti i fornitori e i deployer.',
es: 'El personal que opera o utiliza sistemas de IA debe contar con suficiente alfabetización en materia de IA (formación, directrices). Se aplica desde el 2 de febrero de 2025 a todos los proveedores y responsables del despliegue.',
pl: 'Pracownicy obsługujący lub wykorzystujący systemy AI muszą posiadać wystarczające kompetencje w zakresie AI (szkolenia, wytyczne). Obowiązuje od 2 lutego 2025 r. wszystkich dostawców i podmioty stosujące.',
cs: 'Zaměstnanci, kteří provozují nebo používají systémy AI, musí mít dostatečnou gramotnost v oblasti AI (školení, pokyny). Platí od 2. února 2025 pro všechny poskytovatele a zavádějící subjekty.',
sk: 'Zamestnanci, ktorí prevádzkujú alebo používajú systémy AI, musia mať dostatočnú gramotnosť v oblasti AI (školenia, usmernenia). Platí od 2. februára 2025 pre všetkých poskytovateľov a nasadzujúce subjekty.',
ro: 'Personalul care operează sau utilizează sisteme de IA trebuie să dispună de un nivel suficient de alfabetizare în domeniul IA (formare, orientări). Se aplică de la 2 februarie 2025 tuturor furnizorilor și implementatorilor.',
},
deadline: '2025-02-02',
roles: ['provider', 'deployer', 'importer', 'distributor'],
riskClasses: ['high', 'limited', 'minimal'],
},
// ── Hochrisiko: Anbieter ──────────────────────────────────────────
{
id: 'ob-risk-mgmt',
title: {
de: 'Risikomanagementsystem einrichten',
en: 'Establish a risk management system',
fr: 'Mettre en place un système de gestion des risques',
it: 'Istituire un sistema di gestione dei rischi',
es: 'Establecer un sistema de gestión de riesgos',
pl: 'Ustanowić system zarządzania ryzykiem',
cs: 'Zavést systém řízení rizik',
sk: 'Zaviesť systém riadenia rizík',
ro: 'Instituirea unui sistem de gestionare a riscurilor',
},
articles: 'Art. 9',
description: {
de: 'Kontinuierlicher, iterativer Risikomanagementprozess über den gesamten Lebenszyklus: Risiken identifizieren, bewerten, mindern, testen.',
en: 'Continuous, iterative risk management process across the entire lifecycle: identify, assess, mitigate and test risks.',
fr: 'Processus de gestion des risques continu et itératif sur lensemble du cycle de vie : identifier, évaluer, atténuer et tester les risques.',
it: 'Processo di gestione dei rischi continuo e iterativo lungo lintero ciclo di vita: identificare, valutare, attenuare e testare i rischi.',
es: 'Proceso continuo e iterativo de gestión de riesgos a lo largo de todo el ciclo de vida: identificar, evaluar, mitigar y probar los riesgos.',
pl: 'Ciągły, iteracyjny proces zarządzania ryzykiem w całym cyklu życia: identyfikacja, ocena, ograniczanie i testowanie ryzyka.',
cs: 'Nepřetržitý, iterativní proces řízení rizik v průběhu celého životního cyklu: rizika identifikovat, posoudit, zmírnit a testovat.',
sk: 'Nepretržitý, iteratívny proces riadenia rizík počas celého životného cyklu: riziká identifikovať, posúdiť, zmierniť a testovať.',
ro: 'Proces continuu și iterativ de gestionare a riscurilor pe parcursul întregului ciclu de viață: identificarea, evaluarea, atenuarea și testarea riscurilor.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-data-governance',
title: {
de: 'Daten-Governance für Trainings-/Test-/Validierungsdaten',
en: 'Data governance for training/testing/validation data',
fr: 'Gouvernance des données dentraînement, de test et de validation',
it: 'Governance dei dati di addestramento, prova e convalida',
es: 'Gobernanza de los datos de entrenamiento, prueba y validación',
pl: 'Zarządzanie danymi treningowymi, testowymi i walidacyjnymi',
cs: 'Správa trénovacích, testovacích a validačních dat',
sk: 'Správa trénovacích, testovacích a validačných údajov',
ro: 'Guvernanța datelor de antrenament, de testare și de validare',
},
articles: 'Art. 10',
description: {
de: 'Datensätze müssen relevant, repräsentativ, möglichst fehlerfrei und vollständig sein; Bias-Prüfung und geeignete Erhebungsverfahren dokumentieren.',
en: 'Datasets must be relevant, representative, as error-free and complete as possible; document bias examination and appropriate collection procedures.',
fr: 'Les jeux de données doivent être pertinents, représentatifs, aussi exempts derreurs et complets que possible ; documenter lexamen des biais et les procédures de collecte appropriées.',
it: 'I set di dati devono essere pertinenti, rappresentativi e, per quanto possibile, esenti da errori e completi; documentare lesame dei bias e procedure di raccolta adeguate.',
es: 'Los conjuntos de datos deben ser pertinentes, representativos y, en la medida de lo posible, completos y libres de errores; documentar el examen de sesgos y los procedimientos de recogida adecuados.',
pl: 'Zbiory danych muszą być adekwatne, reprezentatywne, w możliwie największym stopniu wolne od błędów i kompletne; udokumentować badanie pod kątem stronniczości (bias) oraz odpowiednie procedury zbierania danych.',
cs: 'Datové soubory musí být relevantní, reprezentativní a v co největší míře bez chyb a úplné; zdokumentovat přezkum zkreslení (bias) a vhodné postupy sběru dat.',
sk: 'Súbory údajov musia byť relevantné, reprezentatívne a v čo najväčšej miere bez chýb a úplné; zdokumentovať preskúmanie zaujatosti (bias) a vhodné postupy zberu údajov.',
ro: 'Seturile de date trebuie să fie relevante, reprezentative și, în măsura posibilului, complete și fără erori; se documentează examinarea distorsiunilor (bias) și procedurile adecvate de colectare.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-tech-doc',
title: {
de: 'Technische Dokumentation (Annex IV) erstellen',
en: 'Prepare technical documentation (Annex IV)',
fr: 'Établir la documentation technique (annexe IV)',
it: 'Redigere la documentazione tecnica (allegato IV)',
es: 'Elaborar la documentación técnica (anexo IV)',
pl: 'Sporządzić dokumentację techniczną (załącznik IV)',
cs: 'Vypracovat technickou dokumentaci (příloha IV)',
sk: 'Vypracovať technickú dokumentáciu (príloha IV)',
ro: 'Întocmirea documentației tehnice (anexa IV)',
},
articles: 'Art. 11, Annex IV',
description: {
de: 'Vollständige technische Dokumentation vor Inverkehrbringen; für KMU gelten vereinfachte Formulare. Der Dokumenten-Generator dieses Tools erzeugt das Grundgerüst.',
en: 'Complete technical documentation before placing on the market; simplified forms apply to SMEs. This tool generates the skeleton.',
fr: 'Documentation technique complète avant la mise sur le marché ; des formulaires simplifiés sappliquent aux PME. Le générateur de documents de cet outil crée la structure de base.',
it: 'Documentazione tecnica completa prima dellimmissione sul mercato; per le PMI si applicano moduli semplificati. Il generatore di documenti di questo strumento crea la struttura di base.',
es: 'Documentación técnica completa antes de la introducción en el mercado; a las pymes se les aplican formularios simplificados. El generador de documentos de esta herramienta crea la estructura básica.',
pl: 'Kompletna dokumentacja techniczna przed wprowadzeniem do obrotu; dla MŚP przewidziano uproszczone formularze. Generator dokumentów tego narzędzia tworzy podstawowy szkielet.',
cs: 'Úplná technická dokumentace před uvedením na trh; pro malé a střední podniky platí zjednodušené formuláře. Generátor dokumentů tohoto nástroje vytvoří základní kostru.',
sk: 'Úplná technická dokumentácia pred uvedením na trh; pre MSP platia zjednodušené formuláre. Generátor dokumentov tohto nástroja vytvorí základnú kostru.',
ro: 'Documentație tehnică completă înainte de introducerea pe piață; pentru IMM-uri se aplică formulare simplificate. Generatorul de documente al acestui instrument creează structura de bază.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-logging',
title: {
de: 'Protokollierung (Logging) technisch ermöglichen',
en: 'Enable logging technically',
fr: 'Permettre techniquement la journalisation (logging)',
it: 'Rendere tecnicamente possibile la registrazione (logging)',
es: 'Posibilitar técnicamente el registro (logging)',
pl: 'Zapewnić techniczną możliwość rejestracji zdarzeń (logging)',
cs: 'Technicky umožnit vedení záznamů (logging)',
sk: 'Technicky umožniť vedenie záznamov (logging)',
ro: 'Asigurarea tehnică a păstrării evidențelor (logging)',
},
articles: 'Art. 12',
description: {
de: 'Automatische Aufzeichnung von Ereignissen über den Lebenszyklus, um Rückverfolgbarkeit und Marktüberwachung zu ermöglichen.',
en: 'Automatic recording of events across the lifecycle to enable traceability and market surveillance.',
fr: 'Enregistrement automatique des événements tout au long du cycle de vie afin de permettre la traçabilité et la surveillance du marché.',
it: 'Registrazione automatica degli eventi lungo il ciclo di vita per consentire la tracciabilità e la vigilanza del mercato.',
es: 'Registro automático de eventos a lo largo del ciclo de vida para permitir la trazabilidad y la vigilancia del mercado.',
pl: 'Automatyczne rejestrowanie zdarzeń w całym cyklu życia w celu zapewnienia identyfikowalności i nadzoru rynku.',
cs: 'Automatické zaznamenávání událostí v průběhu životního cyklu za účelem sledovatelnosti a dozoru nad trhem.',
sk: 'Automatické zaznamenávanie udalostí počas životného cyklu na účely vysledovateľnosti a dohľadu nad trhom.',
ro: 'Înregistrarea automată a evenimentelor pe parcursul ciclului de viață pentru a permite trasabilitatea și supravegherea pieței.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-transparency-instructions',
title: {
de: 'Betriebsanleitung und Transparenzinformationen bereitstellen',
en: 'Provide instructions for use and transparency information',
fr: 'Fournir la notice dutilisation et les informations de transparence',
it: 'Fornire le istruzioni per luso e le informazioni sulla trasparenza',
es: 'Facilitar las instrucciones de uso y la información de transparencia',
pl: 'Udostępnić instrukcję obsługi i informacje dotyczące przejrzystości',
cs: 'Poskytnout návod k použití a informace o transparentnosti',
sk: 'Poskytnúť návod na použitie a informácie o transparentnosti',
ro: 'Furnizarea instrucțiunilor de utilizare și a informațiilor privind transparența',
},
articles: 'Art. 13',
description: {
de: 'Klare Gebrauchsanweisung: Zweckbestimmung, Genauigkeit, Grenzen, menschliche Aufsicht, erwartete Lebensdauer und Wartung.',
en: 'Clear instructions for use: intended purpose, accuracy, limitations, human oversight, expected lifetime and maintenance.',
fr: 'Notice dutilisation claire : destination, exactitude, limites, contrôle humain, durée de vie attendue et maintenance.',
it: 'Istruzioni per luso chiare: finalità prevista, accuratezza, limiti, sorveglianza umana, durata di vita prevista e manutenzione.',
es: 'Instrucciones de uso claras: finalidad prevista, precisión, limitaciones, supervisión humana, vida útil esperada y mantenimiento.',
pl: 'Jasna instrukcja obsługi: przeznaczenie, dokładność, ograniczenia, nadzór ze strony człowieka, przewidywany okres eksploatacji i konserwacja.',
cs: 'Jasný návod k použití: zamýšlený účel, přesnost, omezení, lidský dohled, očekávaná životnost a údržba.',
sk: 'Jasný návod na použitie: zamýšľaný účel, presnosť, obmedzenia, ľudský dohľad, očakávaná životnosť a údržba.',
ro: 'Instrucțiuni de utilizare clare: scopul preconizat, acuratețea, limitările, supravegherea umană, durata de viață preconizată și mentenanța.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-human-oversight',
title: {
de: 'Menschliche Aufsicht konzipieren',
en: 'Design human oversight',
fr: 'Concevoir le contrôle humain',
it: 'Progettare la sorveglianza umana',
es: 'Diseñar la supervisión humana',
pl: 'Zaprojektować nadzór ze strony człowieka',
cs: 'Navrhnout lidský dohled',
sk: 'Navrhnúť ľudský dohľad',
ro: 'Conceperea supravegherii umane',
},
articles: 'Art. 14',
description: {
de: 'Das System muss wirksam durch Menschen beaufsichtigt werden können (Eingriffs-/Abbruchmöglichkeiten, Automation-Bias-Vorkehrungen).',
en: 'The system must allow effective human oversight (intervention/stop mechanisms, safeguards against automation bias).',
fr: 'Le système doit pouvoir faire lobjet dun contrôle humain effectif (possibilités dintervention et darrêt, mesures contre le biais dautomatisation).',
it: 'Il sistema deve poter essere efficacemente sorvegliato da persone fisiche (possibilità di intervento e arresto, misure contro il bias di automazione).',
es: 'El sistema debe poder ser supervisado eficazmente por personas (mecanismos de intervención y parada, salvaguardias contra el sesgo de automatización).',
pl: 'System musi umożliwiać skuteczny nadzór ze strony człowieka (możliwość interwencji i zatrzymania, środki przeciw tendencyjności automatyzacji).',
cs: 'Systém musí umožňovat účinný lidský dohled (možnosti zásahu a zastavení, opatření proti zkreslení způsobenému automatizací).',
sk: 'Systém musí umožňovať účinný ľudský dohľad (možnosti zásahu a zastavenia, opatrenia proti zaujatosti v dôsledku automatizácie).',
ro: 'Sistemul trebuie să permită o supraveghere umană eficace (mecanisme de intervenție și de oprire, garanții împotriva prejudecății legate de automatizare).',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-accuracy-robustness',
title: {
de: 'Genauigkeit, Robustheit und Cybersicherheit gewährleisten',
en: 'Ensure accuracy, robustness and cybersecurity',
fr: 'Garantir lexactitude, la robustesse et la cybersécurité',
it: 'Garantire accuratezza, robustezza e cibersicurezza',
es: 'Garantizar la precisión, la solidez y la ciberseguridad',
pl: 'Zapewnić dokładność, solidność i cyberbezpieczeństwo',
cs: 'Zajistit přesnost, spolehlivost a kybernetickou bezpečnost',
sk: 'Zabezpečiť presnosť, odolnosť a kybernetickú bezpečnosť',
ro: 'Asigurarea acurateței, robusteței și securității cibernetice',
},
articles: 'Art. 15',
description: {
de: 'Angemessenes Niveau an Genauigkeit und Widerstandsfähigkeit, inkl. Schutz gegen KI-spezifische Angriffe (Data Poisoning, Adversarial Examples, Prompt Injection).',
en: 'Appropriate level of accuracy and resilience, incl. protection against AI-specific attacks (data poisoning, adversarial examples, prompt injection).',
fr: 'Niveau approprié dexactitude et de résilience, y compris la protection contre les attaques propres à lIA (empoisonnement des données, exemples adverses, injection de prompt).',
it: 'Livello adeguato di accuratezza e resilienza, inclusa la protezione contro attacchi specifici dellIA (data poisoning, esempi avversari, prompt injection).',
es: 'Nivel adecuado de precisión y resiliencia, incluida la protección frente a ataques específicos de la IA (envenenamiento de datos, ejemplos adversarios, inyección de instrucciones).',
pl: 'Odpowiedni poziom dokładności i odporności, w tym ochrona przed atakami specyficznymi dla AI (zatruwanie danych, przykłady kontradyktoryjne, prompt injection).',
cs: 'Přiměřená úroveň přesnosti a odolnosti, včetně ochrany před útoky specifickými pro AI (data poisoning, adversariální příklady, prompt injection).',
sk: 'Primeraná úroveň presnosti a odolnosti vrátane ochrany pred útokmi špecifickými pre AI (data poisoning, adversariálne príklady, prompt injection).',
ro: 'Nivel adecvat de acuratețe și reziliență, inclusiv protecție împotriva atacurilor specifice IA (otrăvirea datelor, exemple adversariale, prompt injection).',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-qms',
title: {
de: 'Qualitätsmanagementsystem einführen',
en: 'Implement a quality management system',
fr: 'Mettre en place un système de gestion de la qualité',
it: 'Introdurre un sistema di gestione della qualità',
es: 'Implantar un sistema de gestión de la calidad',
pl: 'Wdrożyć system zarządzania jakością',
cs: 'Zavést systém řízení kvality',
sk: 'Zaviesť systém riadenia kvality',
ro: 'Implementarea unui sistem de management al calității',
},
articles: 'Art. 17',
description: {
de: 'Dokumentiertes QMS: Compliance-Strategie, Prüfverfahren, Datenmanagement, Risikomanagement, Meldeverfahren, Verantwortlichkeiten.',
en: 'Documented QMS: compliance strategy, testing procedures, data management, risk management, reporting procedures, responsibilities.',
fr: 'Système de gestion de la qualité documenté : stratégie de conformité, procédures dessai, gestion des données, gestion des risques, procédures de signalement, responsabilités.',
it: 'Sistema di gestione della qualità documentato: strategia di conformità, procedure di prova, gestione dei dati, gestione dei rischi, procedure di segnalazione, responsabilità.',
es: 'SGC documentado: estrategia de cumplimiento, procedimientos de prueba, gestión de datos, gestión de riesgos, procedimientos de notificación, responsabilidades.',
pl: 'Udokumentowany system zarządzania jakością: strategia zgodności, procedury testowania, zarządzanie danymi, zarządzanie ryzykiem, procedury zgłaszania, zakresy odpowiedzialności.',
cs: 'Zdokumentovaný systém řízení kvality: strategie souladu, zkušební postupy, správa dat, řízení rizik, postupy hlášení, odpovědnosti.',
sk: 'Zdokumentovaný systém riadenia kvality: stratégia súladu, postupy skúšania, správa údajov, riadenie rizík, postupy nahlasovania, zodpovednosti.',
ro: 'Sistem de management al calității documentat: strategie de conformitate, proceduri de testare, gestionarea datelor, gestionarea riscurilor, proceduri de raportare, responsabilități.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-corrective',
title: {
de: 'Korrekturmaßnahmen und Informationspflichten organisieren',
en: 'Organise corrective actions and information duties',
fr: 'Organiser les mesures correctives et les obligations dinformation',
it: 'Organizzare le misure correttive e gli obblighi di informazione',
es: 'Organizar las medidas correctoras y los deberes de información',
pl: 'Zorganizować działania naprawcze i obowiązki informacyjne',
cs: 'Zorganizovat nápravná opatření a informační povinnosti',
sk: 'Zorganizovať nápravné opatrenia a informačné povinnosti',
ro: 'Organizarea măsurilor corective și a obligațiilor de informare',
},
articles: 'Art. 20, 21',
description: {
de: 'Bei Nichtkonformität: unverzüglich korrigieren, zurücknehmen oder zurückrufen; Händler, Betreiber und Behörden informieren; mit zuständigen Behörden kooperieren.',
en: 'In case of non-conformity: immediately correct, withdraw or recall; inform distributors, deployers and authorities; cooperate with competent authorities.',
fr: 'En cas de non-conformité : corriger, retirer ou rappeler sans tarder ; informer les distributeurs, les déployeurs et les autorités ; coopérer avec les autorités compétentes.',
it: 'In caso di non conformità: correggere, ritirare o richiamare senza indugio; informare distributori, deployer e autorità; cooperare con le autorità competenti.',
es: 'En caso de no conformidad: corregir, retirar o recuperar sin demora; informar a los distribuidores, los responsables del despliegue y las autoridades; cooperar con las autoridades competentes.',
pl: 'W przypadku niezgodności: niezwłocznie skorygować, wycofać z obrotu lub z użytku; poinformować dystrybutorów, podmioty stosujące i organy; współpracować z właściwymi organami.',
cs: 'V případě nesouladu: neprodleně napravit, stáhnout z trhu nebo z oběhu; informovat distributory, zavádějící subjekty a orgány; spolupracovat s příslušnými orgány.',
sk: 'V prípade nesúladu: bezodkladne napraviť, stiahnuť z trhu alebo od používateľov; informovať distribútorov, nasadzujúce subjekty a orgány; spolupracovať s príslušnými orgánmi.',
ro: 'În caz de neconformitate: corectarea, retragerea sau rechemarea fără întârziere; informarea distribuitorilor, a implementatorilor și a autorităților; cooperarea cu autoritățile competente.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-authorized-rep',
title: {
de: 'Bevollmächtigten in der EU benennen (Nicht-EU-Anbieter)',
en: 'Appoint an authorised representative in the EU (non-EU providers)',
fr: 'Désigner un mandataire dans lUE (fournisseurs hors UE)',
it: 'Nominare un rappresentante autorizzato nellUE (fornitori extra UE)',
es: 'Designar un representante autorizado en la UE (proveedores de fuera de la UE)',
pl: 'Wyznaczyć upoważnionego przedstawiciela w UE (dostawcy spoza UE)',
cs: 'Jmenovat zplnomocněného zástupce v EU (poskytovatelé ze zemí mimo EU)',
sk: 'Vymenovať splnomocneného zástupcu v EÚ (poskytovatelia z krajín mimo EÚ)',
ro: 'Desemnarea unui reprezentant autorizat în UE (furnizori din afara UE)',
},
articles: 'Art. 22',
description: {
de: 'Anbieter mit Sitz außerhalb der EU müssen vor Bereitstellung einen in der EU niedergelassenen Bevollmächtigten schriftlich mandatieren.',
en: 'Providers established outside the EU must appoint, by written mandate, an authorised representative established in the EU before making systems available.',
fr: 'Les fournisseurs établis en dehors de lUE doivent, avant de mettre leurs systèmes à disposition, désigner par mandat écrit un mandataire établi dans lUE.',
it: 'I fornitori stabiliti al di fuori dellUE devono, prima di mettere a disposizione i sistemi, nominare mediante mandato scritto un rappresentante autorizzato stabilito nellUE.',
es: 'Los proveedores establecidos fuera de la UE deben designar, mediante mandato escrito, un representante autorizado establecido en la UE antes de comercializar sus sistemas.',
pl: 'Dostawcy mający siedzibę poza UE muszą przed udostępnieniem systemów ustanowić, w drodze pisemnego pełnomocnictwa, upoważnionego przedstawiciela mającego siedzibę w UE.',
cs: 'Poskytovatelé usazení mimo EU musí před dodáním systémů na trh písemným pověřením jmenovat zplnomocněného zástupce usazeného v EU.',
sk: 'Poskytovatelia usadení mimo EÚ musia pred sprístupnením systémov písomným splnomocnením vymenovať splnomocneného zástupcu usadeného v EÚ.',
ro: 'Furnizorii stabiliți în afara UE trebuie să desemneze, printr-un mandat scris, un reprezentant autorizat stabilit în UE înainte de punerea la dispoziție a sistemelor.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-conformity',
title: {
de: 'Konformitätsbewertung durchführen, CE-Kennzeichnung, EU-Datenbank-Registrierung',
en: 'Conduct conformity assessment, CE marking, EU database registration',
fr: 'Réaliser lévaluation de la conformité, marquage CE, enregistrement dans la base de données de lUE',
it: 'Effettuare la valutazione della conformità, marcatura CE, registrazione nella banca dati dellUE',
es: 'Realizar la evaluación de la conformidad, marcado CE, registro en la base de datos de la UE',
pl: 'Przeprowadzić ocenę zgodności, oznakowanie CE, rejestracja w bazie danych UE',
cs: 'Provést posouzení shody, označení CE, registrace v databázi EU',
sk: 'Vykonať posudzovanie zhody, označenie CE, registrácia v databáze EÚ',
ro: 'Efectuarea evaluării conformității, marcajul CE, înregistrarea în baza de date a UE',
},
articles: 'Art. 43, 4749',
description: {
de: 'Konformitätsbewertungsverfahren abschließen, EU-Konformitätserklärung ausstellen, CE-Kennzeichnung anbringen und System in der EU-Datenbank registrieren.',
en: 'Complete the conformity assessment procedure, issue the EU declaration of conformity, affix CE marking and register the system in the EU database.',
fr: 'Mener à terme la procédure dévaluation de la conformité, établir la déclaration UE de conformité, apposer le marquage CE et enregistrer le système dans la base de données de lUE.',
it: 'Completare la procedura di valutazione della conformità, rilasciare la dichiarazione di conformità UE, apporre la marcatura CE e registrare il sistema nella banca dati dellUE.',
es: 'Completar el procedimiento de evaluación de la conformidad, expedir la declaración UE de conformidad, colocar el marcado CE y registrar el sistema en la base de datos de la UE.',
pl: 'Zakończyć procedurę oceny zgodności, wystawić deklarację zgodności UE, umieścić oznakowanie CE i zarejestrować system w bazie danych UE.',
cs: 'Dokončit postup posuzování shody, vydat EU prohlášení o shodě, umístit označení CE a zaregistrovat systém v databázi EU.',
sk: 'Dokončiť postup posudzovania zhody, vydať EÚ vyhlásenie o zhode, umiestniť označenie CE a zaregistrovať systém v databáze EÚ.',
ro: 'Finalizarea procedurii de evaluare a conformității, emiterea declarației de conformitate UE, aplicarea marcajului CE și înregistrarea sistemului în baza de date a UE.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-postmarket',
title: {
de: 'Plan zur Beobachtung nach dem Inverkehrbringen aufstellen',
en: 'Establish a post-market monitoring plan',
fr: 'Établir un plan de surveillance après commercialisation',
it: 'Predisporre un piano di monitoraggio successivo allimmissione sul mercato',
es: 'Establecer un plan de vigilancia poscomercialización',
pl: 'Opracować plan monitorowania po wprowadzeniu do obrotu',
cs: 'Vypracovat plán monitorování po uvedení na trh',
sk: 'Vypracovať plán monitorovania po uvedení na trh',
ro: 'Elaborarea unui plan de monitorizare ulterioară introducerii pe piață',
},
articles: 'Art. 72',
description: {
de: 'Systematische Sammlung und Auswertung von Betriebsdaten über die gesamte Lebensdauer, um fortlaufende Konformität sicherzustellen; Teil der technischen Dokumentation.',
en: 'Systematically collect and analyse operational data over the entire lifetime to ensure continued conformity; part of the technical documentation.',
fr: 'Collecter et analyser systématiquement les données dexploitation pendant toute la durée de vie afin de garantir la conformité continue ; fait partie de la documentation technique.',
it: 'Raccogliere e analizzare sistematicamente i dati operativi per lintera durata di vita al fine di garantire la conformità costante; parte della documentazione tecnica.',
es: 'Recopilar y analizar sistemáticamente los datos operativos durante toda la vida útil para garantizar la conformidad continua; forma parte de la documentación técnica.',
pl: 'Systematyczne gromadzenie i analiza danych operacyjnych przez cały okres eksploatacji w celu zapewnienia ciągłej zgodności; część dokumentacji technicznej.',
cs: 'Systematické shromažďování a analýza provozních dat po celou dobu životnosti k zajištění trvalého souladu; součást technické dokumentace.',
sk: 'Systematické zhromažďovanie a analýza prevádzkových údajov počas celej životnosti na zabezpečenie trvalého súladu; súčasť technickej dokumentácie.',
ro: 'Colectarea și analizarea sistematică a datelor operaționale pe întreaga durată de viață pentru a asigura conformitatea continuă; parte a documentației tehnice.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
{
id: 'ob-incident',
title: {
de: 'Meldeprozess für schwerwiegende Vorfälle einrichten',
en: 'Set up a serious-incident reporting process',
fr: 'Mettre en place un processus de signalement des incidents graves',
it: 'Istituire un processo di segnalazione degli incidenti gravi',
es: 'Establecer un proceso de notificación de incidentes graves',
pl: 'Ustanowić proces zgłaszania poważnych incydentów',
cs: 'Zavést proces hlášení závažných incidentů',
sk: 'Zaviesť proces nahlasovania závažných incidentov',
ro: 'Instituirea unui proces de raportare a incidentelor grave',
},
articles: 'Art. 73',
description: {
de: 'Schwerwiegende Vorfälle sind der Marktüberwachungsbehörde zu melden (grundsätzlich binnen 15 Tagen; bei Todesfällen/weitverbreiteten Verstößen kürzere Fristen). Interner Melde- und Untersuchungsprozess erforderlich.',
en: 'Serious incidents must be reported to the market surveillance authority (generally within 15 days; shorter deadlines for deaths/widespread infringements). An internal reporting and investigation process is required.',
fr: 'Les incidents graves doivent être signalés à lautorité de surveillance du marché (en principe dans un délai de 15 jours ; délais plus courts en cas de décès ou dinfractions de grande ampleur). Un processus interne de signalement et denquête est requis.',
it: 'Gli incidenti gravi devono essere segnalati allautorità di vigilanza del mercato (di norma entro 15 giorni; termini più brevi in caso di decessi o violazioni diffuse). È necessario un processo interno di segnalazione e indagine.',
es: 'Los incidentes graves deben notificarse a la autoridad de vigilancia del mercado (por lo general en un plazo de 15 días; plazos más cortos en caso de fallecimientos o infracciones generalizadas). Se requiere un proceso interno de notificación e investigación.',
pl: 'Poważne incydenty należy zgłaszać organowi nadzoru rynku (zasadniczo w ciągu 15 dni; krótsze terminy w przypadku zgonów lub powszechnych naruszeń). Wymagany jest wewnętrzny proces zgłaszania i wyjaśniania.',
cs: 'Závažné incidenty je nutno hlásit orgánu dozoru nad trhem (zpravidla do 15 dnů; kratší lhůty v případě úmrtí nebo rozsáhlých porušení). Je vyžadován interní proces hlášení a šetření.',
sk: 'Závažné incidenty sa musia nahlasovať orgánu dohľadu nad trhom (spravidla do 15 dní; kratšie lehoty v prípade úmrtí alebo rozsiahlych porušení). Vyžaduje sa interný proces nahlasovania a vyšetrovania.',
ro: 'Incidentele grave trebuie raportate autorității de supraveghere a pieței (în principiu în termen de 15 zile; termene mai scurte în caz de decese sau încălcări pe scară largă). Este necesar un proces intern de raportare și investigare.',
},
deadline: '2027-12-02',
roles: ['provider'],
riskClasses: ['high'],
},
// ── Hochrisiko: Betreiber ─────────────────────────────────────────
{
id: 'ob-deployer-use',
title: {
de: 'Nutzung gemäß Betriebsanleitung sicherstellen',
en: 'Ensure use according to instructions',
fr: 'Garantir une utilisation conforme à la notice dutilisation',
it: 'Garantire luso conforme alle istruzioni per luso',
es: 'Garantizar el uso conforme a las instrucciones de uso',
pl: 'Zapewnić użytkowanie zgodnie z instrukcją obsługi',
cs: 'Zajistit používání v souladu s návodem k použití',
sk: 'Zabezpečiť používanie v súlade s návodom na použitie',
ro: 'Asigurarea utilizării conform instrucțiunilor de utilizare',
},
articles: 'Art. 26 Abs. 1',
description: {
de: 'Technische und organisatorische Maßnahmen, damit das System entsprechend der Gebrauchsanweisung des Anbieters genutzt wird.',
en: 'Technical and organisational measures to ensure the system is used in accordance with the providers instructions for use.',
fr: 'Mesures techniques et organisationnelles pour que le système soit utilisé conformément à la notice dutilisation du fournisseur.',
it: 'Misure tecniche e organizzative affinché il sistema sia utilizzato conformemente alle istruzioni per luso del fornitore.',
es: 'Medidas técnicas y organizativas para que el sistema se utilice conforme a las instrucciones de uso del proveedor.',
pl: 'Środki techniczne i organizacyjne zapewniające użytkowanie systemu zgodnie z instrukcją obsługi dostawcy.',
cs: 'Technická a organizační opatření, aby byl systém používán v souladu s návodem k použití poskytovatele.',
sk: 'Technické a organizačné opatrenia, aby sa systém používal v súlade s návodom na použitie poskytovateľa.',
ro: 'Măsuri tehnice și organizatorice pentru ca sistemul să fie utilizat în conformitate cu instrucțiunile de utilizare ale furnizorului.',
},
deadline: '2027-12-02',
roles: ['deployer'],
riskClasses: ['high'],
},
{
id: 'ob-deployer-oversight',
title: {
de: 'Kompetente menschliche Aufsicht zuweisen',
en: 'Assign competent human oversight',
fr: 'Confier le contrôle humain à des personnes compétentes',
it: 'Affidare la sorveglianza umana a persone competenti',
es: 'Asignar una supervisión humana competente',
pl: 'Powierzyć nadzór ze strony człowieka kompetentnym osobom',
cs: 'Svěřit lidský dohled kompetentním osobám',
sk: 'Zveriť ľudský dohľad kompetentným osobám',
ro: 'Atribuirea supravegherii umane unor persoane competente',
},
articles: 'Art. 26 Abs. 2',
description: {
de: 'Aufsicht durch Personen mit erforderlicher Kompetenz, Ausbildung und Befugnis.',
en: 'Oversight by persons with the necessary competence, training and authority.',
fr: 'Contrôle exercé par des personnes disposant des compétences, de la formation et de lautorité nécessaires.',
it: 'Sorveglianza da parte di persone dotate della competenza, della formazione e dellautorità necessarie.',
es: 'Supervisión por personas con la competencia, la formación y la autoridad necesarias.',
pl: 'Nadzór sprawowany przez osoby posiadające niezbędne kompetencje, przeszkolenie i uprawnienia.',
cs: 'Dohled vykonávaný osobami s nezbytnou kompetencí, odbornou přípravou a pravomocí.',
sk: 'Dohľad vykonávaný osobami s potrebnou kompetenciou, odbornou prípravou a právomocou.',
ro: 'Supraveghere exercitată de persoane care dispun de competența, formarea și autoritatea necesare.',
},
deadline: '2027-12-02',
roles: ['deployer'],
riskClasses: ['high'],
},
{
id: 'ob-deployer-input',
title: {
de: 'Relevanz und Repräsentativität der Eingabedaten sicherstellen',
en: 'Ensure relevance and representativeness of input data',
fr: 'Garantir la pertinence et la représentativité des données dentrée',
it: 'Garantire pertinenza e rappresentatività dei dati di input',
es: 'Garantizar la pertinencia y representatividad de los datos de entrada',
pl: 'Zapewnić adekwatność i reprezentatywność danych wejściowych',
cs: 'Zajistit relevanci a reprezentativnost vstupních dat',
sk: 'Zabezpečiť relevantnosť a reprezentatívnosť vstupných údajov',
ro: 'Asigurarea relevanței și reprezentativității datelor de intrare',
},
articles: 'Art. 26 Abs. 4',
description: {
de: 'Soweit der Betreiber die Eingabedaten kontrolliert, müssen diese für die Zweckbestimmung relevant und hinreichend repräsentativ sein.',
en: 'Insofar as the deployer controls the input data, it must be relevant and sufficiently representative for the intended purpose.',
fr: 'Dans la mesure où le déployeur contrôle les données dentrée, celles-ci doivent être pertinentes et suffisamment représentatives au regard de la destination du système.',
it: 'Nella misura in cui il deployer controlla i dati di input, questi devono essere pertinenti e sufficientemente rappresentativi rispetto alla finalità prevista.',
es: 'En la medida en que el responsable del despliegue controle los datos de entrada, estos deben ser pertinentes y suficientemente representativos para la finalidad prevista.',
pl: 'W zakresie, w jakim podmiot stosujący sprawuje kontrolę nad danymi wejściowymi, muszą one być adekwatne i wystarczająco reprezentatywne z punktu widzenia przeznaczenia systemu.',
cs: 'Pokud zavádějící subjekt kontroluje vstupní data, musí být tato data relevantní a dostatečně reprezentativní s ohledem na zamýšlený účel.',
sk: 'Pokiaľ nasadzujúci subjekt kontroluje vstupné údaje, musia byť tieto údaje relevantné a dostatočne reprezentatívne vzhľadom na zamýšľaný účel.',
ro: 'În măsura în care implementatorul controlează datele de intrare, acestea trebuie să fie relevante și suficient de reprezentative în raport cu scopul preconizat.',
},
deadline: '2027-12-02',
roles: ['deployer'],
riskClasses: ['high'],
},
{
id: 'ob-deployer-monitoring',
title: {
de: 'Betrieb überwachen, Vorfälle melden, Logs aufbewahren',
en: 'Monitor operation, report incidents, retain logs',
fr: 'Surveiller le fonctionnement, signaler les incidents, conserver les journaux',
it: 'Monitorare il funzionamento, segnalare gli incidenti, conservare i log',
es: 'Supervisar el funcionamiento, notificar incidentes, conservar los registros',
pl: 'Monitorować działanie, zgłaszać incydenty, przechowywać rejestry zdarzeń',
cs: 'Monitorovat provoz, hlásit incidenty, uchovávat protokoly',
sk: 'Monitorovať prevádzku, nahlasovať incidenty, uchovávať logy',
ro: 'Monitorizarea funcționării, raportarea incidentelor, păstrarea jurnalelor',
},
articles: 'Art. 26 Abs. 56',
description: {
de: 'Betrieb anhand der Anleitung überwachen; bei Risiken Anbieter/Behörden informieren; automatisch erzeugte Logs mind. 6 Monate aufbewahren.',
en: 'Monitor operation based on the instructions; inform provider/authorities of risks; retain automatically generated logs for at least 6 months.',
fr: 'Surveiller le fonctionnement sur la base de la notice ; informer le fournisseur/les autorités en cas de risques ; conserver les journaux générés automatiquement pendant au moins 6 mois.',
it: 'Monitorare il funzionamento sulla base delle istruzioni; informare fornitore/autorità in caso di rischi; conservare i log generati automaticamente per almeno 6 mesi.',
es: 'Supervisar el funcionamiento con arreglo a las instrucciones; informar al proveedor/las autoridades en caso de riesgos; conservar los registros generados automáticamente durante al menos 6 meses.',
pl: 'Monitorować działanie systemu zgodnie z instrukcją; w razie ryzyka informować dostawcę/organy; przechowywać automatycznie generowane rejestry zdarzeń przez co najmniej 6 miesięcy.',
cs: 'Monitorovat provoz na základě návodu; v případě rizik informovat poskytovatele/orgány; automaticky generované protokoly uchovávat nejméně 6 měsíců.',
sk: 'Monitorovať prevádzku na základe návodu; v prípade rizík informovať poskytovateľa/orgány; automaticky generované logy uchovávať najmenej 6 mesiacov.',
ro: 'Monitorizarea funcționării pe baza instrucțiunilor; informarea furnizorului/autorităților în caz de riscuri; păstrarea jurnalelor generate automat timp de cel puțin 6 luni.',
},
deadline: '2027-12-02',
roles: ['deployer'],
riskClasses: ['high'],
},
{
id: 'ob-deployer-workers',
title: {
de: 'Beschäftigte vor Einsatz am Arbeitsplatz informieren',
en: 'Inform employees before workplace use',
fr: 'Informer les travailleurs avant lutilisation sur le lieu de travail',
it: 'Informare i lavoratori prima delluso sul luogo di lavoro',
es: 'Informar a los trabajadores antes del uso en el lugar de trabajo',
pl: 'Poinformować pracowników przed wykorzystaniem w miejscu pracy',
cs: 'Informovat zaměstnance před použitím na pracovišti',
sk: 'Informovať zamestnancov pred použitím na pracovisku',
ro: 'Informarea lucrătorilor înainte de utilizarea la locul de muncă',
},
articles: 'Art. 26 Abs. 7',
description: {
de: 'Vor Inbetriebnahme eines Hochrisiko-Systems am Arbeitsplatz sind Arbeitnehmervertreter und betroffene Beschäftigte zu informieren.',
en: 'Before putting a high-risk system into service at the workplace, workers representatives and affected employees must be informed.',
fr: 'Avant la mise en service dun système à haut risque sur le lieu de travail, les représentants des travailleurs et les travailleurs concernés doivent être informés.',
it: 'Prima della messa in servizio di un sistema ad alto rischio sul luogo di lavoro, i rappresentanti dei lavoratori e i lavoratori interessati devono essere informati.',
es: 'Antes de poner en servicio un sistema de alto riesgo en el lugar de trabajo, deben ser informados los representantes de los trabajadores y los trabajadores afectados.',
pl: 'Przed oddaniem do użytku systemu wysokiego ryzyka w miejscu pracy należy poinformować przedstawicieli pracowników i pracowników, których to dotyczy.',
cs: 'Před uvedením vysoce rizikového systému do provozu na pracovišti musí být informováni zástupci zaměstnanců a dotčení zaměstnanci.',
sk: 'Pred uvedením vysokorizikového systému do prevádzky na pracovisku musia byť informovaní zástupcovia zamestnancov a dotknutí zamestnanci.',
ro: 'Înainte de punerea în funcțiune a unui sistem cu grad ridicat de risc la locul de muncă, trebuie informați reprezentanții lucrătorilor și lucrătorii afectați.',
},
deadline: '2027-12-02',
roles: ['deployer'],
riskClasses: ['high'],
},
{
id: 'ob-registration-deployer',
title: {
de: 'Registrierung in der EU-Datenbank prüfen (öffentliche Stellen)',
en: 'Check EU database registration (public bodies)',
fr: 'Vérifier lenregistrement dans la base de données de lUE (organismes publics)',
it: 'Verificare la registrazione nella banca dati dellUE (organismi pubblici)',
es: 'Comprobar el registro en la base de datos de la UE (organismos públicos)',
pl: 'Sprawdzić rejestrację w bazie danych UE (podmioty publiczne)',
cs: 'Ověřit registraci v databázi EU (veřejné subjekty)',
sk: 'Overiť registráciu v databáze EÚ (verejné subjekty)',
ro: 'Verificarea înregistrării în baza de date a UE (organisme publice)',
},
articles: 'Art. 49 Abs. 3',
description: {
de: 'Betreiber, die Behörden oder öffentliche Einrichtungen sind (oder in deren Auftrag handeln), müssen sich vor Nutzung eines Annex-III-Systems in der EU-Datenbank registrieren.',
en: 'Deployers that are public authorities or bodies (or act on their behalf) must register in the EU database before using an Annex III system.',
fr: 'Les déployeurs qui sont des autorités ou des organismes publics (ou qui agissent pour leur compte) doivent senregistrer dans la base de données de lUE avant dutiliser un système relevant de lannexe III.',
it: 'I deployer che sono autorità o organismi pubblici (o agiscono per loro conto) devono registrarsi nella banca dati dellUE prima di utilizzare un sistema di cui allallegato III.',
es: 'Los responsables del despliegue que sean autoridades u organismos públicos (o actúen en su nombre) deben registrarse en la base de datos de la UE antes de utilizar un sistema del anexo III.',
pl: 'Podmioty stosujące będące organami publicznymi lub instytucjami publicznymi (lub działające w ich imieniu) muszą przed użyciem systemu z załącznika III zarejestrować się w bazie danych UE.',
cs: 'Zavádějící subjekty, které jsou veřejnými orgány či subjekty (nebo jednají jejich jménem), se musí před použitím systému podle přílohy III zaregistrovat v databázi EU.',
sk: 'Nasadzujúce subjekty, ktoré sú orgánmi verejnej moci alebo verejnými subjektmi (alebo konajú v ich mene), sa musia pred použitím systému podľa prílohy III zaregistrovať v databáze EÚ.',
ro: 'Implementatorii care sunt autorități sau organisme publice (sau acționează în numele acestora) trebuie să se înregistreze în baza de date a UE înainte de a utiliza un sistem menționat în anexa III.',
},
deadline: '2027-12-02',
roles: ['deployer'],
riskClasses: ['high'],
},
{
id: 'ob-dsgvo-dpia',
title: {
de: 'Datenschutz-Folgenabschätzung (DSFA) durchführen',
en: 'Carry out a data protection impact assessment (DPIA)',
fr: 'Réaliser une analyse dimpact relative à la protection des données (AIPD)',
it: 'Effettuare una valutazione dimpatto sulla protezione dei dati (DPIA)',
es: 'Realizar una evaluación de impacto relativa a la protección de datos (EIPD)',
pl: 'Przeprowadzić ocenę skutków dla ochrony danych (DPIA)',
cs: 'Provést posouzení vlivu na ochranu osobních údajů (DPIA)',
sk: 'Vykonať posúdenie vplyvu na ochranu údajov (DPIA)',
ro: 'Efectuarea unei evaluări a impactului asupra protecției datelor (DPIA)',
},
articles: 'DSGVO Art. 35 i. V. m. AI Act Art. 26 Abs. 9',
description: {
de: 'Verarbeitet das Hochrisiko-System personenbezogene Daten, ist regelmäßig eine DSFA nach DSGVO erforderlich; die Anbieter-Informationen nach Art. 13 AI Act sind dafür zu nutzen.',
en: 'If the high-risk system processes personal data, a DPIA under the GDPR is regularly required; use the provider information under Art. 13 AI Act for this purpose.',
fr: 'Si le système à haut risque traite des données à caractère personnel, une AIPD au titre du RGPD est généralement requise ; utiliser à cette fin les informations du fournisseur visées à lart. 13 du règlement sur lIA.',
it: 'Se il sistema ad alto rischio tratta dati personali, di norma è necessaria una DPIA ai sensi del GDPR; a tal fine utilizzare le informazioni del fornitore di cui allart. 13 del regolamento sullIA.',
es: 'Si el sistema de alto riesgo trata datos personales, por lo general se requiere una EIPD conforme al RGPD; utilizar para ello la información del proveedor prevista en el art. 13 del Reglamento de IA.',
pl: 'Jeżeli system wysokiego ryzyka przetwarza dane osobowe, co do zasady wymagana jest ocena skutków dla ochrony danych zgodnie z RODO; należy w tym celu wykorzystać informacje dostawcy przewidziane w art. 13 aktu w sprawie AI.',
cs: 'Pokud vysoce rizikový systém zpracovává osobní údaje, je zpravidla vyžadováno posouzení vlivu na ochranu osobních údajů podle GDPR; k tomu je třeba využít informace poskytovatele podle čl. 13 aktu o AI.',
sk: 'Ak vysokorizikový systém spracúva osobné údaje, spravidla sa vyžaduje posúdenie vplyvu na ochranu údajov podľa GDPR; na tento účel treba využiť informácie poskytovateľa podľa čl. 13 aktu o AI.',
ro: 'Dacă sistemul cu grad ridicat de risc prelucrează date cu caracter personal, este de regulă necesară o evaluare a impactului asupra protecției datelor conform RGPD; se utilizează în acest scop informațiile furnizorului prevăzute la art. 13 din Regulamentul privind IA.',
},
deadline: '2027-12-02',
roles: ['deployer'],
riskClasses: ['high'],
},
{
id: 'ob-fria',
title: {
de: 'Grundrechte-Folgenabschätzung (FRIA) prüfen',
en: 'Assess fundamental rights impact (FRIA)',
fr: 'Vérifier lanalyse dimpact sur les droits fondamentaux (FRIA)',
it: 'Verificare la valutazione dimpatto sui diritti fondamentali (FRIA)',
es: 'Comprobar la evaluación de impacto sobre los derechos fundamentales (FRIA)',
pl: 'Zweryfikować ocenę skutków dla praw podstawowych (FRIA)',
cs: 'Prověřit posouzení dopadů na základní práva (FRIA)',
sk: 'Preveriť posúdenie vplyvu na základné práva (FRIA)',
ro: 'Verificarea evaluării impactului asupra drepturilor fundamentale (FRIA)',
},
articles: 'Art. 27',
description: {
de: 'Pflicht für öffentliche Stellen und private Anbieter öffentlicher Dienste sowie bestimmte Annex-III-Fälle (z. B. Kreditwürdigkeit, Versicherung): Folgen für Grundrechte vor Einsatz bewerten.',
en: 'Required for public bodies and private providers of public services as well as certain Annex III cases (e.g. creditworthiness, insurance): assess fundamental rights impact before use.',
fr: 'Obligation pour les organismes publics et les prestataires privés de services publics ainsi que pour certains cas de lannexe III (p. ex. solvabilité, assurance) : évaluer les incidences sur les droits fondamentaux avant lutilisation.',
it: 'Obbligo per gli organismi pubblici e i fornitori privati di servizi pubblici nonché per determinati casi dellallegato III (ad es. affidabilità creditizia, assicurazioni): valutare limpatto sui diritti fondamentali prima delluso.',
es: 'Obligación para los organismos públicos y los proveedores privados de servicios públicos, así como para determinados casos del anexo III (p. ej., solvencia, seguros): evaluar el impacto sobre los derechos fundamentales antes del uso.',
pl: 'Obowiązek dla podmiotów publicznych i prywatnych dostawców usług publicznych oraz w określonych przypadkach z załącznika III (np. zdolność kredytowa, ubezpieczenia): przed użyciem ocenić skutki dla praw podstawowych.',
cs: 'Povinnost pro veřejné subjekty a soukromé poskytovatele veřejných služeb, jakož i pro určité případy podle přílohy III (např. úvěruschopnost, pojištění): před použitím posoudit dopady na základní práva.',
sk: 'Povinnosť pre verejné subjekty a súkromných poskytovateľov verejných služieb, ako aj pre určité prípady podľa prílohy III (napr. úverová bonita, poistenie): pred použitím posúdiť vplyv na základné práva.',
ro: 'Obligație pentru organismele publice și furnizorii privați de servicii publice, precum și pentru anumite cazuri din anexa III (de ex. bonitate, asigurări): evaluarea impactului asupra drepturilor fundamentale înainte de utilizare.',
},
deadline: '2027-12-02',
roles: ['deployer'],
riskClasses: ['high'],
},
// ── Importeur / Händler ───────────────────────────────────────────
{
id: 'ob-importer-verify',
title: {
de: 'Konformität vor Inverkehrbringen prüfen',
en: 'Verify conformity before placing on the market',
fr: 'Vérifier la conformité avant la mise sur le marché',
it: 'Verificare la conformità prima dellimmissione sul mercato',
es: 'Verificar la conformidad antes de la introducción en el mercado',
pl: 'Zweryfikować zgodność przed wprowadzeniem do obrotu',
cs: 'Ověřit shodu před uvedením na trh',
sk: 'Overiť zhodu pred uvedením na trh',
ro: 'Verificarea conformității înainte de introducerea pe piață',
},
articles: 'Art. 23',
description: {
de: 'Importeure müssen prüfen: Konformitätsbewertung durchgeführt, technische Dokumentation vorhanden, CE-Kennzeichnung und Ansprechpartner benannt.',
en: 'Importers must verify: conformity assessment performed, technical documentation available, CE marking affixed and contact person designated.',
fr: 'Les importateurs doivent vérifier : évaluation de la conformité effectuée, documentation technique disponible, marquage CE apposé et point de contact désigné.',
it: 'Gli importatori devono verificare: valutazione della conformità effettuata, documentazione tecnica disponibile, marcatura CE apposta e referente designato.',
es: 'Los importadores deben verificar: evaluación de la conformidad realizada, documentación técnica disponible, marcado CE colocado y persona de contacto designada.',
pl: 'Importerzy muszą zweryfikować: przeprowadzenie oceny zgodności, dostępność dokumentacji technicznej, umieszczenie oznakowania CE oraz wyznaczenie osoby kontaktowej.',
cs: 'Dovozci musí ověřit: provedení posouzení shody, dostupnost technické dokumentace, umístění označení CE a určení kontaktní osoby.',
sk: 'Dovozcovia musia overiť: vykonanie posudzovania zhody, dostupnosť technickej dokumentácie, umiestnenie označenia CE a určenie kontaktnej osoby.',
ro: 'Importatorii trebuie să verifice: efectuarea evaluării conformității, disponibilitatea documentației tehnice, aplicarea marcajului CE și desemnarea unei persoane de contact.',
},
deadline: '2027-12-02',
roles: ['importer'],
riskClasses: ['high'],
},
{
id: 'ob-distributor-verify',
title: {
de: 'Sorgfaltspflichten der Vertriebskette erfüllen',
en: 'Fulfil distribution chain due diligence',
fr: 'Respecter les obligations de diligence de la chaîne de distribution',
it: 'Adempiere agli obblighi di diligenza della catena di distribuzione',
es: 'Cumplir las obligaciones de diligencia de la cadena de distribución',
pl: 'Wypełnić obowiązki staranności w łańcuchu dystrybucji',
cs: 'Splnit povinnosti náležité péče v distribučním řetězci',
sk: 'Splniť povinnosti náležitej starostlivosti v distribučnom reťazci',
ro: 'Îndeplinirea obligațiilor de diligență în lanțul de distribuție',
},
articles: 'Art. 24',
description: {
de: 'Händler prüfen CE-Kennzeichnung, Konformitätserklärung und Gebrauchsanweisung; bei Zweifeln keine Bereitstellung.',
en: 'Distributors check CE marking, declaration of conformity and instructions for use; do not make available in case of doubt.',
fr: 'Les distributeurs vérifient le marquage CE, la déclaration UE de conformité et la notice dutilisation ; en cas de doute, pas de mise à disposition.',
it: 'I distributori verificano marcatura CE, dichiarazione di conformità UE e istruzioni per luso; in caso di dubbi, nessuna messa a disposizione.',
es: 'Los distribuidores comprueban el marcado CE, la declaración UE de conformidad y las instrucciones de uso; en caso de duda, no comercializar.',
pl: 'Dystrybutorzy sprawdzają oznakowanie CE, deklarację zgodności UE i instrukcję obsługi; w razie wątpliwości nie udostępniają systemu.',
cs: 'Distributoři kontrolují označení CE, EU prohlášení o shodě a návod k použití; v případě pochybností systém nedodávají na trh.',
sk: 'Distribútori kontrolujú označenie CE, EÚ vyhlásenie o zhode a návod na použitie; v prípade pochybností systém nesprístupnia.',
ro: 'Distribuitorii verifică marcajul CE, declarația de conformitate UE și instrucțiunile de utilizare; în caz de îndoieli, sistemul nu este pus la dispoziție.',
},
deadline: '2027-12-02',
roles: ['distributor'],
riskClasses: ['high'],
},
// ── Transparenzpflichten (limited) ────────────────────────────────
{
id: 'ob-transparency-art50',
title: {
de: 'Transparenzpflichten nach Art. 50 umsetzen',
en: 'Implement transparency obligations under Art. 50',
fr: 'Mettre en œuvre les obligations de transparence de lart. 50',
it: 'Attuare gli obblighi di trasparenza di cui allart. 50',
es: 'Aplicar las obligaciones de transparencia del art. 50',
pl: 'Wdrożyć obowiązki w zakresie przejrzystości z art. 50',
cs: 'Provést povinnosti transparentnosti podle čl. 50',
sk: 'Vykonať povinnosti transparentnosti podľa čl. 50',
ro: 'Punerea în aplicare a obligațiilor de transparență prevăzute la art. 50',
},
articles: 'Art. 50',
description: {
de: 'Je nach Auslöser: KI-Interaktion offenlegen (Chatbots), synthetische Inhalte maschinenlesbar kennzeichnen, Deepfakes sichtbar kennzeichnen, über Emotionserkennung informieren.',
en: 'Depending on the trigger: disclose AI interaction (chatbots), machine-readably mark synthetic content, visibly label deepfakes, inform about emotion recognition.',
fr: 'Selon le cas : révéler linteraction avec une IA (chatbots), marquer les contenus synthétiques dans un format lisible par machine, étiqueter visiblement les hypertrucages (deepfakes), informer sur la reconnaissance des émotions.',
it: 'A seconda del caso: rendere nota linterazione con lIA (chatbot), contrassegnare i contenuti sintetici in formato leggibile meccanicamente, etichettare in modo visibile i deepfake, informare sul riconoscimento delle emozioni.',
es: 'Según el supuesto: revelar la interacción con IA (chatbots), marcar los contenidos sintéticos en formato legible por máquina, etiquetar visiblemente las ultrafalsificaciones (deepfakes), informar sobre el reconocimiento de emociones.',
pl: 'W zależności od przypadku: ujawnić interakcję z AI (chatboty), oznaczać treści syntetyczne w formacie nadającym się do odczytu maszynowego, w widoczny sposób oznaczać deepfakei, informować o rozpoznawaniu emocji.',
cs: 'Podle konkrétního případu: zveřejnit interakci s AI (chatboty), synteticky vytvořený obsah označit ve strojově čitelném formátu, deepfakes viditelně označit, informovat o rozpoznávání emocí.',
sk: 'Podľa konkrétneho prípadu: zverejniť interakciu s AI (chatboty), synteticky vytvorený obsah označiť v strojovo čitateľnom formáte, deepfakes viditeľne označiť, informovať o rozpoznávaní emócií.',
ro: 'În funcție de caz: divulgarea interacțiunii cu IA (chatboturi), marcarea conținutului sintetic în format prelucrabil automat, etichetarea vizibilă a deepfake-urilor, informarea cu privire la recunoașterea emoțiilor.',
},
deadline: '2026-08-02',
roles: ['provider', 'deployer'],
riskClasses: ['high', 'limited'],
},
// ── GPAI ──────────────────────────────────────────────────────────
{
id: 'ob-gpai',
title: {
de: 'GPAI-Modellpflichten erfüllen',
en: 'Fulfil GPAI model obligations',
fr: 'Remplir les obligations relatives aux modèles GPAI',
it: 'Adempiere agli obblighi relativi ai modelli GPAI',
es: 'Cumplir las obligaciones de los modelos GPAI',
pl: 'Wypełnić obowiązki dotyczące modeli AI ogólnego przeznaczenia (GPAI)',
cs: 'Splnit povinnosti týkající se obecných modelů AI (GPAI)',
sk: 'Splniť povinnosti týkajúce sa modelov AI na všeobecné účely (GPAI)',
ro: 'Îndeplinirea obligațiilor privind modelele de IA de uz general (GPAI)',
},
articles: 'Art. 5355',
description: {
de: 'Für Anbieter von GPAI-Modellen: technische Modell-Dokumentation, Informationen für nachgelagerte Anbieter, Urheberrechts-Policy, Zusammenfassung der Trainingsdaten. Bei systemischem Risiko zusätzlich Evaluierungen und Incident-Meldungen.',
en: 'For providers of GPAI models: technical model documentation, information for downstream providers, copyright policy, training data summary. For systemic risk additionally evaluations and incident reports.',
fr: 'Pour les fournisseurs de modèles GPAI : documentation technique du modèle, informations pour les fournisseurs en aval, politique en matière de droit dauteur, résumé des données dentraînement. En cas de risque systémique, en outre des évaluations et des signalements dincidents.',
it: 'Per i fornitori di modelli GPAI: documentazione tecnica del modello, informazioni per i fornitori a valle, politica sul diritto dautore, sintesi dei dati di addestramento. In caso di rischio sistemico, inoltre valutazioni e segnalazioni di incidenti.',
es: 'Para los proveedores de modelos GPAI: documentación técnica del modelo, información para los proveedores intermedios, política de derechos de autor, resumen de los datos de entrenamiento. En caso de riesgo sistémico, además evaluaciones y notificaciones de incidentes.',
pl: 'Dla dostawców modeli GPAI: techniczna dokumentacja modelu, informacje dla dostawców niższego szczebla, polityka dotycząca prawa autorskiego, streszczenie danych treningowych. W przypadku ryzyka systemowego dodatkowo ewaluacje i zgłaszanie incydentów.',
cs: 'Pro poskytovatele modelů GPAI: technická dokumentace modelu, informace pro navazující poskytovatele, politika v oblasti autorského práva, shrnutí trénovacích dat. V případě systémového rizika navíc evaluace a hlášení incidentů.',
sk: 'Pre poskytovateľov modelov GPAI: technická dokumentácia modelu, informácie pre nadväzujúcich poskytovateľov, politika v oblasti autorského práva, zhrnutie trénovacích údajov. V prípade systémového rizika navyše hodnotenia a nahlasovanie incidentov.',
ro: 'Pentru furnizorii de modele GPAI: documentația tehnică a modelului, informații pentru furnizorii din aval, politică privind drepturile de autor, rezumatul datelor de antrenament. În cazul riscului sistemic, în plus evaluări și raportări de incidente.',
},
deadline: '2025-08-02',
roles: ['provider'],
riskClasses: ['high', 'limited', 'minimal'],
},
];

View File

@ -0,0 +1,37 @@
import type { RiskClass, Role } from '../engine/types';
import type { LText } from '../i18n/types';
/** Checklisten-Item in Quellform (lokalisiert). */
export interface ContentItemSrc {
readonly id: string;
readonly label: LText;
readonly legalRef: string;
readonly hint?: LText;
}
/** Pflicht in Quellform (lokalisiert). */
export interface ObligationSrc {
readonly id: string;
readonly title: LText;
readonly articles: string;
readonly description: LText;
readonly deadline: string;
readonly roles: readonly Role[];
readonly riskClasses: readonly RiskClass[];
}
/** Geltungsfrist in Quellform (lokalisiert). */
export interface DeadlineSrc {
readonly id: string;
readonly date: string;
readonly label: LText;
readonly description: LText;
}
/** Nationales Modul in Quellform (lokalisiert). */
export interface NationalPackSrc {
readonly code: string;
readonly country: LText;
readonly authority: LText;
readonly items: readonly ObligationSrc[];
}

View File

@ -0,0 +1,77 @@
import { deriveObligations } from './obligations';
import type { AISystem, ContentPack, Obligation, ObligationStatus } from './types';
/** Ein Eintrag der systemübergreifenden Aufgabenliste. */
export interface ChecklistEntry {
readonly systemId: string;
readonly systemName: string;
readonly obligation: Obligation;
readonly status: ObligationStatus;
/** Erledigt oder als nicht anwendbar markiert. */
readonly resolved: boolean;
/** Frist liegt am oder vor dem Stichtag. */
readonly due: boolean;
}
/** Gruppierte Aufgabenliste mit Fortschritt. */
export interface Checklist {
/** Fällig (Frist erreicht/überschritten) und noch nicht erledigt. */
readonly dueNow: readonly ChecklistEntry[];
/** Kommt auf das Unternehmen zu (Frist in der Zukunft), noch offen. */
readonly upcoming: readonly ChecklistEntry[];
/** Erledigt oder nicht anwendbar. */
readonly resolved: readonly ChecklistEntry[];
readonly total: number;
readonly resolvedCount: number;
}
/**
* Baut die systemübergreifende, abhakbare Aufgabenliste.
*
* Jede Pflicht jedes Systems wird zu einem Eintrag; Sortierung innerhalb
* der Gruppen nach Frist aufsteigend, dann Systemname.
*
* @param systems - Alle registrierten KI-Systeme
* @param pack - Regulatorischer Content-Pack (Sprache des Aufrufers)
* @param countries - Aktivierte Länder-Module
* @param today - Stichtag im ISO-Format (YYYY-MM-DD)
*/
export function buildChecklist(
systems: readonly AISystem[],
pack: ContentPack,
countries: readonly string[],
today: string,
): Checklist {
const entries: ChecklistEntry[] = systems.flatMap((system) =>
deriveObligations(system.classification, system.answers, pack, countries).map(
(obligation) => {
const status = system.obligationStatus[obligation.id] ?? 'open';
const resolved = status === 'done' || status === 'not-applicable';
return {
systemId: system.id,
systemName: system.name,
obligation,
status,
resolved,
due: obligation.deadline <= today,
};
},
),
);
const byDeadline = (a: ChecklistEntry, b: ChecklistEntry): number =>
a.obligation.deadline.localeCompare(b.obligation.deadline) ||
a.systemName.localeCompare(b.systemName);
const dueNow = entries.filter((e) => !e.resolved && e.due).sort(byDeadline);
const upcoming = entries.filter((e) => !e.resolved && !e.due).sort(byDeadline);
const resolved = entries.filter((e) => e.resolved).sort(byDeadline);
return {
dueNow,
upcoming,
resolved,
total: entries.length,
resolvedCount: resolved.length,
};
}

View File

@ -0,0 +1,111 @@
import { describe, expect, it } from 'vitest';
import { CONTENT_PACK } from '../content/pack';
import { classify } from './classify';
import type { AssessmentAnswers } from './types';
const base: AssessmentAnswers = {
isAISystem: true,
role: 'deployer',
isGPAIModel: false,
prohibitedPractices: [],
annexIIICategories: [],
art63Exception: false,
involvesProfiling: false,
isAnnexISafetyComponent: false,
transparencyTriggers: [],
};
describe('classify', () => {
it('stuft Nicht-KI-Systeme als out-of-scope ein', () => {
const result = classify({ ...base, isAISystem: false }, CONTENT_PACK);
expect(result.riskClass).toBe('out-of-scope');
expect(result.transparencyDuties).toBe(false);
});
it('stuft verbotene Praktiken als prohibited ein — vor allen anderen Prüfungen', () => {
const result = classify(
{
...base,
prohibitedPractices: ['proh-social-scoring'],
annexIIICategories: ['a3-employment'],
transparencyTriggers: ['tr-chatbot'],
},
CONTENT_PACK,
);
expect(result.riskClass).toBe('prohibited');
expect(result.reasons[0]).toContain('Art. 5');
});
it('stuft Annex-I-Sicherheitsbauteile als high ein', () => {
const result = classify({ ...base, isAnnexISafetyComponent: true }, CONTENT_PACK);
expect(result.riskClass).toBe('high');
});
it('stuft Annex-III-Bereiche als high ein', () => {
const result = classify({ ...base, annexIIICategories: ['a3-employment'] }, CONTENT_PACK);
expect(result.riskClass).toBe('high');
expect(result.reasons.some((r) => r.includes('Annex III'))).toBe(true);
});
it('lässt die Art.-6(3)-Ausnahme greifen, wenn kein Profiling vorliegt', () => {
const result = classify(
{ ...base, annexIIICategories: ['a3-employment'], art63Exception: true },
CONTENT_PACK,
);
expect(result.riskClass).toBe('minimal');
expect(result.art64DocumentationDuty).toBe(true);
});
it('schließt die Art.-6(3)-Ausnahme bei Profiling aus', () => {
const result = classify(
{
...base,
annexIIICategories: ['a3-employment'],
art63Exception: true,
involvesProfiling: true,
},
CONTENT_PACK,
);
expect(result.riskClass).toBe('high');
});
it('kombiniert Art.-6(3)-Ausnahme mit Transparenzpflichten zu limited', () => {
const result = classify(
{
...base,
annexIIICategories: ['a3-employment'],
art63Exception: true,
transparencyTriggers: ['tr-chatbot'],
},
CONTENT_PACK,
);
expect(result.riskClass).toBe('limited');
expect(result.transparencyDuties).toBe(true);
expect(result.art64DocumentationDuty).toBe(true);
});
it('stuft reine Transparenz-Auslöser als limited ein (Chatbot-Fall)', () => {
const result = classify({ ...base, transparencyTriggers: ['tr-chatbot'] }, CONTENT_PACK);
expect(result.riskClass).toBe('limited');
});
it('behält Transparenzpflichten bei Hochrisiko-Systemen bei', () => {
const result = classify(
{ ...base, annexIIICategories: ['a3-employment'], transparencyTriggers: ['tr-chatbot'] },
CONTENT_PACK,
);
expect(result.riskClass).toBe('high');
expect(result.transparencyDuties).toBe(true);
});
it('stuft Systeme ohne Auffälligkeiten als minimal ein', () => {
const result = classify(base, CONTENT_PACK);
expect(result.riskClass).toBe('minimal');
});
it('setzt das GPAI-Flag unabhängig von der Risikoklasse', () => {
const result = classify({ ...base, isGPAIModel: true }, CONTENT_PACK);
expect(result.riskClass).toBe('minimal');
expect(result.gpaiObligations).toBe(true);
});
});

View File

@ -0,0 +1,286 @@
import type { Locale } from '../i18n/types';
import type { AssessmentAnswers, Classification, ContentPack } from './types';
interface ClassifyStrings {
readonly outOfScope: string;
readonly prohibited: (label: string, ref: string) => string;
readonly annexI: string;
readonly annexIII: (label: string, ref: string) => string;
readonly profilingBar: string;
readonly art63: string;
readonly transparency: (label: string, ref: string) => string;
readonly minimal: string;
}
const STRINGS: Readonly<Partial<Record<Locale, ClassifyStrings>>> = {
de: {
outOfScope:
'Das System erfüllt die KI-Definition nach Art. 3 Nr. 1 nicht — der AI Act ist nicht anwendbar.',
prohibited: (label, ref) => `Verbotene Praktik: ${label} (${ref})`,
annexI:
'Das System ist Sicherheitsbauteil eines in Annex I regulierten Produkts bzw. selbst ein solches Produkt (Art. 6 Abs. 1) — Hochrisiko.',
annexIII: (label, ref) => `Annex-III-Bereich: ${label} (${ref})`,
profilingBar:
'Das System führt Profiling natürlicher Personen durch — die Ausnahme nach Art. 6 Abs. 3 ist damit ausgeschlossen.',
art63:
'Ausnahme nach Art. 6 Abs. 3 in Anspruch genommen (eng begrenzte/vorbereitende Aufgabe ohne wesentliches Risiko). Die Einschätzung ist nach Art. 6 Abs. 4 zu dokumentieren.',
transparency: (label, ref) => `Transparenzpflicht: ${label} (${ref})`,
minimal:
'Keine verbotene Praktik, kein Hochrisiko-Bereich, keine Transparenzpflicht-Auslöser — minimales Risiko. Es gelten die allgemeine KI-Kompetenzpflicht (Art. 4) und freiwillige Verhaltenskodizes.',
},
en: {
outOfScope:
'The system does not meet the AI definition under Art. 3(1) — the AI Act does not apply.',
prohibited: (label, ref) => `Prohibited practice: ${label} (${ref})`,
annexI:
'The system is a safety component of a product regulated under Annex I, or such a product itself (Art. 6(1)) — high-risk.',
annexIII: (label, ref) => `Annex III area: ${label} (${ref})`,
profilingBar:
'The system performs profiling of natural persons — the exception under Art. 6(3) is therefore excluded.',
art63:
'Exception under Art. 6(3) claimed (narrow procedural/preparatory task without significant risk). The assessment must be documented under Art. 6(4).',
transparency: (label, ref) => `Transparency obligation: ${label} (${ref})`,
minimal:
'No prohibited practice, no high-risk area, no transparency triggers — minimal risk. The general AI literacy duty (Art. 4) and voluntary codes of conduct apply.',
},
fr: {
outOfScope:
'Le système ne répond pas à la définition de lIA selon lart. 3, point 1 — le règlement sur lIA ne sapplique pas.',
prohibited: (label, ref) => `Pratique interdite : ${label} (${ref})`,
annexI:
'Le système est un composant de sécurité dun produit réglementé par lannexe I, ou constitue lui-même un tel produit (art. 6, par. 1) — haut risque.',
annexIII: (label, ref) => `Domaine de lannexe III : ${label} (${ref})`,
profilingBar:
'Le système effectue un profilage de personnes physiques — lexception prévue à lart. 6, par. 3 est donc exclue.',
art63:
'Exception prévue à lart. 6, par. 3 invoquée (tâche étroitement délimitée/préparatoire sans risque important). Lévaluation doit être documentée conformément à lart. 6, par. 4.',
transparency: (label, ref) => `Obligation de transparence : ${label} (${ref})`,
minimal:
'Aucune pratique interdite, aucun domaine à haut risque, aucun déclencheur dobligation de transparence — risque minimal. Sappliquent lobligation générale de maîtrise de lIA (art. 4) et les codes de conduite volontaires.',
},
it: {
outOfScope:
'Il sistema non soddisfa la definizione di IA di cui allart. 3, punto 1 — il regolamento sullIA non è applicabile.',
prohibited: (label, ref) => `Pratica vietata: ${label} (${ref})`,
annexI:
'Il sistema è un componente di sicurezza di un prodotto disciplinato dallallegato I, oppure è esso stesso un tale prodotto (art. 6, par. 1) — alto rischio.',
annexIII: (label, ref) => `Ambito dellallegato III: ${label} (${ref})`,
profilingBar:
'Il sistema effettua la profilazione di persone fisiche — leccezione di cui allart. 6, par. 3 è pertanto esclusa.',
art63:
'Eccezione di cui allart. 6, par. 3 invocata (compito ristretto/preparatorio senza rischio significativo). La valutazione deve essere documentata ai sensi dellart. 6, par. 4.',
transparency: (label, ref) => `Obbligo di trasparenza: ${label} (${ref})`,
minimal:
'Nessuna pratica vietata, nessun ambito ad alto rischio, nessun fattore che attivi obblighi di trasparenza — rischio minimo. Si applicano lobbligo generale di alfabetizzazione in materia di IA (art. 4) e i codici di condotta volontari.',
},
es: {
outOfScope:
'El sistema no cumple la definición de IA del art. 3, punto 1 — el Reglamento de IA no es aplicable.',
prohibited: (label, ref) => `Práctica prohibida: ${label} (${ref})`,
annexI:
'El sistema es un componente de seguridad de un producto regulado en el anexo I, o es él mismo tal producto (art. 6, apdo. 1) — alto riesgo.',
annexIII: (label, ref) => `Ámbito del anexo III: ${label} (${ref})`,
profilingBar:
'El sistema realiza elaboración de perfiles de personas físicas — la excepción del art. 6, apdo. 3 queda por tanto excluida.',
art63:
'Se invoca la excepción del art. 6, apdo. 3 (tarea estrictamente delimitada/preparatoria sin riesgo significativo). La evaluación debe documentarse conforme al art. 6, apdo. 4.',
transparency: (label, ref) => `Obligación de transparencia: ${label} (${ref})`,
minimal:
'Ninguna práctica prohibida, ningún ámbito de alto riesgo, ningún desencadenante de obligaciones de transparencia — riesgo mínimo. Se aplican la obligación general de alfabetización en materia de IA (art. 4) y los códigos de conducta voluntarios.',
},
pl: {
outOfScope:
'System nie spełnia definicji AI z art. 3 pkt 1 — akt w sprawie AI nie ma zastosowania.',
prohibited: (label, ref) => `Zakazana praktyka: ${label} (${ref})`,
annexI:
'System jest związanym z bezpieczeństwem elementem produktu regulowanego w załączniku I lub sam jest takim produktem (art. 6 ust. 1) — wysokie ryzyko.',
annexIII: (label, ref) => `Obszar załącznika III: ${label} (${ref})`,
profilingBar:
'System dokonuje profilowania osób fizycznych — wyjątek z art. 6 ust. 3 jest zatem wykluczony.',
art63:
'Powołano się na wyjątek z art. 6 ust. 3 (wąsko ograniczone/przygotowawcze zadanie bez znaczącego ryzyka). Ocenę należy udokumentować zgodnie z art. 6 ust. 4.',
transparency: (label, ref) => `Obowiązek przejrzystości: ${label} (${ref})`,
minimal:
'Brak zakazanej praktyki, brak obszaru wysokiego ryzyka, brak czynników wywołujących obowiązki przejrzystości — minimalne ryzyko. Obowiązują ogólny obowiązek kompetencji w zakresie AI (art. 4) i dobrowolne kodeksy postępowania.',
},
cs: {
outOfScope:
'Systém nesplňuje definici AI podle čl. 3 bodu 1 — akt o AI se nepoužije.',
prohibited: (label, ref) => `Zakázaná praktika: ${label} (${ref})`,
annexI:
'Systém je bezpečnostní komponentou produktu regulovaného v příloze I, nebo je sám takovým produktem (čl. 6 odst. 1) — vysoké riziko.',
annexIII: (label, ref) => `Oblast přílohy III: ${label} (${ref})`,
profilingBar:
'Systém provádí profilování fyzických osob — výjimka podle čl. 6 odst. 3 je tím vyloučena.',
art63:
'Uplatněna výjimka podle čl. 6 odst. 3 (úzce vymezený/přípravný úkol bez významného rizika). Posouzení je nutno zdokumentovat podle čl. 6 odst. 4.',
transparency: (label, ref) => `Povinnost transparentnosti: ${label} (${ref})`,
minimal:
'Žádná zakázaná praktika, žádná oblast vysokého rizika, žádné spouštěče povinností transparentnosti — minimální riziko. Platí obecná povinnost gramotnosti v oblasti AI (čl. 4) a dobrovolné kodexy chování.',
},
sk: {
outOfScope:
'Systém nespĺňa definíciu AI podľa čl. 3 bodu 1 — akt o AI sa neuplatňuje.',
prohibited: (label, ref) => `Zakázaná praktika: ${label} (${ref})`,
annexI:
'Systém je bezpečnostným komponentom produktu regulovaného v prílohe I, alebo je sám takýmto produktom (čl. 6 ods. 1) — vysoké riziko.',
annexIII: (label, ref) => `Oblasť prílohy III: ${label} (${ref})`,
profilingBar:
'Systém vykonáva profilovanie fyzických osôb — výnimka podľa čl. 6 ods. 3 je tým vylúčená.',
art63:
'Uplatnená výnimka podľa čl. 6 ods. 3 (úzko vymedzená/prípravná úloha bez významného rizika). Posúdenie treba zdokumentovať podľa čl. 6 ods. 4.',
transparency: (label, ref) => `Povinnosť transparentnosti: ${label} (${ref})`,
minimal:
'Žiadna zakázaná praktika, žiadna oblasť vysokého rizika, žiadne spúšťače povinností transparentnosti — minimálne riziko. Platia všeobecná povinnosť gramotnosti v oblasti AI (čl. 4) a dobrovoľné kódexy správania.',
},
ro: {
outOfScope:
'Sistemul nu îndeplinește definiția IA de la art. 3 pct. 1 — Regulamentul privind IA nu se aplică.',
prohibited: (label, ref) => `Practică interzisă: ${label} (${ref})`,
annexI:
'Sistemul este o componentă de siguranță a unui produs reglementat în anexa I sau este el însuși un astfel de produs (art. 6 alin. (1)) — risc ridicat.',
annexIII: (label, ref) => `Domeniu din anexa III: ${label} (${ref})`,
profilingBar:
'Sistemul realizează crearea de profiluri ale persoanelor fizice — excepția de la art. 6 alin. (3) este astfel exclusă.',
art63:
'S-a invocat excepția de la art. 6 alin. (3) (sarcină strict delimitată/pregătitoare, fără risc semnificativ). Evaluarea trebuie documentată conform art. 6 alin. (4).',
transparency: (label, ref) => `Obligație de transparență: ${label} (${ref})`,
minimal:
'Nicio practică interzisă, niciun domeniu cu risc ridicat, niciun factor declanșator al obligațiilor de transparență — risc minim. Se aplică obligația generală de alfabetizare în materie de IA (art. 4) și codurile de conduită voluntare.',
},
};
/**
* Klassifiziert ein KI-System nach dem Risikomodell des EU AI Act.
*
* Prüfreihenfolge (entspricht der Systematik der Verordnung):
* 1. Anwendbarkeit (KI-Definition, Art. 3 Nr. 1)
* 2. Verbotene Praktiken (Art. 5) "prohibited"
* 3. Annex I Sicherheitsbauteil "high"
* 4. Annex III Bereiche, ggf. Ausnahme Art. 6 Abs. 3 "high"
* 5. Transparenzpflichten (Art. 50) "limited"
* 6. Sonst "minimal"
*
* @param answers - Antworten des Bewertungs-Wizards
* @param pack - Regulatorischer Content-Pack (für Begründungstexte)
* @param locale - Sprache der Begründungen (Default: Deutsch)
* @returns Unveränderliches Klassifizierungsergebnis mit Begründungen
*/
export function classify(
answers: AssessmentAnswers,
pack: ContentPack,
locale: Locale = 'de',
): Classification {
// Vollständig lokalisiert; Fallback EN für künftige Sprachen.
const s = STRINGS[locale] ?? (STRINGS.en as ClassifyStrings);
const reasons: string[] = [];
const transparencyDuties = answers.transparencyTriggers.length > 0;
if (!answers.isAISystem) {
return {
riskClass: 'out-of-scope',
reasons: [s.outOfScope],
gpaiObligations: false,
transparencyDuties: false,
art64DocumentationDuty: false,
};
}
if (answers.prohibitedPractices.length > 0) {
for (const id of answers.prohibitedPractices) {
const item = pack.prohibitedPractices.find((p) => p.id === id);
if (item) {
reasons.push(s.prohibited(item.label, item.legalRef));
}
}
return {
riskClass: 'prohibited',
reasons,
gpaiObligations: answers.isGPAIModel,
transparencyDuties: false,
art64DocumentationDuty: false,
};
}
if (answers.isAnnexISafetyComponent) {
reasons.push(s.annexI);
return {
riskClass: 'high',
reasons,
gpaiObligations: answers.isGPAIModel,
transparencyDuties,
art64DocumentationDuty: false,
};
}
if (answers.annexIIICategories.length > 0) {
for (const id of answers.annexIIICategories) {
const item = pack.annexIIICategories.find((c) => c.id === id);
if (item) {
reasons.push(s.annexIII(item.label, item.legalRef));
}
}
if (answers.involvesProfiling) {
reasons.push(s.profilingBar);
return {
riskClass: 'high',
reasons,
gpaiObligations: answers.isGPAIModel,
transparencyDuties,
art64DocumentationDuty: false,
};
}
if (answers.art63Exception) {
reasons.push(s.art63);
return {
riskClass: transparencyDuties ? 'limited' : 'minimal',
reasons: transparencyDuties
? [...reasons, ...transparencyReasons(answers, pack, s)]
: reasons,
gpaiObligations: answers.isGPAIModel,
transparencyDuties,
art64DocumentationDuty: true,
};
}
return {
riskClass: 'high',
reasons,
gpaiObligations: answers.isGPAIModel,
transparencyDuties,
art64DocumentationDuty: false,
};
}
if (transparencyDuties) {
return {
riskClass: 'limited',
reasons: transparencyReasons(answers, pack, s),
gpaiObligations: answers.isGPAIModel,
transparencyDuties: true,
art64DocumentationDuty: false,
};
}
return {
riskClass: 'minimal',
reasons: [s.minimal],
gpaiObligations: answers.isGPAIModel,
transparencyDuties: false,
art64DocumentationDuty: false,
};
}
/** Erzeugt Begründungstexte für zutreffende Art.-50-Auslöser. */
function transparencyReasons(
answers: AssessmentAnswers,
pack: ContentPack,
s: ClassifyStrings,
): string[] {
return answers.transparencyTriggers.flatMap((id) => {
const item = pack.transparencyTriggers.find((t) => t.id === id);
return item ? [s.transparency(item.label, item.legalRef)] : [];
});
}

View File

@ -0,0 +1,694 @@
import type { Locale } from '../i18n/types';
import type { ObligationStatus, RiskClass, Role } from './types';
/** Anzeige-Labels und Textbausteine der Dokument-Generatoren je Sprache. */
export interface DocStrings {
readonly risk: Readonly<Record<RiskClass, string>>;
readonly role: Readonly<Record<Role, string>>;
readonly status: Readonly<Record<ObligationStatus, string>>;
readonly disclaimer: string;
readonly meta: {
readonly system: string;
readonly purpose: string;
readonly vendor: string;
readonly owner: string;
readonly role: string;
readonly riskClass: string;
readonly createdAt: string;
readonly contentPack: string;
readonly company: string;
readonly contact: string;
readonly contactPerson: string;
};
readonly report: {
readonly title: string;
readonly result: string;
readonly reasons: string;
readonly gpai: string;
readonly gpaiText: string;
readonly art64: string;
readonly art64Text: string;
};
readonly plan: {
readonly title: string;
readonly none: string;
readonly obligations: string;
readonly details: string;
readonly colObligation: string;
readonly colLegal: string;
readonly colDeadline: string;
readonly colStatus: string;
};
readonly inventory: {
readonly title: string;
readonly asOf: string;
readonly count: string;
readonly colSystem: string;
readonly colPurpose: string;
readonly colRole: string;
readonly colRisk: string;
readonly colOwner: string;
};
readonly todo: string;
}
const DE: DocStrings = {
risk: {
'out-of-scope': 'Nicht anwendbar (keine KI i. S. d. Art. 3 Nr. 1)',
prohibited: 'VERBOTEN (Art. 5)',
high: 'Hochrisiko',
limited: 'Begrenztes Risiko (Transparenzpflichten)',
minimal: 'Minimales Risiko',
},
role: {
provider: 'Anbieter (Provider)',
deployer: 'Betreiber (Deployer)',
importer: 'Einführer (Importer)',
distributor: 'Händler (Distributor)',
},
status: {
open: 'Offen',
'in-progress': 'In Umsetzung',
done: 'Erledigt',
'not-applicable': 'Nicht anwendbar',
},
disclaimer:
'> **Hinweis:** Dieses Dokument wurde mit dem AI-Act-Kompass erstellt und ist eine strukturierte Arbeitshilfe — **keine Rechtsberatung**. Die rechtliche Bewertung im Einzelfall obliegt dem Unternehmen bzw. seiner Rechtsberatung.',
meta: {
system: 'KI-System',
purpose: 'Zweckbestimmung',
vendor: 'Hersteller/Anbieter',
owner: 'Verantwortlich (intern)',
role: 'Rolle des Unternehmens',
riskClass: 'Risikoklasse',
createdAt: 'Erstellt am',
contentPack: 'Content-Pack',
company: 'Unternehmen',
contact: 'Kontakt',
contactPerson: 'Ansprechpartner',
},
report: {
title: 'Risikoklassifizierung nach EU AI Act',
result: 'Ergebnis',
reasons: 'Begründung',
gpai: 'GPAI',
gpaiText: 'Für dieses System sind zusätzlich GPAI-Modellpflichten (Art. 53 ff.) relevant.',
art64: 'Dokumentationspflicht Art. 6 Abs. 4',
art64Text:
'Die Inanspruchnahme der Ausnahme nach Art. 6 Abs. 3 wurde dokumentiert. Diese Einschätzung ist auf Verlangen der Marktüberwachung vorzulegen.',
},
plan: {
title: 'Maßnahmenplan EU AI Act',
none: 'Für dieses System bestehen keine umsetzbaren Pflichten (verboten oder außerhalb des Anwendungsbereichs).',
obligations: 'Pflichten',
details: 'Details',
colObligation: 'Pflicht',
colLegal: 'Rechtsgrundlage',
colDeadline: 'Frist',
colStatus: 'Status',
},
inventory: {
title: 'KI-Inventar (AI Asset Register)',
asOf: 'Stand',
count: 'Registrierte KI-Systeme',
colSystem: 'System',
colPurpose: 'Zweck',
colRole: 'Rolle',
colRisk: 'Risikoklasse',
colOwner: 'Verantwortlich',
},
todo: '_[AUSFÜLLEN]_',
};
const EN: DocStrings = {
risk: {
'out-of-scope': 'Not applicable (not AI within the meaning of Art. 3(1))',
prohibited: 'PROHIBITED (Art. 5)',
high: 'High-risk',
limited: 'Limited risk (transparency obligations)',
minimal: 'Minimal risk',
},
role: {
provider: 'Provider',
deployer: 'Deployer',
importer: 'Importer',
distributor: 'Distributor',
},
status: {
open: 'Open',
'in-progress': 'In progress',
done: 'Done',
'not-applicable': 'Not applicable',
},
disclaimer:
'> **Note:** This document was created with AI-Act-Kompass and is a structured working aid — **not legal advice**. The legal assessment of the individual case remains with the company and its legal counsel.',
meta: {
system: 'AI system',
purpose: 'Intended purpose',
vendor: 'Manufacturer/provider',
owner: 'Responsible (internal)',
role: 'Company role',
riskClass: 'Risk class',
createdAt: 'Created on',
contentPack: 'Content pack',
company: 'Company',
contact: 'Contact',
contactPerson: 'Contact person',
},
report: {
title: 'Risk classification under the EU AI Act',
result: 'Result',
reasons: 'Reasoning',
gpai: 'GPAI',
gpaiText: 'GPAI model obligations (Art. 53 et seq.) are additionally relevant for this system.',
art64: 'Documentation duty Art. 6(4)',
art64Text:
'The reliance on the exception under Art. 6(3) has been documented. This assessment must be provided to market surveillance authorities upon request.',
},
plan: {
title: 'EU AI Act action plan',
none: 'There are no implementable obligations for this system (prohibited or out of scope).',
obligations: 'Obligations',
details: 'Details',
colObligation: 'Obligation',
colLegal: 'Legal basis',
colDeadline: 'Deadline',
colStatus: 'Status',
},
inventory: {
title: 'AI inventory (AI asset register)',
asOf: 'As of',
count: 'Registered AI systems',
colSystem: 'System',
colPurpose: 'Purpose',
colRole: 'Role',
colRisk: 'Risk class',
colOwner: 'Responsible',
},
todo: '_[TO BE COMPLETED]_',
};
const FR: DocStrings = {
risk: {
'out-of-scope': 'Non applicable (pas une IA au sens de lart. 3, point 1)',
prohibited: 'INTERDIT (art. 5)',
high: 'Haut risque',
limited: 'Risque limité (obligations de transparence)',
minimal: 'Risque minimal',
},
role: {
provider: 'Fournisseur',
deployer: 'Déployeur',
importer: 'Importateur',
distributor: 'Distributeur',
},
status: {
open: 'Ouvert',
'in-progress': 'En cours',
done: 'Terminé',
'not-applicable': 'Non applicable',
},
disclaimer:
'> **Remarque :** Ce document a été créé avec AI-Act-Kompass et constitue une aide de travail structurée — il **ne constitue pas un conseil juridique**. Lappréciation juridique du cas despèce incombe à lentreprise et à son conseil juridique.',
meta: {
system: 'Système dIA',
purpose: 'Destination',
vendor: 'Fabricant/fournisseur',
owner: 'Responsable (interne)',
role: 'Rôle de lentreprise',
riskClass: 'Classe de risque',
createdAt: 'Créé le',
contentPack: 'Pack de contenu',
company: 'Entreprise',
contact: 'Contact',
contactPerson: 'Interlocuteur',
},
report: {
title: 'Classification des risques selon le règlement européen sur lIA',
result: 'Résultat',
reasons: 'Motifs',
gpai: 'GPAI',
gpaiText:
'Les obligations relatives aux modèles GPAI (art. 53 et suivants) sont en outre pertinentes pour ce système.',
art64: 'Obligation de documentation art. 6, par. 4',
art64Text:
'Le recours à lexception prévue à lart. 6, par. 3 a été documenté. Cette évaluation doit être présentée aux autorités de surveillance du marché sur demande.',
},
plan: {
title: 'Plan daction — règlement européen sur lIA',
none: 'Aucune obligation applicable nexiste pour ce système (interdit ou hors champ dapplication).',
obligations: 'Obligations',
details: 'Détails',
colObligation: 'Obligation',
colLegal: 'Base juridique',
colDeadline: 'Échéance',
colStatus: 'Statut',
},
inventory: {
title: 'Inventaire des IA (registre des actifs IA)',
asOf: 'État au',
count: 'Systèmes dIA enregistrés',
colSystem: 'Système',
colPurpose: 'Finalité',
colRole: 'Rôle',
colRisk: 'Classe de risque',
colOwner: 'Responsable',
},
todo: '_[À COMPLÉTER]_',
};
const IT: DocStrings = {
risk: {
'out-of-scope': 'Non applicabile (non è IA ai sensi dellart. 3, punto 1)',
prohibited: 'VIETATO (art. 5)',
high: 'Alto rischio',
limited: 'Rischio limitato (obblighi di trasparenza)',
minimal: 'Rischio minimo',
},
role: {
provider: 'Fornitore',
deployer: 'Deployer',
importer: 'Importatore',
distributor: 'Distributore',
},
status: {
open: 'Aperto',
'in-progress': 'In corso',
done: 'Completato',
'not-applicable': 'Non applicabile',
},
disclaimer:
'> **Nota:** Questo documento è stato creato con AI-Act-Kompass ed è uno strumento di lavoro strutturato — **non costituisce consulenza legale**. La valutazione giuridica del singolo caso spetta allazienda e alla sua consulenza legale.',
meta: {
system: 'Sistema di IA',
purpose: 'Finalità prevista',
vendor: 'Produttore/fornitore',
owner: 'Responsabile (interno)',
role: 'Ruolo dellazienda',
riskClass: 'Classe di rischio',
createdAt: 'Creato il',
contentPack: 'Content pack',
company: 'Azienda',
contact: 'Contatto',
contactPerson: 'Referente',
},
report: {
title: 'Classificazione del rischio ai sensi del regolamento UE sullIA',
result: 'Risultato',
reasons: 'Motivazione',
gpai: 'GPAI',
gpaiText:
'Per questo sistema sono inoltre rilevanti gli obblighi relativi ai modelli GPAI (art. 53 e segg.).',
art64: 'Obbligo di documentazione art. 6, par. 4',
art64Text:
'Il ricorso alleccezione di cui allart. 6, par. 3 è stato documentato. Questa valutazione deve essere presentata alle autorità di vigilanza del mercato su richiesta.',
},
plan: {
title: 'Piano dazione — regolamento UE sullIA',
none: 'Per questo sistema non esistono obblighi attuabili (vietato o al di fuori dellambito di applicazione).',
obligations: 'Obblighi',
details: 'Dettagli',
colObligation: 'Obbligo',
colLegal: 'Base giuridica',
colDeadline: 'Scadenza',
colStatus: 'Stato',
},
inventory: {
title: 'Inventario IA (registro degli asset IA)',
asOf: 'Aggiornato al',
count: 'Sistemi di IA registrati',
colSystem: 'Sistema',
colPurpose: 'Finalità',
colRole: 'Ruolo',
colRisk: 'Classe di rischio',
colOwner: 'Responsabile',
},
todo: '_[DA COMPLETARE]_',
};
const ES: DocStrings = {
risk: {
'out-of-scope': 'No aplicable (no es IA en el sentido del art. 3, punto 1)',
prohibited: 'PROHIBIDO (art. 5)',
high: 'Alto riesgo',
limited: 'Riesgo limitado (obligaciones de transparencia)',
minimal: 'Riesgo mínimo',
},
role: {
provider: 'Proveedor',
deployer: 'Responsable del despliegue',
importer: 'Importador',
distributor: 'Distribuidor',
},
status: {
open: 'Abierto',
'in-progress': 'En curso',
done: 'Completado',
'not-applicable': 'No aplicable',
},
disclaimer:
'> **Nota:** Este documento se ha creado con AI-Act-Kompass y es una ayuda de trabajo estructurada — **no constituye asesoramiento jurídico**. La valoración jurídica del caso concreto corresponde a la empresa y a su asesoría jurídica.',
meta: {
system: 'Sistema de IA',
purpose: 'Finalidad prevista',
vendor: 'Fabricante/proveedor',
owner: 'Responsable (interno)',
role: 'Rol de la empresa',
riskClass: 'Clase de riesgo',
createdAt: 'Creado el',
contentPack: 'Paquete de contenido',
company: 'Empresa',
contact: 'Contacto',
contactPerson: 'Persona de contacto',
},
report: {
title: 'Clasificación de riesgo según el Reglamento de IA de la UE',
result: 'Resultado',
reasons: 'Justificación',
gpai: 'GPAI',
gpaiText:
'Para este sistema son además relevantes las obligaciones relativas a los modelos GPAI (art. 53 y ss.).',
art64: 'Obligación de documentación art. 6, apdo. 4',
art64Text:
'El recurso a la excepción del art. 6, apdo. 3 ha sido documentado. Esta evaluación debe presentarse a las autoridades de vigilancia del mercado previa solicitud.',
},
plan: {
title: 'Plan de medidas — Reglamento de IA de la UE',
none: 'No existen obligaciones aplicables para este sistema (prohibido o fuera del ámbito de aplicación).',
obligations: 'Obligaciones',
details: 'Detalles',
colObligation: 'Obligación',
colLegal: 'Base jurídica',
colDeadline: 'Plazo',
colStatus: 'Estado',
},
inventory: {
title: 'Inventario de IA (registro de activos de IA)',
asOf: 'A fecha de',
count: 'Sistemas de IA registrados',
colSystem: 'Sistema',
colPurpose: 'Finalidad',
colRole: 'Rol',
colRisk: 'Clase de riesgo',
colOwner: 'Responsable',
},
todo: '_[POR COMPLETAR]_',
};
const PL: DocStrings = {
risk: {
'out-of-scope': 'Nie ma zastosowania (nie jest AI w rozumieniu art. 3 pkt 1)',
prohibited: 'ZAKAZANE (art. 5)',
high: 'Wysokie ryzyko',
limited: 'Ograniczone ryzyko (obowiązki przejrzystości)',
minimal: 'Minimalne ryzyko',
},
role: {
provider: 'Dostawca',
deployer: 'Podmiot stosujący',
importer: 'Importer',
distributor: 'Dystrybutor',
},
status: {
open: 'Otwarte',
'in-progress': 'W trakcie realizacji',
done: 'Zakończone',
'not-applicable': 'Nie dotyczy',
},
disclaimer:
'> **Uwaga:** Ten dokument został utworzony za pomocą AI-Act-Kompass i stanowi ustrukturyzowaną pomoc roboczą — **nie stanowi porady prawnej**. Ocena prawna konkretnego przypadku należy do przedsiębiorstwa i jego doradców prawnych.',
meta: {
system: 'System AI',
purpose: 'Przeznaczenie',
vendor: 'Producent/dostawca',
owner: 'Odpowiedzialny (wewnętrznie)',
role: 'Rola przedsiębiorstwa',
riskClass: 'Klasa ryzyka',
createdAt: 'Utworzono dnia',
contentPack: 'Pakiet treści',
company: 'Przedsiębiorstwo',
contact: 'Kontakt',
contactPerson: 'Osoba kontaktowa',
},
report: {
title: 'Klasyfikacja ryzyka zgodnie z unijnym aktem w sprawie AI',
result: 'Wynik',
reasons: 'Uzasadnienie',
gpai: 'GPAI',
gpaiText:
'Dla tego systemu istotne są dodatkowo obowiązki dotyczące modeli GPAI (art. 53 i nast.).',
art64: 'Obowiązek dokumentacyjny art. 6 ust. 4',
art64Text:
'Skorzystanie z wyjątku przewidzianego w art. 6 ust. 3 zostało udokumentowane. Ocenę tę należy przedłożyć organom nadzoru rynku na żądanie.',
},
plan: {
title: 'Plan działań — unijny akt w sprawie AI',
none: 'Dla tego systemu nie istnieją obowiązki możliwe do realizacji (zakazany lub poza zakresem stosowania).',
obligations: 'Obowiązki',
details: 'Szczegóły',
colObligation: 'Obowiązek',
colLegal: 'Podstawa prawna',
colDeadline: 'Termin',
colStatus: 'Status',
},
inventory: {
title: 'Inwentarz AI (rejestr zasobów AI)',
asOf: 'Stan na',
count: 'Zarejestrowane systemy AI',
colSystem: 'System',
colPurpose: 'Cel',
colRole: 'Rola',
colRisk: 'Klasa ryzyka',
colOwner: 'Odpowiedzialny',
},
todo: '_[DO UZUPEŁNIENIA]_',
};
const CS: DocStrings = {
risk: {
'out-of-scope': 'Nepoužije se (není AI ve smyslu čl. 3 bodu 1)',
prohibited: 'ZAKÁZÁNO (čl. 5)',
high: 'Vysoké riziko',
limited: 'Omezené riziko (povinnosti transparentnosti)',
minimal: 'Minimální riziko',
},
role: {
provider: 'Poskytovatel',
deployer: 'Zavádějící subjekt',
importer: 'Dovozce',
distributor: 'Distributor',
},
status: {
open: 'Otevřeno',
'in-progress': 'Probíhá',
done: 'Dokončeno',
'not-applicable': 'Nepoužije se',
},
disclaimer:
'> **Upozornění:** Tento dokument byl vytvořen pomocí AI-Act-Kompass a je strukturovanou pracovní pomůckou — **nepředstavuje právní poradenství**. Právní posouzení konkrétního případu přísluší podniku a jeho právním poradcům.',
meta: {
system: 'Systém AI',
purpose: 'Určený účel',
vendor: 'Výrobce/poskytovatel',
owner: 'Odpovědná osoba (interní)',
role: 'Role podniku',
riskClass: 'Riziková třída',
createdAt: 'Vytvořeno dne',
contentPack: 'Balíček obsahu',
company: 'Podnik',
contact: 'Kontakt',
contactPerson: 'Kontaktní osoba',
},
report: {
title: 'Klasifikace rizika podle aktu EU o AI',
result: 'Výsledek',
reasons: 'Odůvodnění',
gpai: 'GPAI',
gpaiText:
'Pro tento systém jsou navíc relevantní povinnosti týkající se modelů GPAI (čl. 53 a násl.).',
art64: 'Dokumentační povinnost čl. 6 odst. 4',
art64Text:
'Využití výjimky podle čl. 6 odst. 3 bylo zdokumentováno. Toto posouzení je nutno na žádost předložit orgánům dozoru nad trhem.',
},
plan: {
title: 'Akční plán — akt EU o AI',
none: 'Pro tento systém neexistují žádné proveditelné povinnosti (zakázán nebo mimo oblast působnosti).',
obligations: 'Povinnosti',
details: 'Podrobnosti',
colObligation: 'Povinnost',
colLegal: 'Právní základ',
colDeadline: 'Lhůta',
colStatus: 'Stav',
},
inventory: {
title: 'Inventář AI (registr aktiv AI)',
asOf: 'Stav ke dni',
count: 'Registrované systémy AI',
colSystem: 'Systém',
colPurpose: 'Účel',
colRole: 'Role',
colRisk: 'Riziková třída',
colOwner: 'Odpovědná osoba',
},
todo: '_[DOPLNIT]_',
};
const SK: DocStrings = {
risk: {
'out-of-scope': 'Neuplatňuje sa (nie je AI v zmysle čl. 3 bodu 1)',
prohibited: 'ZAKÁZANÉ (čl. 5)',
high: 'Vysoké riziko',
limited: 'Obmedzené riziko (povinnosti transparentnosti)',
minimal: 'Minimálne riziko',
},
role: {
provider: 'Poskytovateľ',
deployer: 'Nasadzujúci subjekt',
importer: 'Dovozca',
distributor: 'Distribútor',
},
status: {
open: 'Otvorené',
'in-progress': 'Prebieha',
done: 'Dokončené',
'not-applicable': 'Neuplatňuje sa',
},
disclaimer:
'> **Upozornenie:** Tento dokument bol vytvorený pomocou AI-Act-Kompass a je štruktúrovanou pracovnou pomôckou — **nepredstavuje právne poradenstvo**. Právne posúdenie konkrétneho prípadu prislúcha podniku a jeho právnym poradcom.',
meta: {
system: 'Systém AI',
purpose: 'Zamýšľaný účel',
vendor: 'Výrobca/poskytovateľ',
owner: 'Zodpovedná osoba (interná)',
role: 'Rola podniku',
riskClass: 'Riziková trieda',
createdAt: 'Vytvorené dňa',
contentPack: 'Balík obsahu',
company: 'Podnik',
contact: 'Kontakt',
contactPerson: 'Kontaktná osoba',
},
report: {
title: 'Klasifikácia rizika podľa aktu EÚ o AI',
result: 'Výsledok',
reasons: 'Odôvodnenie',
gpai: 'GPAI',
gpaiText:
'Pre tento systém sú navyše relevantné povinnosti týkajúce sa modelov GPAI (čl. 53 a nasl.).',
art64: 'Dokumentačná povinnosť čl. 6 ods. 4',
art64Text:
'Využitie výnimky podľa čl. 6 ods. 3 bolo zdokumentované. Toto posúdenie treba na požiadanie predložiť orgánom dohľadu nad trhom.',
},
plan: {
title: 'Akčný plán — akt EÚ o AI',
none: 'Pre tento systém neexistujú žiadne vykonateľné povinnosti (zakázaný alebo mimo rozsahu pôsobnosti).',
obligations: 'Povinnosti',
details: 'Podrobnosti',
colObligation: 'Povinnosť',
colLegal: 'Právny základ',
colDeadline: 'Lehota',
colStatus: 'Stav',
},
inventory: {
title: 'Inventár AI (register aktív AI)',
asOf: 'Stav k',
count: 'Registrované systémy AI',
colSystem: 'Systém',
colPurpose: 'Účel',
colRole: 'Rola',
colRisk: 'Riziková trieda',
colOwner: 'Zodpovedná osoba',
},
todo: '_[DOPLNIŤ]_',
};
const RO: DocStrings = {
risk: {
'out-of-scope': 'Nu se aplică (nu este IA în sensul art. 3 pct. 1)',
prohibited: 'INTERZIS (art. 5)',
high: 'Risc ridicat',
limited: 'Risc limitat (obligații de transparență)',
minimal: 'Risc minim',
},
role: {
provider: 'Furnizor',
deployer: 'Implementator',
importer: 'Importator',
distributor: 'Distribuitor',
},
status: {
open: 'Deschis',
'in-progress': 'În curs',
done: 'Finalizat',
'not-applicable': 'Nu se aplică',
},
disclaimer:
'> **Notă:** Acest document a fost creat cu AI-Act-Kompass și este un instrument de lucru structurat — **nu constituie consultanță juridică**. Evaluarea juridică a cazului concret revine întreprinderii și consilierilor săi juridici.',
meta: {
system: 'Sistem de IA',
purpose: 'Scop preconizat',
vendor: 'Producător/furnizor',
owner: 'Responsabil (intern)',
role: 'Rolul întreprinderii',
riskClass: 'Clasa de risc',
createdAt: 'Creat la',
contentPack: 'Pachet de conținut',
company: 'Întreprindere',
contact: 'Contact',
contactPerson: 'Persoană de contact',
},
report: {
title: 'Clasificarea riscului conform Regulamentului UE privind IA',
result: 'Rezultat',
reasons: 'Motivare',
gpai: 'GPAI',
gpaiText:
'Pentru acest sistem sunt în plus relevante obligațiile privind modelele GPAI (art. 53 și urm.).',
art64: 'Obligația de documentare art. 6 alin. (4)',
art64Text:
'Recurgerea la excepția prevăzută la art. 6 alin. (3) a fost documentată. Această evaluare trebuie prezentată autorităților de supraveghere a pieței, la cerere.',
},
plan: {
title: 'Plan de măsuri — Regulamentul UE privind IA',
none: 'Pentru acest sistem nu există obligații aplicabile (interzis sau în afara domeniului de aplicare).',
obligations: 'Obligații',
details: 'Detalii',
colObligation: 'Obligație',
colLegal: 'Temei juridic',
colDeadline: 'Termen',
colStatus: 'Stare',
},
inventory: {
title: 'Inventar IA (registru de active IA)',
asOf: 'La data de',
count: 'Sisteme de IA înregistrate',
colSystem: 'Sistem',
colPurpose: 'Scop',
colRole: 'Rol',
colRisk: 'Clasa de risc',
colOwner: 'Responsabil',
},
todo: '_[DE COMPLETAT]_',
};
/**
* Liefert die Dokument-Strings für die gewünschte Sprache.
* Vollständig lokalisiert für alle unterstützten Sprachen
* (de/en/fr/it/es/pl/cs/sk/ro).
*/
export function docStrings(locale: Locale): DocStrings {
const DICTS = { de: DE, en: EN, fr: FR, it: IT, es: ES, pl: PL, cs: CS, sk: SK, ro: RO } as const;
return DICTS[locale];
}
/**
* Formatiert ein ISO-Datum landesüblich
* (DE/PL/CS/SK/RO: TT.MM.JJJJ, FR/IT/ES: TT/MM/JJJJ, EN: ISO).
*/
export function formatDocDate(iso: string, locale: Locale): string {
if (locale === 'en') return iso;
const [y, m, d] = iso.split('-');
if (!d || !m || !y) return iso;
const dotLocales: readonly Locale[] = ['de', 'pl', 'cs', 'sk', 'ro'];
return dotLocales.includes(locale) ? `${d}.${m}.${y}` : `${d}/${m}/${y}`;
}

View File

@ -0,0 +1,90 @@
import { describe, expect, it } from 'vitest';
import { CONTENT_PACK } from '../content/pack';
import { classify } from './classify';
import { actionPlan, annexIVSkeleton, inventoryReport, riskReport } from './documents';
import { deriveObligations } from './obligations';
import type { AISystem, AssessmentAnswers, CompanyProfile } from './types';
const answers: AssessmentAnswers = {
isAISystem: true,
role: 'provider',
isGPAIModel: false,
prohibitedPractices: [],
annexIIICategories: ['a3-employment'],
art63Exception: false,
involvesProfiling: true,
isAnnexISafetyComponent: false,
transparencyTriggers: ['tr-chatbot'],
};
const system: AISystem = {
id: 'sys-1',
name: 'HR-Screening',
purpose: 'Vorauswahl von Bewerbungen',
vendor: 'Beispiel GmbH',
owner: 'Jane Doe',
createdAt: '2026-07-01T00:00:00.000Z',
updatedAt: '2026-07-01T00:00:00.000Z',
answers,
classification: classify(answers, CONTENT_PACK),
obligationStatus: { 'ob-risk-mgmt': 'in-progress' },
};
const TODAY = '2026-07-04';
describe('documents', () => {
it('riskReport enthält Klassifizierung, Begründung und Disclaimer', () => {
const md = riskReport(system, CONTENT_PACK, TODAY);
expect(md).toContain('# Risikoklassifizierung');
expect(md).toContain('Hochrisiko');
expect(md).toContain('Annex III');
expect(md).toContain('keine Rechtsberatung');
expect(md).toContain(CONTENT_PACK.version);
});
it('actionPlan listet Pflichten mit Status und Frist', () => {
const obligations = deriveObligations(system.classification, answers, CONTENT_PACK);
const md = actionPlan(system, obligations, CONTENT_PACK, TODAY);
expect(md).toContain('Risikomanagementsystem');
expect(md).toContain('In Umsetzung');
expect(md).toContain('02.12.2027');
});
it('annexIVSkeleton befüllt bekannte Felder und markiert offene Punkte', () => {
const md = annexIVSkeleton(system, CONTENT_PACK, TODAY);
expect(md).toContain('Vorauswahl von Bewerbungen');
expect(md).toContain('_[AUSFÜLLEN]_');
expect(md).toContain('Annex IV');
});
it('inventoryReport listet alle Systeme tabellarisch', () => {
const md = inventoryReport([system], CONTENT_PACK, TODAY);
expect(md).toContain('HR-Screening');
expect(md).toContain('| System |');
expect(md).toContain('Registrierte KI-Systeme: **1**');
});
it('übernimmt das Firmenprofil in den Berichtskopf', () => {
const profile: CompanyProfile = {
name: 'Muster GmbH',
street: 'Musterstraße 1',
zipCity: '60311 Frankfurt',
contactPerson: 'Max Mustermann',
email: 'compliance@muster.de',
phone: '+49 69 000000',
website: 'www.muster.de',
logoDataUrl: '',
countries: [],
};
const md = riskReport(system, CONTENT_PACK, TODAY, profile);
expect(md).toContain('| **Unternehmen** | Muster GmbH |');
expect(md).toContain('compliance@muster.de');
expect(md).toContain('| **Ansprechpartner** | Max Mustermann |');
expect(inventoryReport([system], CONTENT_PACK, TODAY, profile)).toContain('Muster GmbH · Stand');
});
it('lässt den Berichtskopf ohne Profil unverändert', () => {
const md = riskReport(system, CONTENT_PACK, TODAY);
expect(md).not.toContain('**Unternehmen**');
});
});

View File

@ -0,0 +1,445 @@
import type { Locale } from '../i18n/types';
import { docStrings, formatDocDate } from './docStrings';
import type { AISystem, CompanyProfile, ContentPack, Obligation } from './types';
/** Kontaktzeilen aus dem Firmenprofil (leer, wenn kein Profil gepflegt). */
function companyRows(profile: CompanyProfile | undefined, locale: Locale): readonly string[] {
const s = docStrings(locale);
if (!profile || profile.name.trim() === '') return [];
const contact = [profile.street, profile.zipCity, profile.email, profile.phone, profile.website]
.filter((p) => p.trim() !== '')
.join(' · ');
return [
`| **${s.meta.company}** | ${profile.name} |`,
...(contact ? [`| **${s.meta.contact}** | ${contact} |`] : []),
...(profile.contactPerson.trim()
? [`| **${s.meta.contactPerson}** | ${profile.contactPerson} |`]
: []),
];
}
function header(
title: string,
system: AISystem,
pack: ContentPack,
today: string,
locale: Locale,
profile?: CompanyProfile,
): string {
const s = docStrings(locale);
return [
`# ${title}`,
'',
`| | |`,
`|---|---|`,
...companyRows(profile, locale),
`| **${s.meta.system}** | ${system.name} |`,
`| **${s.meta.purpose}** | ${system.purpose || '—'} |`,
`| **${s.meta.vendor}** | ${system.vendor || '—'} |`,
`| **${s.meta.owner}** | ${system.owner || '—'} |`,
`| **${s.meta.role}** | ${s.role[system.answers.role]} |`,
`| **${s.meta.riskClass}** | ${s.risk[system.classification.riskClass]} |`,
`| **${s.meta.createdAt}** | ${formatDocDate(today, locale)} |`,
`| **${s.meta.contentPack}** | v${pack.version} (${pack.legalBasis}) |`,
'',
s.disclaimer,
'',
].join('\n');
}
/**
* Erzeugt den Risikoklassifizierungs-Bericht für ein System als Markdown.
*
* @param system - Bewertetes KI-System
* @param pack - Regulatorischer Content-Pack
* @param today - Stichtag im ISO-Format
* @param profile - Firmenprofil für den Berichtskopf (optional)
* @param locale - Dokumentsprache (Default: Deutsch)
*/
export function riskReport(
system: AISystem,
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const lines = [header(s.report.title, system, pack, today, locale, profile)];
lines.push(`## ${s.report.result}`, '');
lines.push(`**${s.risk[system.classification.riskClass]}**`, '');
lines.push(`## ${s.report.reasons}`, '');
for (const reason of system.classification.reasons) {
lines.push(`- ${reason}`);
}
lines.push('');
if (system.classification.gpaiObligations) {
lines.push(`## ${s.report.gpai}`, '', s.report.gpaiText, '');
}
if (system.classification.art64DocumentationDuty) {
lines.push(`## ${s.report.art64}`, '', s.report.art64Text, '');
}
return lines.join('\n');
}
/**
* Erzeugt den Maßnahmenplan (Pflichten-Checkliste) als Markdown.
*
* @param system - Bewertetes KI-System
* @param obligations - Anwendbare Pflichten
* @param pack - Regulatorischer Content-Pack
* @param today - Stichtag im ISO-Format
* @param profile - Firmenprofil für den Berichtskopf (optional)
* @param locale - Dokumentsprache (Default: Deutsch)
*/
export function actionPlan(
system: AISystem,
obligations: readonly Obligation[],
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const lines = [header(s.plan.title, system, pack, today, locale, profile)];
if (obligations.length === 0) {
lines.push(s.plan.none);
return lines.join('\n');
}
lines.push(`## ${s.plan.obligations}`, '');
lines.push(`| ${s.plan.colObligation} | ${s.plan.colLegal} | ${s.plan.colDeadline} | ${s.plan.colStatus} |`);
lines.push('|---|---|---|---|');
for (const ob of obligations) {
const status = system.obligationStatus[ob.id] ?? 'open';
lines.push(
`| ${ob.title} | ${ob.articles} | ${formatDocDate(ob.deadline, locale)} | ${s.status[status]} |`,
);
}
lines.push('', `## ${s.plan.details}`, '');
for (const ob of obligations) {
lines.push(`### ${ob.title} (${ob.articles})`, '', ob.description, '');
}
return lines.join('\n');
}
const ANNEX_IV_SECTIONS: Readonly<Record<Locale, readonly (readonly [string, readonly string[]])[]>> = {
de: [
['1. Allgemeine Beschreibung des KI-Systems', [
'Zweckbestimmung', 'Anbieter', 'Versionen und Datum des Inverkehrbringens',
'Hardware-Anforderungen / Bereitstellungsform', 'Interaktion mit externer Hard-/Software',
]],
['2. Detaillierte Beschreibung der Elemente und des Entwicklungsprozesses', [
'Entwicklungsmethoden und verwendete Werkzeuge', 'Systemarchitektur und Rechenressourcen',
'Datenanforderungen (Trainings-, Validierungs-, Testdaten, Herkunft, Aufbereitung)',
'Maßnahmen der menschlichen Aufsicht (Art. 14)',
'Vorab festgelegte Änderungen und Kontinuität der Konformität',
]],
['3. Überwachung, Funktionsweise und Kontrolle', [
'Fähigkeiten und Leistungsgrenzen (Genauigkeitsmetriken)',
'Vorhersehbare unbeabsichtigte Ergebnisse und Risikoquellen', 'Eingabedaten-Spezifikation',
]],
['4. Risikomanagementsystem (Art. 9)', ['Beschreibung des Risikomanagementprozesses']],
['5. Änderungen über den Lebenszyklus', ['Änderungshistorie und Update-Prozess']],
['6. Angewandte harmonisierte Normen und Spezifikationen', [
'Liste der Normen (z. B. ISO/IEC 42001, ISO/IEC 23894)',
]],
['7. EU-Konformitätserklärung', ['Kopie der Konformitätserklärung (Art. 47)']],
['8. Bewertung nach dem Inverkehrbringen (Art. 72)', [
'Plan zur Beobachtung nach dem Inverkehrbringen',
]],
],
en: [
['1. General description of the AI system', [
'Intended purpose', 'Provider', 'Versions and date of placing on the market',
'Hardware requirements / form of provision', 'Interaction with external hardware/software',
]],
['2. Detailed description of elements and development process', [
'Development methods and tools used', 'System architecture and computational resources',
'Data requirements (training, validation, test data; provenance, preparation)',
'Human oversight measures (Art. 14)',
'Pre-determined changes and continuity of conformity',
]],
['3. Monitoring, functioning and control', [
'Capabilities and performance limitations (accuracy metrics)',
'Foreseeable unintended outcomes and sources of risk', 'Input data specification',
]],
['4. Risk management system (Art. 9)', ['Description of the risk management process']],
['5. Changes over the lifecycle', ['Change history and update process']],
['6. Applied harmonised standards and specifications', [
'List of standards (e.g. ISO/IEC 42001, ISO/IEC 23894)',
]],
['7. EU declaration of conformity', ['Copy of the declaration of conformity (Art. 47)']],
['8. Post-market evaluation (Art. 72)', ['Post-market monitoring plan']],
],
fr: [
['1. Description générale du système dIA', [
'Destination', 'Fournisseur', 'Versions et date de mise sur le marché',
'Exigences matérielles / forme de mise à disposition', 'Interaction avec du matériel/des logiciels externes',
]],
['2. Description détaillée des éléments et du processus de développement', [
'Méthodes de développement et outils utilisés', 'Architecture du système et ressources de calcul',
'Exigences en matière de données (données dentraînement, de validation et de test ; provenance, préparation)',
'Mesures de contrôle humain (art. 14)',
'Modifications prédéterminées et continuité de la conformité',
]],
['3. Surveillance, fonctionnement et contrôle', [
'Capacités et limites de performance (métriques dexactitude)',
'Résultats non intentionnels prévisibles et sources de risque', 'Spécification des données dentrée',
]],
['4. Système de gestion des risques (art. 9)', ['Description du processus de gestion des risques']],
['5. Modifications au cours du cycle de vie', ['Historique des modifications et processus de mise à jour']],
['6. Normes harmonisées et spécifications appliquées', [
'Liste des normes (p. ex. ISO/IEC 42001, ISO/IEC 23894)',
]],
['7. Déclaration UE de conformité', ['Copie de la déclaration de conformité (art. 47)']],
['8. Évaluation après la mise sur le marché (art. 72)', [
'Plan de surveillance après commercialisation',
]],
],
it: [
['1. Descrizione generale del sistema di IA', [
'Finalità prevista', 'Fornitore', 'Versioni e data di immissione sul mercato',
'Requisiti hardware / forma di fornitura', 'Interazione con hardware/software esterni',
]],
['2. Descrizione dettagliata degli elementi e del processo di sviluppo', [
'Metodi di sviluppo e strumenti utilizzati', 'Architettura del sistema e risorse computazionali',
'Requisiti dei dati (dati di addestramento, convalida e prova; provenienza, preparazione)',
'Misure di sorveglianza umana (art. 14)',
'Modifiche predeterminate e continuità della conformità',
]],
['3. Monitoraggio, funzionamento e controllo', [
'Capacità e limiti di prestazione (metriche di accuratezza)',
'Risultati indesiderati prevedibili e fonti di rischio', 'Specifica dei dati di input',
]],
['4. Sistema di gestione dei rischi (art. 9)', ['Descrizione del processo di gestione dei rischi']],
['5. Modifiche nel corso del ciclo di vita', ['Cronologia delle modifiche e processo di aggiornamento']],
['6. Norme armonizzate e specifiche applicate', [
'Elenco delle norme (ad es. ISO/IEC 42001, ISO/IEC 23894)',
]],
['7. Dichiarazione di conformità UE', ['Copia della dichiarazione di conformità (art. 47)']],
['8. Valutazione successiva allimmissione sul mercato (art. 72)', [
'Piano di monitoraggio successivo allimmissione sul mercato',
]],
],
es: [
['1. Descripción general del sistema de IA', [
'Finalidad prevista', 'Proveedor', 'Versiones y fecha de introducción en el mercado',
'Requisitos de hardware / forma de suministro', 'Interacción con hardware/software externos',
]],
['2. Descripción detallada de los elementos y del proceso de desarrollo', [
'Métodos de desarrollo y herramientas utilizadas', 'Arquitectura del sistema y recursos computacionales',
'Requisitos de datos (datos de entrenamiento, validación y prueba; procedencia, preparación)',
'Medidas de supervisión humana (art. 14)',
'Modificaciones predeterminadas y continuidad de la conformidad',
]],
['3. Seguimiento, funcionamiento y control', [
'Capacidades y limitaciones de rendimiento (métricas de precisión)',
'Resultados no deseados previsibles y fuentes de riesgo', 'Especificación de los datos de entrada',
]],
['4. Sistema de gestión de riesgos (art. 9)', ['Descripción del proceso de gestión de riesgos']],
['5. Modificaciones durante el ciclo de vida', ['Historial de cambios y proceso de actualización']],
['6. Normas armonizadas y especificaciones aplicadas', [
'Lista de normas (p. ej., ISO/IEC 42001, ISO/IEC 23894)',
]],
['7. Declaración UE de conformidad', ['Copia de la declaración de conformidad (art. 47)']],
['8. Evaluación posterior a la comercialización (art. 72)', [
'Plan de vigilancia poscomercialización',
]],
],
pl: [
['1. Ogólny opis systemu AI', [
'Przeznaczenie', 'Dostawca', 'Wersje i data wprowadzenia do obrotu',
'Wymagania sprzętowe / forma udostępnienia', 'Interakcja z zewnętrznym sprzętem/oprogramowaniem',
]],
['2. Szczegółowy opis elementów i procesu rozwoju', [
'Metody rozwoju i użyte narzędzia', 'Architektura systemu i zasoby obliczeniowe',
'Wymagania dotyczące danych (dane treningowe, walidacyjne, testowe; pochodzenie, przygotowanie)',
'Środki nadzoru ludzkiego (art. 14)',
'Z góry określone zmiany i ciągłość zgodności',
]],
['3. Monitorowanie, funkcjonowanie i kontrola', [
'Zdolności i ograniczenia skuteczności (metryki dokładności)',
'Przewidywalne niezamierzone wyniki i źródła ryzyka', 'Specyfikacja danych wejściowych',
]],
['4. System zarządzania ryzykiem (art. 9)', ['Opis procesu zarządzania ryzykiem']],
['5. Zmiany w cyklu życia', ['Historia zmian i proces aktualizacji']],
['6. Zastosowane normy zharmonizowane i specyfikacje', [
'Lista norm (np. ISO/IEC 42001, ISO/IEC 23894)',
]],
['7. Deklaracja zgodności UE', ['Kopia deklaracji zgodności (art. 47)']],
['8. Ocena po wprowadzeniu do obrotu (art. 72)', [
'Plan monitorowania po wprowadzeniu do obrotu',
]],
],
cs: [
['1. Obecný popis systému AI', [
'Určený účel', 'Poskytovatel', 'Verze a datum uvedení na trh',
'Hardwarové požadavky / forma poskytování', 'Interakce s externím hardwarem/softwarem',
]],
['2. Podrobný popis prvků a procesu vývoje', [
'Metody vývoje a použité nástroje', 'Architektura systému a výpočetní zdroje',
'Požadavky na data (trénovací, validační a testovací data; původ, příprava)',
'Opatření lidského dohledu (čl. 14)',
'Předem stanovené změny a kontinuita shody',
]],
['3. Monitorování, fungování a kontrola', [
'Schopnosti a výkonnostní omezení (metriky přesnosti)',
'Předvídatelné nezamýšlené výsledky a zdroje rizik', 'Specifikace vstupních dat',
]],
['4. Systém řízení rizik (čl. 9)', ['Popis procesu řízení rizik']],
['5. Změny v průběhu životního cyklu', ['Historie změn a proces aktualizací']],
['6. Použité harmonizované normy a specifikace', [
'Seznam norem (např. ISO/IEC 42001, ISO/IEC 23894)',
]],
['7. EU prohlášení o shodě', ['Kopie prohlášení o shodě (čl. 47)']],
['8. Hodnocení po uvedení na trh (čl. 72)', [
'Plán monitorování po uvedení na trh',
]],
],
sk: [
['1. Všeobecný opis systému AI', [
'Zamýšľaný účel', 'Poskytovateľ', 'Verzie a dátum uvedenia na trh',
'Hardvérové požiadavky / forma poskytovania', 'Interakcia s externým hardvérom/softvérom',
]],
['2. Podrobný opis prvkov a procesu vývoja', [
'Metódy vývoja a použité nástroje', 'Architektúra systému a výpočtové zdroje',
'Požiadavky na dáta (trénovacie, validačné a testovacie dáta; pôvod, príprava)',
'Opatrenia ľudského dohľadu (čl. 14)',
'Vopred určené zmeny a kontinuita zhody',
]],
['3. Monitorovanie, fungovanie a kontrola', [
'Schopnosti a výkonnostné obmedzenia (metriky presnosti)',
'Predvídateľné nezamýšľané výsledky a zdroje rizík', 'Špecifikácia vstupných dát',
]],
['4. Systém riadenia rizík (čl. 9)', ['Opis procesu riadenia rizík']],
['5. Zmeny počas životného cyklu', ['História zmien a proces aktualizácií']],
['6. Použité harmonizované normy a špecifikácie', [
'Zoznam noriem (napr. ISO/IEC 42001, ISO/IEC 23894)',
]],
['7. EÚ vyhlásenie o zhode', ['Kópia vyhlásenia o zhode (čl. 47)']],
['8. Hodnotenie po uvedení na trh (čl. 72)', [
'Plán monitorovania po uvedení na trh',
]],
],
ro: [
['1. Descrierea generală a sistemului de IA', [
'Scop preconizat', 'Furnizor', 'Versiuni și data introducerii pe piață',
'Cerințe hardware / forma de punere la dispoziție', 'Interacțiunea cu hardware/software extern',
]],
['2. Descrierea detaliată a elementelor și a procesului de dezvoltare', [
'Metode de dezvoltare și instrumente utilizate', 'Arhitectura sistemului și resurse de calcul',
'Cerințe privind datele (date de antrenare, validare și testare; proveniență, pregătire)',
'Măsuri de supraveghere umană (art. 14)',
'Modificări predeterminate și continuitatea conformității',
]],
['3. Monitorizare, funcționare și control', [
'Capacități și limite de performanță (metrici de acuratețe)',
'Rezultate neintenționate previzibile și surse de risc', 'Specificația datelor de intrare',
]],
['4. Sistemul de gestionare a riscurilor (art. 9)', ['Descrierea procesului de gestionare a riscurilor']],
['5. Modificări pe parcursul ciclului de viață', ['Istoricul modificărilor și procesul de actualizare']],
['6. Standarde armonizate și specificații aplicate', [
'Lista standardelor (de ex. ISO/IEC 42001, ISO/IEC 23894)',
]],
['7. Declarația UE de conformitate', ['Copie a declarației de conformitate (art. 47)']],
['8. Evaluarea după introducerea pe piață (art. 72)', [
'Plan de monitorizare ulterioară introducerii pe piață',
]],
],
};
/**
* Erzeugt das Grundgerüst der technischen Dokumentation nach Annex IV.
*
* Vorbefüllte Abschnitte stammen aus den Wizard-Antworten; offene Punkte
* sind als Platzhalter markiert.
*
* @param system - Bewertetes KI-System
* @param pack - Regulatorischer Content-Pack
* @param today - Stichtag im ISO-Format
* @param profile - Firmenprofil für den Berichtskopf (optional)
* @param locale - Dokumentsprache (Default: Deutsch)
*/
export function annexIVSkeleton(
system: AISystem,
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const ANNEX_IV_TITLE: Readonly<Record<Locale, string>> = {
de: 'Technische Dokumentation (Annex IV) — Grundgerüst',
en: 'Technical documentation (Annex IV) — skeleton',
fr: 'Documentation technique (annexe IV) — trame',
it: 'Documentazione tecnica (allegato IV) — struttura di base',
es: 'Documentación técnica (anexo IV) — esqueleto',
pl: 'Dokumentacja techniczna (załącznik IV) — szkielet',
cs: 'Technická dokumentace (příloha IV) — základní struktura',
sk: 'Technická dokumentácia (príloha IV) — základná štruktúra',
ro: 'Documentația tehnică (anexa IV) — schelet',
};
const lines = [header(ANNEX_IV_TITLE[locale], system, pack, today, locale, profile)];
const prefilled: Readonly<Record<string, string>> = {
[ANNEX_IV_SECTIONS[locale][0]?.[1][0] ?? '']: system.purpose,
[ANNEX_IV_SECTIONS[locale][0]?.[1][1] ?? '']: system.vendor,
};
for (const [section, items] of ANNEX_IV_SECTIONS[locale]) {
lines.push(`## ${section}`, '');
for (const item of items) {
const value = prefilled[item];
lines.push(`- **${item}:** ${value && value.trim() !== '' ? value : s.todo}`);
}
lines.push('');
}
return lines.join('\n');
}
/**
* Erzeugt das KI-Inventar über alle registrierten Systeme als Markdown.
*
* @param systems - Alle registrierten KI-Systeme
* @param pack - Regulatorischer Content-Pack
* @param today - Stichtag im ISO-Format
* @param profile - Firmenprofil für den Berichtskopf (optional)
* @param locale - Dokumentsprache (Default: Deutsch)
*/
export function inventoryReport(
systems: readonly AISystem[],
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const company = profile && profile.name.trim() !== '' ? `${profile.name} · ` : '';
const lines = [
`# ${s.inventory.title}`,
'',
`${company}${s.inventory.asOf}: ${formatDocDate(today, locale)} · Content-Pack v${pack.version}`,
'',
s.disclaimer,
'',
`${s.inventory.count}: **${systems.length}**`,
'',
`| ${s.inventory.colSystem} | ${s.inventory.colPurpose} | ${s.inventory.colRole} | ${s.inventory.colRisk} | ${s.inventory.colOwner} |`,
'|---|---|---|---|---|',
];
for (const sys of systems) {
lines.push(
`| ${sys.name} | ${sys.purpose || '—'} | ${s.role[sys.answers.role]} | ${
s.risk[sys.classification.riskClass]
} | ${sys.owner || '—'} |`,
);
}
return lines.join('\n');
}

View File

@ -0,0 +1,448 @@
import type { Locale } from '../i18n/types';
import { docStrings, formatDocDate } from './docStrings';
import type { AISystem, CompanyProfile, ContentPack } from './types';
/** Anforderung im Lastenheft. */
interface Requirement {
readonly id: string;
readonly must: boolean;
readonly de: string;
readonly en: string;
readonly fr: string;
readonly it: string;
readonly es: string;
readonly pl: string;
readonly cs: string;
readonly sk: string;
readonly ro: string;
/** Nur bei Hochrisiko aufnehmen. */
readonly highOnly?: boolean;
}
const REQUIREMENTS: readonly Requirement[] = [
{ id: 'REQ-01', must: true, highOnly: true,
de: 'CE-Kennzeichnung und EU-Konformitätserklärung (Art. 47, 48) liegen vor und werden mitgeliefert.',
en: 'CE marking and EU declaration of conformity (Art. 47, 48) exist and are supplied.',
fr: 'Le marquage CE et la déclaration UE de conformité (art. 47, 48) existent et sont fournis.',
it: 'La marcatura CE e la dichiarazione di conformità UE (art. 47, 48) esistono e vengono fornite.',
es: 'El marcado CE y la declaración UE de conformidad (art. 47, 48) existen y se entregan.',
pl: 'Oznakowanie CE i deklaracja zgodności UE (art. 47, 48) istnieją i są dostarczane.',
cs: 'Označení CE a EU prohlášení o shodě (čl. 47, 48) existují a jsou dodávány.',
sk: 'Označenie CE a EÚ vyhlásenie o zhode (čl. 47, 48) existujú a sú dodávané.',
ro: 'Marcajul CE și declarația UE de conformitate (art. 47, 48) există și sunt furnizate.' },
{ id: 'REQ-02', must: true, highOnly: true,
de: 'Registrierung des Systems in der EU-Datenbank (Art. 49) ist nachgewiesen.',
en: 'Registration of the system in the EU database (Art. 49) is evidenced.',
fr: 'Lenregistrement du système dans la base de données de lUE (art. 49) est attesté.',
it: 'La registrazione del sistema nella banca dati dellUE (art. 49) è comprovata.',
es: 'El registro del sistema en la base de datos de la UE (art. 49) está acreditado.',
pl: 'Rejestracja systemu w bazie danych UE (art. 49) jest udokumentowana.',
cs: 'Registrace systému v databázi EU (čl. 49) je doložena.',
sk: 'Registrácia systému v databáze EÚ (čl. 49) je preukázaná.',
ro: 'Înregistrarea sistemului în baza de date a UE (art. 49) este dovedită.' },
{ id: 'REQ-03', must: true,
de: 'Vollständige Betriebsanleitung nach Art. 13 (Zweckbestimmung, Genauigkeit, Grenzen, Aufsicht, Wartung) in der Vertragssprache.',
en: 'Complete instructions for use under Art. 13 (purpose, accuracy, limitations, oversight, maintenance) in the contract language.',
fr: 'Notice dutilisation complète selon lart. 13 (destination, exactitude, limites, contrôle, maintenance) dans la langue du contrat.',
it: 'Istruzioni per luso complete ai sensi dellart. 13 (finalità, accuratezza, limiti, sorveglianza, manutenzione) nella lingua del contratto.',
es: 'Instrucciones de uso completas conforme al art. 13 (finalidad, precisión, limitaciones, supervisión, mantenimiento) en el idioma del contrato.',
pl: 'Kompletna instrukcja obsługi zgodnie z art. 13 (przeznaczenie, dokładność, ograniczenia, nadzór, konserwacja) w języku umowy.',
cs: 'Úplný návod k použití podle čl. 13 (účel, přesnost, omezení, dohled, údržba) v jazyce smlouvy.',
sk: 'Úplný návod na použitie podľa čl. 13 (účel, presnosť, obmedzenia, dohľad, údržba) v jazyku zmluvy.',
ro: 'Instrucțiuni de utilizare complete conform art. 13 (scop, acuratețe, limitări, supraveghere, întreținere) în limba contractului.' },
{ id: 'REQ-04', must: true, highOnly: true,
de: 'Logging-Fähigkeit nach Art. 12: automatische Ereignisprotokolle sind für den Betreiber zugänglich und mind. 6 Monate speicherbar.',
en: 'Logging capability under Art. 12: automatic event logs are accessible to the deployer and storable for at least 6 months.',
fr: 'Capacité de journalisation selon lart. 12 : les journaux dévénements automatiques sont accessibles au déployeur et conservables pendant au moins 6 mois.',
it: 'Capacità di registrazione ai sensi dellart. 12: i log automatici degli eventi sono accessibili al deployer e conservabili per almeno 6 mesi.',
es: 'Capacidad de registro conforme al art. 12: los registros automáticos de eventos son accesibles para el responsable del despliegue y pueden conservarse durante al menos 6 meses.',
pl: 'Zdolność rejestrowania zdarzeń zgodnie z art. 12: automatyczne dzienniki zdarzeń są dostępne dla podmiotu stosującego i mogą być przechowywane przez co najmniej 6 miesięcy.',
cs: 'Schopnost protokolování podle čl. 12: automatické protokoly událostí jsou přístupné zavádějícímu subjektu a lze je uchovávat nejméně 6 měsíců.',
sk: 'Schopnosť protokolovania podľa čl. 12: automatické protokoly udalostí sú prístupné nasadzujúcemu subjektu a možno ich uchovávať najmenej 6 mesiacov.',
ro: 'Capacitate de jurnalizare conform art. 12: jurnalele automate de evenimente sunt accesibile implementatorului și pot fi păstrate cel puțin 6 luni.' },
{ id: 'REQ-05', must: true, highOnly: true,
de: 'Schnittstellen für menschliche Aufsicht nach Art. 14 (Eingriff, Abbruch, Übersteuerung) sind vorhanden und dokumentiert.',
en: 'Human oversight interfaces under Art. 14 (intervention, stop, override) exist and are documented.',
fr: 'Les interfaces de contrôle humain selon lart. 14 (intervention, arrêt, neutralisation) existent et sont documentées.',
it: 'Le interfacce per la sorveglianza umana ai sensi dellart. 14 (intervento, arresto, override) esistono e sono documentate.',
es: 'Existen y están documentadas las interfaces de supervisión humana conforme al art. 14 (intervención, parada, anulación).',
pl: 'Interfejsy nadzoru ludzkiego zgodnie z art. 14 (interwencja, zatrzymanie, przejęcie kontroli) istnieją i są udokumentowane.',
cs: 'Rozhraní pro lidský dohled podle čl. 14 (zásah, zastavení, převzetí řízení) existují a jsou zdokumentována.',
sk: 'Rozhrania pre ľudský dohľad podľa čl. 14 (zásah, zastavenie, prevzatie riadenia) existujú a sú zdokumentované.',
ro: 'Interfețele de supraveghere umană conform art. 14 (intervenție, oprire, preluarea controlului) există și sunt documentate.' },
{ id: 'REQ-06', must: true, highOnly: true,
de: 'Nachweis von Genauigkeit, Robustheit und Cybersicherheit nach Art. 15 inkl. Schutz gegen Prompt Injection, Data Poisoning und Adversarial Attacks.',
en: 'Evidence of accuracy, robustness and cybersecurity under Art. 15 incl. protection against prompt injection, data poisoning and adversarial attacks.',
fr: 'Preuve de lexactitude, de la robustesse et de la cybersécurité selon lart. 15, y compris la protection contre linjection de prompts, lempoisonnement des données et les attaques adverses.',
it: 'Prova di accuratezza, robustezza e cibersicurezza ai sensi dellart. 15, inclusa la protezione contro prompt injection, data poisoning e attacchi avversari.',
es: 'Prueba de precisión, robustez y ciberseguridad conforme al art. 15, incluida la protección contra inyección de instrucciones (prompt injection), envenenamiento de datos y ataques adversarios.',
pl: 'Wykazanie dokładności, solidności i cyberbezpieczeństwa zgodnie z art. 15, w tym ochrony przed prompt injection, zatruwaniem danych (data poisoning) i atakami adwersarialnymi.',
cs: 'Prokázání přesnosti, spolehlivosti a kybernetické bezpečnosti podle čl. 15 vč. ochrany proti prompt injection, otravě dat (data poisoning) a adversariálním útokům.',
sk: 'Preukázanie presnosti, spoľahlivosti a kybernetickej bezpečnosti podľa čl. 15 vrátane ochrany proti prompt injection, otrave dát (data poisoning) a adverzariálnym útokom.',
ro: 'Dovada acurateței, robusteții și securității cibernetice conform art. 15, inclusiv protecția împotriva prompt injection, a otrăvirii datelor (data poisoning) și a atacurilor adversariale.' },
{ id: 'REQ-07', must: true,
de: 'Transparenzfunktionen nach Art. 50 (KI-Offenlegung, maschinenlesbare Kennzeichnung synthetischer Inhalte) sind implementiert, soweit einschlägig.',
en: 'Transparency features under Art. 50 (AI disclosure, machine-readable marking of synthetic content) are implemented where applicable.',
fr: 'Les fonctions de transparence selon lart. 50 (divulgation de lIA, marquage lisible par machine des contenus synthétiques) sont mises en œuvre, le cas échéant.',
it: 'Le funzioni di trasparenza ai sensi dellart. 50 (divulgazione dellIA, marcatura leggibile meccanicamente dei contenuti sintetici) sono implementate, ove pertinente.',
es: 'Las funciones de transparencia conforme al art. 50 (divulgación de IA, marcado legible por máquina de contenidos sintéticos) están implementadas, cuando proceda.',
pl: 'Funkcje przejrzystości zgodnie z art. 50 (ujawnienie AI, nadające się do odczytu maszynowego oznaczanie treści syntetycznych) są wdrożone, o ile mają zastosowanie.',
cs: 'Funkce transparentnosti podle čl. 50 (zveřejnění AI, strojově čitelné označování syntetického obsahu) jsou implementovány, pokud jsou relevantní.',
sk: 'Funkcie transparentnosti podľa čl. 50 (zverejnenie AI, strojovo čitateľné označovanie syntetického obsahu) sú implementované, pokiaľ sú relevantné.',
ro: 'Funcțiile de transparență conform art. 50 (divulgarea IA, marcarea lizibilă automat a conținutului sintetic) sunt implementate, acolo unde este cazul.' },
{ id: 'REQ-08', must: true,
de: 'Unterstützung bei Vorfallmeldungen: Anbieter meldet schwerwiegende Vorfälle (Art. 73) und informiert den Auftraggeber unverzüglich.',
en: 'Incident reporting support: provider reports serious incidents (Art. 73) and informs the customer without undue delay.',
fr: 'Assistance pour la notification des incidents : le fournisseur signale les incidents graves (art. 73) et informe le client sans retard injustifié.',
it: 'Supporto per la segnalazione degli incidenti: il fornitore segnala gli incidenti gravi (art. 73) e informa il committente senza indebito ritardo.',
es: 'Apoyo en la notificación de incidentes: el proveedor notifica los incidentes graves (art. 73) e informa al cliente sin demora indebida.',
pl: 'Wsparcie przy zgłaszaniu incydentów: dostawca zgłasza poważne incydenty (art. 73) i niezwłocznie informuje zamawiającego.',
cs: 'Podpora při hlášení incidentů: poskytovatel hlásí závažné incidenty (čl. 73) a neprodleně informuje zadavatele.',
sk: 'Podpora pri hlásení incidentov: poskytovateľ hlási závažné incidenty (čl. 73) a bezodkladne informuje objednávateľa.',
ro: 'Sprijin pentru raportarea incidentelor: furnizorul raportează incidentele grave (art. 73) și informează fără întârziere clientul.' },
{ id: 'REQ-09', must: true,
de: 'DSGVO-Konformität: Auftragsverarbeitungsvertrag, Angaben zu Datenflüssen, Speicherorten (EU), Unterauftragnehmern und Löschkonzept.',
en: 'GDPR conformity: data processing agreement, information on data flows, storage locations (EU), sub-processors and deletion concept.',
fr: 'Conformité au RGPD : contrat de sous-traitance, informations sur les flux de données, les lieux de stockage (UE), les sous-traitants ultérieurs et le concept de suppression.',
it: 'Conformità al GDPR: contratto di trattamento dei dati, informazioni su flussi di dati, luoghi di archiviazione (UE), sub-responsabili e piano di cancellazione.',
es: 'Conformidad con el RGPD: contrato de encargo de tratamiento, información sobre flujos de datos, ubicaciones de almacenamiento (UE), subencargados y plan de supresión.',
pl: 'Zgodność z RODO: umowa powierzenia przetwarzania, informacje o przepływach danych, miejscach przechowywania (UE), podwykonawcach przetwarzania i koncepcji usuwania danych.',
cs: 'Soulad s GDPR: smlouva o zpracování údajů, informace o tocích dat, místech uložení (EU), dalších zpracovatelích a koncepci výmazu.',
sk: 'Súlad s GDPR: zmluva o spracúvaní údajov, informácie o tokoch dát, miestach uloženia (EÚ), ďalších sprostredkovateľoch a koncepcii vymazania.',
ro: 'Conformitate cu RGPD: contract de prelucrare a datelor, informații privind fluxurile de date, locurile de stocare (UE), subîmputerniciții și conceptul de ștergere.' },
{ id: 'REQ-10', must: false,
de: 'Update- und Support-Zusagen: Sicherheitsupdates, Re-Zertifizierung bei wesentlichen Änderungen, Reaktionszeiten.',
en: 'Update and support commitments: security updates, re-certification upon substantial modification, response times.',
fr: 'Engagements de mise à jour et de support : mises à jour de sécurité, recertification en cas de modification substantielle, délais de réaction.',
it: 'Impegni di aggiornamento e supporto: aggiornamenti di sicurezza, ricertificazione in caso di modifica sostanziale, tempi di risposta.',
es: 'Compromisos de actualización y soporte: actualizaciones de seguridad, recertificación en caso de modificación sustancial, tiempos de respuesta.',
pl: 'Zobowiązania dotyczące aktualizacji i wsparcia: aktualizacje bezpieczeństwa, ponowna certyfikacja przy istotnych zmianach, czasy reakcji.',
cs: 'Závazky týkající se aktualizací a podpory: bezpečnostní aktualizace, recertifikace při podstatné změně, doby odezvy.',
sk: 'Záväzky týkajúce sa aktualizácií a podpory: bezpečnostné aktualizácie, recertifikácia pri podstatnej zmene, reakčné časy.',
ro: 'Angajamente de actualizare și asistență: actualizări de securitate, recertificare în cazul modificărilor substanțiale, timpi de reacție.' },
{ id: 'REQ-11', must: false,
de: 'Exit-Strategie: Datenexport in offenem Format, Übergabe von Konfiguration und Protokollen bei Vertragsende.',
en: 'Exit strategy: data export in an open format, handover of configuration and logs at contract end.',
fr: 'Stratégie de sortie : export des données dans un format ouvert, remise de la configuration et des journaux à la fin du contrat.',
it: 'Strategia di uscita: esportazione dei dati in un formato aperto, consegna della configurazione e dei log alla fine del contratto.',
es: 'Estrategia de salida: exportación de datos en un formato abierto, entrega de la configuración y los registros al finalizar el contrato.',
pl: 'Strategia wyjścia: eksport danych w otwartym formacie, przekazanie konfiguracji i dzienników po zakończeniu umowy.',
cs: 'Strategie ukončení: export dat v otevřeném formátu, předání konfigurace a protokolů při skončení smlouvy.',
sk: 'Stratégia ukončenia: export dát v otvorenom formáte, odovzdanie konfigurácie a protokolov pri skončení zmluvy.',
ro: 'Strategie de ieșire: export de date într-un format deschis, predarea configurației și a jurnalelor la încetarea contractului.' },
{ id: 'REQ-12', must: false, highOnly: true,
de: 'Einsicht in relevante Teile der technischen Dokumentation (Annex IV) unter Vertraulichkeit, soweit für Betreiberpflichten erforderlich.',
en: 'Access to relevant parts of the technical documentation (Annex IV) under confidentiality, insofar as required for deployer duties.',
fr: 'Accès aux parties pertinentes de la documentation technique (annexe IV) sous confidentialité, dans la mesure nécessaire aux obligations du déployeur.',
it: 'Accesso alle parti pertinenti della documentazione tecnica (allegato IV) in regime di riservatezza, nella misura necessaria agli obblighi del deployer.',
es: 'Acceso a las partes pertinentes de la documentación técnica (anexo IV) bajo confidencialidad, en la medida necesaria para las obligaciones del responsable del despliegue.',
pl: 'Wgląd w istotne części dokumentacji technicznej (załącznik IV) z zachowaniem poufności, w zakresie niezbędnym dla obowiązków podmiotu stosującego.',
cs: 'Přístup k relevantním částem technické dokumentace (příloha IV) za podmínek důvěrnosti, v rozsahu nezbytném pro povinnosti zavádějícího subjektu.',
sk: 'Prístup k relevantným častiam technickej dokumentácie (príloha IV) za podmienok dôvernosti, v rozsahu nevyhnutnom pre povinnosti nasadzujúceho subjektu.',
ro: 'Acces la părțile relevante ale documentației tehnice (anexa IV) sub obligație de confidențialitate, în măsura necesară pentru obligațiile implementatorului.' },
];
const PROC = {
de: {
title: 'Lastenheft KI-Beschaffung — AI-Act-Anforderungen an den Anbieter',
intro:
'Dieses Lastenheft definiert die regulatorischen Mindestanforderungen (EU AI Act, DSGVO) an den Anbieter des unten bezeichneten KI-Systems. Es ist Grundlage für Angebot, Pflichtenheft und Vertrag.',
colId: 'Nr.', colReq: 'Anforderung', colPrio: 'Priorität', colFulfilled: 'Erfüllt (Anbieter)',
must: 'MUSS', should: 'SOLL', fulfilled: 'JA / NEIN / TEILWEISE',
note: 'Hinweis: Bei Hochrisiko-Systemen gelten alle MUSS-Anforderungen zwingend; Nichterfüllung schließt die Beauftragung aus.',
},
en: {
title: 'AI procurement requirements specification — AI Act requirements for the provider',
intro:
'This requirements specification defines the minimum regulatory requirements (EU AI Act, GDPR) for the provider of the AI system identified below. It forms the basis for offer, implementation specification and contract.',
colId: 'No.', colReq: 'Requirement', colPrio: 'Priority', colFulfilled: 'Fulfilled (provider)',
must: 'MUST', should: 'SHOULD', fulfilled: 'YES / NO / PARTIALLY',
note: 'Note: For high-risk systems all MUST requirements are mandatory; non-fulfilment excludes the award.',
},
fr: {
title: 'Cahier des charges pour lacquisition dIA — exigences du règlement sur lIA envers le fournisseur',
intro:
'Ce cahier des charges définit les exigences réglementaires minimales (règlement européen sur lIA, RGPD) envers le fournisseur du système dIA désigné ci-dessous. Il sert de base à loffre, aux spécifications de réalisation et au contrat.',
colId: 'N°', colReq: 'Exigence', colPrio: 'Priorité', colFulfilled: 'Rempli (fournisseur)',
must: 'DOIT', should: 'DEVRAIT', fulfilled: 'OUI / NON / PARTIELLEMENT',
note: 'Remarque : pour les systèmes à haut risque, toutes les exigences DOIT sont impératives ; leur non-respect exclut lattribution du marché.',
},
it: {
title: 'Capitolato per lacquisto di IA — requisiti del regolamento sullIA per il fornitore',
intro:
'Questo capitolato definisce i requisiti normativi minimi (regolamento UE sullIA, GDPR) per il fornitore del sistema di IA indicato di seguito. Costituisce la base per offerta, specifiche di attuazione e contratto.',
colId: 'N.', colReq: 'Requisito', colPrio: 'Priorità', colFulfilled: 'Soddisfatto (fornitore)',
must: 'DEVE', should: 'DOVREBBE', fulfilled: 'SÌ / NO / PARZIALMENTE',
note: 'Nota: per i sistemi ad alto rischio tutti i requisiti DEVE sono vincolanti; il mancato soddisfacimento esclude laggiudicazione.',
},
es: {
title: 'Pliego de condiciones para la adquisición de IA — requisitos del Reglamento de IA para el proveedor',
intro:
'Este pliego de condiciones define los requisitos regulatorios mínimos (Reglamento de IA de la UE, RGPD) para el proveedor del sistema de IA indicado a continuación. Constituye la base para la oferta, el pliego de prescripciones técnicas y el contrato.',
colId: 'N.º', colReq: 'Requisito', colPrio: 'Prioridad', colFulfilled: 'Cumplido (proveedor)',
must: 'DEBE', should: 'DEBERÍA', fulfilled: 'SÍ / NO / PARCIALMENTE',
note: 'Nota: en los sistemas de alto riesgo todos los requisitos DEBE son obligatorios; su incumplimiento excluye la adjudicación.',
},
pl: {
title: 'Specyfikacja wymagań dla zakupu AI — wymagania aktu w sprawie AI wobec dostawcy',
intro:
'Niniejsza specyfikacja wymagań określa minimalne wymagania regulacyjne (unijny akt w sprawie AI, RODO) wobec dostawcy wskazanego poniżej systemu AI. Stanowi podstawę oferty, specyfikacji realizacyjnej i umowy.',
colId: 'Nr', colReq: 'Wymaganie', colPrio: 'Priorytet', colFulfilled: 'Spełnione (dostawca)',
must: 'MUSI', should: 'POWINIEN', fulfilled: 'TAK / NIE / CZĘŚCIOWO',
note: 'Uwaga: w przypadku systemów wysokiego ryzyka wszystkie wymagania MUSI są bezwzględnie obowiązujące; ich niespełnienie wyklucza udzielenie zamówienia.',
},
cs: {
title: 'Zadávací dokumentace pro pořízení AI — požadavky aktu o AI na poskytovatele',
intro:
'Tato zadávací dokumentace definuje minimální regulační požadavky (akt EU o AI, GDPR) na poskytovatele níže uvedeného systému AI. Je základem pro nabídku, prováděcí specifikaci a smlouvu.',
colId: 'Č.', colReq: 'Požadavek', colPrio: 'Priorita', colFulfilled: 'Splněno (poskytovatel)',
must: 'MUSÍ', should: 'MĚL BY', fulfilled: 'ANO / NE / ČÁSTEČNĚ',
note: 'Upozornění: u vysoce rizikových systémů jsou všechny požadavky MUSÍ závazné; jejich nesplnění vylučuje zadání zakázky.',
},
sk: {
title: 'Zadávacia dokumentácia pre obstaranie AI — požiadavky aktu o AI na poskytovateľa',
intro:
'Táto zadávacia dokumentácia definuje minimálne regulačné požiadavky (akt EÚ o AI, GDPR) na poskytovateľa nižšie uvedeného systému AI. Je základom pre ponuku, realizačnú špecifikáciu a zmluvu.',
colId: 'Č.', colReq: 'Požiadavka', colPrio: 'Priorita', colFulfilled: 'Splnené (poskytovateľ)',
must: 'MUSÍ', should: 'MAL BY', fulfilled: 'ÁNO / NIE / ČIASTOČNE',
note: 'Upozornenie: pri vysokorizikových systémoch sú všetky požiadavky MUSÍ záväzné; ich nesplnenie vylučuje zadanie zákazky.',
},
ro: {
title: 'Caiet de sarcini pentru achiziția de IA — cerințele Regulamentului privind IA față de furnizor',
intro:
'Acest caiet de sarcini definește cerințele de reglementare minime (Regulamentul UE privind IA, RGPD) față de furnizorul sistemului de IA indicat mai jos. Constituie baza pentru ofertă, specificația de implementare și contract.',
colId: 'Nr.', colReq: 'Cerință', colPrio: 'Prioritate', colFulfilled: 'Îndeplinit (furnizor)',
must: 'TREBUIE', should: 'AR TREBUI', fulfilled: 'DA / NU / PARȚIAL',
note: 'Notă: pentru sistemele cu risc ridicat, toate cerințele TREBUIE sunt obligatorii; neîndeplinirea lor exclude atribuirea contractului.',
},
} as const;
/**
* Erzeugt das Lastenheft für die KI-Beschaffung (Betreiber-Perspektive):
* AI-Act-Anforderungen, die der Anbieter erfüllen und im Pflichtenheft
* beantworten muss.
*
* @param system - Bewertetes KI-System
* @param pack - Regulatorischer Content-Pack
* @param today - Stichtag im ISO-Format
* @param profile - Firmenprofil für den Berichtskopf (optional)
* @param locale - Dokumentsprache (Default: Deutsch)
*/
export function procurementSpec(
system: AISystem,
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const p = PROC[locale];
const high = system.classification.riskClass === 'high';
const requirements = REQUIREMENTS.filter((r) => high || !r.highOnly);
const lines = [
`# ${p.title}`,
'',
`| | |`,
`|---|---|`,
...(profile && profile.name.trim() !== '' ? [`| **${s.meta.company}** | ${profile.name} |`] : []),
`| **${s.meta.system}** | ${system.name} |`,
`| **${s.meta.purpose}** | ${system.purpose || '—'} |`,
`| **${s.meta.riskClass}** | ${s.risk[system.classification.riskClass]} |`,
`| **${s.meta.createdAt}** | ${formatDocDate(today, locale)} |`,
`| **${s.meta.contentPack}** | v${pack.version} |`,
'',
s.disclaimer,
'',
p.intro,
'',
`| ${p.colId} | ${p.colReq} | ${p.colPrio} | ${p.colFulfilled} |`,
'|---|---|---|---|',
];
for (const r of requirements) {
lines.push(`| ${r.id} | ${r[locale]} | ${r.must ? p.must : p.should} | ${p.fulfilled} |`);
}
lines.push('', p.note);
return lines.join('\n');
}
const DECL = {
de: {
title: 'EU-Konformitätserklärung (Entwurf, Art. 47 / Annex V)',
intro:
'Entwurf auf Basis von Annex V der Verordnung (EU) 2024/1689. Vor Verwendung rechtlich prüfen und durch die Geschäftsleitung unterzeichnen.',
fields: [
['1. KI-System (Name, Typ, Version)', ''],
['2. Anbieter (Name und Anschrift)', ''],
['3. Verantwortung', 'Die alleinige Verantwortung für die Ausstellung dieser Konformitätserklärung trägt der Anbieter.'],
['4. Gegenstand der Erklärung', 'Das oben bezeichnete KI-System steht im Einklang mit der Verordnung (EU) 2024/1689 und ggf. weiteren einschlägigen Harmonisierungsvorschriften der Union.'],
['5. Angewandte harmonisierte Normen / gemeinsame Spezifikationen', '_[AUSFÜLLEN]_'],
['6. Notifizierte Stelle (falls einschlägig)', 'Name, Kennnummer, Bescheinigung: _[AUSFÜLLEN]_'],
['7. DSGVO-Erklärung (falls personenbezogene Daten verarbeitet werden)', 'Das System entspricht den Verordnungen (EU) 2016/679 und (EU) 2018/1725 bzw. der Richtlinie (EU) 2016/680.'],
['8. Ort, Datum der Ausstellung', '_[AUSFÜLLEN]_'],
['9. Unterzeichnet für und im Namen von', 'Name, Funktion, Unterschrift: _[AUSFÜLLEN]_'],
],
},
en: {
title: 'EU declaration of conformity (draft, Art. 47 / Annex V)',
intro:
'Draft based on Annex V of Regulation (EU) 2024/1689. Have it legally reviewed and signed by management before use.',
fields: [
['1. AI system (name, type, version)', ''],
['2. Provider (name and address)', ''],
['3. Responsibility', 'This declaration of conformity is issued under the sole responsibility of the provider.'],
['4. Object of the declaration', 'The AI system identified above is in conformity with Regulation (EU) 2024/1689 and, where applicable, other relevant Union harmonisation legislation.'],
['5. Applied harmonised standards / common specifications', '_[TO BE COMPLETED]_'],
['6. Notified body (where applicable)', 'Name, identification number, certificate: _[TO BE COMPLETED]_'],
['7. GDPR statement (where personal data is processed)', 'The system complies with Regulations (EU) 2016/679 and (EU) 2018/1725 or Directive (EU) 2016/680.'],
['8. Place and date of issue', '_[TO BE COMPLETED]_'],
['9. Signed for and on behalf of', 'Name, function, signature: _[TO BE COMPLETED]_'],
],
},
fr: {
title: 'Déclaration UE de conformité (projet, art. 47 / annexe V)',
intro:
'Projet fondé sur lannexe V du règlement (UE) 2024/1689. À faire vérifier juridiquement et signer par la direction avant utilisation.',
fields: [
['1. Système dIA (nom, type, version)', ''],
['2. Fournisseur (nom et adresse)', ''],
['3. Responsabilité', 'La présente déclaration de conformité est établie sous la seule responsabilité du fournisseur.'],
['4. Objet de la déclaration', 'Le système dIA désigné ci-dessus est conforme au règlement (UE) 2024/1689 et, le cas échéant, aux autres actes législatifs dharmonisation de lUnion applicables.'],
['5. Normes harmonisées appliquées / spécifications communes', '_[À COMPLÉTER]_'],
['6. Organisme notifié (le cas échéant)', 'Nom, numéro didentification, certificat : _[À COMPLÉTER]_'],
['7. Déclaration RGPD (si des données à caractère personnel sont traitées)', 'Le système est conforme aux règlements (UE) 2016/679 et (UE) 2018/1725 ou à la directive (UE) 2016/680.'],
['8. Lieu et date de délivrance', '_[À COMPLÉTER]_'],
['9. Signé par et au nom de', 'Nom, fonction, signature : _[À COMPLÉTER]_'],
],
},
it: {
title: 'Dichiarazione di conformità UE (bozza, art. 47 / allegato V)',
intro:
'Bozza basata sullallegato V del regolamento (UE) 2024/1689. Da sottoporre a verifica legale e far firmare dalla direzione prima delluso.',
fields: [
['1. Sistema di IA (nome, tipo, versione)', ''],
['2. Fornitore (nome e indirizzo)', ''],
['3. Responsabilità', 'La presente dichiarazione di conformità è rilasciata sotto la responsabilità esclusiva del fornitore.'],
['4. Oggetto della dichiarazione', 'Il sistema di IA sopra indicato è conforme al regolamento (UE) 2024/1689 e, ove applicabile, ad altre normative di armonizzazione dellUnione pertinenti.'],
['5. Norme armonizzate applicate / specifiche comuni', '_[DA COMPLETARE]_'],
['6. Organismo notificato (se applicabile)', 'Nome, numero di identificazione, certificato: _[DA COMPLETARE]_'],
['7. Dichiarazione GDPR (se vengono trattati dati personali)', 'Il sistema è conforme ai regolamenti (UE) 2016/679 e (UE) 2018/1725 o alla direttiva (UE) 2016/680.'],
['8. Luogo e data di rilascio', '_[DA COMPLETARE]_'],
['9. Firmato a nome e per conto di', 'Nome, funzione, firma: _[DA COMPLETARE]_'],
],
},
es: {
title: 'Declaración UE de conformidad (borrador, art. 47 / anexo V)',
intro:
'Borrador basado en el anexo V del Reglamento (UE) 2024/1689. Debe someterse a revisión jurídica y ser firmado por la dirección antes de su uso.',
fields: [
['1. Sistema de IA (nombre, tipo, versión)', ''],
['2. Proveedor (nombre y dirección)', ''],
['3. Responsabilidad', 'La presente declaración de conformidad se expide bajo la exclusiva responsabilidad del proveedor.'],
['4. Objeto de la declaración', 'El sistema de IA arriba indicado es conforme con el Reglamento (UE) 2024/1689 y, en su caso, con otra legislación de armonización de la Unión aplicable.'],
['5. Normas armonizadas aplicadas / especificaciones comunes', '_[POR COMPLETAR]_'],
['6. Organismo notificado (en su caso)', 'Nombre, número de identificación, certificado: _[POR COMPLETAR]_'],
['7. Declaración RGPD (si se tratan datos personales)', 'El sistema cumple los Reglamentos (UE) 2016/679 y (UE) 2018/1725 o la Directiva (UE) 2016/680.'],
['8. Lugar y fecha de expedición', '_[POR COMPLETAR]_'],
['9. Firmado en nombre y por cuenta de', 'Nombre, cargo, firma: _[POR COMPLETAR]_'],
],
},
pl: {
title: 'Deklaracja zgodności UE (projekt, art. 47 / załącznik V)',
intro:
'Projekt na podstawie załącznika V rozporządzenia (UE) 2024/1689. Przed użyciem poddać weryfikacji prawnej i przedłożyć zarządowi do podpisu.',
fields: [
['1. System AI (nazwa, typ, wersja)', ''],
['2. Dostawca (nazwa i adres)', ''],
['3. Odpowiedzialność', 'Niniejsza deklaracja zgodności wydawana jest na wyłączną odpowiedzialność dostawcy.'],
['4. Przedmiot deklaracji', 'Wskazany powyżej system AI jest zgodny z rozporządzeniem (UE) 2024/1689 oraz, w stosownych przypadkach, z innym właściwym unijnym prawodawstwem harmonizacyjnym.'],
['5. Zastosowane normy zharmonizowane / wspólne specyfikacje', '_[DO UZUPEŁNIENIA]_'],
['6. Jednostka notyfikowana (w stosownych przypadkach)', 'Nazwa, numer identyfikacyjny, certyfikat: _[DO UZUPEŁNIENIA]_'],
['7. Oświadczenie RODO (jeżeli przetwarzane są dane osobowe)', 'System jest zgodny z rozporządzeniami (UE) 2016/679 i (UE) 2018/1725 lub dyrektywą (UE) 2016/680.'],
['8. Miejsce i data wydania', '_[DO UZUPEŁNIENIA]_'],
['9. Podpisano w imieniu i na rzecz', 'Imię i nazwisko, funkcja, podpis: _[DO UZUPEŁNIENIA]_'],
],
},
cs: {
title: 'EU prohlášení o shodě (návrh, čl. 47 / příloha V)',
intro:
'Návrh na základě přílohy V nařízení (EU) 2024/1689. Před použitím nechat právně ověřit a podepsat vedením.',
fields: [
['1. Systém AI (název, typ, verze)', ''],
['2. Poskytovatel (název a adresa)', ''],
['3. Odpovědnost', 'Toto prohlášení o shodě se vydává na výhradní odpovědnost poskytovatele.'],
['4. Předmět prohlášení', 'Výše uvedený systém AI je ve shodě s nařízením (EU) 2024/1689 a případně s dalšími příslušnými harmonizačními právními předpisy Unie.'],
['5. Použité harmonizované normy / společné specifikace', '_[DOPLNIT]_'],
['6. Oznámený subjekt (přichází-li v úvahu)', 'Název, identifikační číslo, certifikát: _[DOPLNIT]_'],
['7. Prohlášení GDPR (jsou-li zpracovávány osobní údaje)', 'Systém je v souladu s nařízeními (EU) 2016/679 a (EU) 2018/1725, resp. se směrnicí (EU) 2016/680.'],
['8. Místo a datum vydání', '_[DOPLNIT]_'],
['9. Podepsáno za a jménem', 'Jméno, funkce, podpis: _[DOPLNIT]_'],
],
},
sk: {
title: 'EÚ vyhlásenie o zhode (návrh, čl. 47 / príloha V)',
intro:
'Návrh na základe prílohy V nariadenia (EÚ) 2024/1689. Pred použitím nechať právne overiť a podpísať vedením.',
fields: [
['1. Systém AI (názov, typ, verzia)', ''],
['2. Poskytovateľ (názov a adresa)', ''],
['3. Zodpovednosť', 'Toto vyhlásenie o zhode sa vydáva na výhradnú zodpovednosť poskytovateľa.'],
['4. Predmet vyhlásenia', 'Vyššie uvedený systém AI je v zhode s nariadením (EÚ) 2024/1689 a prípadne s ďalšími príslušnými harmonizačnými právnymi predpismi Únie.'],
['5. Použité harmonizované normy / spoločné špecifikácie', '_[DOPLNIŤ]_'],
['6. Notifikovaná osoba (ak je to relevantné)', 'Názov, identifikačné číslo, certifikát: _[DOPLNIŤ]_'],
['7. Vyhlásenie GDPR (ak sa spracúvajú osobné údaje)', 'Systém je v súlade s nariadeniami (EÚ) 2016/679 a (EÚ) 2018/1725, resp. so smernicou (EÚ) 2016/680.'],
['8. Miesto a dátum vydania', '_[DOPLNIŤ]_'],
['9. Podpísané za a v mene', 'Meno, funkcia, podpis: _[DOPLNIŤ]_'],
],
},
ro: {
title: 'Declarație UE de conformitate (proiect, art. 47 / anexa V)',
intro:
'Proiect pe baza anexei V la Regulamentul (UE) 2024/1689. Înainte de utilizare, a se supune verificării juridice și semnării de către conducere.',
fields: [
['1. Sistem de IA (denumire, tip, versiune)', ''],
['2. Furnizor (denumire și adresă)', ''],
['3. Responsabilitate', 'Prezenta declarație de conformitate este emisă pe răspunderea exclusivă a furnizorului.'],
['4. Obiectul declarației', 'Sistemul de IA indicat mai sus este în conformitate cu Regulamentul (UE) 2024/1689 și, după caz, cu alte acte legislative de armonizare ale Uniunii aplicabile.'],
['5. Standarde armonizate aplicate / specificații comune', '_[DE COMPLETAT]_'],
['6. Organism notificat (după caz)', 'Denumire, număr de identificare, certificat: _[DE COMPLETAT]_'],
['7. Declarație RGPD (dacă se prelucrează date cu caracter personal)', 'Sistemul respectă Regulamentele (UE) 2016/679 și (UE) 2018/1725 sau Directiva (UE) 2016/680.'],
['8. Locul și data emiterii', '_[DE COMPLETAT]_'],
['9. Semnat pentru și în numele', 'Nume, funcție, semnătură: _[DE COMPLETAT]_'],
],
},
} as const;
/**
* Erzeugt den Entwurf der EU-Konformitätserklärung (Anbieter, Hochrisiko).
*
* @param system - Bewertetes KI-System
* @param pack - Regulatorischer Content-Pack
* @param today - Stichtag im ISO-Format
* @param profile - Firmenprofil (Anbieterangaben werden vorbefüllt)
* @param locale - Dokumentsprache (Default: Deutsch)
*/
export function conformityDeclaration(
system: AISystem,
_pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const d = DECL[locale];
const provider =
profile && profile.name.trim() !== ''
? [profile.name, profile.street, profile.zipCity].filter((x) => x.trim() !== '').join(', ')
: s.todo;
const lines = [`# ${d.title}`, '', s.disclaimer, '', d.intro, ''];
for (const [label, preset] of d.fields) {
let value: string = preset;
if (label.startsWith('1.')) value = `${system.name}${system.purpose ? `${system.purpose}` : ''}`;
if (label.startsWith('2.')) value = provider;
if (label.startsWith('8.')) value = `${profile?.zipCity ?? ''} ${formatDocDate(today, locale)}`.trim();
lines.push(`## ${label}`, '', value || s.todo, '');
}
return lines.join('\n');
}

View File

@ -0,0 +1,185 @@
import { describe, expect, it } from 'vitest';
import { CONTENT_PACK, getContentPack } from '../content/pack';
import { buildChecklist } from './checklist';
import { classify } from './classify';
import { conformityDeclaration, procurementSpec } from './extraDocs';
import { deriveObligations } from './obligations';
import type { AISystem, AssessmentAnswers, CompanyProfile } from './types';
const base: AssessmentAnswers = {
isAISystem: true,
role: 'deployer',
isGPAIModel: false,
prohibitedPractices: [],
annexIIICategories: [],
art63Exception: false,
involvesProfiling: false,
isAnnexISafetyComponent: false,
transparencyTriggers: [],
};
const profile: CompanyProfile = {
name: 'Muster GmbH',
street: 'Musterstraße 1',
zipCity: '60311 Frankfurt',
contactPerson: '',
email: '',
phone: '',
website: '',
logoDataUrl: '',
countries: ['DE', 'IT'],
};
function makeSystem(answers: AssessmentAnswers, locale: 'de' | 'en' = 'de'): AISystem {
return {
id: 'sys-1',
name: 'HR-Screening',
purpose: 'Bewerbervorauswahl',
vendor: 'Beispiel GmbH',
owner: 'Jane Doe',
createdAt: '2026-07-01T00:00:00.000Z',
updatedAt: '2026-07-01T00:00:00.000Z',
answers,
classification: classify(answers, getContentPack(locale), locale),
obligationStatus: {},
};
}
describe('mehrsprachiger Content-Pack', () => {
it('liefert identische IDs und Strukturen in DE und EN', () => {
const de = getContentPack('de');
const en = getContentPack('en');
expect(en.obligations.map((o) => o.id)).toEqual(de.obligations.map((o) => o.id));
expect(en.national.map((n) => n.code)).toEqual(de.national.map((n) => n.code));
expect(en.prohibitedPractices).toHaveLength(de.prohibitedPractices.length);
});
it('übersetzt Inhalte tatsächlich (kein deutscher Text im EN-Pack)', () => {
const en = getContentPack('en');
const literacy = en.obligations.find((o) => o.id === 'ob-ai-literacy');
expect(literacy?.title).toBe('Ensure AI literacy of staff');
expect(en.national.find((n) => n.code === 'DE')?.country).toBe('Germany');
});
it('klassifiziert mit englischen Begründungen', () => {
const result = classify(
{ ...base, annexIIICategories: ['a3-employment'] },
getContentPack('en'),
'en',
);
expect(result.riskClass).toBe('high');
expect(result.reasons[0]).toContain('Annex III area');
});
it('liefert für FR/IT/ES vollständig übersetzte Rechtstexte', () => {
const en = getContentPack('en');
for (const locale of ['fr', 'it', 'es', 'pl', 'cs', 'sk', 'ro'] as const) {
const pack = getContentPack(locale);
expect(pack.obligations.map((o) => o.id)).toEqual(en.obligations.map((o) => o.id));
// Tatsächlich übersetzt, nicht EN-Fallback:
expect(pack.obligations[0]?.title).not.toBe(en.obligations[0]?.title);
expect(pack.deadlines[0]?.description).not.toBe(en.deadlines[0]?.description);
const result = classify({ ...base, annexIIICategories: ['a3-employment'] }, pack, locale);
expect(result.riskClass).toBe('high');
expect(result.reasons[0]).not.toContain('Annex III area'); // nicht mehr EN
}
});
});
describe('UI-Wörterbücher FR/IT/ES', () => {
it('sind vollständig (gleiche Schlüssel wie Deutsch)', async () => {
const { uiStrings } = await import('../i18n/ui');
const deKeys = Object.keys(uiStrings('de')).sort();
for (const locale of ['fr', 'it', 'es', 'pl', 'cs', 'sk', 'ro'] as const) {
const dict = uiStrings(locale) as Record<string, string>;
expect(Object.keys(dict).sort()).toEqual(deKeys);
// Stichprobe: tatsächlich übersetzt, nicht kopiert
expect(dict['btnSave']).not.toBe(uiStrings('de').btnSave);
}
});
});
describe('nationale Module', () => {
const answers: AssessmentAnswers = { ...base, annexIIICategories: ['a3-employment'] };
it('ergänzt deutsche und italienische Pflichten bei aktivierten Modulen', () => {
const classification = classify(answers, CONTENT_PACK);
const ids = deriveObligations(classification, answers, CONTENT_PACK, ['DE', 'IT']).map((o) => o.id);
expect(ids).toContain('de-betrvg');
expect(ids).toContain('it-l132-workers');
expect(ids).not.toContain('es-aesia');
});
it('liefert ohne Länderauswahl nur EU-Pflichten', () => {
const classification = classify(answers, CONTENT_PACK);
const ids = deriveObligations(classification, answers, CONTENT_PACK).map((o) => o.id);
expect(ids.some((id) => id.startsWith('de-') || id.startsWith('it-'))).toBe(false);
});
it('respektiert Rolle und Risikoklasse auch bei nationalen Pflichten', () => {
const providerAnswers: AssessmentAnswers = { ...answers, role: 'provider' };
const classification = classify(providerAnswers, CONTENT_PACK);
const ids = deriveObligations(classification, providerAnswers, CONTENT_PACK, ['DE']).map((o) => o.id);
expect(ids).not.toContain('de-betrvg'); // nur Betreiber
expect(ids).toContain('de-kimig-authority');
});
it('enthält neue EU-Pflichten (Art. 72/73) für Hochrisiko-Anbieter', () => {
const providerAnswers: AssessmentAnswers = { ...answers, role: 'provider' };
const classification = classify(providerAnswers, CONTENT_PACK);
const ids = deriveObligations(classification, providerAnswers, CONTENT_PACK).map((o) => o.id);
expect(ids).toContain('ob-postmarket');
expect(ids).toContain('ob-incident');
expect(ids).toContain('ob-corrective');
});
});
describe('buildChecklist', () => {
it('gruppiert nach fällig / anstehend / erledigt und zählt Fortschritt', () => {
const system = makeSystem({ ...base, annexIIICategories: ['a3-employment'] });
const withStatus: AISystem = {
...system,
obligationStatus: { 'ob-ai-literacy': 'done' },
};
const checklist = buildChecklist([withStatus], CONTENT_PACK, ['DE'], '2026-07-04');
expect(checklist.total).toBeGreaterThan(5);
expect(checklist.resolvedCount).toBe(1);
// KI-Kompetenz (2025) ist erledigt; BetrVG (2025) ist fällig
expect(checklist.dueNow.some((e) => e.obligation.id === 'de-betrvg')).toBe(true);
// Art.-26-Pflichten (2027) stehen an
expect(checklist.upcoming.some((e) => e.obligation.id === 'ob-deployer-oversight')).toBe(true);
expect(checklist.resolved[0]?.obligation.id).toBe('ob-ai-literacy');
});
it('ist leer ohne Systeme', () => {
const checklist = buildChecklist([], CONTENT_PACK, [], '2026-07-04');
expect(checklist.total).toBe(0);
});
});
describe('Zusatzdokumente', () => {
it('Lastenheft enthält MUSS-Anforderungen und Hochrisiko-Punkte', () => {
const system = makeSystem({ ...base, annexIIICategories: ['a3-employment'] });
const md = procurementSpec(system, CONTENT_PACK, '2026-07-04', profile);
expect(md).toContain('Lastenheft');
expect(md).toContain('REQ-01');
expect(md).toContain('MUSS');
expect(md).toContain('keine Rechtsberatung');
});
it('Lastenheft lässt Hochrisiko-Anforderungen bei limited weg', () => {
const system = makeSystem({ ...base, transparencyTriggers: ['tr-chatbot'] });
const md = procurementSpec(system, CONTENT_PACK, '2026-07-04', profile);
expect(md).not.toContain('REQ-01'); // CE-Kennzeichnung nur Hochrisiko
expect(md).toContain('REQ-03'); // Betriebsanleitung immer
});
it('Konformitätserklärung füllt Anbieter aus dem Profil vor (EN)', () => {
const system = makeSystem({ ...base, role: 'provider', annexIIICategories: ['a3-employment'] }, 'en');
const md = conformityDeclaration(system, getContentPack('en'), '2026-07-04', profile, 'en');
expect(md).toContain('EU declaration of conformity');
expect(md).toContain('Muster GmbH, Musterstraße 1, 60311 Frankfurt');
expect(md).toContain('not legal advice');
});
});

View File

@ -0,0 +1,105 @@
import { describe, expect, it } from 'vitest';
import { CONTENT_PACK, getContentPack } from '../content/pack';
import { buildChecklist } from './checklist';
import { checklistIcs } from './ics';
import { classify } from './classify';
import type { AISystem, AssessmentAnswers } from './types';
const answers: AssessmentAnswers = {
isAISystem: true,
role: 'deployer',
isGPAIModel: false,
prohibitedPractices: [],
annexIIICategories: ['a3-employment'],
art63Exception: false,
involvesProfiling: false,
isAnnexISafetyComponent: false,
transparencyTriggers: [],
};
const system: AISystem = {
id: 'sys-1',
name: 'Bewerber-Screening; GmbH, Test',
purpose: 'Vorauswahl',
vendor: '',
owner: '',
createdAt: '2026-07-01T00:00:00.000Z',
updatedAt: '2026-07-01T00:00:00.000Z',
answers,
classification: classify(answers, CONTENT_PACK),
obligationStatus: {},
};
const TODAY = '2026-07-04';
const TIMESTAMP = '2026-07-04T12:00:00.000Z';
function makeIcs(): string {
const checklist = buildChecklist([system], CONTENT_PACK, ['DE'], TODAY);
return checklistIcs({
entries: [...checklist.dueNow, ...checklist.upcoming],
deadlines: CONTENT_PACK.deadlines,
today: TODAY,
timestamp: TIMESTAMP,
calendarName: 'AI-Act-Kompass',
});
}
describe('checklistIcs', () => {
it('erzeugt einen gültigen VCALENDAR-Rahmen mit CRLF', () => {
const ics = makeIcs();
expect(ics.startsWith('BEGIN:VCALENDAR\r\n')).toBe(true);
expect(ics.endsWith('END:VCALENDAR\r\n')).toBe(true);
expect(ics).toContain('VERSION:2.0');
expect(ics).toContain('X-WR-CALNAME:AI-Act-Kompass');
expect(ics.includes('\n') && !ics.replace(/\r\n/g, '').includes('\n')).toBe(true);
});
it('exportiert nur zukünftige Fristen als ganztägige Termine mit stabiler UID', () => {
const ics = makeIcs();
// Art.-26-Pflichten (2027-12-02) sind enthalten …
expect(ics).toContain('DTSTART;VALUE=DATE:20271202');
expect(ics).toContain('DTEND;VALUE=DATE:20271203');
expect(ics).toContain('UID:sys-1-ob-deployer-oversight@ai-act-kompass');
// … verstrichene (KI-Kompetenz 2025-02-02) nicht:
expect(ics).not.toContain('DTSTART;VALUE=DATE:20250202');
// Allgemeine zukünftige Geltungsfristen sind enthalten:
expect(ics).toContain('UID:deadline-dl-annex3@ai-act-kompass');
});
it('setzt zwei Erinnerungen (30 und 7 Tage vorher) je Termin', () => {
const ics = makeIcs();
const eventCount = (ics.match(/BEGIN:VEVENT/g) ?? []).length;
expect((ics.match(/TRIGGER:-P30D/g) ?? []).length).toBe(eventCount);
expect((ics.match(/TRIGGER:-P7D/g) ?? []).length).toBe(eventCount);
expect(eventCount).toBeGreaterThan(3);
});
it('maskiert Sonderzeichen und faltet lange Zeilen RFC-konform', () => {
const ics = makeIcs();
// Systemname enthält ; und , — müssen maskiert sein:
expect(ics).toContain('Bewerber-Screening\\;');
expect(ics.replace(/\r\n /g, '')).toContain('GmbH\\, Test');
// Keine entfaltete Zeile länger als 75 Oktette:
for (const line of ics.split('\r\n')) {
expect(new TextEncoder().encode(line).length).toBeLessThanOrEqual(75);
}
});
it('lokalisiert Termintitel über den Content-Pack', () => {
const packFr = getContentPack('fr');
const checklist = buildChecklist(
[{ ...system, classification: classify(answers, packFr, 'fr') }],
packFr,
[],
TODAY,
);
const ics = checklistIcs({
entries: [...checklist.dueNow, ...checklist.upcoming],
deadlines: packFr.deadlines,
today: TODAY,
timestamp: TIMESTAMP,
calendarName: 'AI-Act-Kompass',
});
expect(ics.replace(/\r\n /g, '')).toContain('contrôle humain');
});
});

View File

@ -0,0 +1,157 @@
import type { ChecklistEntry } from './checklist';
import type { Deadline } from './types';
/**
* iCalendar-Export (RFC 5545) für Fristen und Pflichten.
*
* Erzeugt eine .ics-Datei mit ganztägigen Terminen und eingebauten
* Erinnerungen (VALARM, 30 und 7 Tage vor Fälligkeit). Die Datei lässt
* sich in Outlook, Apple Kalender, Google Kalender, Thunderbird u. a.
* importieren auf Smartphone und Desktop, komplett ohne Server.
*/
/** Erinnerungszeitpunkte in Tagen vor der Frist. */
const ALARM_DAYS_BEFORE: readonly number[] = [30, 7];
/** Maskiert Text nach RFC 5545 (Backslash, Semikolon, Komma, Zeilenumbruch). */
function escapeIcs(text: string): string {
return text
.replaceAll('\\', '\\\\')
.replaceAll(';', '\\;')
.replaceAll(',', '\\,')
.replaceAll('\r\n', '\\n')
.replaceAll('\n', '\\n');
}
/**
* Faltet eine Content-Zeile nach RFC 5545 (max. 75 Oktette je Zeile,
* Fortsetzungszeilen beginnen mit einem Leerzeichen).
*/
function foldLine(line: string): string {
const bytes = new TextEncoder().encode(line);
if (bytes.length <= 75) return line;
const parts: string[] = [];
let current = '';
let currentBytes = 0;
for (const char of line) {
const charBytes = new TextEncoder().encode(char).length;
const limit = parts.length === 0 ? 75 : 74; // Folgezeilen: 1 Oktett für das Leerzeichen
if (currentBytes + charBytes > limit) {
parts.push(current);
current = char;
currentBytes = charBytes;
} else {
current += char;
currentBytes += charBytes;
}
}
if (current !== '') parts.push(current);
return parts.join('\r\n ');
}
/** YYYY-MM-DD → YYYYMMDD (DATE-Wert nach RFC 5545). */
function toIcsDate(isoDate: string): string {
return isoDate.replaceAll('-', '');
}
/** ISO-Zeitstempel → YYYYMMDDTHHMMSSZ (UTC, DTSTAMP). */
function toIcsTimestamp(isoDateTime: string): string {
return `${isoDateTime.slice(0, 19).replace(/[-:]/g, '')}Z`;
}
/** Folgetag eines ISO-Datums (DTEND ganztägiger Termine ist exklusiv). */
function nextDay(isoDate: string): string {
const [y, m, d] = isoDate.split('-').map(Number);
const date = new Date(Date.UTC(y ?? 1970, (m ?? 1) - 1, d ?? 1));
date.setUTCDate(date.getUTCDate() + 1);
return date.toISOString().slice(0, 10);
}
interface IcsEvent {
readonly uid: string;
readonly date: string;
readonly summary: string;
readonly description: string;
}
function eventBlock(event: IcsEvent, dtstamp: string): readonly string[] {
const lines = [
'BEGIN:VEVENT',
`UID:${event.uid}`,
`DTSTAMP:${dtstamp}`,
`DTSTART;VALUE=DATE:${toIcsDate(event.date)}`,
`DTEND;VALUE=DATE:${toIcsDate(nextDay(event.date))}`,
`SUMMARY:${escapeIcs(event.summary)}`,
`DESCRIPTION:${escapeIcs(event.description)}`,
'CATEGORIES:AI-Act-Kompass',
'TRANSP:TRANSPARENT',
];
for (const days of ALARM_DAYS_BEFORE) {
lines.push(
'BEGIN:VALARM',
'ACTION:DISPLAY',
`TRIGGER:-P${days}D`,
`DESCRIPTION:${escapeIcs(event.summary)}`,
'END:VALARM',
);
}
lines.push('END:VEVENT');
return lines;
}
/** Parameter für {@link checklistIcs}. */
export interface ChecklistIcsParams {
/** Offene Aufgaben (fällig + anstehend) aus der Checkliste. */
readonly entries: readonly ChecklistEntry[];
/** Allgemeine Geltungsfristen des AI Act (Content-Pack). */
readonly deadlines: readonly Deadline[];
/** Stichtag im ISO-Format — nur Termine ab diesem Tag werden exportiert. */
readonly today: string;
/** Erzeugungszeitpunkt (ISO-Datetime) für DTSTAMP. */
readonly timestamp: string;
/** Anzeigename des Kalenders. */
readonly calendarName: string;
}
/**
* Erzeugt eine iCalendar-Datei mit allen zukünftigen Pflicht-Fristen
* (je System) und den allgemeinen AI-Act-Geltungsfristen jeweils als
* ganztägiger Termin mit Erinnerungen 30 und 7 Tage vorher.
*
* @returns Inhalt der .ics-Datei (CRLF-Zeilenenden, RFC-5545-Faltung)
*/
export function checklistIcs(params: ChecklistIcsParams): string {
const dtstamp = toIcsTimestamp(params.timestamp);
const taskEvents: IcsEvent[] = params.entries
.filter((e) => e.obligation.deadline >= params.today)
.map((e) => ({
uid: `${e.systemId}-${e.obligation.id}@ai-act-kompass`,
date: e.obligation.deadline,
summary: `AI Act: ${e.obligation.title}${e.systemName}`,
description: `${e.obligation.articles} · ${e.obligation.description}\n\nAI-Act-Kompass`,
}));
const deadlineEvents: IcsEvent[] = params.deadlines
.filter((d) => d.date >= params.today)
.map((d) => ({
uid: `deadline-${d.id}@ai-act-kompass`,
date: d.date,
summary: `AI Act: ${d.label}`,
description: `${d.description}\n\nAI-Act-Kompass`,
}));
const lines = [
'BEGIN:VCALENDAR',
'VERSION:2.0',
'PRODID:-//AI-Act-Kompass//Compliance Reminders//DE',
'CALSCALE:GREGORIAN',
'METHOD:PUBLISH',
`X-WR-CALNAME:${escapeIcs(params.calendarName)}`,
...[...taskEvents, ...deadlineEvents].flatMap((e) => eventBlock(e, dtstamp)),
'END:VCALENDAR',
];
return lines.map(foldLine).join('\r\n') + '\r\n';
}

View File

@ -0,0 +1,92 @@
import { describe, expect, it } from 'vitest';
import { CONTENT_PACK } from '../content/pack';
import { classify } from './classify';
import { deriveObligations, nextDeadline } from './obligations';
import type { AssessmentAnswers } from './types';
const base: AssessmentAnswers = {
isAISystem: true,
role: 'deployer',
isGPAIModel: false,
prohibitedPractices: [],
annexIIICategories: [],
art63Exception: false,
involvesProfiling: false,
isAnnexISafetyComponent: false,
transparencyTriggers: [],
};
function obligationsFor(answers: AssessmentAnswers): readonly string[] {
const classification = classify(answers, CONTENT_PACK);
return deriveObligations(classification, answers, CONTENT_PACK).map((o) => o.id);
}
describe('deriveObligations', () => {
it('liefert keine Pflichten für verbotene Systeme', () => {
expect(obligationsFor({ ...base, prohibitedPractices: ['proh-social-scoring'] })).toEqual([]);
});
it('liefert keine Pflichten für out-of-scope', () => {
expect(obligationsFor({ ...base, isAISystem: false })).toEqual([]);
});
it('liefert Anbieter-Pflichten für Hochrisiko-Anbieter (Art. 917, 43 ff.)', () => {
const ids = obligationsFor({
...base,
role: 'provider',
annexIIICategories: ['a3-employment'],
});
expect(ids).toContain('ob-risk-mgmt');
expect(ids).toContain('ob-tech-doc');
expect(ids).toContain('ob-conformity');
expect(ids).not.toContain('ob-deployer-oversight');
});
it('liefert Betreiber-Pflichten für Hochrisiko-Betreiber (Art. 26)', () => {
const ids = obligationsFor({ ...base, annexIIICategories: ['a3-employment'] });
expect(ids).toContain('ob-deployer-oversight');
expect(ids).toContain('ob-deployer-workers');
expect(ids).not.toContain('ob-risk-mgmt');
});
it('liefert Transparenzpflicht für Chatbots (limited)', () => {
const ids = obligationsFor({ ...base, transparencyTriggers: ['tr-chatbot'] });
expect(ids).toContain('ob-transparency-art50');
expect(ids).toContain('ob-ai-literacy');
});
it('liefert GPAI-Pflichten nur für Anbieter mit GPAI-Flag', () => {
expect(obligationsFor({ ...base, role: 'provider', isGPAIModel: true })).toContain('ob-gpai');
expect(obligationsFor({ ...base, isGPAIModel: true })).not.toContain('ob-gpai');
expect(obligationsFor({ ...base, role: 'provider' })).not.toContain('ob-gpai');
});
it('sortiert Pflichten nach Frist aufsteigend', () => {
const answers: AssessmentAnswers = {
...base,
annexIIICategories: ['a3-employment'],
transparencyTriggers: ['tr-chatbot'],
};
const classification = classify(answers, CONTENT_PACK);
const deadlines = deriveObligations(classification, answers, CONTENT_PACK).map(
(o) => o.deadline,
);
expect(deadlines).toEqual([...deadlines].sort());
});
});
describe('nextDeadline', () => {
it('findet die nächste bevorstehende Frist', () => {
const answers: AssessmentAnswers = { ...base, annexIIICategories: ['a3-employment'] };
const classification = classify(answers, CONTENT_PACK);
const obligations = deriveObligations(classification, answers, CONTENT_PACK);
expect(nextDeadline(obligations, '2026-07-04')).toBe('2027-12-02');
});
it('liefert null, wenn alle Fristen verstrichen sind', () => {
const answers: AssessmentAnswers = { ...base, annexIIICategories: ['a3-employment'] };
const classification = classify(answers, CONTENT_PACK);
const obligations = deriveObligations(classification, answers, CONTENT_PACK);
expect(nextDeadline(obligations, '2030-01-01')).toBeNull();
});
});

View File

@ -0,0 +1,63 @@
import type { AssessmentAnswers, Classification, ContentPack, Obligation } from './types';
/**
* Leitet die anwendbaren Pflichten für ein klassifiziertes System ab.
*
* Auswahlkriterien je Pflicht: Risikoklasse und Rolle müssen passen;
* GPAI- und Transparenzpflichten werden nur bei entsprechendem Flag
* aufgenommen. Zusätzlich werden die Pflichten der aktivierten
* nationalen Module (Länderauswahl) einbezogen.
*
* @param classification - Ergebnis von {@link classify}
* @param answers - Wizard-Antworten (Rolle, GPAI-Flag)
* @param pack - Regulatorischer Content-Pack
* @param countries - Aktivierte Länder-Module (ISO-Codes, z. B. ["DE","IT"])
* @returns Deduplizierte, nach Frist sortierte Pflichtenliste
*/
export function deriveObligations(
classification: Classification,
answers: AssessmentAnswers,
pack: ContentPack,
countries: readonly string[] = [],
): readonly Obligation[] {
if (classification.riskClass === 'out-of-scope' || classification.riskClass === 'prohibited') {
return [];
}
const matches = (ob: Obligation): boolean => {
if (ob.id === 'ob-gpai') {
return classification.gpaiObligations && answers.role === 'provider';
}
if (ob.id === 'ob-transparency-art50') {
return classification.transparencyDuties && ob.roles.includes(answers.role);
}
return ob.riskClasses.includes(classification.riskClass) && ob.roles.includes(answers.role);
};
const euObligations = pack.obligations.filter(matches);
const nationalObligations = pack.national
.filter((n) => countries.includes(n.code))
.flatMap((n) => n.items.filter(matches));
return [...euObligations, ...nationalObligations].sort((a, b) =>
a.deadline.localeCompare(b.deadline),
);
}
/**
* Ermittelt die nächste noch bevorstehende Geltungsfrist für ein System.
*
* @param obligations - Anwendbare Pflichten des Systems
* @param today - Stichtag im ISO-Format (YYYY-MM-DD)
* @returns Früheste Frist nach dem Stichtag, oder null wenn alle verstrichen
*/
export function nextDeadline(
obligations: readonly Obligation[],
today: string,
): string | null {
const upcoming = obligations
.map((ob) => ob.deadline)
.filter((d) => d >= today)
.sort();
return upcoming[0] ?? null;
}

View File

@ -0,0 +1,139 @@
import { describe, expect, it } from 'vitest';
import { CONTENT_PACK } from '../content/pack';
import {
answerKeyDoc,
certificateDoc,
getQuiz,
handoutDoc,
printableTestDoc,
scoreQuiz,
trainingLogDoc,
} from './quiz';
import { QUIZ_PASS_PCT, QUIZ_QUESTIONS } from './quizContent';
import type { CompanyProfile } from './types';
const profile: CompanyProfile = {
name: 'Muster GmbH',
street: '',
zipCity: '',
contactPerson: '',
email: '',
phone: '',
website: '',
logoDataUrl: '',
countries: [],
};
describe('KI-Kompetenztest', () => {
it('hat 12 einfache Fragen mit je 3 Optionen und gültigem Lösungsindex', () => {
expect(QUIZ_QUESTIONS).toHaveLength(12);
for (const q of QUIZ_QUESTIONS) {
expect(q.options).toHaveLength(3);
expect([0, 1, 2]).toContain(q.correctIndex);
}
});
it('löst Fragen lokalisiert auf (DE und EN unterscheiden sich)', () => {
const de = getQuiz('de');
const en = getQuiz('en');
expect(de).toHaveLength(en.length);
expect(de[0]?.question).not.toBe(en[0]?.question);
});
it('wertet korrekt aus: alle richtig = bestanden, alle falsch = durchgefallen', () => {
const perfect = scoreQuiz(QUIZ_QUESTIONS.map((q) => q.correctIndex));
expect(perfect.pct).toBe(100);
expect(perfect.passed).toBe(true);
const wrong = scoreQuiz(QUIZ_QUESTIONS.map((q) => ((q.correctIndex + 1) % 3) as 0 | 1 | 2));
expect(wrong.correct).toBe(0);
expect(wrong.passed).toBe(false);
});
it('wendet die Bestehensgrenze an (knapp darunter = durchgefallen)', () => {
// 8 von 12 = 67 % < 70 % → nicht bestanden; 9 von 12 = 75 % → bestanden
const eight = scoreQuiz(
QUIZ_QUESTIONS.map((q, i) => (i < 8 ? q.correctIndex : ((q.correctIndex + 1) % 3) as 0 | 1 | 2)),
);
expect(eight.passed).toBe(false);
const nine = scoreQuiz(
QUIZ_QUESTIONS.map((q, i) => (i < 9 ? q.correctIndex : ((q.correctIndex + 1) % 3) as 0 | 1 | 2)),
);
expect(nine.passed).toBe(true);
expect(QUIZ_PASS_PCT).toBe(70);
});
it('erzeugt ein Zertifikat mit Name, Ergebnis, Art.-4-Bezug und Disclaimer', () => {
const score = scoreQuiz(QUIZ_QUESTIONS.map((q) => q.correctIndex));
const md = certificateDoc('Max Mustermann', score, CONTENT_PACK, '2026-07-04', profile);
expect(md).toContain('Nachweis KI-Kompetenz (Art. 4');
expect(md).toContain('Max Mustermann');
expect(md).toContain('BESTANDEN');
expect(md).toContain('Muster GmbH');
expect(md).toContain('keine Rechtsberatung');
});
it('Papierfassung enthält alle Fragen, Ankreuzfelder und Auswertungszeile', () => {
const md = printableTestDoc(CONTENT_PACK, '2026-07-04', profile);
expect(md).toContain('Papierfassung');
expect((md.match(/☐/g) ?? []).length).toBe(36); // 12 Fragen × 3 Optionen
expect(md).toContain('**Name:**');
expect(md).toContain('Ergebnis: ______ / 12');
expect(md).not.toContain('richtige Antwort'); // keine Lösungen im Testbogen
});
it('Lösungsbogen enthält je Frage den Fragetext, die richtige Antwort im Wortlaut und die Erklärung', () => {
const md = answerKeyDoc(CONTENT_PACK, '2026-07-04', profile);
expect(md).toContain('Lösungsbogen');
// Fragetext enthalten (selbsterklärend, ohne Testbogen daneben):
expect((md.match(/^## \d+\./gm) ?? []).length).toBe(12);
expect(md).toContain('Was macht ein KI-System');
// Richtige Antwort mit Buchstabe UND Wortlaut:
expect((md.match(/\*\*Richtige Antwort: [ABC]\)\*\*/g) ?? []).length).toBe(12);
expect(md).toContain('Nein — nur in vom Unternehmen freigegebene KI-Systeme.');
// Erklärungen enthalten:
expect((md.match(/_Erklärung:_/g) ?? []).length).toBe(12);
});
it('Schulungshandout enthält die 12 Erklärungen und ist lokalisiert', () => {
const de = handoutDoc(CONTENT_PACK, '2026-07-04', profile, 'de');
expect(de).toContain('Schulungshandout');
expect((de.match(/^## \d+\./gm) ?? []).length).toBe(12);
const en = handoutDoc(CONTENT_PACK, '2026-07-04', profile, 'en');
expect(en).toContain('Training handout');
expect(en).not.toBe(de);
});
it('erzeugt das Schulungsregister mit Quelle, Beleg-Prüfsumme und ID', () => {
const md = trainingLogDoc(
[
{
id: 'abcdef12-3456',
name: 'Max Mustermann',
date: '2026-07-04',
scorePct: 92,
passed: true,
source: 'paper',
attachment: { fileName: 'scan.pdf', sha256: 'f'.repeat(64), dataUrl: 'data:application/pdf;base64,x' },
},
{ id: '2', name: 'Erika Musterfrau', date: '2026-07-03', scorePct: 58, passed: false },
],
CONTENT_PACK,
'2026-07-04',
profile,
);
expect(md).toContain('Schulungsregister');
expect(md).toContain('| Papier |'); // Quelle Papier-Test
expect(md).toContain('| App |'); // Alt-Einträge ohne source = App
expect(md).toContain('`ffffffffffffffff…`'); // Beleg-Prüfsumme (gekürzt)
expect(md).toContain('`abcdef12`'); // Register-ID (gekürzt)
expect(md).toContain('NICHT BESTANDEN');
});
it('Zertifikat enthält die Register-ID für die Nachweiskette', () => {
const score = scoreQuiz(QUIZ_QUESTIONS.map((q) => q.correctIndex));
const md = certificateDoc('Max', score, CONTENT_PACK, '2026-07-04', profile, 'de', 'abcdef12-3456-7890');
expect(md).toContain('Register-ID');
expect(md).toContain('`abcdef12`');
});
});

View File

@ -0,0 +1,386 @@
import { resolveText } from '../i18n/types';
import type { Locale } from '../i18n/types';
import { docStrings, formatDocDate } from './docStrings';
import { QUIZ_PASS_PCT, QUIZ_QUESTIONS } from './quizContent';
import type { CompanyProfile, ContentPack } from './types';
/** Aufgelöste Quizfrage in einer Zielsprache. */
export interface QuizQuestion {
readonly id: string;
readonly question: string;
readonly options: readonly [string, string, string];
readonly correctIndex: 0 | 1 | 2;
readonly explanation: string;
}
/** Testergebnis einer Person. */
export interface QuizScore {
readonly correct: number;
readonly total: number;
readonly pct: number;
readonly passed: boolean;
}
/** Beleg-Anhang eines Registereintrags (z. B. eingescannter Testbogen). */
export interface TrainingAttachment {
readonly fileName: string;
/** SHA-256-Prüfsumme der Originaldatei (Hex). */
readonly sha256: string;
/** Dateiinhalt als Data-URL — bleibt lokal im Browser. */
readonly dataUrl: string;
}
/** Eintrag im lokalen Schulungsregister (Art.-4-Nachweis). */
export interface TrainingRecord {
readonly id: string;
readonly name: string;
readonly date: string;
readonly scorePct: number;
readonly passed: boolean;
/** Durchführung in der App oder auf Papier (Alt-Einträge: App). */
readonly source?: 'app' | 'paper';
/** Eingescannter, ausgewerteter Testbogen als Beleg. */
readonly attachment?: TrainingAttachment;
}
/** Liefert den Fragenkatalog in der gewünschten Sprache. */
export function getQuiz(locale: Locale): readonly QuizQuestion[] {
return QUIZ_QUESTIONS.map((q) => ({
id: q.id,
question: resolveText(q.question, locale),
options: [
resolveText(q.options[0], locale),
resolveText(q.options[1], locale),
resolveText(q.options[2], locale),
],
correctIndex: q.correctIndex,
explanation: resolveText(q.explanation, locale),
}));
}
/**
* Wertet abgegebene Antworten aus.
*
* @param answers - Gewählter Optionsindex je Frage (Reihenfolge des Katalogs)
*/
export function scoreQuiz(answers: readonly (number | null)[]): QuizScore {
const total = QUIZ_QUESTIONS.length;
const correct = QUIZ_QUESTIONS.reduce(
(acc, q, i) => acc + (answers[i] === q.correctIndex ? 1 : 0),
0,
);
const pct = Math.round((correct / total) * 100);
return { correct, total, pct, passed: pct >= QUIZ_PASS_PCT };
}
interface CertStrings {
readonly title: string;
readonly intro: string;
readonly name: string;
readonly date: string;
readonly result: string;
readonly resultPassed: string;
readonly resultFailed: string;
readonly topics: string;
readonly topicList: string;
readonly evidence: string;
readonly signature: string;
readonly logTitle: string;
readonly logIntro: string;
readonly logCols: string;
readonly sourceApp: string;
readonly sourcePaper: string;
}
const CERT: Readonly<Record<'de' | 'en', CertStrings>> = {
de: {
title: 'Nachweis KI-Kompetenz (Art. 4 EU-KI-VO)',
intro:
'Die nachfolgend genannte Person hat den KI-Kompetenztest des Unternehmens absolviert. Der Test vermittelt und prüft die Grundlagen für den verantwortungsvollen Umgang mit KI-Systemen.',
name: 'Name',
date: 'Datum',
result: 'Ergebnis',
resultPassed: 'BESTANDEN',
resultFailed: 'NICHT BESTANDEN — Wiederholung erforderlich',
topics: 'Geprüfte Themen',
topicList:
'Funktionsweise und Grenzen von KI · Umgang mit vertraulichen Daten · Prüfung von KI-Ausgaben (Halluzinationen) · menschliche Aufsicht · Transparenzpflichten (Art. 50) · verbotene Praktiken (Art. 5) · Hochrisiko-KI (Annex III) · DSGVO · interne Meldewege (Art. 73) · Freigabeprozess (Schatten-KI) · Kennzeichnung KI-generierter Inhalte · KI-Kompetenzpflicht (Art. 4)',
evidence:
'Dieser Nachweis ist Teil der Art.-4-Dokumentation des Unternehmens (Schulungsplan & Nachweis KI-Kompetenz) und wird dort abgelegt.',
signature: 'Ort, Datum: _______________ Unterschrift Beschäftigte/r: _______________ Unterschrift Arbeitgeber: _______________',
logTitle: 'Schulungsregister KI-Kompetenz (Art. 4 EU-KI-VO)',
logIntro: 'Fortlaufender Nachweis der durchgeführten KI-Kompetenztests. Bestehensgrenze: {pct} %.',
logCols: '| Datum | Name | Quelle | Ergebnis | Status | Beleg (SHA-256) | ID |',
sourceApp: 'App',
sourcePaper: 'Papier',
},
en: {
title: 'Evidence of AI literacy (Art. 4 EU AI Act)',
intro:
'The person named below has completed the companys AI literacy test. The test teaches and verifies the basics of responsible use of AI systems.',
name: 'Name',
date: 'Date',
result: 'Result',
resultPassed: 'PASSED',
resultFailed: 'NOT PASSED — retake required',
topics: 'Topics covered',
topicList:
'How AI works and its limits · handling confidential data · checking AI output (hallucinations) · human oversight · transparency obligations (Art. 50) · prohibited practices (Art. 5) · high-risk AI (Annex III) · GDPR · internal reporting channels (Art. 73) · approval process (shadow AI) · marking AI-generated content · AI literacy duty (Art. 4)',
evidence:
'This evidence forms part of the companys Art. 4 documentation (AI literacy training plan & record) and is filed there.',
signature: 'Place, date: _______________ Signature employee: _______________ Signature employer: _______________',
logTitle: 'AI literacy training register (Art. 4 EU AI Act)',
logIntro: 'Continuous record of completed AI literacy tests. Pass threshold: {pct} %.',
logCols: '| Date | Name | Source | Score | Status | Evidence (SHA-256) | ID |',
sourceApp: 'App',
sourcePaper: 'Paper',
},
};
function certStrings(locale: Locale): CertStrings {
return locale === 'de' ? CERT.de : CERT.en;
}
/**
* Erzeugt das druckbare Zertifikat (Art.-4-Nachweis) als Markdown.
*
* @param name - Name der geprüften Person
* @param score - Testergebnis
* @param pack - Content-Pack (Versionsangabe)
* @param today - Datum im ISO-Format
* @param profile - Firmenprofil (Briefkopf)
* @param locale - Dokumentsprache
* @param recordId - ID des zugehörigen Registereintrags (Nachweiskette)
*/
export function certificateDoc(
name: string,
score: QuizScore,
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
recordId?: string,
): string {
const s = docStrings(locale);
const c = certStrings(locale);
const company = profile && profile.name.trim() !== '' ? profile.name : '_______________';
return [
`# ${c.title}`,
'',
`**${s.meta.company}:** ${company} · Content-Pack v${pack.version}`,
'',
s.disclaimer,
'',
c.intro,
'',
`| | |`,
`|---|---|`,
`| **${c.name}** | ${name} |`,
`| **${c.date}** | ${formatDocDate(today, locale)} |`,
`| **${c.result}** | ${score.correct}/${score.total} (${score.pct} %) — **${score.passed ? c.resultPassed : c.resultFailed}** |`,
...(recordId ? [`| **${locale === 'de' ? 'Register-ID' : 'Register ID'}** | \`${recordId.slice(0, 8)}\` |`] : []),
'',
`## ${c.topics}`,
'',
c.topicList,
'',
c.evidence,
'',
c.signature,
].join('\n');
}
interface PrintStrings {
readonly testTitle: string;
readonly testIntro: string;
readonly nameDateLine: string;
readonly testFooter: string;
readonly keyTitle: string;
readonly keyIntro: string;
readonly keyCorrect: string;
readonly keyWhy: string;
readonly handoutTitle: string;
readonly handoutIntro: string;
readonly handoutFooter: string;
}
const PRINT: Readonly<Record<'de' | 'en', PrintStrings>> = {
de: {
testTitle: 'KI-Kompetenztest (Art. 4 EU-KI-VO) — Papierfassung',
testIntro:
'Bitte kreuzen Sie je Frage genau eine Antwort an. Bestehensgrenze: {pct} % ({min} von {total} Fragen). Die Auswertung erfolgt mit dem Lösungsbogen; das Ergebnis wird im Schulungsregister dokumentiert.',
nameDateLine: '**Name:** ______________________________ **Datum:** ______________ **Abteilung:** ______________________________',
testFooter: 'Unterschrift Beschäftigte/r: _______________ Ausgewertet durch (Name, Unterschrift): _______________ Ergebnis: ______ / {total}',
keyTitle: 'KI-Kompetenztest — Lösungsbogen (nur für Auswertende)',
keyIntro: 'Alle Fragen mit richtiger Antwort und Erklärung. Bestehensgrenze: {pct} % ({min} von {total} Fragen).',
keyCorrect: 'Richtige Antwort',
keyWhy: 'Erklärung',
handoutTitle: 'Schulungshandout: Die 12 wichtigsten Regeln im Umgang mit KI',
handoutIntro:
'Dieses Handout fasst die Kernregeln für den Arbeitsalltag zusammen und dient als Schulungsunterlage nach Art. 4 EU-KI-VO. Es kann vor dem Kompetenztest ausgeteilt werden.',
handoutFooter:
'Bei Fragen oder Vorfällen: an die/den KI-Beauftragte/n wenden (siehe interne Melde- und Eskalationsrichtlinie).',
},
en: {
testTitle: 'AI literacy test (Art. 4 EU AI Act) — paper version',
testIntro:
'Please tick exactly one answer per question. Pass threshold: {pct} % ({min} of {total} questions). Marking is done with the answer key; the result is documented in the training register.',
nameDateLine: '**Name:** ______________________________ **Date:** ______________ **Department:** ______________________________',
testFooter: 'Signature employee: _______________ Marked by (name, signature): _______________ Score: ______ / {total}',
keyTitle: 'AI literacy test — answer key (for markers only)',
keyIntro: 'All questions with the correct answer and explanation. Pass threshold: {pct} % ({min} of {total} questions).',
keyCorrect: 'Correct answer',
keyWhy: 'Explanation',
handoutTitle: 'Training handout: the 12 most important rules for working with AI',
handoutIntro:
'This handout summarises the core rules for everyday work and serves as training material under Art. 4 EU AI Act. It can be handed out before the literacy test.',
handoutFooter:
'For questions or incidents: contact the AI officer (see the internal reporting and escalation policy).',
},
};
function printStrings(locale: Locale): PrintStrings {
return locale === 'de' ? PRINT.de : PRINT.en;
}
const OPTION_LETTERS = ['A', 'B', 'C'] as const;
function minCorrect(): number {
return Math.ceil((QUIZ_PASS_PCT / 100) * QUIZ_QUESTIONS.length);
}
function fillIn(template: string): string {
return template
.replace('{pct}', String(QUIZ_PASS_PCT))
.replace('{min}', String(minCorrect()))
.replaceAll('{total}', String(QUIZ_QUESTIONS.length));
}
/**
* Erzeugt die Papierfassung des Kompetenztests (zum Ausdrucken und
* handschriftlichen Ausfüllen) als Markdown.
*/
export function printableTestDoc(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const p = printStrings(locale);
const company = profile && profile.name.trim() !== '' ? profile.name : '_______________';
const lines = [
`# ${p.testTitle}`,
'',
`**${s.meta.company}:** ${company} · ${s.inventory.asOf}: ${formatDocDate(today, locale)} · Content-Pack v${pack.version}`,
'',
p.nameDateLine,
'',
fillIn(p.testIntro),
'',
];
getQuiz(locale).forEach((q, i) => {
lines.push(`## ${i + 1}. ${q.question}`, '');
q.options.forEach((option, oi) => {
lines.push(`- ☐ **${OPTION_LETTERS[oi]})** ${option}`);
});
lines.push('');
});
lines.push(fillIn(p.testFooter));
return lines.join('\n');
}
/** Erzeugt den Lösungsbogen (richtige Antworten + Erklärungen) als Markdown. */
export function answerKeyDoc(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const p = printStrings(locale);
const company = profile && profile.name.trim() !== '' ? profile.name : '_______________';
const lines = [
`# ${p.keyTitle}`,
'',
`**${s.meta.company}:** ${company} · ${s.inventory.asOf}: ${formatDocDate(today, locale)} · Content-Pack v${pack.version}`,
'',
fillIn(p.keyIntro),
'',
];
getQuiz(locale).forEach((q, i) => {
lines.push(
`## ${i + 1}. ${q.question}`,
'',
`**${p.keyCorrect}: ${OPTION_LETTERS[q.correctIndex]})** ${q.options[q.correctIndex]}`,
'',
`_${p.keyWhy}:_ ${q.explanation}`,
'',
);
});
return lines.join('\n');
}
/** Erzeugt das Schulungshandout (Kernregeln aus den Erklärungen) als Markdown. */
export function handoutDoc(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const p = printStrings(locale);
const company = profile && profile.name.trim() !== '' ? profile.name : '_______________';
const lines = [
`# ${p.handoutTitle}`,
'',
`**${s.meta.company}:** ${company} · ${s.inventory.asOf}: ${formatDocDate(today, locale)} · Content-Pack v${pack.version}`,
'',
s.disclaimer,
'',
p.handoutIntro,
'',
];
getQuiz(locale).forEach((q, i) => {
lines.push(`## ${i + 1}. ${q.question}`, '', q.explanation, '');
});
lines.push(p.handoutFooter);
return lines.join('\n');
}
/**
* Erzeugt das druckbare Schulungsregister (alle Testdurchläufe) als Markdown.
*/
export function trainingLogDoc(
records: readonly TrainingRecord[],
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const c = certStrings(locale);
const company = profile && profile.name.trim() !== '' ? profile.name : '_______________';
const lines = [
`# ${c.logTitle}`,
'',
`**${s.meta.company}:** ${company} · ${s.inventory.asOf}: ${formatDocDate(today, locale)} · Content-Pack v${pack.version}`,
'',
s.disclaimer,
'',
c.logIntro.replace('{pct}', String(QUIZ_PASS_PCT)),
'',
c.logCols,
'|---|---|---|---|---|---|---|',
];
for (const r of records) {
const source = (r.source ?? 'app') === 'paper' ? c.sourcePaper : c.sourceApp;
const evidence = r.attachment ? `\`${r.attachment.sha256.slice(0, 16)}\`` : '—';
lines.push(
`| ${formatDocDate(r.date, locale)} | ${r.name} | ${source} | ${r.scorePct} % | ${
r.passed ? c.resultPassed : c.resultFailed
} | ${evidence} | \`${r.id.slice(0, 8)}\` |`,
);
}
return lines.join('\n');
}

View File

@ -0,0 +1,760 @@
import type { LText } from '../i18n/types';
/**
* Fragenkatalog des KI-Kompetenztests (Art. 4 EU-KI-VO).
*
* Bewusst einfach gehalten (für Dummies"): 12 Fragen zu den
* Grundlagen, die jede/r Beschäftigte kennen muss KI-Basics,
* Verbote, Transparenz, Datenschutz, interne Prozesse.
* Teil des versionierten Content-Packs; Übersetzungen als
* vollständige LText-Objekte (DE/EN/FR/IT/ES/PL/CS/SK/RO).
*/
/** Frage in Quellform (lokalisiert). */
export interface QuizQuestionSrc {
readonly id: string;
readonly question: LText;
/** Genau drei Antwortoptionen. */
readonly options: readonly [LText, LText, LText];
/** Index der richtigen Option (02). */
readonly correctIndex: 0 | 1 | 2;
readonly explanation: LText;
}
/** Bestehensgrenze in Prozent. */
export const QUIZ_PASS_PCT = 70;
export const QUIZ_QUESTIONS: readonly QuizQuestionSrc[] = [
{
id: 'q-basics',
question: {
de: 'Was macht ein KI-System — vereinfacht gesagt?',
en: 'What does an AI system do — put simply?',
fr: 'Que fait un système dIA — pour faire simple ?',
it: 'Cosa fa un sistema di IA — detto in parole semplici?',
es: '¿Qué hace un sistema de IA, dicho de forma sencilla?',
pl: 'Co robi system AI — mówiąc najprościej?',
cs: 'Co dělá systém AI — jednoduše řečeno?',
sk: 'Čo robí systém AI — jednoducho povedané?',
ro: 'Ce face un sistem de IA — pe scurt?',
},
options: [
{
de: 'Es folgt immer exakt fest einprogrammierten Regeln.',
en: 'It always follows exactly pre-programmed rules.',
fr: 'Il suit toujours exactement des règles programmées à lavance.',
it: 'Segue sempre esattamente regole programmate in anticipo.',
es: 'Sigue siempre exactamente reglas programadas de antemano.',
pl: 'Zawsze dokładnie trzyma się z góry zaprogramowanych reguł.',
cs: 'Vždy se přesně řídí předem naprogramovanými pravidly.',
sk: 'Vždy sa presne riadi vopred naprogramovanými pravidlami.',
ro: 'Urmează întotdeauna exact reguli programate dinainte.',
},
{
de: 'Es leitet aus Daten selbstständig ab, welche Ausgabe passt — und kann dabei auch danebenliegen.',
en: 'It infers from data which output fits — and can also get it wrong.',
fr: 'Il déduit lui-même à partir de données quelle réponse convient — et peut aussi se tromper.',
it: 'Deduce autonomamente dai dati quale risultato è adatto — e può anche sbagliarsi.',
es: 'Deduce por sí mismo a partir de datos qué resultado encaja — y también puede equivocarse.',
pl: 'Samodzielnie wnioskuje z danych, jaki wynik pasuje — i może się przy tym mylić.',
cs: 'Samostatně z dat odvozuje, jaký výstup se hodí — a může se přitom i mýlit.',
sk: 'Samostatne z údajov odvodzuje, aký výstup sa hodí — a môže sa pritom aj mýliť.',
ro: 'Deduce singur din date ce rezultat se potrivește — și poate să și greșească.',
},
{
de: 'Es versteht Inhalte wie ein Mensch und macht deshalb keine Fehler.',
en: 'It understands content like a human and therefore makes no mistakes.',
fr: 'Il comprend les contenus comme un humain et ne fait donc jamais derreur.',
it: 'Capisce i contenuti come un essere umano e quindi non commette errori.',
es: 'Entiende los contenidos como un ser humano y, por eso, no comete errores.',
pl: 'Rozumie treści jak człowiek i dlatego nie popełnia błędów.',
cs: 'Rozumí obsahu jako člověk, a proto nedělá chyby.',
sk: 'Rozumie obsahu ako človek, a preto nerobí chyby.',
ro: 'Înțelege conținutul ca un om și de aceea nu face greșeli.',
},
],
correctIndex: 1,
explanation: {
de: 'KI erzeugt Ausgaben statistisch aus Daten. Sie kann überzeugend klingen und trotzdem falsch liegen.',
en: 'AI generates outputs statistically from data. It can sound convincing and still be wrong.',
fr: 'LIA génère ses réponses de façon statistique à partir de données. Elle peut sembler convaincante et se tromper quand même.',
it: 'LIA genera i risultati in modo statistico a partire dai dati. Può sembrare convincente e sbagliarsi comunque.',
es: 'La IA genera resultados de forma estadística a partir de datos. Puede sonar convincente y aun así estar equivocada.',
pl: 'AI generuje wyniki statystycznie na podstawie danych. Może brzmieć przekonująco, a mimo to się mylić.',
cs: 'AI vytváří výstupy statisticky z dat. Může znít přesvědčivě, a přesto se mýlit.',
sk: 'AI vytvára výstupy štatisticky z údajov. Môže znieť presvedčivo, a napriek tomu sa mýliť.',
ro: 'IA generează rezultate statistic, pe baza datelor. Poate suna convingător și totuși să greșească.',
},
},
{
id: 'q-secrets',
question: {
de: 'Dürfen Sie Kundendaten oder Geschäftsgeheimnisse in einen öffentlichen KI-Chatbot eingeben?',
en: 'May you enter customer data or trade secrets into a public AI chatbot?',
fr: 'Avez-vous le droit de saisir des données clients ou des secrets daffaires dans un chatbot dIA public ?',
it: 'È consentito inserire dati dei clienti o segreti aziendali in un chatbot di IA pubblico?',
es: '¿Puede introducir datos de clientes o secretos comerciales en un chatbot de IA público?',
pl: 'Czy wolno wpisywać dane klientów lub tajemnice firmy do publicznego chatbota AI?',
cs: 'Smíte zadávat údaje zákazníků nebo obchodní tajemství do veřejného AI chatbota?',
sk: 'Smiete zadávať údaje zákazníkov alebo obchodné tajomstvá do verejného AI chatbota?',
ro: 'Aveți voie să introduceți date ale clienților sau secrete de afaceri într-un chatbot de IA public?',
},
options: [
{
de: 'Ja, wenn es die Arbeit beschleunigt.',
en: 'Yes, if it speeds up the work.',
fr: 'Oui, si cela accélère le travail.',
it: 'Sì, se accelera il lavoro.',
es: 'Sí, si acelera el trabajo.',
pl: 'Tak, jeśli przyspiesza to pracę.',
cs: 'Ano, pokud to urychlí práci.',
sk: 'Áno, ak to urýchli prácu.',
ro: 'Da, dacă accelerează munca.',
},
{
de: 'Ja, solange ich das Ergebnis danach lösche.',
en: 'Yes, as long as I delete the result afterwards.',
fr: 'Oui, à condition de supprimer le résultat ensuite.',
it: 'Sì, purché poi cancelli il risultato.',
es: 'Sí, siempre que borre el resultado después.',
pl: 'Tak, o ile potem usunę wynik.',
cs: 'Ano, pokud výsledek potom smažu.',
sk: 'Áno, pokiaľ výsledok potom vymažem.',
ro: 'Da, cu condiția să șterg rezultatul după aceea.',
},
{
de: 'Nein — nur in vom Unternehmen freigegebene KI-Systeme.',
en: 'No — only into AI systems approved by the company.',
fr: 'Non — uniquement dans les systèmes dIA approuvés par lentreprise.',
it: 'No — solo nei sistemi di IA approvati dallazienda.',
es: 'No — solo en sistemas de IA aprobados por la empresa.',
pl: 'Nie — tylko do systemów AI zatwierdzonych przez firmę.',
cs: 'Ne — pouze do AI systémů schválených firmou.',
sk: 'Nie — iba do AI systémov schválených firmou.',
ro: 'Nu — doar în sisteme de IA aprobate de companie.',
},
],
correctIndex: 2,
explanation: {
de: 'Eingaben in fremde Cloud-KI können gespeichert und weiterverwendet werden. Es gilt die interne KI-Richtlinie: nur freigegebene Systeme nutzen.',
en: 'Input into third-party cloud AI can be stored and reused. The internal AI policy applies: use approved systems only.',
fr: 'Ce qui est saisi dans une IA cloud externe peut être stocké et réutilisé. La politique interne en matière dIA sapplique : utiliser uniquement des systèmes approuvés.',
it: 'I dati inseriti in IA cloud di terzi possono essere memorizzati e riutilizzati. Vale la policy interna sullIA: usare solo sistemi approvati.',
es: 'Lo que se introduce en una IA en la nube de terceros puede almacenarse y reutilizarse. Se aplica la política interna de IA: usar solo sistemas aprobados.',
pl: 'Dane wpisane do obcej chmurowej AI mogą być zapisywane i dalej wykorzystywane. Obowiązuje wewnętrzna polityka AI: korzystać tylko z zatwierdzonych systemów.',
cs: 'Zadání do cizí cloudové AI mohou být uložena a dále využita. Platí interní směrnice pro AI: používat pouze schválené systémy.',
sk: 'Zadania do cudzej cloudovej AI môžu byť uložené a ďalej využité. Platí interná smernica pre AI: používať iba schválené systémy.',
ro: 'Datele introduse într-o IA cloud a unui terț pot fi stocate și reutilizate. Se aplică politica internă privind IA: folosiți doar sisteme aprobate.',
},
},
{
id: 'q-hallucination',
question: {
de: 'Eine KI liefert Ihnen eine Antwort mit Quellenangaben. Was tun Sie?',
en: 'An AI gives you an answer with source references. What do you do?',
fr: 'Une IA vous fournit une réponse avec des sources. Que faites-vous ?',
it: 'UnIA vi fornisce una risposta con indicazione delle fonti. Cosa fate?',
es: 'Una IA le da una respuesta con referencias a fuentes. ¿Qué hace usted?',
pl: 'AI podaje Ci odpowiedź z odnośnikami do źródeł. Co robisz?',
cs: 'AI vám dá odpověď s uvedením zdrojů. Co uděláte?',
sk: 'AI vám dá odpoveď s uvedením zdrojov. Čo urobíte?',
ro: 'O IA vă oferă un răspuns cu trimiteri la surse. Ce faceți?',
},
options: [
{
de: 'Wichtige Fakten und Quellen prüfen, bevor ich sie verwende — KI erfindet manchmal beides.',
en: 'Check important facts and sources before using them — AI sometimes invents both.',
fr: 'Vérifier les faits importants et les sources avant de les utiliser — lIA invente parfois les deux.',
it: 'Verifico i fatti importanti e le fonti prima di usarli — a volte lIA inventa entrambi.',
es: 'Comprobar los datos importantes y las fuentes antes de usarlos — la IA a veces inventa ambos.',
pl: 'Sprawdzam ważne fakty i źródła, zanim ich użyję — AI czasem zmyśla jedno i drugie.',
cs: 'Důležitá fakta a zdroje ověřím, než je použiji — AI si občas vymýšlí obojí.',
sk: 'Dôležité fakty a zdroje si overím, kým ich použijem — AI si občas vymýšľa oboje.',
ro: 'Verific faptele importante și sursele înainte să le folosesc — IA le inventează uneori pe amândouă.',
},
{
de: 'Direkt übernehmen — mit Quellen ist es verlässlich.',
en: 'Use it directly — with sources it is reliable.',
fr: 'Reprendre tel quel — avec des sources, cest fiable.',
it: 'La uso così comè — con le fonti è affidabile.',
es: 'Usarla tal cual — con fuentes es fiable.',
pl: 'Przejmuję od razu — skoro są źródła, to jest wiarygodne.',
cs: 'Převezmu rovnou — se zdroji je to spolehlivé.',
sk: 'Prevezmem rovno — so zdrojmi je to spoľahlivé.',
ro: 'O preiau direct — cu surse e de încredere.',
},
{
de: 'Die KI bitten, zu bestätigen, dass alles stimmt.',
en: 'Ask the AI to confirm everything is correct.',
fr: 'Demander à lIA de confirmer que tout est exact.',
it: 'Chiedo allIA di confermare che tutto sia corretto.',
es: 'Pedir a la IA que confirme que todo es correcto.',
pl: 'Proszę AI o potwierdzenie, że wszystko się zgadza.',
cs: 'Požádám AI, aby potvrdila, že vše sedí.',
sk: 'Požiadam AI, aby potvrdila, že všetko sedí.',
ro: 'Rog IA să confirme că totul e corect.',
},
],
correctIndex: 0,
explanation: {
de: '„Halluzinationen" sind erfundene, aber plausibel klingende Angaben — auch Quellen können erfunden sein. Selbstbestätigung der KI ist kein Beleg.',
en: '“Hallucinations” are invented but plausible-sounding statements — sources can be invented too. AI self-confirmation is no proof.',
fr: 'Les « hallucinations » sont des affirmations inventées mais plausibles — même les sources peuvent être inventées. Lautoconfirmation de lIA ne prouve rien.',
it: 'Le «allucinazioni» sono affermazioni inventate ma plausibili — anche le fonti possono essere inventate. Lautoconferma dellIA non è una prova.',
es: 'Las «alucinaciones» son afirmaciones inventadas pero que suenan plausibles — también las fuentes pueden ser inventadas. La autoconfirmación de la IA no es una prueba.',
pl: '„Halucynacje” to zmyślone, ale wiarygodnie brzmiące informacje — zmyślone mogą być też źródła. Samopotwierdzenie AI nie jest dowodem.',
cs: '„Halucinace" jsou vymyšlené, ale věrohodně znějící údaje — vymyšlené mohou být i zdroje. Sebepotvrzení AI není důkaz.',
sk: '„Halucinácie" sú vymyslené, ale vierohodne znejúce údaje — vymyslené môžu byť aj zdroje. Sebapotvrdenie AI nie je dôkaz.',
ro: '„Halucinațiile” sunt afirmații inventate, dar care sună plauzibil — și sursele pot fi inventate. Autoconfirmarea IA nu e o dovadă.',
},
},
{
id: 'q-oversight',
question: {
de: 'Die KI schlägt vor, einen Bewerber abzulehnen. Wer entscheidet?',
en: 'The AI suggests rejecting an applicant. Who decides?',
fr: 'LIA propose de rejeter un candidat. Qui décide ?',
it: 'LIA propone di respingere un candidato. Chi decide?',
es: 'La IA propone rechazar a un candidato. ¿Quién decide?',
pl: 'AI proponuje odrzucić kandydata. Kto decyduje?',
cs: 'AI navrhuje odmítnout uchazeče. Kdo rozhoduje?',
sk: 'AI navrhuje odmietnuť uchádzača. Kto rozhoduje?',
ro: 'IA propune respingerea unui candidat. Cine decide?',
},
options: [
{
de: 'Die KI — dafür ist sie da.',
en: 'The AI — that is what it is for.',
fr: 'LIA — cest bien à ça quelle sert.',
it: 'LIA — è lì per questo.',
es: 'La IA — para eso está.',
pl: 'AI — od tego przecież jest.',
cs: 'AI — od toho tu přece je.',
sk: 'AI — veď na to tu je.',
ro: 'IA — de aceea există.',
},
{
de: 'Ein Mensch prüft den Vorschlag und trifft die Entscheidung.',
en: 'A human reviews the suggestion and takes the decision.',
fr: 'Un humain examine la proposition et prend la décision.',
it: 'Un essere umano esamina la proposta e prende la decisione.',
es: 'Una persona revisa la propuesta y toma la decisión.',
pl: 'Człowiek sprawdza propozycję i podejmuje decyzję.',
cs: 'Člověk návrh posoudí a rozhodne.',
sk: 'Človek návrh posúdi a rozhodne.',
ro: 'Un om verifică propunerea și ia decizia.',
},
{
de: 'Niemand — die Entscheidung fällt automatisch nach 48 Stunden.',
en: 'No one — the decision is taken automatically after 48 hours.',
fr: 'Personne — la décision tombe automatiquement au bout de 48 heures.',
it: 'Nessuno — la decisione scatta automaticamente dopo 48 ore.',
es: 'Nadie — la decisión se toma automáticamente a las 48 horas.',
pl: 'Nikt — decyzja zapada automatycznie po 48 godzinach.',
cs: 'Nikdo — rozhodnutí padne automaticky po 48 hodinách.',
sk: 'Nikto — rozhodnutie padne automaticky po 48 hodinách.',
ro: 'Nimeni — decizia se ia automat după 48 de ore.',
},
],
correctIndex: 1,
explanation: {
de: 'Bei Entscheidungen mit Wirkung für Menschen ist die KI nur Unterstützung — die Letztentscheidung trifft ein kompetenter Mensch (menschliche Aufsicht).',
en: 'For decisions affecting people, AI is support only — the final decision is taken by a competent human (human oversight).',
fr: 'Pour les décisions qui touchent des personnes, lIA nest quun soutien — la décision finale revient à un humain compétent (contrôle humain).',
it: 'Per le decisioni che riguardano le persone, lIA è solo un supporto — la decisione finale spetta a un essere umano competente (sorveglianza umana).',
es: 'En decisiones que afectan a personas, la IA es solo un apoyo — la decisión final la toma una persona competente (supervisión humana).',
pl: 'Przy decyzjach dotyczących ludzi AI jest tylko wsparciem — ostateczną decyzję podejmuje kompetentny człowiek (nadzór ze strony człowieka).',
cs: 'U rozhodnutí s dopadem na lidi je AI jen podporou — konečné rozhodnutí činí kompetentní člověk (lidský dohled).',
sk: 'Pri rozhodnutiach s dosahom na ľudí je AI len podporou — konečné rozhodnutie prijíma kompetentný človek (ľudský dohľad).',
ro: 'La deciziile care afectează oameni, IA este doar un sprijin — decizia finală o ia un om competent (supraveghere umană).',
},
},
{
id: 'q-transparency',
question: {
de: 'Ihr Unternehmen setzt einen Kunden-Chatbot ein. Was ist Pflicht?',
en: 'Your company uses a customer chatbot. What is mandatory?',
fr: 'Votre entreprise utilise un chatbot pour les clients. Quest-ce qui est obligatoire ?',
it: 'La vostra azienda usa un chatbot per i clienti. Cosa è obbligatorio?',
es: 'Su empresa utiliza un chatbot para clientes. ¿Qué es obligatorio?',
pl: 'Twoja firma używa chatbota dla klientów. Co jest obowiązkowe?',
cs: 'Vaše firma používá zákaznický chatbot. Co je povinné?',
sk: 'Vaša firma používa zákaznícky chatbot. Čo je povinné?',
ro: 'Compania dvs. folosește un chatbot pentru clienți. Ce este obligatoriu?',
},
options: [
{
de: 'Nichts — Hauptsache, er antwortet freundlich.',
en: 'Nothing — as long as it answers politely.',
fr: 'Rien — lessentiel est quil réponde poliment.',
it: 'Niente — limportante è che risponda in modo gentile.',
es: 'Nada — lo importante es que responda con amabilidad.',
pl: 'Nic — grunt, żeby odpowiadał uprzejmie.',
cs: 'Nic — hlavně že odpovídá slušně.',
sk: 'Nič — hlavne, že odpovedá slušne.',
ro: 'Nimic — important e să răspundă politicos.',
},
{
de: 'Kunden müssen erkennen können, dass sie mit einer KI sprechen.',
en: 'Customers must be able to recognise they are talking to an AI.',
fr: 'Les clients doivent pouvoir reconnaître quils parlent à une IA.',
it: 'I clienti devono poter riconoscere che stanno parlando con unIA.',
es: 'Los clientes deben poder reconocer que están hablando con una IA.',
pl: 'Klienci muszą móc rozpoznać, że rozmawiają z AI.',
cs: 'Zákazníci musí mít možnost poznat, že mluví s AI.',
sk: 'Zákazníci musia mať možnosť rozpoznať, že hovoria s AI.',
ro: 'Clienții trebuie să poată recunoaște că vorbesc cu o IA.',
},
{
de: 'Der Chatbot muss sich als Mensch ausgeben, damit Kunden Vertrauen haben.',
en: 'The chatbot must pose as a human so customers trust it.',
fr: 'Le chatbot doit se faire passer pour un humain afin dinspirer confiance aux clients.',
it: 'Il chatbot deve spacciarsi per un essere umano, così i clienti si fidano.',
es: 'El chatbot debe hacerse pasar por humano para que los clientes confíen.',
pl: 'Chatbot musi udawać człowieka, żeby klienci mieli zaufanie.',
cs: 'Chatbot se musí vydávat za člověka, aby mu zákazníci důvěřovali.',
sk: 'Chatbot sa musí vydávať za človeka, aby mu zákazníci dôverovali.',
ro: 'Chatbotul trebuie să se dea drept om, ca să aibă clienții încredere.',
},
],
correctIndex: 1,
explanation: {
de: 'Art. 50 EU-KI-VO: KI-Interaktion muss offengelegt werden; KI-generierte Inhalte sind zu kennzeichnen.',
en: 'Art. 50 EU AI Act: AI interaction must be disclosed; AI-generated content must be marked.',
fr: 'Article 50 du règlement européen sur lIA : linteraction avec une IA doit être révélée ; les contenus générés par IA doivent être signalés.',
it: 'Articolo 50 del regolamento europeo sullIA: linterazione con unIA deve essere resa nota; i contenuti generati dallIA vanno etichettati.',
es: 'Artículo 50 del Reglamento europeo de IA: hay que revelar la interacción con una IA; los contenidos generados por IA deben marcarse.',
pl: 'Art. 50 unijnego aktu w sprawie AI: interakcję z AI trzeba ujawnić; treści wygenerowane przez AI należy oznaczać.',
cs: 'Čl. 50 aktu EU o AI: interakce s AI musí být zveřejněna; obsah vytvořený AI je nutné označit.',
sk: 'Čl. 50 aktu EÚ o AI: interakcia s AI musí byť zverejnená; obsah vytvorený AI treba označiť.',
ro: 'Art. 50 din Regulamentul UE privind IA: interacțiunea cu o IA trebuie dezvăluită; conținutul generat de IA trebuie marcat.',
},
},
{
id: 'q-prohibited',
question: {
de: 'Welche dieser KI-Anwendungen ist in der EU verboten?',
en: 'Which of these AI applications is prohibited in the EU?',
fr: 'Laquelle de ces applications dIA est interdite dans lUE ?',
it: 'Quale di queste applicazioni di IA è vietata nellUE?',
es: '¿Cuál de estas aplicaciones de IA está prohibida en la UE?',
pl: 'Które z tych zastosowań AI jest zakazane w UE?',
cs: 'Které z těchto použití AI je v EU zakázané?',
sk: 'Ktoré z týchto použití AI je v EÚ zakázané?',
ro: 'Care dintre aceste utilizări ale IA este interzisă în UE?',
},
options: [
{
de: 'Rechtschreibkorrektur in E-Mails.',
en: 'Spell-checking in emails.',
fr: 'La correction orthographique dans les e-mails.',
it: 'La correzione ortografica nelle e-mail.',
es: 'La corrección ortográfica en los correos electrónicos.',
pl: 'Sprawdzanie pisowni w e-mailach.',
cs: 'Kontrola pravopisu v e-mailech.',
sk: 'Kontrola pravopisu v e-mailoch.',
ro: 'Corectarea ortografică în e-mailuri.',
},
{
de: 'Emotionserkennung zur Überwachung der Stimmung am Arbeitsplatz.',
en: 'Emotion recognition to monitor mood at the workplace.',
fr: 'La reconnaissance des émotions pour surveiller lhumeur sur le lieu de travail.',
it: 'Il riconoscimento delle emozioni per monitorare lumore sul posto di lavoro.',
es: 'El reconocimiento de emociones para vigilar el estado de ánimo en el trabajo.',
pl: 'Rozpoznawanie emocji do monitorowania nastrojów w miejscu pracy.',
cs: 'Rozpoznávání emocí ke sledování nálady na pracovišti.',
sk: 'Rozpoznávanie emócií na sledovanie nálady na pracovisku.',
ro: 'Recunoașterea emoțiilor pentru monitorizarea stării de spirit la locul de muncă.',
},
{
de: 'Automatische Übersetzung von Dokumenten.',
en: 'Automatic translation of documents.',
fr: 'La traduction automatique de documents.',
it: 'La traduzione automatica di documenti.',
es: 'La traducción automática de documentos.',
pl: 'Automatyczne tłumaczenie dokumentów.',
cs: 'Automatický překlad dokumentů.',
sk: 'Automatický preklad dokumentov.',
ro: 'Traducerea automată a documentelor.',
},
],
correctIndex: 1,
explanation: {
de: 'Art. 5 EU-KI-VO verbietet u. a. Emotionserkennung am Arbeitsplatz sowie Social Scoring und manipulative Techniken — seit Februar 2025.',
en: 'Art. 5 EU AI Act prohibits emotion recognition in the workplace, social scoring and manipulative techniques, among others — since February 2025.',
fr: 'Larticle 5 du règlement sur lIA interdit notamment la reconnaissance des émotions sur le lieu de travail, la notation sociale et les techniques manipulatrices — depuis février 2025.',
it: 'Larticolo 5 del regolamento sullIA vieta, tra laltro, il riconoscimento delle emozioni sul posto di lavoro, il punteggio sociale e le tecniche manipolative — da febbraio 2025.',
es: 'El artículo 5 del Reglamento de IA prohíbe, entre otras cosas, el reconocimiento de emociones en el trabajo, la puntuación social y las técnicas manipuladoras — desde febrero de 2025.',
pl: 'Art. 5 aktu w sprawie AI zakazuje m.in. rozpoznawania emocji w miejscu pracy, scoringu społecznego i technik manipulacyjnych — od lutego 2025 r.',
cs: 'Čl. 5 aktu o AI zakazuje mimo jiné rozpoznávání emocí na pracovišti, sociální skórování a manipulativní techniky — od února 2025.',
sk: 'Čl. 5 aktu o AI zakazuje okrem iného rozpoznávanie emócií na pracovisku, sociálne skórovanie a manipulatívne techniky — od februára 2025.',
ro: 'Art. 5 din Regulamentul privind IA interzice, printre altele, recunoașterea emoțiilor la locul de muncă, scorul social și tehnicile manipulative — din februarie 2025.',
},
},
{
id: 'q-highrisk',
question: {
de: 'Warum gelten für KI im Bewerber-Screening besonders strenge Regeln?',
en: 'Why do particularly strict rules apply to AI in applicant screening?',
fr: 'Pourquoi des règles particulièrement strictes sappliquent-elles à lIA de présélection des candidatures ?',
it: 'Perché allIA usata nella selezione dei candidati si applicano regole particolarmente severe?',
es: '¿Por qué se aplican reglas especialmente estrictas a la IA en la selección de candidatos?',
pl: 'Dlaczego AI stosowana przy selekcji kandydatów podlega szczególnie surowym zasadom?',
cs: 'Proč pro AI při výběru uchazečů platí obzvlášť přísná pravidla?',
sk: 'Prečo pre AI pri výbere uchádzačov platia obzvlášť prísne pravidlá?',
ro: 'De ce se aplică reguli deosebit de stricte pentru IA folosită la trierea candidaților?',
},
options: [
{
de: 'Weil sie über Lebenschancen von Menschen mitentscheidet — sie gilt als Hochrisiko-KI.',
en: 'Because it co-decides on peoples life chances — it counts as high-risk AI.',
fr: 'Parce quelle participe à des décisions qui influencent la vie des gens — elle est considérée comme une IA à haut risque.',
it: 'Perché contribuisce a decidere sulle opportunità di vita delle persone — è considerata IA ad alto rischio.',
es: 'Porque codecide sobre las oportunidades vitales de las personas — se considera IA de alto riesgo.',
pl: 'Bo współdecyduje o życiowych szansach ludzi — uznaje się ją za AI wysokiego ryzyka.',
cs: 'Protože spolurozhoduje o životních šancích lidí — považuje se za vysoce rizikovou AI.',
sk: 'Pretože spolurozhoduje o životných šanciach ľudí — považuje sa za vysokorizikovú AI.',
ro: 'Pentru că participă la decizii privind șansele în viață ale oamenilor — este considerată IA cu grad ridicat de risc.',
},
{
de: 'Weil sie teuer ist.',
en: 'Because it is expensive.',
fr: 'Parce quelle coûte cher.',
it: 'Perché è costosa.',
es: 'Porque es cara.',
pl: 'Bo jest droga.',
cs: 'Protože je drahá.',
sk: 'Pretože je drahá.',
ro: 'Pentru că e scumpă.',
},
{
de: 'Es gelten keine besonderen Regeln.',
en: 'No special rules apply.',
fr: 'Aucune règle particulière ne sapplique.',
it: 'Non si applicano regole particolari.',
es: 'No se aplican reglas especiales.',
pl: 'Nie obowiązują żadne szczególne zasady.',
cs: 'Žádná zvláštní pravidla neplatí.',
sk: 'Žiadne osobitné pravidlá neplatia.',
ro: 'Nu se aplică reguli speciale.',
},
],
correctIndex: 0,
explanation: {
de: 'Beschäftigungsbezogene KI (Auswahl, Beförderung, Kündigung) steht in Annex III der EU-KI-VO — Hochrisiko mit strengen Pflichten.',
en: 'Employment-related AI (selection, promotion, termination) is listed in Annex III of the EU AI Act — high-risk with strict obligations.',
fr: 'LIA liée à lemploi (sélection, promotion, licenciement) figure à lannexe III du règlement sur lIA — haut risque, avec des obligations strictes.',
it: 'LIA legata alloccupazione (selezione, promozione, licenziamento) figura nellallegato III del regolamento sullIA — alto rischio con obblighi severi.',
es: 'La IA relacionada con el empleo (selección, promoción, despido) figura en el anexo III del Reglamento de IA — alto riesgo con obligaciones estrictas.',
pl: 'AI związana z zatrudnieniem (rekrutacja, awanse, zwolnienia) figuruje w załączniku III aktu w sprawie AI — wysokie ryzyko i surowe obowiązki.',
cs: 'AI související se zaměstnáním (výběr, povýšení, výpověď) je uvedena v příloze III aktu o AI — vysoké riziko s přísnými povinnostmi.',
sk: 'AI súvisiaca so zamestnaním (výber, povýšenie, výpoveď) je uvedená v prílohe III aktu o AI — vysoké riziko s prísnymi povinnosťami.',
ro: 'IA legată de ocuparea forței de muncă (selecție, promovare, concediere) figurează în anexa III la Regulamentul privind IA — risc ridicat, cu obligații stricte.',
},
},
{
id: 'q-gdpr',
question: {
de: 'KI und personenbezogene Daten — was gilt?',
en: 'AI and personal data — what applies?',
fr: 'IA et données personnelles — quest-ce qui sapplique ?',
it: 'IA e dati personali — cosa vale?',
es: 'IA y datos personales — ¿qué se aplica?',
pl: 'AI a dane osobowe — co obowiązuje?',
cs: 'AI a osobní údaje — co platí?',
sk: 'AI a osobné údaje — čo platí?',
ro: 'IA și datele personale — ce reguli se aplică?',
},
options: [
{
de: 'Die DSGVO gilt bei KI nicht.',
en: 'The GDPR does not apply to AI.',
fr: 'Le RGPD ne sapplique pas à lIA.',
it: 'Il GDPR non si applica allIA.',
es: 'El RGPD no se aplica a la IA.',
pl: 'RODO nie obowiązuje przy AI.',
cs: 'GDPR se na AI nevztahuje.',
sk: 'GDPR sa na AI nevzťahuje.',
ro: 'RGPD nu se aplică în cazul IA.',
},
{
de: 'Die DSGVO gilt weiter: Rechtsgrundlage nötig, Datensparsamkeit, Betroffenenrechte.',
en: 'The GDPR continues to apply: legal basis required, data minimisation, data subject rights.',
fr: 'Le RGPD continue de sappliquer : base légale requise, minimisation des données, droits des personnes concernées.',
it: 'Il GDPR continua ad applicarsi: serve una base giuridica, minimizzazione dei dati, diritti degli interessati.',
es: 'El RGPD sigue aplicándose: se necesita base jurídica, minimización de datos, derechos de los interesados.',
pl: 'RODO obowiązuje nadal: potrzebna podstawa prawna, minimalizacja danych, prawa osób, których dane dotyczą.',
cs: 'GDPR platí dál: nutný právní základ, minimalizace údajů, práva subjektů údajů.',
sk: 'GDPR platí ďalej: potrebný právny základ, minimalizácia údajov, práva dotknutých osôb.',
ro: 'RGPD se aplică în continuare: e nevoie de temei juridic, minimizarea datelor, drepturile persoanelor vizate.',
},
{
de: 'Solange die KI die Daten nur „liest", ist alles erlaubt.',
en: 'As long as the AI only “reads” the data, everything is allowed.',
fr: 'Tant que lIA ne fait que « lire » les données, tout est permis.',
it: 'Finché lIA si limita a «leggere» i dati, è tutto permesso.',
es: 'Mientras la IA solo «lea» los datos, todo está permitido.',
pl: 'Dopóki AI tylko „czyta” dane, wszystko jest dozwolone.',
cs: 'Dokud AI data jen „čte", je vše dovoleno.',
sk: 'Kým AI údaje len „číta", je všetko dovolené.',
ro: 'Atâta timp cât IA doar „citește” datele, totul e permis.',
},
],
correctIndex: 1,
explanation: {
de: 'KI-Verarbeitung personenbezogener Daten ist Datenverarbeitung im Sinne der DSGVO — mit allen Pflichten, ggf. inkl. Datenschutz-Folgenabschätzung.',
en: 'AI processing of personal data is data processing under the GDPR — with all obligations, possibly including a data protection impact assessment.',
fr: 'Le traitement de données personnelles par une IA est un traitement au sens du RGPD — avec toutes les obligations, y compris, le cas échéant, une analyse dimpact relative à la protection des données.',
it: 'Il trattamento di dati personali da parte dellIA è un trattamento ai sensi del GDPR — con tutti gli obblighi, eventualmente inclusa una valutazione dimpatto sulla protezione dei dati.',
es: 'El tratamiento de datos personales por IA es un tratamiento en el sentido del RGPD — con todas las obligaciones, incluida, en su caso, una evaluación de impacto en la protección de datos.',
pl: 'Przetwarzanie danych osobowych przez AI to przetwarzanie danych w rozumieniu RODO — ze wszystkimi obowiązkami, w razie potrzeby łącznie z oceną skutków dla ochrony danych.',
cs: 'Zpracování osobních údajů pomocí AI je zpracováním údajů ve smyslu GDPR — se všemi povinnostmi, případně včetně posouzení vlivu na ochranu osobních údajů.',
sk: 'Spracúvanie osobných údajov pomocou AI je spracúvaním údajov v zmysle GDPR — so všetkými povinnosťami, prípadne vrátane posúdenia vplyvu na ochranu údajov.',
ro: 'Prelucrarea datelor personale de către IA este prelucrare de date în sensul RGPD — cu toate obligațiile, eventual inclusiv o evaluare a impactului asupra protecției datelor.',
},
},
{
id: 'q-incident',
question: {
de: 'Eine KI verhält sich merkwürdig oder diskriminiert offenbar. Was tun Sie?',
en: 'An AI behaves strangely or apparently discriminates. What do you do?',
fr: 'Une IA se comporte bizarrement ou semble discriminer. Que faites-vous ?',
it: 'UnIA si comporta in modo strano o sembra discriminare. Cosa fate?',
es: 'Una IA se comporta de forma extraña o aparentemente discrimina. ¿Qué hace usted?',
pl: 'AI zachowuje się dziwnie albo najwyraźniej dyskryminuje. Co robisz?',
cs: 'AI se chová podivně nebo zjevně diskriminuje. Co uděláte?',
sk: 'AI sa správa čudne alebo zjavne diskriminuje. Čo urobíte?',
ro: 'O IA se comportă ciudat sau aparent discriminează. Ce faceți?',
},
options: [
{
de: 'Weiter nutzen und hoffen, dass es sich gibt.',
en: 'Keep using it and hope it goes away.',
fr: 'Continuer à lutiliser en espérant que ça passe.',
it: 'Continuo a usarla sperando che passi da sola.',
es: 'Seguir usándola y esperar que se pase solo.',
pl: 'Używam dalej i mam nadzieję, że samo przejdzie.',
cs: 'Používám dál a doufám, že to přejde.',
sk: 'Používam ďalej a dúfam, že to prejde.',
ro: 'Continui să o folosesc și sper că trece de la sine.',
},
{
de: 'Sofort intern melden (KI-Beauftragte/r) — es gibt gesetzliche Meldefristen.',
en: 'Report it internally immediately (AI officer) — there are statutory reporting deadlines.',
fr: 'Le signaler immédiatement en interne (référent IA) — il existe des délais légaux de signalement.',
it: 'Lo segnalo subito internamente (referente IA) — esistono termini di segnalazione previsti per legge.',
es: 'Notificarlo internamente de inmediato (responsable de IA) — existen plazos legales de notificación.',
pl: 'Natychmiast zgłaszam wewnętrznie (pełnomocnik ds. AI) — istnieją ustawowe terminy zgłoszeń.',
cs: 'Okamžitě to nahlásím interně (pověřenec pro AI) — existují zákonné lhůty pro hlášení.',
sk: 'Okamžite to nahlásim interne (poverenec pre AI) — existujú zákonné lehoty na hlásenie.',
ro: 'O raportez imediat intern (responsabilul IA) — există termene legale de raportare.',
},
{
de: 'Das System heimlich abschalten und niemandem etwas sagen.',
en: 'Secretly switch the system off and tell no one.',
fr: 'Éteindre le système en douce et nen parler à personne.',
it: 'Spengo il sistema di nascosto e non lo dico a nessuno.',
es: 'Apagar el sistema a escondidas y no decirle nada a nadie.',
pl: 'Po cichu wyłączam system i nikomu nic nie mówię.',
cs: 'Systém potají vypnu a nikomu nic neřeknu.',
sk: 'Systém potajomky vypnem a nikomu nič nepoviem.',
ro: 'Opresc sistemul pe ascuns și nu spun nimănui nimic.',
},
],
correctIndex: 1,
explanation: {
de: 'Für schwerwiegende Vorfälle gelten Meldefristen von bis zu 15 Tagen (Art. 73). Deshalb: sofort intern melden — der Meldeweg steht in der internen Melderichtlinie.',
en: 'Serious incidents are subject to reporting deadlines of up to 15 days (Art. 73). Therefore: report internally at once — the channel is in the internal reporting policy.',
fr: 'Les incidents graves sont soumis à des délais de signalement pouvant aller jusquà 15 jours (article 73). Donc : signaler immédiatement en interne — la marche à suivre figure dans la directive interne de signalement.',
it: 'Per gli incidenti gravi valgono termini di segnalazione fino a 15 giorni (articolo 73). Quindi: segnalare subito internamente — la procedura è descritta nella direttiva interna sulle segnalazioni.',
es: 'Para los incidentes graves rigen plazos de notificación de hasta 15 días (artículo 73). Por eso: notificar internamente de inmediato — el procedimiento está en la política interna de notificación.',
pl: 'Dla poważnych incydentów obowiązują terminy zgłoszeń do 15 dni (art. 73). Dlatego: natychmiast zgłoś wewnętrznie — ścieżka zgłoszenia jest opisana w wewnętrznej procedurze zgłaszania.',
cs: 'Pro závažné incidenty platí lhůty pro hlášení až 15 dnů (čl. 73). Proto: okamžitě nahlásit interně — postup je popsán v interní směrnici pro hlášení.',
sk: 'Pre závažné incidenty platia lehoty na hlásenie do 15 dní (čl. 73). Preto: okamžite nahlásiť interne — postup je opísaný v internej smernici pre hlásenie.',
ro: 'Pentru incidentele grave se aplică termene de raportare de până la 15 zile (art. 73). De aceea: raportați imediat intern — procedura este descrisă în politica internă de raportare.',
},
},
{
id: 'q-shadow',
question: {
de: 'Sie finden ein tolles neues KI-Tool im Internet. Dürfen Sie es für die Arbeit nutzen?',
en: 'You find a great new AI tool on the internet. May you use it for work?',
fr: 'Vous découvrez un super nouvel outil dIA sur Internet. Avez-vous le droit de lutiliser pour le travail ?',
it: 'Trovate su Internet un nuovo fantastico strumento di IA. Potete usarlo per il lavoro?',
es: 'Encuentra en Internet una nueva herramienta de IA estupenda. ¿Puede usarla para el trabajo?',
pl: 'Znajdujesz w internecie świetne nowe narzędzie AI. Czy możesz używać go w pracy?',
cs: 'Najdete na internetu skvělý nový AI nástroj. Smíte ho používat pro práci?',
sk: 'Nájdete na internete skvelý nový AI nástroj. Smiete ho používať v práci?',
ro: 'Găsiți pe internet un instrument de IA nou și grozav. Aveți voie să-l folosiți la muncă?',
},
options: [
{
de: 'Ja — was nichts kostet, kann man nutzen.',
en: 'Yes — if it is free, you can use it.',
fr: 'Oui — ce qui est gratuit peut être utilisé.',
it: 'Sì — se è gratis, si può usare.',
es: 'Sí — lo que es gratis se puede usar.',
pl: 'Tak — co nic nie kosztuje, można używać.',
cs: 'Ano — co nic nestojí, to se může používat.',
sk: 'Áno — čo nič nestojí, to sa môže používať.',
ro: 'Da — ce e gratuit se poate folosi.',
},
{
de: 'Ja, wenn Kolleginnen und Kollegen es auch benutzen.',
en: 'Yes, if colleagues use it too.',
fr: 'Oui, si les collègues lutilisent aussi.',
it: 'Sì, se lo usano anche i colleghi.',
es: 'Sí, si los compañeros también lo usan.',
pl: 'Tak, jeśli koleżanki i koledzy też go używają.',
cs: 'Ano, pokud ho používají i kolegové.',
sk: 'Áno, ak ho používajú aj kolegovia.',
ro: 'Da, dacă îl folosesc și colegii.',
},
{
de: 'Erst nach interner Freigabe — sonst entsteht „Schatten-KI" ohne Kontrolle.',
en: 'Only after internal approval — otherwise “shadow AI” arises without control.',
fr: 'Seulement après approbation interne — sinon on crée de l« IA fantôme » sans aucun contrôle.',
it: 'Solo dopo lapprovazione interna — altrimenti nasce una «IA ombra» senza controllo.',
es: 'Solo tras la aprobación interna — si no, surge «IA en la sombra» sin control.',
pl: 'Dopiero po wewnętrznym zatwierdzeniu — inaczej powstaje „shadow AI” bez żadnej kontroli.',
cs: 'Až po interním schválení — jinak vzniká „stínová AI" bez kontroly.',
sk: 'Až po internom schválení — inak vzniká „tieňová AI" bez kontroly.',
ro: 'Doar după aprobarea internă — altfel apare „IA din umbră” fără control.',
},
],
correctIndex: 2,
explanation: {
de: 'Nicht freigegebene Tools umgehen Datenschutz-, Sicherheits- und KI-Prüfungen. Es gilt der Freigabeprozess (Freigabeantrag KI-System).',
en: 'Unapproved tools bypass data protection, security and AI checks. The approval process applies (AI system approval request).',
fr: 'Les outils non approuvés contournent les contrôles de protection des données, de sécurité et dIA. Le processus dapprobation sapplique (demande dapprobation de système dIA).',
it: 'Gli strumenti non approvati aggirano i controlli su protezione dei dati, sicurezza e IA. Vale il processo di approvazione (richiesta di approvazione del sistema di IA).',
es: 'Las herramientas no aprobadas eluden los controles de protección de datos, seguridad e IA. Se aplica el proceso de aprobación (solicitud de aprobación de sistema de IA).',
pl: 'Niezatwierdzone narzędzia omijają kontrole ochrony danych, bezpieczeństwa i AI. Obowiązuje proces zatwierdzania (wniosek o zatwierdzenie systemu AI).',
cs: 'Neschválené nástroje obcházejí kontroly ochrany údajů, bezpečnosti a AI. Platí schvalovací proces (žádost o schválení AI systému).',
sk: 'Neschválené nástroje obchádzajú kontroly ochrany údajov, bezpečnosti a AI. Platí schvaľovací proces (žiadosť o schválenie AI systému).',
ro: 'Instrumentele neaprobate ocolesc verificările de protecție a datelor, securitate și IA. Se aplică procesul de aprobare (cerere de aprobare a sistemului de IA).',
},
},
{
id: 'q-content',
question: {
de: 'Sie veröffentlichen einen KI-generierten Text oder ein KI-Bild. Was ist zu beachten?',
en: 'You publish an AI-generated text or image. What must you consider?',
fr: 'Vous publiez un texte ou une image générés par IA. À quoi faut-il faire attention ?',
it: 'Pubblicate un testo o unimmagine generati dallIA. A cosa bisogna fare attenzione?',
es: 'Usted publica un texto o una imagen generados por IA. ¿Qué hay que tener en cuenta?',
pl: 'Publikujesz tekst lub obraz wygenerowany przez AI. Na co trzeba uważać?',
cs: 'Zveřejňujete text nebo obrázek vytvořený AI. Na co je třeba dbát?',
sk: 'Zverejňujete text alebo obrázok vytvorený AI. Na čo treba dbať?',
ro: 'Publicați un text sau o imagine generate de IA. La ce trebuie să fiți atenți?',
},
options: [
{
de: 'Inhalt fachlich prüfen und KI-generierte Inhalte gemäß Vorgaben kennzeichnen.',
en: 'Review the content professionally and mark AI-generated content according to the rules.',
fr: 'Vérifier le contenu sur le fond et signaler les contenus générés par IA conformément aux règles.',
it: 'Verificare il contenuto nel merito ed etichettare i contenuti generati dallIA secondo le regole.',
es: 'Revisar el contenido a fondo y marcar los contenidos generados por IA según las normas.',
pl: 'Sprawdzić treść merytorycznie i oznaczyć treści wygenerowane przez AI zgodnie z wytycznymi.',
cs: 'Obsah odborně zkontrolovat a obsah vytvořený AI označit podle pravidel.',
sk: 'Obsah odborne skontrolovať a obsah vytvorený AI označiť podľa pravidiel.',
ro: 'Verific conținutul pe fond și marchez conținutul generat de IA conform regulilor.',
},
{
de: 'Nichts — was die KI erstellt, gehört automatisch dem Unternehmen und stimmt.',
en: 'Nothing — whatever the AI creates automatically belongs to the company and is correct.',
fr: 'Rien — ce que lIA crée appartient automatiquement à lentreprise et est exact.',
it: 'Niente — ciò che crea lIA appartiene automaticamente allazienda ed è corretto.',
es: 'Nada — lo que crea la IA pertenece automáticamente a la empresa y es correcto.',
pl: 'Nic — co tworzy AI, automatycznie należy do firmy i jest poprawne.',
cs: 'Nic — co AI vytvoří, patří automaticky firmě a je to správně.',
sk: 'Nič — čo AI vytvorí, patrí automaticky firme a je to správne.',
ro: 'Nimic — ce creează IA aparține automat companiei și este corect.',
},
{
de: 'Nur die Rechtschreibung prüfen.',
en: 'Only check the spelling.',
fr: 'Vérifier seulement lorthographe.',
it: 'Controllare solo lortografia.',
es: 'Revisar solo la ortografía.',
pl: 'Sprawdzić tylko pisownię.',
cs: 'Zkontrolovat jen pravopis.',
sk: 'Skontrolovať len pravopis.',
ro: 'Verific doar ortografia.',
},
],
correctIndex: 0,
explanation: {
de: 'KI-Inhalte können Fehler, fremde Rechte oder Verzerrungen enthalten; synthetische Inhalte sind zu kennzeichnen (Art. 50) und Deepfakes sichtbar zu markieren.',
en: 'AI content can contain errors, third-party rights or bias; synthetic content must be marked (Art. 50) and deepfakes visibly labelled.',
fr: 'Les contenus dIA peuvent contenir des erreurs, des droits de tiers ou des biais ; les contenus synthétiques doivent être signalés (article 50) et les deepfakes marqués de façon visible.',
it: 'I contenuti dellIA possono contenere errori, diritti di terzi o distorsioni; i contenuti sintetici vanno etichettati (articolo 50) e i deepfake contrassegnati in modo visibile.',
es: 'Los contenidos de IA pueden contener errores, derechos de terceros o sesgos; los contenidos sintéticos deben marcarse (artículo 50) y los deepfakes etiquetarse de forma visible.',
pl: 'Treści AI mogą zawierać błędy, prawa osób trzecich lub uprzedzenia; treści syntetyczne trzeba oznaczać (art. 50), a deepfaki wyraźnie oznaczać.',
cs: 'Obsah z AI může obsahovat chyby, práva třetích stran nebo zkreslení; syntetický obsah je nutné označit (čl. 50) a deepfaky viditelně vyznačit.',
sk: 'Obsah z AI môže obsahovať chyby, práva tretích strán alebo skreslenia; syntetický obsah treba označiť (čl. 50) a deepfaky viditeľne vyznačiť.',
ro: 'Conținutul IA poate conține erori, drepturi ale terților sau distorsiuni; conținutul sintetic trebuie marcat (art. 50), iar deepfake-urile etichetate vizibil.',
},
},
{
id: 'q-art4',
question: {
de: 'Warum machen Sie diesen Test überhaupt?',
en: 'Why are you taking this test in the first place?',
fr: 'Au fait, pourquoi passez-vous ce test ?',
it: 'Ma perché state facendo questo test?',
es: '¿Por qué está haciendo este test, en realidad?',
pl: 'Właściwie po co w ogóle robisz ten test?',
cs: 'Proč vlastně tento test děláte?',
sk: 'Prečo vlastne tento test robíte?',
ro: 'De ce faceți, de fapt, acest test?',
},
options: [
{
de: 'Reine Firmen-Schikane.',
en: 'Pure company chicanery.',
fr: 'Pure brimade de lentreprise.',
it: 'Pura vessazione aziendale.',
es: 'Pura tortura de la empresa.',
pl: 'Czysta firmowa szykana.',
cs: 'Čistá firemní šikana.',
sk: 'Čistá firemná šikana.',
ro: 'Curată șicană din partea firmei.',
},
{
de: 'Art. 4 EU-KI-VO verpflichtet Unternehmen seit Februar 2025, KI-Kompetenz ihres Personals sicherzustellen — dieser Test ist Teil des Nachweises.',
en: 'Art. 4 EU AI Act has obliged companies since February 2025 to ensure their staffs AI literacy — this test is part of the evidence.',
fr: 'Larticle 4 du règlement européen sur lIA oblige les entreprises, depuis février 2025, à garantir la maîtrise de lIA de leur personnel — ce test fait partie de la preuve.',
it: 'Larticolo 4 del regolamento europeo sullIA obbliga le aziende, da febbraio 2025, a garantire lalfabetizzazione in materia di IA del proprio personale — questo test fa parte della documentazione.',
es: 'El artículo 4 del Reglamento europeo de IA obliga a las empresas, desde febrero de 2025, a garantizar la alfabetización en materia de IA de su personal — este test forma parte de la prueba.',
pl: 'Art. 4 unijnego aktu w sprawie AI od lutego 2025 r. zobowiązuje firmy do zapewnienia kompetencji w zakresie AI swojego personelu — ten test jest częścią dowodu.',
cs: 'Čl. 4 aktu EU o AI od února 2025 ukládá firmám povinnost zajistit gramotnost v oblasti AI u svých zaměstnanců — tento test je součástí dokladu.',
sk: 'Čl. 4 aktu EÚ o AI od februára 2025 ukladá firmám povinnosť zabezpečiť gramotnosť v oblasti AI u svojich zamestnancov — tento test je súčasťou dokladu.',
ro: 'Art. 4 din Regulamentul UE privind IA obligă companiile, din februarie 2025, să asigure alfabetizarea în domeniul IA a personalului — acest test face parte din dovadă.',
},
{
de: 'Die KI hat es so angeordnet.',
en: 'The AI ordered it.',
fr: 'Cest lIA qui la ordonné.',
it: 'Lha ordinato lIA.',
es: 'La IA lo ha ordenado así.',
pl: 'Tak zarządziła AI.',
cs: 'Nařídila to AI.',
sk: 'Nariadila to AI.',
ro: 'Așa a ordonat IA.',
},
],
correctIndex: 1,
explanation: {
de: 'Die KI-Kompetenzpflicht (Art. 4) gilt für alle Anbieter und Betreiber von KI — unabhängig von der Risikoklasse. Geschulte Beschäftigte sind die wichtigste Schutzmaßnahme.',
en: 'The AI literacy duty (Art. 4) applies to all providers and deployers of AI — regardless of risk class. Trained staff are the most important safeguard.',
fr: 'Lobligation de maîtrise de lIA (article 4) sapplique à tous les fournisseurs et déployeurs dIA — quelle que soit la classe de risque. Un personnel formé est la mesure de protection la plus importante.',
it: 'Lobbligo di alfabetizzazione in materia di IA (articolo 4) vale per tutti i fornitori e i deployer di IA — indipendentemente dalla classe di rischio. Il personale formato è la misura di protezione più importante.',
es: 'La obligación de alfabetización en materia de IA (artículo 4) se aplica a todos los proveedores y responsables del despliegue de IA — con independencia de la clase de riesgo. El personal formado es la medida de protección más importante.',
pl: 'Obowiązek zapewnienia kompetencji w zakresie AI (art. 4) dotyczy wszystkich dostawców i podmiotów stosujących AI — niezależnie od klasy ryzyka. Przeszkolony personel to najważniejszy środek ochrony.',
cs: 'Povinnost gramotnosti v oblasti AI (čl. 4) platí pro všechny poskytovatele AI a zavádějící subjekty — bez ohledu na rizikovou třídu. Proškolení zaměstnanci jsou nejdůležitějším ochranným opatřením.',
sk: 'Povinnosť gramotnosti v oblasti AI (čl. 4) platí pre všetkých poskytovateľov AI a nasadzujúce subjekty — bez ohľadu na rizikovú triedu. Vyškolení zamestnanci sú najdôležitejším ochranným opatrením.',
ro: 'Obligația de alfabetizare în domeniul IA (art. 4) se aplică tuturor furnizorilor și implementatorilor de IA — indiferent de clasa de risc. Personalul instruit este cea mai importantă măsură de protecție.',
},
},
];

View File

@ -0,0 +1,137 @@
import { describe, expect, it } from 'vitest';
import { CONTENT_PACK, getContentPack } from '../content/pack';
import { classify } from './classify';
import { aiPolicy, trainingPlan, worksAgreement } from './templatesCompany';
import { approvalRequest, auditChecklist, reportingPolicy } from './templatesInternal';
import { employeeInfo, friaTemplate, incidentReportForm, worksCouncilInfo } from './templatesSystem';
import type { AISystem, AssessmentAnswers, CompanyProfile } from './types';
const answers: AssessmentAnswers = {
isAISystem: true,
role: 'deployer',
isGPAIModel: false,
prohibitedPractices: [],
annexIIICategories: ['a3-employment'],
art63Exception: false,
involvesProfiling: false,
isAnnexISafetyComponent: false,
transparencyTriggers: [],
};
const system: AISystem = {
id: 'sys-1',
name: 'Bewerber-Screening',
purpose: 'Vorauswahl',
vendor: 'ACME',
owner: 'Jane',
createdAt: '2026-07-01T00:00:00.000Z',
updatedAt: '2026-07-01T00:00:00.000Z',
answers,
classification: classify(answers, CONTENT_PACK),
obligationStatus: {},
};
const profile: CompanyProfile = {
name: 'Muster GmbH',
street: '',
zipCity: '',
contactPerson: '',
email: '',
phone: '',
website: '',
logoDataUrl: '',
countries: ['DE'],
};
const TODAY = '2026-07-04';
describe('systembezogene Vordrucke', () => {
it('Betriebsrats-Information nennt § 90 und § 87 BetrVG', () => {
const md = worksCouncilInfo(system, CONTENT_PACK, TODAY, profile);
expect(md).toContain('§ 90');
expect(md).toContain('§ 87 Abs. 1 Nr. 6');
expect(md).toContain('Muster GmbH');
expect(md).toContain('keine Rechtsberatung');
});
it('Mitarbeiterinformation verweist auf Art. 26 Abs. 7', () => {
const md = employeeInfo(system, CONTENT_PACK, TODAY, profile);
expect(md).toContain('Art. 26 Abs. 7');
expect(md).toContain('Bewerber-Screening');
});
it('FRIA-Vorlage enthält die Art.-27-Prüfschritte', () => {
const md = friaTemplate(system, CONTENT_PACK, TODAY, profile);
expect(md).toContain('Art. 27');
expect(md).toContain('Grundrechte');
expect(md).toContain('_[AUSFÜLLEN]_');
});
it('Vorfallmeldung nennt die Art.-73-Fristen (15/10/2 Tage)', () => {
const md = incidentReportForm(system, CONTENT_PACK, TODAY, profile);
expect(md).toContain('Art. 73');
expect(md).toContain('15 Tage');
expect(md).toContain('2 Tage');
});
it('Vordrucke sind auch auf Englisch verfügbar', () => {
const md = worksCouncilInfo(system, getContentPack('en'), TODAY, profile, 'en');
expect(md).toContain('works council');
expect(md).toContain('Sec. 90 BetrVG');
});
});
describe('unternehmensweite Vorlagen', () => {
it('KI-Richtlinie enthält Kernabschnitte', () => {
const md = aiPolicy(CONTENT_PACK, TODAY, profile);
expect(md).toContain('KI-Richtlinie');
expect(md).toContain('Verbotene Nutzungen');
expect(md).toContain('Art. 50');
});
it('Schulungsplan listet betroffene Systeme', () => {
const md = trainingPlan([system], CONTENT_PACK, TODAY, profile);
expect(md).toContain('Art. 4');
expect(md).toContain('Schulungsmatrix');
expect(md).toContain('Bewerber-Screening');
});
it('Betriebsvereinbarung enthält Paragrafen und Unterschriftszeile', () => {
const md = worksAgreement(CONTENT_PACK, TODAY, profile);
expect(md).toContain('§ 1 Geltungsbereich');
expect(md).toContain('§ 3 Keine vollautomatisierten Personalentscheidungen');
expect(md).toContain('Betriebsrat: _______________');
});
});
describe('interne Prozess-Dokumente', () => {
it('Melderichtlinie enthält interne Fristen, Eskalationsstufen und HinSchG-Schutz', () => {
const md = reportingPolicy(CONTENT_PACK, TODAY, profile);
expect(md).toContain('interne Meldepflicht');
expect(md).toContain('24 Stunden');
expect(md).toContain('Eskalationsstufen');
expect(md).toContain('HinSchG');
expect(md).toContain('Art. 73');
});
it('Freigabeantrag enthält Prüffelder und Entscheidungsblock', () => {
const md = approvalRequest(CONTENT_PACK, TODAY, profile);
expect(md).toContain('Freigabeantrag');
expect(md).toContain('Risiko-Voreinschätzung');
expect(md).toContain('☐ freigegeben');
expect(md).toContain('KI-Inventar');
});
it('Audit-Checkliste enthält nummerierte Prüfpunkte und Abzeichnung', () => {
const md = auditChecklist(CONTENT_PACK, TODAY, profile);
expect(md).toContain('| 1 |');
expect(md).toContain('Schatten-IT');
expect(md).toContain('Abzeichnung');
});
it('interne Dokumente sind auch auf Englisch verfügbar', () => {
const md = reportingPolicy(getContentPack('en'), TODAY, profile, 'en');
expect(md).toContain('escalation policy');
expect(md).toContain('within 24 hours');
});
});

View File

@ -0,0 +1,504 @@
import type { Locale } from '../i18n/types';
import { docStrings, formatDocDate } from './docStrings';
import type { AISystem, CompanyProfile, ContentPack } from './types';
/** Gemeinsamer Kopf für unternehmensweite Vordrucke. */
function head(
title: string,
pack: ContentPack,
today: string,
locale: Locale,
profile?: CompanyProfile,
): string {
const s = docStrings(locale);
const company = profile && profile.name.trim() !== '' ? profile.name : '_______________';
return [
`# ${title}`,
'',
`**${s.meta.company}:** ${company} · **${s.meta.createdAt}:** ${formatDocDate(today, locale)} · Content-Pack v${pack.version}`,
'',
s.disclaimer,
'',
].join('\n');
}
/** Vordruck: Interne KI-Richtlinie (AI Policy) — Rahmenentwurf. */
export function aiPolicy(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const T_ALL = {
de: {
title: 'Interne KI-Richtlinie (Rahmenentwurf)',
sections: [
['Geltungsbereich', 'Diese Richtlinie gilt für alle Beschäftigten und regelt die Nutzung von KI-Systemen und KI-generierten Inhalten im Unternehmen.'],
['Freigegebene KI-Systeme', 'Für dienstliche Zwecke dürfen nur KI-Systeme genutzt werden, die im KI-Inventar des Unternehmens gelistet sind. Neue Tools bedürfen der vorherigen Freigabe durch [zuständige Stelle].'],
['Verbotene Nutzungen', 'Die Eingabe von Geschäftsgeheimnissen, personenbezogenen Daten oder Kundendaten in nicht freigegebene KI-Dienste ist untersagt. Nach Art. 5 EU-KI-VO verbotene Praktiken dürfen weder umgesetzt noch beauftragt werden.'],
['Menschliche Aufsicht', 'KI-Ausgaben, die personenwirksame Entscheidungen unterstützen, werden vor Wirksamwerden durch eine fachkundige Person geprüft.'],
['Transparenz', 'KI-Interaktion mit Kunden und KI-generierte Inhalte werden gemäß Art. 50 EU-KI-VO offengelegt bzw. gekennzeichnet.'],
['Datenschutz', 'DSGVO-Anforderungen (Rechtsgrundlage, Informationspflichten, ggf. DSFA) werden vor jedem Einsatz geprüft.'],
['Schulung', 'Alle Beschäftigten, die KI nutzen, erhalten rollengerechte Schulungen (Art. 4 EU-KI-VO); die Teilnahme wird dokumentiert.'],
['Vorfälle', 'Fehlfunktionen und mutmaßlich schwerwiegende Vorfälle sind unverzüglich an [Kontakt] zu melden; es gilt der Meldeprozess nach Art. 73.'],
['Verantwortlichkeiten', 'KI-Beauftragte/r: [Name]. Datenschutzbeauftragte/r: [Name]. Einbindung des Betriebsrats gemäß BetrVG/Betriebsvereinbarung.'],
['Inkrafttreten und Überprüfung', 'Diese Richtlinie tritt am [Datum] in Kraft und wird mindestens jährlich überprüft.'],
],
},
en: {
title: 'Internal AI policy (draft framework)',
sections: [
['Scope', 'This policy applies to all employees and governs the use of AI systems and AI-generated content in the company.'],
['Approved AI systems', 'Only AI systems listed in the company AI inventory may be used for business purposes. New tools require prior approval by [responsible unit].'],
['Prohibited uses', 'Entering trade secrets, personal data or customer data into non-approved AI services is prohibited. Practices prohibited under Art. 5 EU AI Act must not be implemented or commissioned.'],
['Human oversight', 'AI output supporting decisions affecting persons must be reviewed by a competent human before taking effect.'],
['Transparency', 'AI interaction with customers and AI-generated content is disclosed and marked in accordance with Art. 50 EU AI Act.'],
['Data protection', 'GDPR requirements (legal basis, information duties, DPIA where required) are checked before any deployment.'],
['Training', 'All employees using AI receive training appropriate to their role (Art. 4 EU AI Act); participation is documented.'],
['Incidents', 'Malfunctions and suspected serious incidents must be reported immediately to [contact]; the Art. 73 reporting process applies.'],
['Responsibilities', 'AI officer: [name]. Data protection officer: [name]. Works council involvement per BetrVG/works agreement.'],
['Entry into force and review', 'This policy enters into force on [date] and is reviewed at least annually.'],
],
},
fr: {
title: 'Politique interne dIA (projet de cadre)',
sections: [
['Champ dapplication', 'La présente politique sapplique à lensemble des salariés et régit lutilisation des systèmes dIA et des contenus générés par lIA dans lentreprise.'],
['Systèmes dIA approuvés', 'Seuls les systèmes dIA figurant dans linventaire IA de lentreprise peuvent être utilisés à des fins professionnelles. Les nouveaux outils nécessitent lapprobation préalable de [service compétent].'],
['Utilisations interdites', 'Il est interdit de saisir des secrets daffaires, des données personnelles ou des données clients dans des services dIA non approuvés. Les pratiques interdites par lart. 5 du règlement européen sur lIA ne doivent être ni mises en œuvre ni commandées.'],
['Contrôle humain', 'Les sorties dIA qui appuient des décisions affectant des personnes doivent être vérifiées par une personne compétente avant de prendre effet.'],
['Transparence', 'Linteraction de lIA avec les clients et les contenus générés par lIA sont divulgués et marqués conformément à lart. 50 du règlement européen sur lIA.'],
['Protection des données', 'Les exigences du RGPD (base juridique, obligations dinformation, AIPD le cas échéant) sont vérifiées avant tout déploiement.'],
['Formation', 'Tous les salariés utilisant lIA reçoivent une formation adaptée à leur rôle au titre de la maîtrise de lIA (art. 4 du règlement européen sur lIA) ; la participation est documentée.'],
['Incidents', 'Les dysfonctionnements et les incidents graves présumés doivent être signalés immédiatement à [contact] ; le processus de signalement de lart. 73 sapplique.'],
['Responsabilités', 'Référent IA : [nom]. Délégué à la protection des données : [nom]. Implication du comité dentreprise conformément au BetrVG/à laccord dentreprise.'],
['Entrée en vigueur et révision', 'La présente politique entre en vigueur le [date] et est révisée au moins une fois par an.'],
],
},
it: {
title: 'Policy interna sullIA (bozza di quadro)',
sections: [
['Ambito di applicazione', 'La presente policy si applica a tutti i dipendenti e disciplina luso dei sistemi di IA e dei contenuti generati dallIA in azienda.'],
['Sistemi di IA approvati', 'Per scopi aziendali possono essere utilizzati solo i sistemi di IA elencati nellinventario IA dellazienda. I nuovi strumenti richiedono lapprovazione preventiva di [funzione competente].'],
['Usi vietati', 'È vietato inserire segreti commerciali, dati personali o dati dei clienti in servizi di IA non approvati. Le pratiche vietate dallart. 5 del regolamento europeo sullIA non devono essere né attuate né commissionate.'],
['Sorveglianza umana', 'Gli output dellIA che supportano decisioni con effetti sulle persone devono essere verificati da una persona competente prima di produrre effetti.'],
['Trasparenza', 'Linterazione dellIA con i clienti e i contenuti generati dallIA sono resi noti e contrassegnati ai sensi dellart. 50 del regolamento europeo sullIA.'],
['Protezione dei dati', 'I requisiti del GDPR (base giuridica, obblighi informativi, DPIA ove necessaria) vengono verificati prima di ogni impiego.'],
['Formazione', 'Tutti i dipendenti che utilizzano lIA ricevono una formazione adeguata al ruolo nellambito dellalfabetizzazione IA (art. 4 del regolamento europeo sullIA); la partecipazione viene documentata.'],
['Incidenti', 'Malfunzionamenti e presunti incidenti gravi devono essere segnalati immediatamente a [contatto]; si applica il processo di segnalazione di cui allart. 73.'],
['Responsabilità', 'Referente IA: [nome]. Responsabile della protezione dei dati: [nome]. Coinvolgimento del consiglio aziendale ai sensi del BetrVG/dellaccordo aziendale.'],
['Entrata in vigore e revisione', 'La presente policy entra in vigore il [data] ed è riesaminata almeno una volta allanno.'],
],
},
es: {
title: 'Política interna de IA (borrador marco)',
sections: [
['Ámbito de aplicación', 'Esta política se aplica a todos los empleados y regula el uso de sistemas de IA y de contenidos generados por IA en la empresa.'],
['Sistemas de IA aprobados', 'Para fines profesionales solo pueden utilizarse los sistemas de IA incluidos en el inventario de IA de la empresa. Las nuevas herramientas requieren la aprobación previa de [unidad responsable].'],
['Usos prohibidos', 'Está prohibido introducir secretos comerciales, datos personales o datos de clientes en servicios de IA no aprobados. Las prácticas prohibidas por el art. 5 del Reglamento europeo de IA no deben implementarse ni encargarse.'],
['Supervisión humana', 'Los resultados de IA que apoyen decisiones con efectos sobre personas deben ser revisados por una persona competente antes de surtir efecto.'],
['Transparencia', 'La interacción de la IA con los clientes y los contenidos generados por IA se divulgan y se marcan conforme al art. 50 del Reglamento europeo de IA.'],
['Protección de datos', 'Los requisitos del RGPD (base jurídica, deberes de información, EIPD cuando proceda) se comprueban antes de cada despliegue.'],
['Formación', 'Todos los empleados que utilizan IA reciben formación adecuada a su función en el marco de la alfabetización en IA (art. 4 del Reglamento europeo de IA); la participación se documenta.'],
['Incidentes', 'Los fallos de funcionamiento y los presuntos incidentes graves deben comunicarse de inmediato a [contacto]; se aplica el proceso de notificación del art. 73.'],
['Responsabilidades', 'Responsable de IA: [nombre]. Delegado de protección de datos: [nombre]. Participación del comité de empresa conforme al BetrVG/acuerdo de empresa.'],
['Entrada en vigor y revisión', 'Esta política entra en vigor el [fecha] y se revisa al menos una vez al año.'],
],
},
pl: {
title: 'Wewnętrzna polityka AI (projekt ramowy)',
sections: [
['Zakres obowiązywania', 'Niniejsza polityka obowiązuje wszystkich pracowników i reguluje korzystanie z systemów AI oraz treści generowanych przez AI w przedsiębiorstwie.'],
['Zatwierdzone systemy AI', 'Do celów służbowych wolno korzystać wyłącznie z systemów AI ujętych w firmowym rejestrze AI. Nowe narzędzia wymagają uprzedniego zatwierdzenia przez [właściwą jednostkę].'],
['Zakazane zastosowania', 'Wprowadzanie tajemnic przedsiębiorstwa, danych osobowych lub danych klientów do niezatwierdzonych usług AI jest zabronione. Praktyki zakazane na mocy art. 5 europejskiego rozporządzenia w sprawie AI nie mogą być ani wdrażane, ani zlecane.'],
['Nadzór człowieka', 'Wyniki AI wspierające decyzje wywierające skutki wobec osób są przed ich wejściem w życie weryfikowane przez kompetentną osobę.'],
['Przejrzystość', 'Interakcja AI z klientami oraz treści generowane przez AI są ujawniane i oznaczane zgodnie z art. 50 europejskiego rozporządzenia w sprawie AI.'],
['Ochrona danych', 'Wymogi RODO (podstawa prawna, obowiązki informacyjne, w razie potrzeby DPIA) są weryfikowane przed każdym wdrożeniem.'],
['Szkolenia', 'Wszyscy pracownicy korzystający z AI otrzymują szkolenia dostosowane do roli w ramach kompetencji w zakresie AI (art. 4 europejskiego rozporządzenia w sprawie AI); udział jest dokumentowany.'],
['Incydenty', 'Nieprawidłowe działanie i podejrzenia poważnych incydentów należy niezwłocznie zgłaszać do [kontakt]; obowiązuje proces zgłaszania zgodnie z art. 73.'],
['Zakresy odpowiedzialności', 'Pełnomocnik ds. AI: [imię i nazwisko]. Inspektor ochrony danych: [imię i nazwisko]. Udział rady zakładowej zgodnie z BetrVG/porozumieniem zakładowym.'],
['Wejście w życie i przegląd', 'Niniejsza polityka wchodzi w życie w dniu [data] i podlega przeglądowi co najmniej raz w roku.'],
],
},
cs: {
title: 'Interní politika AI (rámcový návrh)',
sections: [
['Oblast působnosti', 'Tato politika platí pro všechny zaměstnance a upravuje používání systémů AI a obsahu generovaného AI ve společnosti.'],
['Schválené systémy AI', 'Pro pracovní účely smí být používány pouze systémy AI uvedené v inventáři AI společnosti. Nové nástroje vyžadují předchozí schválení ze strany [příslušné místo].'],
['Zakázaná použití', 'Zadávání obchodních tajemství, osobních údajů nebo údajů zákazníků do neschválených služeb AI je zakázáno. Praktiky zakázané podle čl. 5 evropského nařízení o AI nesmí být zaváděny ani zadávány.'],
['Lidský dohled', 'Výstupy AI, které podporují rozhodnutí s dopadem na osoby, jsou před nabytím účinnosti přezkoumány odborně způsobilou osobou.'],
['Transparentnost', 'Interakce AI se zákazníky a obsah generovaný AI jsou zveřejňovány a označovány v souladu s čl. 50 evropského nařízení o AI.'],
['Ochrana osobních údajů', 'Požadavky GDPR (právní základ, informační povinnosti, případně DPIA) jsou ověřovány před každým nasazením.'],
['Školení', 'Všichni zaměstnanci používající AI absolvují školení odpovídající jejich roli v rámci gramotnosti v oblasti AI (čl. 4 evropského nařízení o AI); účast je dokumentována.'],
['Incidenty', 'Poruchy a podezření na závažné incidenty je nutno neprodleně hlásit na [kontakt]; platí proces hlášení podle čl. 73.'],
['Odpovědnosti', 'Pověřenec pro AI: [jméno]. Pověřenec pro ochranu osobních údajů: [jméno]. Zapojení podnikové rady podle BetrVG/podnikové dohody.'],
['Nabytí účinnosti a přezkum', 'Tato politika nabývá účinnosti dne [datum] a je přezkoumávána nejméně jednou ročně.'],
],
},
sk: {
title: 'Interná politika AI (rámcový návrh)',
sections: [
['Rozsah pôsobnosti', 'Táto politika platí pre všetkých zamestnancov a upravuje používanie systémov AI a obsahu generovaného AI v spoločnosti.'],
['Schválené systémy AI', 'Na pracovné účely sa smú používať len systémy AI uvedené v inventári AI spoločnosti. Nové nástroje vyžadujú predchádzajúce schválenie zo strany [príslušný útvar].'],
['Zakázané použitia', 'Zadávanie obchodných tajomstiev, osobných údajov alebo údajov zákazníkov do neschválených služieb AI je zakázané. Praktiky zakázané podľa čl. 5 európskeho nariadenia o AI sa nesmú zavádzať ani zadávať.'],
['Ľudský dohľad', 'Výstupy AI, ktoré podporujú rozhodnutia s dosahom na osoby, pred nadobudnutím účinnosti preverí odborne spôsobilá osoba.'],
['Transparentnosť', 'Interakcia AI so zákazníkmi a obsah generovaný AI sa zverejňujú a označujú v súlade s čl. 50 európskeho nariadenia o AI.'],
['Ochrana osobných údajov', 'Požiadavky GDPR (právny základ, informačné povinnosti, prípadne DPIA) sa preverujú pred každým nasadením.'],
['Školenia', 'Všetci zamestnanci používajúci AI absolvujú školenia zodpovedajúce ich úlohe v rámci gramotnosti v oblasti AI (čl. 4 európskeho nariadenia o AI); účasť sa dokumentuje.'],
['Incidenty', 'Poruchy a podozrenia na závažné incidenty treba bezodkladne hlásiť na [kontakt]; platí proces hlásenia podľa čl. 73.'],
['Zodpovednosti', 'Zodpovedná osoba za AI: [meno]. Zodpovedná osoba za ochranu údajov: [meno]. Zapojenie zamestnaneckej rady podľa BetrVG/podnikovej dohody.'],
['Nadobudnutie účinnosti a preskúmanie', 'Táto politika nadobúda účinnosť dňa [dátum] a preskúmava sa najmenej raz ročne.'],
],
},
ro: {
title: 'Politica internă privind IA (proiect-cadru)',
sections: [
['Domeniu de aplicare', 'Prezenta politică se aplică tuturor angajaților și reglementează utilizarea sistemelor de IA și a conținutului generat de IA în cadrul întreprinderii.'],
['Sisteme de IA aprobate', 'În scopuri profesionale pot fi utilizate numai sistemele de IA incluse în inventarul IA al întreprinderii. Instrumentele noi necesită aprobarea prealabilă a [unității competente].'],
['Utilizări interzise', 'Este interzisă introducerea de secrete comerciale, date cu caracter personal sau date ale clienților în servicii de IA neaprobate. Practicile interzise de art. 5 din Regulamentul european privind IA nu trebuie nici implementate, nici comandate.'],
['Supraveghere umană', 'Rezultatele IA care sprijină decizii cu efecte asupra persoanelor sunt verificate de o persoană competentă înainte de a produce efecte.'],
['Transparență', 'Interacțiunea IA cu clienții și conținutul generat de IA sunt divulgate și marcate în conformitate cu art. 50 din Regulamentul european privind IA.'],
['Protecția datelor', 'Cerințele RGPD (temei juridic, obligații de informare, DPIA dacă este necesară) sunt verificate înaintea oricărei utilizări.'],
['Instruire', 'Toți angajații care utilizează IA beneficiază de instruire adecvată rolului lor, în cadrul alfabetizării în domeniul IA (art. 4 din Regulamentul european privind IA); participarea este documentată.'],
['Incidente', 'Defecțiunile și incidentele grave suspectate trebuie raportate imediat la [contact]; se aplică procesul de raportare prevăzut la art. 73.'],
['Responsabilități', 'Responsabil IA: [nume]. Responsabil cu protecția datelor: [nume]. Implicarea comitetului de întreprindere conform BetrVG/acordului de întreprindere.'],
['Intrare în vigoare și revizuire', 'Prezenta politică intră în vigoare la [data] și este revizuită cel puțin o dată pe an.'],
],
},
} as const;
const T = T_ALL[locale];
const lines = [head(T.title, pack, today, locale, profile)];
T.sections.forEach(([sec, body], i) => {
lines.push(`## ${i + 1}. ${sec}`, '', body ?? s.todo, '');
});
return lines.join('\n');
}
/** Vordruck: Schulungsplan & Nachweis KI-Kompetenz (Art. 4). */
export function trainingPlan(
systems: readonly AISystem[],
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const T_ALL = {
de: {
title: 'Schulungsplan & Nachweis KI-Kompetenz (Art. 4)',
intro: 'Art. 4 EU-KI-VO verlangt ein ausreichendes Maß an KI-Kompetenz für Personal, das mit KI-Systemen umgeht — in Kraft seit 2. Februar 2025. Dieses Dokument plant die Maßnahmen und dient als Nachweis.',
matrix: 'Schulungsmatrix',
cols: '| Zielgruppe | Inhalte | Format | Turnus | Nachweis |',
colsSep: '|---|---|---|---|---|',
rows: [
'| Alle Beschäftigten | KI-Grundlagen, Chancen/Risiken, interne KI-Richtlinie | E-Learning | jährlich | Teilnahmeliste |',
'| Nutzer der unten gelisteten Systeme | systemspezifische Bedienung, Grenzen, menschliche Aufsicht | Workshop | vor Erstnutzung + bei Änderungen | Zertifikat |',
'| Führungskräfte / KI-Beauftragte | AI-Act-Pflichten, Vorfallprozess, Haftung | Seminar | jährlich | Zertifikat |',
],
record: 'Schulungsnachweis (fortlaufend zu führen)',
recordCols: '| Datum | Beschäftigte/r | Schulung | Trainer | Unterschrift |',
recordSep: '|---|---|---|---|---|',
systemsTitle: 'Betroffene Systeme',
},
en: {
title: 'AI literacy training plan & record (Art. 4)',
intro: 'Art. 4 EU AI Act requires a sufficient level of AI literacy for staff dealing with AI systems — in force since 2 February 2025. This document plans the measures and serves as evidence.',
matrix: 'Training matrix',
cols: '| Target group | Content | Format | Interval | Evidence |',
colsSep: '|---|---|---|---|---|',
rows: [
'| All employees | AI basics, opportunities/risks, internal AI policy | e-learning | annually | participation list |',
'| Users of the systems listed below | system-specific operation, limits, human oversight | workshop | before first use + on changes | certificate |',
'| Management / AI officer | AI Act obligations, incident process, liability | seminar | annually | certificate |',
],
record: 'Training record (to be completed)',
recordCols: '| Date | Employee | Training | Trainer | Signature |',
recordSep: '|---|---|---|---|---|',
systemsTitle: 'Systems in scope',
},
fr: {
title: 'Plan de formation et attestation — maîtrise de lIA (art. 4)',
intro: 'Lart. 4 du règlement européen sur lIA exige un niveau suffisant de maîtrise de lIA pour le personnel travaillant avec des systèmes dIA — en vigueur depuis le 2 février 2025. Ce document planifie les mesures et sert de justificatif.',
matrix: 'Matrice de formation',
cols: '| Groupe cible | Contenus | Format | Fréquence | Justificatif |',
colsSep: '|---|---|---|---|---|',
rows: [
'| Tous les salariés | fondamentaux de lIA, opportunités/risques, politique interne dIA | e-learning | annuel | liste de présence |',
'| Utilisateurs des systèmes listés ci-dessous | utilisation spécifique au système, limites, contrôle humain | atelier | avant la première utilisation + en cas de modifications | certificat |',
'| Direction / référent IA | obligations du règlement sur lIA, processus dincident, responsabilité | séminaire | annuel | certificat |',
],
record: 'Registre de formation (à tenir en continu)',
recordCols: '| Date | Salarié(e) | Formation | Formateur | Signature |',
recordSep: '|---|---|---|---|---|',
systemsTitle: 'Systèmes concernés',
},
it: {
title: 'Piano di formazione e attestazione — alfabetizzazione IA (art. 4)',
intro: 'Lart. 4 del regolamento europeo sullIA richiede un livello sufficiente di alfabetizzazione IA per il personale che opera con sistemi di IA — in vigore dal 2 febbraio 2025. Questo documento pianifica le misure e funge da evidenza.',
matrix: 'Matrice formativa',
cols: '| Gruppo destinatario | Contenuti | Formato | Cadenza | Evidenza |',
colsSep: '|---|---|---|---|---|',
rows: [
'| Tutti i dipendenti | nozioni di base sullIA, opportunità/rischi, policy interna sullIA | e-learning | annuale | lista di partecipazione |',
'| Utenti dei sistemi elencati di seguito | uso specifico del sistema, limiti, sorveglianza umana | workshop | prima del primo utilizzo + in caso di modifiche | certificato |',
'| Dirigenti / referente IA | obblighi dellAI Act, processo per gli incidenti, responsabilità | seminario | annuale | certificato |',
],
record: 'Registro delle formazioni (da tenere in modo continuativo)',
recordCols: '| Data | Dipendente | Formazione | Formatore | Firma |',
recordSep: '|---|---|---|---|---|',
systemsTitle: 'Sistemi interessati',
},
es: {
title: 'Plan de formación y registro — alfabetización en IA (art. 4)',
intro: 'El art. 4 del Reglamento europeo de IA exige un nivel suficiente de alfabetización en IA para el personal que trabaja con sistemas de IA — en vigor desde el 2 de febrero de 2025. Este documento planifica las medidas y sirve como justificante.',
matrix: 'Matriz de formación',
cols: '| Grupo destinatario | Contenidos | Formato | Periodicidad | Justificante |',
colsSep: '|---|---|---|---|---|',
rows: [
'| Todos los empleados | fundamentos de IA, oportunidades/riesgos, política interna de IA | e-learning | anual | lista de asistencia |',
'| Usuarios de los sistemas listados abajo | manejo específico del sistema, límites, supervisión humana | taller | antes del primer uso + en caso de cambios | certificado |',
'| Directivos / responsable de IA | obligaciones del Reglamento de IA, proceso de incidentes, responsabilidad | seminario | anual | certificado |',
],
record: 'Registro de formación (a cumplimentar de forma continua)',
recordCols: '| Fecha | Empleado/a | Formación | Formador | Firma |',
recordSep: '|---|---|---|---|---|',
systemsTitle: 'Sistemas afectados',
},
pl: {
title: 'Plan szkoleń i potwierdzenie kompetencji w zakresie AI (art. 4)',
intro: 'Art. 4 europejskiego rozporządzenia w sprawie AI wymaga wystarczającego poziomu kompetencji w zakresie AI od personelu pracującego z systemami AI — obowiązuje od 2 lutego 2025 r. Niniejszy dokument planuje działania i służy jako potwierdzenie.',
matrix: 'Matryca szkoleń',
cols: '| Grupa docelowa | Treści | Format | Częstotliwość | Potwierdzenie |',
colsSep: '|---|---|---|---|---|',
rows: [
'| Wszyscy pracownicy | podstawy AI, szanse/ryzyka, wewnętrzna polityka AI | e-learning | co roku | lista obecności |',
'| Użytkownicy systemów wymienionych poniżej | obsługa specyficzna dla systemu, ograniczenia, nadzór człowieka | warsztat | przed pierwszym użyciem + przy zmianach | certyfikat |',
'| Kadra kierownicza / pełnomocnik ds. AI | obowiązki wynikające z rozporządzenia w sprawie AI, proces obsługi incydentów, odpowiedzialność | seminarium | co roku | certyfikat |',
],
record: 'Rejestr szkoleń (do prowadzenia na bieżąco)',
recordCols: '| Data | Pracownik | Szkolenie | Prowadzący | Podpis |',
recordSep: '|---|---|---|---|---|',
systemsTitle: 'Systemy objęte planem',
},
cs: {
title: 'Plán školení a doklad o gramotnosti v oblasti AI (čl. 4)',
intro: 'Čl. 4 evropského nařízení o AI vyžaduje dostatečnou úroveň gramotnosti v oblasti AI u personálu pracujícího se systémy AI — účinné od 2. února 2025. Tento dokument plánuje opatření a slouží jako doklad.',
matrix: 'Matice školení',
cols: '| Cílová skupina | Obsah | Formát | Interval | Doklad |',
colsSep: '|---|---|---|---|---|',
rows: [
'| Všichni zaměstnanci | základy AI, příležitosti/rizika, interní politika AI | e-learning | ročně | prezenční listina |',
'| Uživatelé níže uvedených systémů | obsluha specifická pro systém, limity, lidský dohled | workshop | před prvním použitím + při změnách | certifikát |',
'| Vedoucí pracovníci / pověřenec pro AI | povinnosti podle nařízení o AI, proces řešení incidentů, odpovědnost | seminář | ročně | certifikát |',
],
record: 'Záznam o školeních (vést průběžně)',
recordCols: '| Datum | Zaměstnanec | Školení | Školitel | Podpis |',
recordSep: '|---|---|---|---|---|',
systemsTitle: 'Dotčené systémy',
},
sk: {
title: 'Plán školení a doklad o gramotnosti v oblasti AI (čl. 4)',
intro: 'Čl. 4 európskeho nariadenia o AI vyžaduje dostatočnú úroveň gramotnosti v oblasti AI u personálu pracujúceho so systémami AI — účinné od 2. februára 2025. Tento dokument plánuje opatrenia a slúži ako doklad.',
matrix: 'Matica školení',
cols: '| Cieľová skupina | Obsah | Formát | Interval | Doklad |',
colsSep: '|---|---|---|---|---|',
rows: [
'| Všetci zamestnanci | základy AI, príležitosti/riziká, interná politika AI | e-learning | ročne | prezenčná listina |',
'| Používatelia nižšie uvedených systémov | obsluha špecifická pre systém, limity, ľudský dohľad | workshop | pred prvým použitím + pri zmenách | certifikát |',
'| Vedúci pracovníci / zodpovedná osoba za AI | povinnosti podľa nariadenia o AI, proces riešenia incidentov, zodpovednosť | seminár | ročne | certifikát |',
],
record: 'Záznam o školeniach (viesť priebežne)',
recordCols: '| Dátum | Zamestnanec | Školenie | Školiteľ | Podpis |',
recordSep: '|---|---|---|---|---|',
systemsTitle: 'Dotknuté systémy',
},
ro: {
title: 'Plan de instruire și dovadă — alfabetizare în domeniul IA (art. 4)',
intro: 'Art. 4 din Regulamentul european privind IA impune un nivel suficient de alfabetizare în domeniul IA pentru personalul care lucrează cu sisteme de IA — în vigoare de la 2 februarie 2025. Prezentul document planifică măsurile și servește drept dovadă.',
matrix: 'Matricea de instruire',
cols: '| Grup-țintă | Conținut | Format | Periodicitate | Dovadă |',
colsSep: '|---|---|---|---|---|',
rows: [
'| Toți angajații | noțiuni de bază despre IA, oportunități/riscuri, politica internă privind IA | e-learning | anual | listă de prezență |',
'| Utilizatorii sistemelor enumerate mai jos | operare specifică sistemului, limite, supraveghere umană | atelier | înainte de prima utilizare + la modificări | certificat |',
'| Conducere / responsabil IA | obligațiile din Regulamentul privind IA, procesul de gestionare a incidentelor, răspundere | seminar | anual | certificat |',
],
record: 'Registrul instruirilor (de completat în mod continuu)',
recordCols: '| Data | Angajat | Instruire | Formator | Semnătură |',
recordSep: '|---|---|---|---|---|',
systemsTitle: 'Sisteme vizate',
},
} as const;
const T = T_ALL[locale];
const lines = [head(T.title, pack, today, locale, profile)];
lines.push(T.intro, '', `## ${T.matrix}`, '', T.cols, T.colsSep, ...T.rows, '');
lines.push(`## ${T.systemsTitle}`, '');
if (systems.length === 0) {
lines.push('—', '');
} else {
for (const sys of systems) {
lines.push(`- ${sys.name}${sys.purpose ? `${sys.purpose}` : ''}`);
}
lines.push('');
}
lines.push(`## ${T.record}`, '', T.recordCols, T.recordSep, '| | | | | |', '| | | | | |', '| | | | | |');
return lines.join('\n');
}
/** Vordruck: Betriebsvereinbarung KI (Rahmenentwurf, Deutschland). */
export function worksAgreement(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const T_ALL = {
de: {
title: 'Betriebsvereinbarung über den Einsatz von KI-Systemen (Rahmenentwurf)',
parties: 'Zwischen dem Arbeitgeber [Firma] und dem Betriebsrat des Betriebs [Standort] wird gemäß § 87 Abs. 1 Nr. 6, § 90 BetrVG folgende Betriebsvereinbarung geschlossen:',
sections: [
['§ 1 Geltungsbereich', 'Diese Vereinbarung gilt für alle Beschäftigten des Betriebs und für die in Anlage 1 (KI-Inventar) aufgeführten KI-Systeme.'],
['§ 2 Zweckbindung', 'Die Systeme werden ausschließlich zu den in Anlage 1 beschriebenen Zwecken eingesetzt. Eine darüber hinausgehende Leistungs- und Verhaltenskontrolle findet nicht statt.'],
['§ 3 Keine vollautomatisierten Personalentscheidungen', 'Entscheidungen mit Rechtswirkung für Beschäftigte (z. B. Einstellung, Beförderung, Kündigung) trifft stets ein Mensch; KI-Ausgaben sind nur Entscheidungsunterstützung.'],
['§ 4 Datenschutz', 'Beschäftigtendaten werden nur gemäß Anlage 2 (Datenkatalog) verarbeitet. Auswertungen zur individuellen Leistungsbeurteilung bedürfen der Zustimmung des Betriebsrats.'],
['§ 5 Information und Schulung', 'Betroffene Beschäftigte werden vor Inbetriebnahme informiert (Art. 26 Abs. 7 KI-VO) und nach Art. 4 KI-VO geschult.'],
['§ 6 Einführung neuer Systeme / Änderungen', 'Neue KI-Systeme oder wesentliche Änderungen erfordern die rechtzeitige Unterrichtung des Betriebsrats (§ 90 BetrVG) und eine Ergänzung der Anlage 1.'],
['§ 7 Rechte des Betriebsrats', 'Der Betriebsrat kann beschäftigtenrelevante Protokolldaten einsehen und bei Bedarf externen Sachverstand hinzuziehen (§ 80 Abs. 3 BetrVG).'],
['§ 8 Laufzeit und Kündigung', 'Diese Vereinbarung tritt mit Unterzeichnung in Kraft und kann mit einer Frist von [3] Monaten gekündigt werden; sie wirkt nach.'],
],
signature: 'Ort, Datum: _______________\n\nArbeitgeber: _______________ Betriebsrat: _______________',
},
en: {
title: 'Works agreement on the use of AI systems (draft framework, Germany)',
parties: 'Between the employer [company] and the works council of [site], the following works agreement is concluded pursuant to Sec. 87 (1) No. 6, Sec. 90 BetrVG:',
sections: [
['§ 1 Scope', 'This agreement applies to all employees of the site and to the AI systems listed in Annex 1 (AI inventory).'],
['§ 2 Purpose limitation', 'The systems are used exclusively for the purposes described in Annex 1. Performance and behaviour monitoring beyond that is not permitted.'],
['§ 3 No fully automated personnel decisions', 'Decisions with legal effect for employees (e.g. hiring, promotion, termination) are always taken by humans; AI output is decision support only.'],
['§ 4 Data protection', 'Employee data is processed only per Annex 2 (data catalogue). Evaluations for individual performance review require the works councils consent.'],
['§ 5 Information and training', 'Affected employees are informed before commissioning (Art. 26(7) AI Act) and trained per Art. 4 AI Act.'],
['§ 6 Introduction of new systems / changes', 'New AI systems or substantial changes require timely information of the works council (Sec. 90 BetrVG) and an addendum to Annex 1.'],
['§ 7 Rights of the works council', 'The works council may inspect logging data relevant to employees and consult external expertise where required (Sec. 80 (3) BetrVG).'],
['§ 8 Term and termination', 'This agreement enters into force upon signature and may be terminated with [3] months notice; its after-effect applies.'],
],
signature: 'Place, date: _______________\n\nEmployer: _______________ Works council: _______________',
},
fr: {
title: 'Accord dentreprise sur lutilisation de systèmes dIA (projet de cadre, Allemagne)',
parties: 'Entre lemployeur [entreprise] et le comité dentreprise de létablissement [site], laccord dentreprise suivant est conclu conformément au § 87 Abs. 1 Nr. 6 et au § 90 BetrVG :',
sections: [
['§ 1 Champ dapplication', 'Le présent accord sapplique à tous les salariés de létablissement et aux systèmes dIA énumérés à lannexe 1 (inventaire IA).'],
['§ 2 Limitation de la finalité', 'Les systèmes sont utilisés exclusivement aux fins décrites à lannexe 1. Toute surveillance des performances et du comportement allant au-delà est exclue.'],
['§ 3 Pas de décisions RH entièrement automatisées', 'Les décisions ayant des effets juridiques pour les salariés (p. ex. embauche, promotion, licenciement) sont toujours prises par un être humain ; les sorties dIA ne constituent quune aide à la décision.'],
['§ 4 Protection des données', 'Les données des salariés ne sont traitées que conformément à lannexe 2 (catalogue de données). Les analyses aux fins dévaluation individuelle des performances requièrent laccord du comité dentreprise.'],
['§ 5 Information et formation', 'Les salariés concernés sont informés avant la mise en service (art. 26, par. 7 du règlement sur lIA) et formés conformément à lart. 4 du règlement sur lIA.'],
['§ 6 Introduction de nouveaux systèmes / modifications', 'Les nouveaux systèmes dIA ou les modifications substantielles requièrent linformation en temps utile du comité dentreprise (§ 90 BetrVG) et un complément à lannexe 1.'],
['§ 7 Droits du comité dentreprise', 'Le comité dentreprise peut consulter les données de journalisation pertinentes pour les salariés et, si nécessaire, faire appel à une expertise externe (§ 80 Abs. 3 BetrVG).'],
['§ 8 Durée et résiliation', 'Le présent accord entre en vigueur à la signature et peut être résilié moyennant un préavis de [3] mois ; il continue de produire ses effets après résiliation.'],
],
signature: 'Lieu, date : _______________\n\nEmployeur : _______________ Comité dentreprise : _______________',
},
it: {
title: 'Accordo aziendale sullimpiego di sistemi di IA (bozza di quadro, Germania)',
parties: 'Tra il datore di lavoro [azienda] e il consiglio aziendale dello stabilimento [sede] viene stipulato, ai sensi del § 87 Abs. 1 Nr. 6 e del § 90 BetrVG, il seguente accordo aziendale:',
sections: [
['§ 1 Ambito di applicazione', 'Il presente accordo si applica a tutti i dipendenti dello stabilimento e ai sistemi di IA elencati nellallegato 1 (inventario IA).'],
['§ 2 Vincolo di finalità', 'I sistemi sono impiegati esclusivamente per gli scopi descritti nellallegato 1. Non ha luogo alcun controllo delle prestazioni e del comportamento che vada oltre tali scopi.'],
['§ 3 Nessuna decisione sul personale completamente automatizzata', 'Le decisioni con effetti giuridici per i dipendenti (ad es. assunzione, promozione, licenziamento) sono sempre prese da un essere umano; gli output dellIA costituiscono solo un supporto decisionale.'],
['§ 4 Protezione dei dati', 'I dati dei dipendenti vengono trattati solo conformemente allallegato 2 (catalogo dei dati). Le analisi ai fini della valutazione individuale delle prestazioni richiedono il consenso del consiglio aziendale.'],
['§ 5 Informazione e formazione', 'I dipendenti interessati vengono informati prima della messa in servizio (art. 26, par. 7 del regolamento sullIA) e formati ai sensi dellart. 4 del regolamento sullIA.'],
['§ 6 Introduzione di nuovi sistemi / modifiche', 'Nuovi sistemi di IA o modifiche sostanziali richiedono la tempestiva informazione del consiglio aziendale (§ 90 BetrVG) e unintegrazione dellallegato 1.'],
['§ 7 Diritti del consiglio aziendale', 'Il consiglio aziendale può consultare i dati di log rilevanti per i dipendenti e, ove necessario, avvalersi di competenze esterne (§ 80 Abs. 3 BetrVG).'],
['§ 8 Durata e recesso', 'Il presente accordo entra in vigore con la firma e può essere disdetto con un preavviso di [3] mesi; continua a produrre effetti dopo la disdetta.'],
],
signature: 'Luogo, data: _______________\n\nDatore di lavoro: _______________ Consiglio aziendale: _______________',
},
es: {
title: 'Acuerdo de empresa sobre el uso de sistemas de IA (borrador marco, Alemania)',
parties: 'Entre el empleador [empresa] y el comité de empresa del centro [ubicación] se celebra, conforme al § 87 Abs. 1 Nr. 6 y al § 90 BetrVG, el siguiente acuerdo de empresa:',
sections: [
['§ 1 Ámbito de aplicación', 'El presente acuerdo se aplica a todos los empleados del centro y a los sistemas de IA enumerados en el anexo 1 (inventario de IA).'],
['§ 2 Limitación de la finalidad', 'Los sistemas se utilizan exclusivamente para los fines descritos en el anexo 1. No se realiza ningún control del rendimiento ni del comportamiento que vaya más allá.'],
['§ 3 Sin decisiones de personal totalmente automatizadas', 'Las decisiones con efectos jurídicos para los empleados (p. ej. contratación, promoción, despido) las toma siempre una persona; los resultados de la IA son solo apoyo a la decisión.'],
['§ 4 Protección de datos', 'Los datos de los empleados se tratan únicamente conforme al anexo 2 (catálogo de datos). Las evaluaciones para la valoración individual del rendimiento requieren el consentimiento del comité de empresa.'],
['§ 5 Información y formación', 'Los empleados afectados son informados antes de la puesta en servicio (art. 26, apdo. 7 del Reglamento de IA) y formados conforme al art. 4 del Reglamento de IA.'],
['§ 6 Introducción de nuevos sistemas / cambios', 'Los nuevos sistemas de IA o los cambios sustanciales requieren la información oportuna al comité de empresa (§ 90 BetrVG) y una adenda al anexo 1.'],
['§ 7 Derechos del comité de empresa', 'El comité de empresa puede consultar los datos de registro relevantes para los empleados y, en caso necesario, recurrir a expertos externos (§ 80 Abs. 3 BetrVG).'],
['§ 8 Vigencia y denuncia', 'El presente acuerdo entra en vigor con la firma y puede denunciarse con un preaviso de [3] meses; sus efectos se mantienen tras la denuncia.'],
],
signature: 'Lugar, fecha: _______________\n\nEmpleador: _______________ Comité de empresa: _______________',
},
pl: {
title: 'Porozumienie zakładowe w sprawie stosowania systemów AI (projekt ramowy, Niemcy)',
parties: 'Pomiędzy pracodawcą [firma] a radą zakładową zakładu [lokalizacja] zawiera się, zgodnie z § 87 Abs. 1 Nr. 6 i § 90 BetrVG, następujące porozumienie zakładowe:',
sections: [
['§ 1 Zakres obowiązywania', 'Niniejsze porozumienie obowiązuje wszystkich pracowników zakładu i obejmuje systemy AI wymienione w załączniku 1 (rejestr AI).'],
['§ 2 Ograniczenie celu', 'Systemy są wykorzystywane wyłącznie do celów opisanych w załączniku 1. Wykraczająca poza to kontrola wydajności i zachowania nie ma miejsca.'],
['§ 3 Zakaz w pełni zautomatyzowanych decyzji kadrowych', 'Decyzje wywołujące skutki prawne dla pracowników (np. zatrudnienie, awans, wypowiedzenie) podejmuje zawsze człowiek; wyniki AI stanowią jedynie wsparcie decyzji.'],
['§ 4 Ochrona danych', 'Dane pracowników są przetwarzane wyłącznie zgodnie z załącznikiem 2 (katalog danych). Analizy służące indywidualnej ocenie wydajności wymagają zgody rady zakładowej.'],
['§ 5 Informowanie i szkolenia', 'Pracownicy, których to dotyczy, są informowani przed uruchomieniem (art. 26 ust. 7 rozporządzenia w sprawie AI) i szkoleni zgodnie z art. 4 rozporządzenia w sprawie AI.'],
['§ 6 Wprowadzanie nowych systemów / zmiany', 'Nowe systemy AI lub istotne zmiany wymagają terminowego poinformowania rady zakładowej (§ 90 BetrVG) oraz uzupełnienia załącznika 1.'],
['§ 7 Prawa rady zakładowej', 'Rada zakładowa może mieć wgląd w dane z logów dotyczące pracowników i w razie potrzeby korzystać z zewnętrznej wiedzy eksperckiej (§ 80 Abs. 3 BetrVG).'],
['§ 8 Okres obowiązywania i wypowiedzenie', 'Niniejsze porozumienie wchodzi w życie z chwilą podpisania i może zostać wypowiedziane z zachowaniem okresu wypowiedzenia wynoszącego [3] miesiące; wywiera skutek następczy.'],
],
signature: 'Miejscowość, data: _______________\n\nPracodawca: _______________ Rada zakładowa: _______________',
},
cs: {
title: 'Podniková dohoda o nasazení systémů AI (rámcový návrh, Německo)',
parties: 'Mezi zaměstnavatelem [firma] a podnikovou radou závodu [místo] se podle § 87 Abs. 1 Nr. 6 a § 90 BetrVG uzavírá následující podniková dohoda:',
sections: [
['§ 1 Oblast působnosti', 'Tato dohoda platí pro všechny zaměstnance závodu a pro systémy AI uvedené v příloze 1 (inventář AI).'],
['§ 2 Účelové omezení', 'Systémy se používají výhradně k účelům popsaným v příloze 1. Kontrola výkonu a chování nad tento rámec se neprovádí.'],
['§ 3 Žádná plně automatizovaná personální rozhodnutí', 'Rozhodnutí s právními účinky pro zaměstnance (např. přijetí, povýšení, výpověď) činí vždy člověk; výstupy AI slouží pouze jako podpora rozhodování.'],
['§ 4 Ochrana osobních údajů', 'Údaje zaměstnanců se zpracovávají pouze podle přílohy 2 (katalog údajů). Vyhodnocování za účelem individuálního hodnocení výkonu vyžaduje souhlas podnikové rady.'],
['§ 5 Informování a školení', 'Dotčení zaměstnanci jsou informováni před uvedením do provozu (čl. 26 odst. 7 nařízení o AI) a školeni podle čl. 4 nařízení o AI.'],
['§ 6 Zavádění nových systémů / změny', 'Nové systémy AI nebo podstatné změny vyžadují včasné informování podnikové rady (§ 90 BetrVG) a doplnění přílohy 1.'],
['§ 7 Práva podnikové rady', 'Podniková rada může nahlížet do protokolových údajů relevantních pro zaměstnance a v případě potřeby přizvat externí odborníky (§ 80 Abs. 3 BetrVG).'],
['§ 8 Doba platnosti a výpověď', 'Tato dohoda nabývá účinnosti podpisem a lze ji vypovědět s výpovědní lhůtou [3] měsíců; její účinky trvají i po výpovědi.'],
],
signature: 'Místo, datum: _______________\n\nZaměstnavatel: _______________ Podniková rada: _______________',
},
sk: {
title: 'Podniková dohoda o nasadení systémov AI (rámcový návrh, Nemecko)',
parties: 'Medzi zamestnávateľom [firma] a zamestnaneckou radou prevádzky [miesto] sa podľa § 87 Abs. 1 Nr. 6 a § 90 BetrVG uzatvára nasledujúca podniková dohoda:',
sections: [
['§ 1 Rozsah pôsobnosti', 'Táto dohoda platí pre všetkých zamestnancov prevádzky a pre systémy AI uvedené v prílohe 1 (inventár AI).'],
['§ 2 Účelové obmedzenie', 'Systémy sa používajú výlučne na účely opísané v prílohe 1. Kontrola výkonu a správania nad tento rámec sa nevykonáva.'],
['§ 3 Žiadne plne automatizované personálne rozhodnutia', 'Rozhodnutia s právnymi účinkami pre zamestnancov (napr. prijatie, povýšenie, výpoveď) prijíma vždy človek; výstupy AI slúžia len ako podpora rozhodovania.'],
['§ 4 Ochrana osobných údajov', 'Údaje zamestnancov sa spracúvajú len podľa prílohy 2 (katalóg údajov). Vyhodnocovanie na účely individuálneho hodnotenia výkonu vyžaduje súhlas zamestnaneckej rady.'],
['§ 5 Informovanie a školenie', 'Dotknutí zamestnanci sú informovaní pred uvedením do prevádzky (čl. 26 ods. 7 nariadenia o AI) a školení podľa čl. 4 nariadenia o AI.'],
['§ 6 Zavádzanie nových systémov / zmeny', 'Nové systémy AI alebo podstatné zmeny vyžadujú včasné informovanie zamestnaneckej rady (§ 90 BetrVG) a doplnenie prílohy 1.'],
['§ 7 Práva zamestnaneckej rady', 'Zamestnanecká rada môže nahliadať do protokolových údajov relevantných pre zamestnancov a v prípade potreby prizvať externých odborníkov (§ 80 Abs. 3 BetrVG).'],
['§ 8 Doba platnosti a výpoveď', 'Táto dohoda nadobúda účinnosť podpisom a možno ju vypovedať s výpovednou lehotou [3] mesiacov; jej účinky trvajú aj po výpovedi.'],
],
signature: 'Miesto, dátum: _______________\n\nZamestnávateľ: _______________ Zamestnanecká rada: _______________',
},
ro: {
title: 'Acord de întreprindere privind utilizarea sistemelor de IA (proiect-cadru, Germania)',
parties: 'Între angajatorul [firma] și comitetul de întreprindere al unității [locația] se încheie, în temeiul § 87 Abs. 1 Nr. 6 și § 90 BetrVG, următorul acord de întreprindere:',
sections: [
['§ 1 Domeniu de aplicare', 'Prezentul acord se aplică tuturor angajaților unității și sistemelor de IA enumerate în anexa 1 (inventarul IA).'],
['§ 2 Limitarea scopului', 'Sistemele sunt utilizate exclusiv în scopurile descrise în anexa 1. Nu are loc nicio monitorizare a performanței și a comportamentului care să depășească acest cadru.'],
['§ 3 Fără decizii de personal complet automatizate', 'Deciziile cu efecte juridice pentru angajați (de ex. angajare, promovare, concediere) sunt luate întotdeauna de un om; rezultatele IA constituie doar un sprijin decizional.'],
['§ 4 Protecția datelor', 'Datele angajaților sunt prelucrate numai conform anexei 2 (catalogul datelor). Evaluările în scopul aprecierii individuale a performanței necesită acordul comitetului de întreprindere.'],
['§ 5 Informare și instruire', 'Angajații vizați sunt informați înainte de punerea în funcțiune (art. 26 alin. 7 din Regulamentul privind IA) și instruiți conform art. 4 din Regulamentul privind IA.'],
['§ 6 Introducerea de sisteme noi / modificări', 'Sistemele de IA noi sau modificările substanțiale necesită informarea în timp util a comitetului de întreprindere (§ 90 BetrVG) și o completare a anexei 1.'],
['§ 7 Drepturile comitetului de întreprindere', 'Comitetul de întreprindere poate consulta datele de jurnalizare relevante pentru angajați și, dacă este necesar, poate apela la expertiză externă (§ 80 Abs. 3 BetrVG).'],
['§ 8 Durată și denunțare', 'Prezentul acord intră în vigoare la semnare și poate fi denunțat cu un preaviz de [3] luni; efectele sale se mențin și după denunțare.'],
],
signature: 'Localitatea, data: _______________\n\nAngajator: _______________ Comitetul de întreprindere: _______________',
},
} as const;
const T = T_ALL[locale];
const lines = [head(T.title, pack, today, locale, profile)];
lines.push(T.parties, '');
for (const [sec, body] of T.sections) {
lines.push(`## ${sec}`, '', body ?? s.todo, '');
}
lines.push(T.signature);
return lines.join('\n');
}

View File

@ -0,0 +1,535 @@
import type { Locale } from '../i18n/types';
import { docStrings, formatDocDate } from './docStrings';
import type { CompanyProfile, ContentPack } from './types';
/** Gemeinsamer Kopf für interne Prozess-Dokumente. */
function head(
title: string,
pack: ContentPack,
today: string,
locale: Locale,
profile?: CompanyProfile,
): string {
const s = docStrings(locale);
const company = profile && profile.name.trim() !== '' ? profile.name : '_______________';
return [
`# ${title}`,
'',
`**${s.meta.company}:** ${company} · **${s.meta.createdAt}:** ${formatDocDate(today, locale)} · Content-Pack v${pack.version}`,
'',
s.disclaimer,
'',
].join('\n');
}
/**
* Vordruck: Interne Melde- und Eskalationsrichtlinie für KI-Vorfälle
* (interne Meldepflicht Prozess, der die Art.-73-Meldung vorbereitet).
*/
export function reportingPolicy(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const T_ALL = {
de: {
title: 'Interne Melde- und Eskalationsrichtlinie für KI-Vorfälle (Entwurf)',
sections: [
['1. Zweck', 'Diese Richtlinie regelt die interne Meldepflicht für Störungen und Vorfälle im Zusammenhang mit KI-Systemen. Sie stellt sicher, dass das Unternehmen die gesetzlichen Meldefristen einhalten kann (Art. 73 EU-KI-VO: 15 Tage, Todesfall 10 Tage, weitverbreiteter Verstoß/kritische Infrastruktur 2 Tage).'],
['2. Was zu melden ist', 'Jede/r Beschäftigte meldet unverzüglich: (a) Fehlfunktionen oder unerwartetes Verhalten eines KI-Systems, (b) Verdacht auf Schäden für Gesundheit, Sicherheit oder Grundrechte, (c) Verdacht auf Diskriminierung durch KI-gestützte Entscheidungen, (d) Datenschutzvorfälle mit KI-Bezug, (e) Umgehung der menschlichen Aufsicht.'],
['3. Meldeweg', 'Erstmeldung an: KI-Beauftragte/r [Name, Kontakt] — mündlich oder über [Kanal]. Bei Nichterreichbarkeit: [Vertretung]. Meldungen sind auch vertraulich möglich; der Schutz nach dem Hinweisgeberschutzgesetz (HinSchG) bleibt unberührt.'],
['4. Interne Fristen', 'Meldung durch Beschäftigte: sofort, spätestens 24 Stunden nach Kenntnis. Erstbewertung durch KI-Beauftragte/n: binnen 48 Stunden. Entscheidung über externe Meldung (Art. 73) mit der Geschäftsleitung: unverzüglich, sodass die gesetzlichen Fristen gewahrt bleiben.'],
['5. Eskalationsstufen', 'Stufe 1: KI-Beauftragte/r (Bewertung, Eindämmung). Stufe 2: Geschäftsleitung + Datenschutzbeauftragte/r + Recht. Stufe 3: externe Meldung an die Marktüberwachungsbehörde sowie ggf. Information des Anbieters (Art. 26 Abs. 5) und Betroffener.'],
['6. Dokumentation', 'Jede Meldung wird mit dem Formular „Vorfallmeldung (Art. 73)" dokumentiert und mindestens [5] Jahre aufbewahrt. Der/die KI-Beauftragte führt das Vorfallregister.'],
['7. Keine Sanktionen bei gutgläubiger Meldung', 'Beschäftigten, die in gutem Glauben melden, dürfen keine Nachteile entstehen.'],
['8. Inkrafttreten', 'Diese Richtlinie tritt am [Datum] in Kraft.'],
],
},
en: {
title: 'Internal reporting and escalation policy for AI incidents (draft)',
sections: [
['1. Purpose', 'This policy defines the internal reporting duty for malfunctions and incidents involving AI systems. It ensures that the company can meet its statutory reporting deadlines (Art. 73 EU AI Act: 15 days, death 10 days, widespread infringement/critical infrastructure 2 days).'],
['2. What must be reported', 'Every employee reports without undue delay: (a) malfunctions or unexpected behaviour of an AI system, (b) suspected harm to health, safety or fundamental rights, (c) suspected discrimination by AI-supported decisions, (d) data protection incidents involving AI, (e) circumvention of human oversight.'],
['3. Reporting channel', 'First report to: AI officer [name, contact] — verbally or via [channel]. If unavailable: [deputy]. Reports may also be made confidentially; whistleblower protection under the applicable whistleblowing rules remains unaffected.'],
['4. Internal deadlines', 'Report by employee: immediately, at the latest within 24 hours of becoming aware. Initial assessment by AI officer: within 48 hours. Decision on external report (Art. 73) with management: without undue delay, so that the statutory deadlines are met.'],
['5. Escalation levels', 'Level 1: AI officer (assessment, containment). Level 2: management + data protection officer + legal. Level 3: external report to the market surveillance authority and, where applicable, information of the provider (Art. 26(5)) and affected persons.'],
['6. Documentation', 'Every report is documented using the serious incident report form and retained for at least [5] years. The AI officer maintains the incident register.'],
['7. No sanctions for good-faith reports', 'Employees who report in good faith must not suffer any disadvantage.'],
['8. Entry into force', 'This policy enters into force on [date].'],
],
},
fr: {
title: 'Politique interne de signalement et descalade pour les incidents dIA (projet)',
sections: [
['1. Objet', 'La présente politique définit lobligation interne de signalement des dysfonctionnements et incidents liés aux systèmes dIA. Elle garantit que lentreprise peut respecter les délais légaux de notification (art. 73 du règlement européen sur lIA : 15 jours, décès 10 jours, infraction de grande ampleur/infrastructure critique 2 jours).'],
['2. Ce qui doit être signalé', 'Chaque salarié signale sans délai : (a) les dysfonctionnements ou comportements inattendus dun système dIA, (b) les soupçons datteinte à la santé, à la sécurité ou aux droits fondamentaux, (c) les soupçons de discrimination par des décisions assistées par lIA, (d) les incidents de protection des données liés à lIA, (e) le contournement du contrôle humain.'],
['3. Canal de signalement', 'Premier signalement à : référent IA [nom, contact] — oralement ou via [canal]. En cas dindisponibilité : [suppléant]. Les signalements peuvent aussi être effectués de manière confidentielle ; la protection des lanceurs dalerte au titre de la loi allemande sur la protection des lanceurs dalerte (HinSchG) demeure inchangée.'],
['4. Délais internes', 'Signalement par les salariés : immédiatement, au plus tard 24 heures après en avoir eu connaissance. Première évaluation par le référent IA : sous 48 heures. Décision sur la notification externe (art. 73) avec la direction : sans délai, de sorte que les délais légaux soient respectés.'],
['5. Niveaux descalade', 'Niveau 1 : référent IA (évaluation, confinement). Niveau 2 : direction + délégué à la protection des données + service juridique. Niveau 3 : notification externe à lautorité de surveillance du marché ainsi que, le cas échéant, information du fournisseur (art. 26, par. 5) et des personnes concernées.'],
['6. Documentation', 'Chaque signalement est documenté au moyen du formulaire de notification dincident grave et conservé pendant au moins [5] ans. Le référent IA tient le registre des incidents.'],
['7. Absence de sanctions en cas de signalement de bonne foi', 'Les salariés qui signalent de bonne foi ne doivent subir aucun préjudice.'],
['8. Entrée en vigueur', 'La présente politique entre en vigueur le [date].'],
],
},
it: {
title: 'Policy interna di segnalazione ed escalation per incidenti di IA (bozza)',
sections: [
['1. Finalità', 'La presente policy disciplina lobbligo interno di segnalazione di malfunzionamenti e incidenti connessi ai sistemi di IA. Garantisce che lazienda possa rispettare i termini di notifica previsti dalla legge (art. 73 del regolamento europeo sullIA: 15 giorni, decesso 10 giorni, violazione diffusa/infrastruttura critica 2 giorni).'],
['2. Che cosa va segnalato', 'Ogni dipendente segnala senza indugio: (a) malfunzionamenti o comportamenti inattesi di un sistema di IA, (b) sospetti danni alla salute, alla sicurezza o ai diritti fondamentali, (c) sospetta discriminazione da parte di decisioni supportate dallIA, (d) incidenti di protezione dei dati connessi allIA, (e) elusione della sorveglianza umana.'],
['3. Canale di segnalazione', 'Prima segnalazione a: referente IA [nome, contatto] — verbalmente o tramite [canale]. In caso di irreperibilità: [sostituto]. Le segnalazioni possono essere effettuate anche in via riservata; resta impregiudicata la tutela degli informatori ai sensi della legge tedesca sulla protezione degli informatori (HinSchG).'],
['4. Termini interni', 'Segnalazione da parte dei dipendenti: subito, al più tardi entro 24 ore dalla conoscenza. Prima valutazione da parte del referente IA: entro 48 ore. Decisione sulla notifica esterna (art. 73) con la direzione: senza indugio, in modo da rispettare i termini di legge.'],
['5. Livelli di escalation', 'Livello 1: referente IA (valutazione, contenimento). Livello 2: direzione + responsabile della protezione dei dati + ufficio legale. Livello 3: notifica esterna allautorità di vigilanza del mercato nonché, se del caso, informazione del fornitore (art. 26, par. 5) e delle persone interessate.'],
['6. Documentazione', 'Ogni segnalazione viene documentata con il modulo di notifica degli incidenti gravi e conservata per almeno [5] anni. Il referente IA tiene il registro degli incidenti.'],
['7. Nessuna sanzione per segnalazioni in buona fede', 'Ai dipendenti che segnalano in buona fede non deve derivare alcun pregiudizio.'],
['8. Entrata in vigore', 'La presente policy entra in vigore il [data].'],
],
},
es: {
title: 'Política interna de notificación y escalado para incidentes de IA (borrador)',
sections: [
['1. Objeto', 'Esta política regula la obligación interna de notificar fallos e incidentes relacionados con sistemas de IA. Garantiza que la empresa pueda cumplir los plazos legales de notificación (art. 73 del Reglamento europeo de IA: 15 días, fallecimiento 10 días, infracción generalizada/infraestructura crítica 2 días).'],
['2. Qué debe notificarse', 'Cada empleado notifica sin demora: (a) fallos de funcionamiento o comportamientos inesperados de un sistema de IA, (b) sospechas de daños a la salud, la seguridad o los derechos fundamentales, (c) sospechas de discriminación por decisiones apoyadas en IA, (d) incidentes de protección de datos relacionados con la IA, (e) elusión de la supervisión humana.'],
['3. Canal de notificación', 'Primera notificación a: responsable de IA [nombre, contacto] — verbalmente o a través de [canal]. Si no está disponible: [suplente]. Las notificaciones también pueden hacerse de forma confidencial; la protección de los denunciantes conforme a la ley alemana de protección de denunciantes (HinSchG) no se ve afectada.'],
['4. Plazos internos', 'Notificación por los empleados: de inmediato, a más tardar 24 horas después de tener conocimiento. Evaluación inicial por el responsable de IA: en un plazo de 48 horas. Decisión sobre la notificación externa (art. 73) con la dirección: sin demora, de modo que se respeten los plazos legales.'],
['5. Niveles de escalado', 'Nivel 1: responsable de IA (evaluación, contención). Nivel 2: dirección + delegado de protección de datos + departamento jurídico. Nivel 3: notificación externa a la autoridad de vigilancia del mercado y, en su caso, información al proveedor (art. 26, apdo. 5) y a las personas afectadas.'],
['6. Documentación', 'Cada notificación se documenta con el formulario de notificación de incidentes graves y se conserva durante al menos [5] años. El responsable de IA lleva el registro de incidentes.'],
['7. Sin sanciones por notificaciones de buena fe', 'Los empleados que notifiquen de buena fe no deben sufrir ningún perjuicio.'],
['8. Entrada en vigor', 'Esta política entra en vigor el [fecha].'],
],
},
pl: {
title: 'Wewnętrzna polityka zgłaszania i eskalacji incydentów AI (projekt)',
sections: [
['1. Cel', 'Niniejsza polityka reguluje wewnętrzny obowiązek zgłaszania zakłóceń i incydentów związanych z systemami AI. Zapewnia, że przedsiębiorstwo może dotrzymać ustawowych terminów zgłoszeń (art. 73 europejskiego rozporządzenia w sprawie AI: 15 dni, zgon 10 dni, naruszenie na szeroką skalę/infrastruktura krytyczna 2 dni).'],
['2. Co należy zgłaszać', 'Każdy pracownik niezwłocznie zgłasza: (a) nieprawidłowe działanie lub nieoczekiwane zachowanie systemu AI, (b) podejrzenie szkód dla zdrowia, bezpieczeństwa lub praw podstawowych, (c) podejrzenie dyskryminacji przez decyzje wspierane przez AI, (d) incydenty ochrony danych związane z AI, (e) obchodzenie nadzoru człowieka.'],
['3. Ścieżka zgłoszenia', 'Pierwsze zgłoszenie do: pełnomocnik ds. AI [imię i nazwisko, kontakt] — ustnie lub przez [kanał]. W razie niedostępności: [zastępstwo]. Zgłoszenia są możliwe również poufnie; ochrona na podstawie ustawy o ochronie sygnalistów (HinSchG) pozostaje nienaruszona.'],
['4. Terminy wewnętrzne', 'Zgłoszenie przez pracowników: natychmiast, najpóźniej 24 godziny od powzięcia wiadomości. Wstępna ocena przez pełnomocnika ds. AI: w ciągu 48 godzin. Decyzja o zgłoszeniu zewnętrznym (art. 73) z zarządem: niezwłocznie, tak aby dotrzymać terminów ustawowych.'],
['5. Poziomy eskalacji', 'Poziom 1: pełnomocnik ds. AI (ocena, ograniczenie skutków). Poziom 2: zarząd + inspektor ochrony danych + dział prawny. Poziom 3: zgłoszenie zewnętrzne do organu nadzoru rynku oraz w razie potrzeby poinformowanie dostawcy (art. 26 ust. 5) i osób, których dotyczy incydent.'],
['6. Dokumentacja', 'Każde zgłoszenie jest dokumentowane formularzem zgłoszenia poważnego incydentu i przechowywane co najmniej [5] lat. Pełnomocnik ds. AI prowadzi rejestr incydentów.'],
['7. Brak sankcji za zgłoszenia w dobrej wierze', 'Pracownicy zgłaszający w dobrej wierze nie mogą ponosić z tego tytułu żadnych negatywnych konsekwencji.'],
['8. Wejście w życie', 'Niniejsza polityka wchodzi w życie w dniu [data].'],
],
},
cs: {
title: 'Interní politika hlášení a eskalace incidentů AI (návrh)',
sections: [
['1. Účel', 'Tato politika upravuje interní ohlašovací povinnost pro poruchy a incidenty související se systémy AI. Zajišťuje, že společnost může dodržet zákonné lhůty pro hlášení (čl. 73 evropského nařízení o AI: 15 dnů, úmrtí 10 dnů, rozsáhlé porušení/kritická infrastruktura 2 dny).'],
['2. Co je třeba hlásit', 'Každý zaměstnanec neprodleně hlásí: (a) poruchy nebo neočekávané chování systému AI, (b) podezření na poškození zdraví, bezpečnosti nebo základních práv, (c) podezření na diskriminaci rozhodnutími podporovanými AI, (d) incidenty v oblasti ochrany osobních údajů související s AI, (e) obcházení lidského dohledu.'],
['3. Ohlašovací kanál', 'První hlášení na: pověřenec pro AI [jméno, kontakt] — ústně nebo přes [kanál]. V případě nedostupnosti: [zástupce]. Hlášení lze podat i důvěrně; ochrana oznamovatelů podle německého zákona o ochraně oznamovatelů (HinSchG) zůstává nedotčena.'],
['4. Interní lhůty', 'Hlášení zaměstnancem: ihned, nejpozději do 24 hodin od zjištění. Prvotní posouzení pověřencem pro AI: do 48 hodin. Rozhodnutí o externím hlášení (čl. 73) s vedením: neprodleně, aby byly dodrženy zákonné lhůty.'],
['5. Úrovně eskalace', 'Úroveň 1: pověřenec pro AI (posouzení, omezení dopadů). Úroveň 2: vedení + pověřenec pro ochranu osobních údajů + právní oddělení. Úroveň 3: externí hlášení orgánu dozoru nad trhem a případně informování poskytovatele (čl. 26 odst. 5) a dotčených osob.'],
['6. Dokumentace', 'Každé hlášení se dokumentuje formulářem pro hlášení závažných incidentů a uchovává nejméně [5] let. Pověřenec pro AI vede registr incidentů.'],
['7. Žádné sankce za hlášení v dobré víře', 'Zaměstnancům, kteří hlásí v dobré víře, nesmí vzniknout žádná újma.'],
['8. Nabytí účinnosti', 'Tato politika nabývá účinnosti dne [datum].'],
],
},
sk: {
title: 'Interná politika hlásenia a eskalácie incidentov AI (návrh)',
sections: [
['1. Účel', 'Táto politika upravuje internú ohlasovaciu povinnosť pri poruchách a incidentoch súvisiacich so systémami AI. Zabezpečuje, aby spoločnosť mohla dodržať zákonné lehoty na hlásenie (čl. 73 európskeho nariadenia o AI: 15 dní, úmrtie 10 dní, rozsiahle porušenie/kritická infraštruktúra 2 dni).'],
['2. Čo treba hlásiť', 'Každý zamestnanec bezodkladne hlási: (a) poruchy alebo neočakávané správanie systému AI, (b) podozrenie na poškodenie zdravia, bezpečnosti alebo základných práv, (c) podozrenie na diskrimináciu rozhodnutiami podporovanými AI, (d) incidenty v oblasti ochrany osobných údajov súvisiace s AI, (e) obchádzanie ľudského dohľadu.'],
['3. Kanál hlásenia', 'Prvé hlásenie na: zodpovedná osoba za AI [meno, kontakt] — ústne alebo cez [kanál]. V prípade nedostupnosti: [zástupca]. Hlásenia možno podať aj dôverne; ochrana oznamovateľov podľa nemeckého zákona o ochrane oznamovateľov (HinSchG) zostáva nedotknutá.'],
['4. Interné lehoty', 'Hlásenie zamestnancom: ihneď, najneskôr do 24 hodín od zistenia. Prvotné posúdenie zodpovednou osobou za AI: do 48 hodín. Rozhodnutie o externom hlásení (čl. 73) s vedením: bezodkladne, aby boli dodržané zákonné lehoty.'],
['5. Úrovne eskalácie', 'Úroveň 1: zodpovedná osoba za AI (posúdenie, obmedzenie dosahov). Úroveň 2: vedenie + zodpovedná osoba za ochranu údajov + právne oddelenie. Úroveň 3: externé hlásenie orgánu dohľadu nad trhom a v prípade potreby informovanie poskytovateľa (čl. 26 ods. 5) a dotknutých osôb.'],
['6. Dokumentácia', 'Každé hlásenie sa dokumentuje formulárom na hlásenie závažných incidentov a uchováva najmenej [5] rokov. Zodpovedná osoba za AI vedie register incidentov.'],
['7. Žiadne sankcie za hlásenia v dobrej viere', 'Zamestnancom, ktorí hlásia v dobrej viere, nesmie vzniknúť žiadna ujma.'],
['8. Nadobudnutie účinnosti', 'Táto politika nadobúda účinnosť dňa [dátum].'],
],
},
ro: {
title: 'Politica internă de raportare și escaladare pentru incidente de IA (proiect)',
sections: [
['1. Scop', 'Prezenta politică reglementează obligația internă de raportare a defecțiunilor și incidentelor legate de sistemele de IA. Ea asigură că întreprinderea poate respecta termenele legale de raportare (art. 73 din Regulamentul european privind IA: 15 zile, deces 10 zile, încălcare pe scară largă/infrastructură critică 2 zile).'],
['2. Ce trebuie raportat', 'Fiecare angajat raportează fără întârziere: (a) defecțiuni sau comportamente neașteptate ale unui sistem de IA, (b) suspiciuni de prejudicii aduse sănătății, siguranței sau drepturilor fundamentale, (c) suspiciuni de discriminare prin decizii sprijinite de IA, (d) incidente de protecție a datelor legate de IA, (e) eludarea supravegherii umane.'],
['3. Canalul de raportare', 'Prima raportare către: responsabil IA [nume, contact] — verbal sau prin [canal]. În caz de indisponibilitate: [supleant]. Raportările pot fi făcute și confidențial; protecția avertizorilor conform legii germane privind protecția avertizorilor (HinSchG) rămâne neafectată.'],
['4. Termene interne', 'Raportare de către angajați: imediat, cel târziu în 24 de ore de la luarea la cunoștință. Evaluare inițială de către responsabilul IA: în termen de 48 de ore. Decizia privind raportarea externă (art. 73) împreună cu conducerea: fără întârziere, astfel încât termenele legale să fie respectate.'],
['5. Niveluri de escaladare', 'Nivelul 1: responsabil IA (evaluare, limitarea efectelor). Nivelul 2: conducere + responsabil cu protecția datelor + departamentul juridic. Nivelul 3: raportare externă către autoritatea de supraveghere a pieței și, dacă este cazul, informarea furnizorului (art. 26 alin. 5) și a persoanelor vizate.'],
['6. Documentare', 'Fiecare raportare este documentată cu formularul de raportare a incidentelor grave și păstrată cel puțin [5] ani. Responsabilul IA ține registrul incidentelor.'],
['7. Fără sancțiuni pentru raportări de bună-credință', 'Angajații care raportează cu bună-credință nu trebuie să sufere niciun dezavantaj.'],
['8. Intrare în vigoare', 'Prezenta politică intră în vigoare la [data].'],
],
},
} as const;
const T = T_ALL[locale];
const lines = [head(T.title, pack, today, locale, profile)];
for (const [sec, body] of T.sections) {
lines.push(`## ${sec}`, '', body ?? '', '');
}
return lines.join('\n');
}
/** Vordruck: Freigabeantrag für ein neues KI-System (interner Genehmigungsprozess). */
export function approvalRequest(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const T_ALL = {
de: {
title: 'Freigabeantrag für ein neues KI-System (internes Formular)',
intro: 'Von der anfordernden Fachabteilung auszufüllen, bevor ein neues KI-System produktiv genutzt oder ein bestehendes wesentlich geändert wird. Die Freigabe erteilt [KI-Beauftragte/r / Geschäftsleitung].',
fields: [
'Anfordernde Abteilung / Person / Datum',
'Name und Anbieter des KI-Systems (inkl. Version, Bereitstellungsform: Cloud/On-Premises)',
'Zweckbestimmung und erwarteter Nutzen',
'Verarbeitete Datenarten (personenbezogen? besondere Kategorien? Geschäftsgeheimnisse?)',
'Betroffene Personen (Beschäftigte, Bewerber, Kunden)',
'Risiko-Voreinschätzung (Annex-III-Bereich betroffen? Transparenz-Auslöser?)',
'Vorliegende Anbieterunterlagen (Betriebsanleitung, AVV, Zertifizierungen)',
'Geplante menschliche Aufsicht und verantwortliche Person',
],
decision: 'Entscheidung',
decisionBody: '☐ freigegeben ☐ freigegeben mit Auflagen: _______________ ☐ abgelehnt\n\nAuflagen/Hinweise: _______________\n\nDatum, Unterschrift (KI-Beauftragte/r): _______________ Datum, Unterschrift (Geschäftsleitung, soweit erforderlich): _______________\n\nNach Freigabe: System ins KI-Inventar aufnehmen und die Risikobewertung in diesem Tool durchführen.',
},
en: {
title: 'Approval request for a new AI system (internal form)',
intro: 'To be completed by the requesting department before any productive use of a new AI system or a substantial change to an existing one. Approval is granted by [AI officer / management].',
fields: [
'Requesting department / person / date',
'Name and provider of the AI system (incl. version, deployment form: cloud/on-premises)',
'Intended purpose and expected benefit',
'Categories of data processed (personal data? special categories? trade secrets?)',
'Affected persons (employees, applicants, customers)',
'Preliminary risk view (Annex III area affected? transparency triggers?)',
'Provider documents available (instructions for use, DPA, certifications)',
'Planned human oversight and responsible person',
],
decision: 'Decision',
decisionBody: '☐ approved ☐ approved with conditions: _______________ ☐ rejected\n\nConditions/notes: _______________\n\nDate, signature (AI officer): _______________ Date, signature (management, where required): _______________\n\nAfter approval: enter the system in the AI inventory and run the risk assessment in this tool.',
},
fr: {
title: 'Demande dapprobation dun nouveau système dIA (formulaire interne)',
intro: 'À remplir par le service demandeur avant toute utilisation productive dun nouveau système dIA ou toute modification substantielle dun système existant. Lapprobation est délivrée par [référent IA / direction].',
fields: [
'Service demandeur / personne / date',
'Nom et fournisseur du système dIA (version incluse, mode de déploiement : cloud/sur site)',
'Destination prévue et bénéfice attendu',
'Catégories de données traitées (données personnelles ? catégories particulières ? secrets daffaires ?)',
'Personnes concernées (salariés, candidats, clients)',
'Pré-évaluation du risque (domaine de lannexe III concerné ? déclencheurs de transparence ?)',
'Documents du fournisseur disponibles (notice dutilisation, contrat de sous-traitance, certifications)',
'Contrôle humain prévu et personne responsable',
],
decision: 'Décision',
decisionBody: '☐ approuvé ☐ approuvé sous conditions : _______________ ☐ rejeté\n\nConditions/remarques : _______________\n\nDate, signature (référent IA) : _______________ Date, signature (direction, si nécessaire) : _______________\n\nAprès approbation : inscrire le système dans linventaire IA et effectuer lévaluation des risques dans cet outil.',
},
it: {
title: 'Richiesta di approvazione per un nuovo sistema di IA (modulo interno)',
intro: 'Da compilare a cura del reparto richiedente prima di qualsiasi uso produttivo di un nuovo sistema di IA o di una modifica sostanziale di uno esistente. Lapprovazione è rilasciata da [referente IA / direzione].',
fields: [
'Reparto richiedente / persona / data',
'Nome e fornitore del sistema di IA (incl. versione, modalità di fornitura: cloud/on-premises)',
'Finalità prevista e beneficio atteso',
'Categorie di dati trattati (dati personali? categorie particolari? segreti commerciali?)',
'Persone interessate (dipendenti, candidati, clienti)',
'Valutazione preliminare del rischio (area dellallegato III interessata? fattori che attivano obblighi di trasparenza?)',
'Documenti del fornitore disponibili (istruzioni per luso, accordo sul trattamento dei dati, certificazioni)',
'Sorveglianza umana prevista e persona responsabile',
],
decision: 'Decisione',
decisionBody: '☐ approvato ☐ approvato con condizioni: _______________ ☐ respinto\n\nCondizioni/note: _______________\n\nData, firma (referente IA): _______________ Data, firma (direzione, ove necessario): _______________\n\nDopo lapprovazione: inserire il sistema nellinventario IA ed eseguire la valutazione del rischio in questo strumento.',
},
es: {
title: 'Solicitud de aprobación de un nuevo sistema de IA (formulario interno)',
intro: 'A cumplimentar por el departamento solicitante antes de cualquier uso productivo de un nuevo sistema de IA o de un cambio sustancial en uno existente. La aprobación la concede [responsable de IA / dirección].',
fields: [
'Departamento solicitante / persona / fecha',
'Nombre y proveedor del sistema de IA (incl. versión, forma de despliegue: nube/local)',
'Finalidad prevista y beneficio esperado',
'Categorías de datos tratados (¿datos personales? ¿categorías especiales? ¿secretos comerciales?)',
'Personas afectadas (empleados, candidatos, clientes)',
'Evaluación preliminar del riesgo (¿área del anexo III afectada? ¿desencadenantes de transparencia?)',
'Documentos del proveedor disponibles (instrucciones de uso, contrato de encargo de tratamiento, certificaciones)',
'Supervisión humana prevista y persona responsable',
],
decision: 'Decisión',
decisionBody: '☐ aprobado ☐ aprobado con condiciones: _______________ ☐ rechazado\n\nCondiciones/observaciones: _______________\n\nFecha, firma (responsable de IA): _______________ Fecha, firma (dirección, cuando proceda): _______________\n\nTras la aprobación: registrar el sistema en el inventario de IA y realizar la evaluación de riesgos en esta herramienta.',
},
pl: {
title: 'Wniosek o zatwierdzenie nowego systemu AI (formularz wewnętrzny)',
intro: 'Do wypełnienia przez wnioskujący dział przed produkcyjnym użyciem nowego systemu AI lub istotną zmianą istniejącego. Zatwierdzenia udziela [pełnomocnik ds. AI / zarząd].',
fields: [
'Wnioskujący dział / osoba / data',
'Nazwa i dostawca systemu AI (wraz z wersją, forma udostępnienia: chmura/on-premises)',
'Przeznaczenie i oczekiwane korzyści',
'Rodzaje przetwarzanych danych (osobowe? szczególne kategorie? tajemnice przedsiębiorstwa?)',
'Osoby, których dotyczy (pracownicy, kandydaci, klienci)',
'Wstępna ocena ryzyka (obszar załącznika III? przesłanki obowiązków przejrzystości?)',
'Dostępne dokumenty dostawcy (instrukcja obsługi, umowa powierzenia przetwarzania, certyfikaty)',
'Planowany nadzór człowieka i osoba odpowiedzialna',
],
decision: 'Decyzja',
decisionBody: '☐ zatwierdzono ☐ zatwierdzono z warunkami: _______________ ☐ odrzucono\n\nWarunki/uwagi: _______________\n\nData, podpis (pełnomocnik ds. AI): _______________ Data, podpis (zarząd, o ile wymagane): _______________\n\nPo zatwierdzeniu: wpisać system do rejestru AI i przeprowadzić ocenę ryzyka w tym narzędziu.',
},
cs: {
title: 'Žádost o schválení nového systému AI (interní formulář)',
intro: 'Vyplní žádající oddělení před produktivním použitím nového systému AI nebo podstatnou změnou stávajícího. Schválení uděluje [pověřenec pro AI / vedení].',
fields: [
'Žádající oddělení / osoba / datum',
'Název a poskytovatel systému AI (vč. verze, forma nasazení: cloud/on-premises)',
'Zamýšlený účel a očekávaný přínos',
'Kategorie zpracovávaných údajů (osobní údaje? zvláštní kategorie? obchodní tajemství?)',
'Dotčené osoby (zaměstnanci, uchazeči, zákazníci)',
'Předběžné posouzení rizika (dotčena oblast přílohy III? spouštěče povinností transparentnosti?)',
'Dostupné podklady poskytovatele (návod k použití, smlouva o zpracování údajů, certifikace)',
'Plánovaný lidský dohled a odpovědná osoba',
],
decision: 'Rozhodnutí',
decisionBody: '☐ schváleno ☐ schváleno s podmínkami: _______________ ☐ zamítnuto\n\nPodmínky/poznámky: _______________\n\nDatum, podpis (pověřenec pro AI): _______________ Datum, podpis (vedení, je-li vyžadováno): _______________\n\nPo schválení: zapsat systém do inventáře AI a provést posouzení rizik v tomto nástroji.',
},
sk: {
title: 'Žiadosť o schválenie nového systému AI (interný formulár)',
intro: 'Vyplní žiadajúce oddelenie pred produktívnym použitím nového systému AI alebo podstatnou zmenou existujúceho. Schválenie udeľuje [zodpovedná osoba za AI / vedenie].',
fields: [
'Žiadajúce oddelenie / osoba / dátum',
'Názov a poskytovateľ systému AI (vrát. verzie, forma nasadenia: cloud/on-premises)',
'Zamýšľaný účel a očakávaný prínos',
'Kategórie spracúvaných údajov (osobné údaje? osobitné kategórie? obchodné tajomstvá?)',
'Dotknuté osoby (zamestnanci, uchádzači, zákazníci)',
'Predbežné posúdenie rizika (dotknutá oblasť prílohy III? spúšťače povinností transparentnosti?)',
'Dostupné podklady poskytovateľa (návod na použitie, zmluva o spracúvaní údajov, certifikácie)',
'Plánovaný ľudský dohľad a zodpovedná osoba',
],
decision: 'Rozhodnutie',
decisionBody: '☐ schválené ☐ schválené s podmienkami: _______________ ☐ zamietnuté\n\nPodmienky/poznámky: _______________\n\nDátum, podpis (zodpovedná osoba za AI): _______________ Dátum, podpis (vedenie, ak sa vyžaduje): _______________\n\nPo schválení: zapísať systém do inventára AI a vykonať posúdenie rizík v tomto nástroji.',
},
ro: {
title: 'Cerere de aprobare pentru un nou sistem de IA (formular intern)',
intro: 'Se completează de departamentul solicitant înainte de orice utilizare productivă a unui nou sistem de IA sau de o modificare substanțială a unuia existent. Aprobarea este acordată de [responsabil IA / conducere].',
fields: [
'Departament solicitant / persoană / dată',
'Denumirea și furnizorul sistemului de IA (incl. versiunea, forma de furnizare: cloud/on-premises)',
'Scopul preconizat și beneficiul așteptat',
'Categorii de date prelucrate (date cu caracter personal? categorii speciale? secrete comerciale?)',
'Persoane vizate (angajați, candidați, clienți)',
'Evaluare preliminară a riscului (domeniu din anexa III vizat? factori care declanșează obligații de transparență?)',
'Documente ale furnizorului disponibile (instrucțiuni de utilizare, acord de prelucrare a datelor, certificări)',
'Supravegherea umană planificată și persoana responsabilă',
],
decision: 'Decizie',
decisionBody: '☐ aprobat ☐ aprobat cu condiții: _______________ ☐ respins\n\nCondiții/observații: _______________\n\nData, semnătura (responsabil IA): _______________ Data, semnătura (conducere, dacă este necesar): _______________\n\nDupă aprobare: înregistrați sistemul în inventarul IA și efectuați evaluarea riscurilor în acest instrument.',
},
} as const;
const T = T_ALL[locale];
const lines = [head(T.title, pack, today, locale, profile)];
lines.push(T.intro, '');
T.fields.forEach((f, i) => {
lines.push(`## ${i + 1}. ${f}`, '', s.todo, '');
});
lines.push(`## ${T.decision}`, '', T.decisionBody);
return lines.join('\n');
}
/** Vordruck: Interne Audit-Checkliste KI-Compliance (periodische Selbstprüfung). */
export function auditChecklist(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const T_ALL = {
de: {
title: 'Interne Audit-Checkliste KI-Compliance (periodische Selbstprüfung)',
intro: 'Empfohlener Turnus: alle [6] Monate sowie nach wesentlichen Änderungen. Prüfer: [KI-Beauftragte/r]. Ergebnis an die Geschäftsleitung.',
cols: '| # | Prüfpunkt | Ergebnis (OK / Lücke) | Maßnahme / Verantwortlich / Frist |',
sep: '|---|---|---|---|',
rows: [
'KI-Inventar vollständig? (Schatten-IT-Check: neue Tools in Fachabteilungen, Browser-Erweiterungen, API-Nutzung)',
'Risikoklassifizierungen noch zutreffend? (Zweck oder Umfang geändert? Neubewertung durchgeführt?)',
'Alle Pflichten der Aufgabenliste abgearbeitet oder im Plan?',
'KI-Kompetenz-Schulungen (Art. 4) für alle relevanten Beschäftigten durchgeführt und dokumentiert?',
'Transparenzpflichten (Art. 50) in allen kundenseitigen Systemen umgesetzt?',
'Protokolle der Hochrisiko-Systeme aufbewahrt (mind. 6 Monate) und zugänglich?',
'Vorfallregister geführt; interne Melderichtlinie den Beschäftigten bekannt?',
'Anbieterunterlagen (Betriebsanleitung, AVV, Zertifikate) aktuell und abgelegt?',
'Betriebsvereinbarungen / Mitarbeiterinformationen auf aktuellem Stand?',
'Änderungen der Länder-Module geprüft (neue Dekrete, Behördenleitlinien)?',
'Backup der Daten dieses Tools exportiert und abgelegt?',
],
result: 'Gesamtergebnis & Abzeichnung',
resultBody: 'Festgestellte Lücken: _______________\n\nDatum, Unterschrift (Prüfer): _______________ Datum, Unterschrift (Geschäftsleitung): _______________',
},
en: {
title: 'Internal AI compliance audit checklist (periodic self-review)',
intro: 'Recommended interval: every [6] months and after material changes. Auditor: [AI officer]. Result to management.',
cols: '| # | Check | Result (OK / gap) | Action / owner / due date |',
sep: '|---|---|---|---|',
rows: [
'AI inventory complete? (shadow IT check: new tools in departments, browser extensions, API usage)',
'Risk classifications still accurate? (purpose or scope changed? reassessment run?)',
'All obligations in the task list processed or on schedule?',
'AI literacy trainings (Art. 4) carried out and documented for all relevant staff?',
'Transparency duties (Art. 50) implemented in all customer-facing systems?',
'Logs of high-risk systems retained (min. 6 months) and accessible?',
'Incident register maintained; internal reporting policy known to staff?',
'Provider documents (instructions, DPA, certificates) current and on file?',
'Works council agreements / employee information up to date?',
'National module changes checked (new decrees, authority guidance)?',
'Backup of this tools data exported and stored?',
],
result: 'Overall result & sign-off',
resultBody: 'Gaps found: _______________\n\nDate, signature (auditor): _______________ Date, signature (management): _______________',
},
fr: {
title: 'Check-list daudit interne — conformité IA (auto-contrôle périodique)',
intro: 'Fréquence recommandée : tous les [6] mois ainsi quaprès des modifications importantes. Auditeur : [référent IA]. Résultat à la direction.',
cols: '| # | Point de contrôle | Résultat (OK / lacune) | Mesure / responsable / échéance |',
sep: '|---|---|---|---|',
rows: [
'Inventaire IA complet ? (contrôle de lIA fantôme : nouveaux outils dans les services, extensions de navigateur, utilisation dAPI)',
'Classifications des risques toujours exactes ? (finalité ou périmètre modifiés ? réévaluation effectuée ?)',
'Toutes les obligations de la liste des tâches traitées ou dans les délais ?',
'Formations à la maîtrise de lIA (art. 4) réalisées et documentées pour tout le personnel concerné ?',
'Obligations de transparence (art. 50) mises en œuvre dans tous les systèmes orientés clients ?',
'Journaux des systèmes à haut risque conservés (min. 6 mois) et accessibles ?',
'Registre des incidents tenu ; politique interne de signalement connue du personnel ?',
'Documents des fournisseurs (notices dutilisation, contrat de sous-traitance, certificats) à jour et archivés ?',
'Accords dentreprise / informations aux salariés à jour ?',
'Modifications des modules nationaux vérifiées (nouveaux décrets, lignes directrices des autorités) ?',
'Sauvegarde des données de cet outil exportée et archivée ?',
],
result: 'Résultat global & validation',
resultBody: 'Lacunes constatées : _______________\n\nDate, signature (auditeur) : _______________ Date, signature (direction) : _______________',
},
it: {
title: 'Checklist di audit interno — conformità IA (autoverifica periodica)',
intro: 'Cadenza raccomandata: ogni [6] mesi e dopo modifiche sostanziali. Auditor: [referente IA]. Esito alla direzione.',
cols: '| # | Punto di verifica | Esito (OK / lacuna) | Misura / responsabile / scadenza |',
sep: '|---|---|---|---|',
rows: [
'Inventario IA completo? (controllo shadow AI: nuovi strumenti nei reparti, estensioni del browser, utilizzo di API)',
'Classificazioni del rischio ancora corrette? (finalità o ambito modificati? nuova valutazione eseguita?)',
'Tutti gli obblighi dellelenco delle attività evasi o nei tempi previsti?',
'Formazioni di alfabetizzazione IA (art. 4) svolte e documentate per tutto il personale rilevante?',
'Obblighi di trasparenza (art. 50) attuati in tutti i sistemi rivolti ai clienti?',
'Log dei sistemi ad alto rischio conservati (min. 6 mesi) e accessibili?',
'Registro degli incidenti tenuto; policy interna di segnalazione nota al personale?',
'Documenti dei fornitori (istruzioni per luso, accordo sul trattamento dei dati, certificati) aggiornati e archiviati?',
'Accordi aziendali / informazioni ai dipendenti aggiornati?',
'Modifiche dei moduli nazionali verificate (nuovi decreti, linee guida delle autorità)?',
'Backup dei dati di questo strumento esportato e archiviato?',
],
result: 'Esito complessivo e approvazione',
resultBody: 'Lacune riscontrate: _______________\n\nData, firma (auditor): _______________ Data, firma (direzione): _______________',
},
es: {
title: 'Lista de comprobación de auditoría interna — cumplimiento de IA (autoevaluación periódica)',
intro: 'Periodicidad recomendada: cada [6] meses y tras cambios sustanciales. Auditor: [responsable de IA]. Resultado a la dirección.',
cols: '| # | Punto de control | Resultado (OK / deficiencia) | Medida / responsable / plazo |',
sep: '|---|---|---|---|',
rows: [
'¿Inventario de IA completo? (control de IA en la sombra: nuevas herramientas en los departamentos, extensiones de navegador, uso de API)',
'¿Clasificaciones de riesgo todavía correctas? (¿finalidad o alcance modificados? ¿reevaluación realizada?)',
'¿Todas las obligaciones de la lista de tareas completadas o dentro del plazo?',
'¿Formaciones de alfabetización en IA (art. 4) realizadas y documentadas para todo el personal pertinente?',
'¿Obligaciones de transparencia (art. 50) implementadas en todos los sistemas orientados al cliente?',
'¿Registros de los sistemas de alto riesgo conservados (mín. 6 meses) y accesibles?',
'¿Registro de incidentes al día? ¿Política interna de notificación conocida por el personal?',
'¿Documentos del proveedor (instrucciones de uso, contrato de encargo de tratamiento, certificados) actualizados y archivados?',
'¿Acuerdos de empresa / información a los empleados actualizados?',
'¿Cambios en los módulos nacionales comprobados (nuevos decretos, directrices de las autoridades)?',
'¿Copia de seguridad de los datos de esta herramienta exportada y archivada?',
],
result: 'Resultado global y firma',
resultBody: 'Deficiencias detectadas: _______________\n\nFecha, firma (auditor): _______________ Fecha, firma (dirección): _______________',
},
pl: {
title: 'Wewnętrzna lista kontrolna audytu zgodności AI (okresowa samokontrola)',
intro: 'Zalecana częstotliwość: co [6] miesięcy oraz po istotnych zmianach. Audytor: [pełnomocnik ds. AI]. Wynik przekazywany zarządowi.',
cols: '| # | Punkt kontrolny | Wynik (OK / luka) | Działanie / odpowiedzialny / termin |',
sep: '|---|---|---|---|',
rows: [
'Rejestr AI kompletny? (kontrola shadow AI: nowe narzędzia w działach, rozszerzenia przeglądarki, użycie API)',
'Klasyfikacje ryzyka nadal trafne? (zmieniony cel lub zakres? przeprowadzono ponowną ocenę?)',
'Wszystkie obowiązki z listy zadań wykonane lub zgodne z planem?',
'Szkolenia z kompetencji w zakresie AI (art. 4) przeprowadzone i udokumentowane dla wszystkich właściwych pracowników?',
'Obowiązki przejrzystości (art. 50) wdrożone we wszystkich systemach skierowanych do klientów?',
'Logi systemów wysokiego ryzyka przechowywane (min. 6 miesięcy) i dostępne?',
'Rejestr incydentów prowadzony; wewnętrzna polityka zgłaszania znana pracownikom?',
'Dokumenty dostawców (instrukcje obsługi, umowa powierzenia przetwarzania, certyfikaty) aktualne i zarchiwizowane?',
'Porozumienia zakładowe / informacje dla pracowników aktualne?',
'Zmiany modułów krajowych sprawdzone (nowe dekrety, wytyczne organów)?',
'Kopia zapasowa danych tego narzędzia wyeksportowana i zarchiwizowana?',
],
result: 'Wynik ogólny i zatwierdzenie',
resultBody: 'Stwierdzone luki: _______________\n\nData, podpis (audytor): _______________ Data, podpis (zarząd): _______________',
},
cs: {
title: 'Interní auditní kontrolní seznam — compliance AI (pravidelná sebekontrola)',
intro: 'Doporučený interval: každých [6] měsíců a po podstatných změnách. Auditor: [pověřenec pro AI]. Výsledek vedení.',
cols: '| # | Kontrolní bod | Výsledek (OK / mezera) | Opatření / odpovědná osoba / termín |',
sep: '|---|---|---|---|',
rows: [
'Inventář AI úplný? (kontrola stínové AI: nové nástroje v odděleních, rozšíření prohlížeče, používání API)',
'Klasifikace rizik stále správné? (změněn účel nebo rozsah? provedeno nové posouzení?)',
'Všechny povinnosti ze seznamu úkolů splněny nebo dle plánu?',
'Školení gramotnosti v oblasti AI (čl. 4) provedena a dokumentována pro všechny relevantní zaměstnance?',
'Povinnosti transparentnosti (čl. 50) zavedeny ve všech systémech směřujících k zákazníkům?',
'Protokoly vysoce rizikových systémů uchovávány (min. 6 měsíců) a přístupné?',
'Registr incidentů veden; interní politika hlášení známa zaměstnancům?',
'Podklady poskytovatelů (návody k použití, smlouva o zpracování údajů, certifikáty) aktuální a uloženy?',
'Podnikové dohody / informace pro zaměstnance aktuální?',
'Změny národních modulů zkontrolovány (nové dekrety, pokyny úřadů)?',
'Záloha dat tohoto nástroje exportována a uložena?',
],
result: 'Celkový výsledek a schválení',
resultBody: 'Zjištěné mezery: _______________\n\nDatum, podpis (auditor): _______________ Datum, podpis (vedení): _______________',
},
sk: {
title: 'Interný auditný kontrolný zoznam — compliance AI (pravidelná samokontrola)',
intro: 'Odporúčaný interval: každých [6] mesiacov a po podstatných zmenách. Audítor: [zodpovedná osoba za AI]. Výsledok vedeniu.',
cols: '| # | Kontrolný bod | Výsledok (OK / medzera) | Opatrenie / zodpovedný / termín |',
sep: '|---|---|---|---|',
rows: [
'Inventár AI úplný? (kontrola tieňovej AI: nové nástroje v oddeleniach, rozšírenia prehliadača, používanie API)',
'Klasifikácie rizík stále správne? (zmenený účel alebo rozsah? vykonané nové posúdenie?)',
'Všetky povinnosti zo zoznamu úloh splnené alebo podľa plánu?',
'Školenia gramotnosti v oblasti AI (čl. 4) vykonané a zdokumentované pre všetkých relevantných zamestnancov?',
'Povinnosti transparentnosti (čl. 50) zavedené vo všetkých systémoch orientovaných na zákazníkov?',
'Protokoly vysokorizikových systémov uchovávané (min. 6 mesiacov) a prístupné?',
'Register incidentov vedený; interná politika hlásenia známa zamestnancom?',
'Podklady poskytovateľov (návody na použitie, zmluva o spracúvaní údajov, certifikáty) aktuálne a uložené?',
'Podnikové dohody / informácie pre zamestnancov aktuálne?',
'Zmeny národných modulov skontrolované (nové dekréty, usmernenia úradov)?',
'Záloha údajov tohto nástroja exportovaná a uložená?',
],
result: 'Celkový výsledok a schválenie',
resultBody: 'Zistené medzery: _______________\n\nDátum, podpis (audítor): _______________ Dátum, podpis (vedenie): _______________',
},
ro: {
title: 'Listă de verificare pentru audit intern — conformitate IA (autoevaluare periodică)',
intro: 'Periodicitate recomandată: la fiecare [6] luni și după modificări substanțiale. Auditor: [responsabil IA]. Rezultatul se transmite conducerii.',
cols: '| # | Punct de verificare | Rezultat (OK / lacună) | Măsură / responsabil / termen |',
sep: '|---|---|---|---|',
rows: [
'Inventarul IA este complet? (verificare shadow AI: instrumente noi în departamente, extensii de browser, utilizare de API-uri)',
'Clasificările de risc sunt încă corecte? (scop sau domeniu modificat? reevaluare efectuată?)',
'Toate obligațiile din lista de sarcini îndeplinite sau conform planului?',
'Instruirile de alfabetizare în domeniul IA (art. 4) efectuate și documentate pentru tot personalul relevant?',
'Obligațiile de transparență (art. 50) implementate în toate sistemele orientate către clienți?',
'Jurnalele sistemelor cu grad ridicat de risc păstrate (min. 6 luni) și accesibile?',
'Registrul incidentelor ținut la zi; politica internă de raportare cunoscută de personal?',
'Documentele furnizorilor (instrucțiuni de utilizare, acord de prelucrare a datelor, certificate) actuale și arhivate?',
'Acordurile de întreprindere / informările angajaților actualizate?',
'Modificările modulelor naționale verificate (decrete noi, orientări ale autorităților)?',
'Copia de siguranță a datelor acestui instrument exportată și arhivată?',
],
result: 'Rezultat general și semnare',
resultBody: 'Lacune constatate: _______________\n\nData, semnătura (auditor): _______________ Data, semnătura (conducere): _______________',
},
} as const;
const T = T_ALL[locale];
const lines = [head(T.title, pack, today, locale, profile)];
lines.push(T.intro, '', T.cols, T.sep);
T.rows.forEach((row, i) => {
lines.push(`| ${i + 1} | ${row} | | |`);
});
lines.push('', `## ${T.result}`, '', T.resultBody);
return lines.join('\n');
}

View File

@ -0,0 +1,606 @@
import type { Locale } from '../i18n/types';
import { docStrings, formatDocDate } from './docStrings';
import type { AISystem, CompanyProfile, ContentPack } from './types';
/** Gemeinsamer Kopf für systembezogene Vordrucke. */
function head(
title: string,
system: AISystem,
pack: ContentPack,
today: string,
locale: Locale,
profile?: CompanyProfile,
): string {
const s = docStrings(locale);
return [
`# ${title}`,
'',
`| | |`,
`|---|---|`,
...(profile && profile.name.trim() !== '' ? [`| **${s.meta.company}** | ${profile.name} |`] : []),
`| **${s.meta.system}** | ${system.name} |`,
`| **${s.meta.purpose}** | ${system.purpose || '—'} |`,
`| **${s.meta.riskClass}** | ${s.risk[system.classification.riskClass]} |`,
`| **${s.meta.createdAt}** | ${formatDocDate(today, locale)} |`,
`| **${s.meta.contentPack}** | v${pack.version} |`,
'',
s.disclaimer,
'',
].join('\n');
}
/**
* Vordruck: Information des Betriebsrats nach § 90 BetrVG (Deutschland)
* über den geplanten Einsatz eines KI-Systems.
*/
export function worksCouncilInfo(
system: AISystem,
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const T_ALL = {
de: {
title: 'Information des Betriebsrats nach § 90 BetrVG (Entwurf)',
to: 'An den Betriebsrat der',
subject: 'Betreff: Unterrichtung über den geplanten Einsatz eines KI-Systems',
body: 'Sehr geehrte Mitglieder des Betriebsrats,\n\ngemäß § 90 Abs. 1 Nr. 3 BetrVG unterrichten wir Sie rechtzeitig über den geplanten Einsatz des folgenden KI-Systems und bieten die Beratung nach § 90 Abs. 2 BetrVG an. Sofern das System geeignet ist, Verhalten oder Leistung der Beschäftigten zu überwachen, werden wir zusätzlich Ihre Mitbestimmung nach § 87 Abs. 1 Nr. 6 BetrVG einholen (Betriebsvereinbarung).',
sections: [
['Geplanter Einführungszeitpunkt', ''],
['Betroffene Abteilungen / Beschäftigtengruppen', ''],
['Zweck und Funktionsweise des Systems (Kurzbeschreibung)', ''],
['Verarbeitete Beschäftigtendaten', ''],
['Auswirkungen auf Arbeitsabläufe und Arbeitsplätze', ''],
['Geplante Schulungsmaßnahmen (Art. 4 AI Act)', ''],
['Ansprechpartner für die Beratung', ''],
],
closing: 'Wir freuen uns auf die Beratung und stehen für Rückfragen zur Verfügung.\n\nOrt, Datum: _______________ Unterschrift (Arbeitgeber): _______________',
},
en: {
title: 'Information to the works council pursuant to Sec. 90 BetrVG (draft)',
to: 'To the works council of',
subject: 'Subject: Information on the planned use of an AI system',
body: 'Dear members of the works council,\n\npursuant to Sec. 90 (1) No. 3 BetrVG we inform you in due time about the planned use of the following AI system and offer consultation pursuant to Sec. 90 (2) BetrVG. If the system is capable of monitoring the behaviour or performance of employees, we will additionally seek your co-determination pursuant to Sec. 87 (1) No. 6 BetrVG (works agreement).',
sections: [
['Planned date of introduction', ''],
['Affected departments / groups of employees', ''],
['Purpose and functioning of the system (summary)', ''],
['Data processed relating to employees', ''],
['Effects on work processes and workplaces', ''],
['Planned training measures (Art. 4 AI Act)', ''],
['Contact person for consultation', ''],
],
closing: 'We look forward to the consultation and remain at your disposal for questions.\n\nPlace, date: _______________ Signature (employer): _______________',
},
fr: {
title: 'Information du comité dentreprise conformément au § 90 BetrVG (projet)',
to: 'Au comité dentreprise de',
subject: 'Objet : Information sur lutilisation prévue dun système dIA',
body: 'Mesdames et Messieurs les membres du comité dentreprise,\n\nconformément au § 90 al. 1 n° 3 BetrVG, nous vous informons en temps utile de lutilisation prévue du système dIA décrit ci-après et vous proposons une concertation conformément au § 90 al. 2 BetrVG. Si le système est susceptible de surveiller le comportement ou les performances des salariés, nous solliciterons en outre votre codétermination conformément au § 87 al. 1 n° 6 BetrVG (accord dentreprise).',
sections: [
['Date dintroduction prévue', ''],
['Services / groupes de salariés concernés', ''],
['Finalité et fonctionnement du système (résumé)', ''],
['Données des salariés traitées', ''],
['Effets sur les processus de travail et les postes de travail', ''],
['Mesures de formation prévues (art. 4 du règlement sur lIA)', ''],
['Interlocuteur pour la concertation', ''],
],
closing: 'Nous nous réjouissons de la concertation et restons à votre disposition pour toute question.\n\nLieu, date : _______________ Signature (employeur) : _______________',
},
it: {
title: 'Informazione del consiglio aziendale ai sensi del § 90 BetrVG (bozza)',
to: 'Al consiglio aziendale di',
subject: 'Oggetto: informazione sullimpiego previsto di un sistema di IA',
body: 'Gentili membri del consiglio aziendale,\n\nai sensi del § 90 c. 1 n. 3 BetrVG vi informiamo tempestivamente in merito allimpiego previsto del seguente sistema di IA e offriamo la consultazione ai sensi del § 90 c. 2 BetrVG. Qualora il sistema sia idoneo a monitorare il comportamento o le prestazioni dei dipendenti, richiederemo inoltre la vostra codeterminazione ai sensi del § 87 c. 1 n. 6 BetrVG (accordo aziendale).',
sections: [
['Data di introduzione prevista', ''],
['Reparti / gruppi di dipendenti interessati', ''],
['Finalità e funzionamento del sistema (sintesi)', ''],
['Dati dei dipendenti trattati', ''],
['Effetti sui processi di lavoro e sui posti di lavoro', ''],
['Misure di formazione previste (art. 4 del regolamento sullIA)', ''],
['Referente per la consultazione', ''],
],
closing: 'Restiamo in attesa della consultazione e a disposizione per eventuali domande.\n\nLuogo, data: _______________ Firma (datore di lavoro): _______________',
},
es: {
title: 'Información al comité de empresa conforme al § 90 BetrVG (borrador)',
to: 'Al comité de empresa de',
subject: 'Asunto: Información sobre el uso previsto de un sistema de IA',
body: 'Estimados miembros del comité de empresa:\n\nconforme al § 90 apdo. 1 n.º 3 BetrVG, les informamos con la debida antelación sobre el uso previsto del siguiente sistema de IA y les ofrecemos la consulta conforme al § 90 apdo. 2 BetrVG. Si el sistema es apto para supervisar el comportamiento o el rendimiento de los empleados, recabaremos además su cogestión conforme al § 87 apdo. 1 n.º 6 BetrVG (acuerdo de empresa).',
sections: [
['Fecha de introducción prevista', ''],
['Departamentos / grupos de empleados afectados', ''],
['Finalidad y funcionamiento del sistema (resumen)', ''],
['Datos de los empleados tratados', ''],
['Efectos sobre los procesos de trabajo y los puestos de trabajo', ''],
['Medidas de formación previstas (art. 4 del Reglamento de IA)', ''],
['Persona de contacto para la consulta', ''],
],
closing: 'Quedamos a la espera de la consulta y a su disposición para cualquier pregunta.\n\nLugar, fecha: _______________ Firma (empleador): _______________',
},
pl: {
title: 'Informacja dla rady zakładowej zgodnie z § 90 BetrVG (projekt)',
to: 'Do rady zakładowej',
subject: 'Temat: Informacja o planowanym wykorzystaniu systemu AI',
body: 'Szanowni Członkowie rady zakładowej,\n\nzgodnie z § 90 ust. 1 pkt 3 BetrVG informujemy Państwa w odpowiednim czasie o planowanym wykorzystaniu opisanego poniżej systemu AI i oferujemy konsultacje zgodnie z § 90 ust. 2 BetrVG. Jeżeli system umożliwia monitorowanie zachowania lub wydajności pracowników, dodatkowo wystąpimy o Państwa współdecydowanie zgodnie z § 87 ust. 1 pkt 6 BetrVG (porozumienie zakładowe).',
sections: [
['Planowany termin wdrożenia', ''],
['Objęte działy / grupy pracowników', ''],
['Cel i sposób działania systemu (krótki opis)', ''],
['Przetwarzane dane pracowników', ''],
['Wpływ na procesy pracy i stanowiska pracy', ''],
['Planowane działania szkoleniowe (art. 4 aktu w sprawie AI)', ''],
['Osoba do kontaktu w sprawie konsultacji', ''],
],
closing: 'Oczekujemy na konsultacje i pozostajemy do Państwa dyspozycji w razie pytań.\n\nMiejscowość, data: _______________ Podpis (pracodawca): _______________',
},
cs: {
title: 'Informování podnikové rady podle § 90 BetrVG (návrh)',
to: 'Podnikové radě společnosti',
subject: 'Věc: Informace o plánovaném nasazení systému AI',
body: 'Vážení členové podnikové rady,\n\npodle § 90 odst. 1 č. 3 BetrVG Vás včas informujeme o plánovaném nasazení níže popsaného systému AI a nabízíme projednání podle § 90 odst. 2 BetrVG. Pokud je systém způsobilý sledovat chování nebo výkon zaměstnanců, vyžádáme si navíc Vaše spolurozhodování podle § 87 odst. 1 č. 6 BetrVG (podniková dohoda).',
sections: [
['Plánovaný termín zavedení', ''],
['Dotčená oddělení / skupiny zaměstnanců', ''],
['Účel a způsob fungování systému (stručný popis)', ''],
['Zpracovávané údaje zaměstnanců', ''],
['Dopady na pracovní postupy a pracovní místa', ''],
['Plánovaná školicí opatření (čl. 4 aktu o AI)', ''],
['Kontaktní osoba pro projednání', ''],
],
closing: 'Těšíme se na projednání a jsme Vám k dispozici pro případné dotazy.\n\nMísto, datum: _______________ Podpis (zaměstnavatel): _______________',
},
sk: {
title: 'Informovanie zamestnaneckej rady podľa § 90 BetrVG (návrh)',
to: 'Zamestnaneckej rade spoločnosti',
subject: 'Vec: Informácia o plánovanom nasadení systému AI',
body: 'Vážení členovia zamestnaneckej rady,\n\npodľa § 90 ods. 1 č. 3 BetrVG Vás včas informujeme o plánovanom nasadení nižšie opísaného systému AI a ponúkame prerokovanie podľa § 90 ods. 2 BetrVG. Ak je systém spôsobilý monitorovať správanie alebo výkon zamestnancov, vyžiadame si navyše Vaše spolurozhodovanie podľa § 87 ods. 1 č. 6 BetrVG (podniková dohoda).',
sections: [
['Plánovaný termín zavedenia', ''],
['Dotknuté oddelenia / skupiny zamestnancov', ''],
['Účel a spôsob fungovania systému (stručný opis)', ''],
['Spracúvané údaje zamestnancov', ''],
['Vplyvy na pracovné postupy a pracovné miesta', ''],
['Plánované školiace opatrenia (čl. 4 aktu o AI)', ''],
['Kontaktná osoba pre prerokovanie', ''],
],
closing: 'Tešíme sa na prerokovanie a sme Vám k dispozícii pre prípadné otázky.\n\nMiesto, dátum: _______________ Podpis (zamestnávateľ): _______________',
},
ro: {
title: 'Informarea comitetului de întreprindere conform § 90 BetrVG (proiect)',
to: 'Către comitetul de întreprindere al',
subject: 'Subiect: Informare privind utilizarea planificată a unui sistem de IA',
body: 'Stimați membri ai comitetului de întreprindere,\n\nconform § 90 alin. 1 nr. 3 BetrVG, vă informăm în timp util cu privire la utilizarea planificată a sistemului de IA descris mai jos și vă oferim consultarea conform § 90 alin. 2 BetrVG. În cazul în care sistemul este apt să monitorizeze comportamentul sau performanța angajaților, vom solicita în plus codeterminarea dumneavoastră conform § 87 alin. 1 nr. 6 BetrVG (acord de întreprindere).',
sections: [
['Data planificată a introducerii', ''],
['Departamente / grupuri de angajați vizate', ''],
['Scopul și modul de funcționare a sistemului (descriere succintă)', ''],
['Datele angajaților prelucrate', ''],
['Efecte asupra proceselor de muncă și a locurilor de muncă', ''],
['Măsuri de formare planificate (art. 4 din Regulamentul privind IA)', ''],
['Persoana de contact pentru consultare', ''],
],
closing: 'Așteptăm cu interes consultarea și vă stăm la dispoziție pentru întrebări.\n\nLocalitate, data: _______________ Semnătura (angajator): _______________',
},
} as const;
const T = T_ALL[locale];
const lines = [head(T.title, system, pack, today, locale, profile)];
lines.push(`${T.to} ${profile?.name ?? '_______________'}`, '', `**${T.subject}**`, '', T.body, '');
for (const [label] of T.sections) {
lines.push(`## ${label}`, '', s.todo, '');
}
lines.push(T.closing);
return lines.join('\n');
}
/**
* Vordruck: Information der Beschäftigten über den KI-Einsatz
* (Art. 26 Abs. 7 AI Act; in Italien zusätzlich Legge 132/2025).
*/
export function employeeInfo(
system: AISystem,
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const T_ALL = {
de: {
title: 'Mitarbeiterinformation zum Einsatz eines KI-Systems (Entwurf)',
body: 'Liebe Kolleginnen und Kollegen,\n\nhiermit informieren wir Sie, dass in unserem Unternehmen das nachfolgend beschriebene KI-System eingesetzt wird. Diese Information erfolgt nach Art. 26 Abs. 7 der EU-KI-Verordnung sowie einschlägigem nationalem Recht.',
sections: [
['Was das System tut und wofür es eingesetzt wird', ''],
['Welche Entscheidungen das System unterstützt (Letztentscheidung trifft der Mensch)', ''],
['Welche Ihrer Daten verarbeitet werden', ''],
['Menschliche Aufsicht: wer das System überwacht und wie Sie Einwände erheben können', ''],
['Ihre Ansprechpartner (Fachabteilung, Datenschutzbeauftragte/r, Betriebsrat)', ''],
],
},
en: {
title: 'Employee information on the use of an AI system (draft)',
body: 'Dear colleagues,\n\nwe hereby inform you that the AI system described below will be used in our company. This information is provided pursuant to Art. 26(7) of the EU AI Act and applicable national law.',
sections: [
['What the system does and what it is used for', ''],
['Which decisions the system supports (final decisions are made by humans)', ''],
['Which of your data is processed', ''],
['Human oversight: who supervises the system and how you can raise objections', ''],
['Your contacts (specialist department, data protection officer, works council)', ''],
],
},
fr: {
title: 'Information des salariés sur lutilisation dun système dIA (projet)',
body: 'Chères et chers collègues,\n\nnous vous informons par la présente que le système dIA décrit ci-après sera utilisé dans notre entreprise. Cette information est fournie par le déployeur conformément à larticle 26, paragraphe 7, du règlement européen sur lIA ainsi quau droit national applicable.',
sections: [
['Ce que fait le système et à quoi il sert', ''],
['Quelles décisions le système soutient (la décision finale revient à lhumain)', ''],
['Quelles données vous concernant sont traitées', ''],
['Contrôle humain : qui supervise le système et comment vous pouvez formuler des objections', ''],
['Vos interlocuteurs (service spécialisé, délégué·e à la protection des données, comité dentreprise)', ''],
],
},
it: {
title: 'Informazione ai dipendenti sullimpiego di un sistema di IA (bozza)',
body: 'Care colleghe e cari colleghi,\n\ncon la presente vi informiamo che nella nostra azienda sarà impiegato il sistema di IA descritto di seguito. Questa informazione è fornita dal deployer ai sensi dellart. 26, par. 7, del regolamento europeo sullIA nonché del diritto nazionale applicabile.',
sections: [
['Che cosa fa il sistema e a che cosa serve', ''],
['Quali decisioni il sistema supporta (la decisione finale spetta allessere umano)', ''],
['Quali dei vostri dati vengono trattati', ''],
['Sorveglianza umana: chi supervisiona il sistema e come potete sollevare obiezioni', ''],
['I vostri referenti (reparto competente, responsabile della protezione dei dati, consiglio aziendale)', ''],
],
},
es: {
title: 'Información a los empleados sobre el uso de un sistema de IA (borrador)',
body: 'Estimadas compañeras y compañeros:\n\npor la presente les informamos de que en nuestra empresa se utilizará el sistema de IA descrito a continuación. Esta información la facilita el responsable del despliegue conforme al art. 26, apdo. 7, del Reglamento europeo de IA y al Derecho nacional aplicable.',
sections: [
['Qué hace el sistema y para qué se utiliza', ''],
['Qué decisiones apoya el sistema (la decisión final la toma una persona)', ''],
['Cuáles de sus datos se tratan', ''],
['Supervisión humana: quién supervisa el sistema y cómo pueden plantear objeciones', ''],
['Sus personas de contacto (departamento especializado, delegado/a de protección de datos, comité de empresa)', ''],
],
},
pl: {
title: 'Informacja dla pracowników o wykorzystaniu systemu AI (projekt)',
body: 'Drogie Koleżanki, drodzy Koledzy,\n\nniniejszym informujemy, że w naszym przedsiębiorstwie będzie wykorzystywany opisany poniżej system AI. Informacja ta jest przekazywana przez podmiot stosujący zgodnie z art. 26 ust. 7 europejskiego rozporządzenia w sprawie AI oraz właściwym prawem krajowym.',
sections: [
['Co robi system i do czego jest wykorzystywany', ''],
['Jakie decyzje system wspiera (ostateczną decyzję podejmuje człowiek)', ''],
['Które z Państwa danych są przetwarzane', ''],
['Nadzór ludzki: kto nadzoruje system i jak mogą Państwo zgłaszać zastrzeżenia', ''],
['Osoby do kontaktu (dział merytoryczny, inspektor ochrony danych, rada zakładowa)', ''],
],
},
cs: {
title: 'Informace pro zaměstnance o nasazení systému AI (návrh)',
body: 'Milé kolegyně, milí kolegové,\n\ntímto Vás informujeme, že v naší společnosti bude nasazen níže popsaný systém AI. Tuto informaci poskytuje zavádějící subjekt podle čl. 26 odst. 7 evropského aktu o AI a příslušného vnitrostátního práva.',
sections: [
['Co systém dělá a k čemu se používá', ''],
['Jaká rozhodnutí systém podporuje (konečné rozhodnutí činí člověk)', ''],
['Které z Vašich údajů jsou zpracovávány', ''],
['Lidský dohled: kdo na systém dohlíží a jak můžete vznést námitky', ''],
['Vaše kontaktní osoby (odborné oddělení, pověřenec pro ochranu osobních údajů, podniková rada)', ''],
],
},
sk: {
title: 'Informácia pre zamestnancov o nasadení systému AI (návrh)',
body: 'Milé kolegyne, milí kolegovia,\n\ntýmto Vás informujeme, že v našej spoločnosti bude nasadený nižšie opísaný systém AI. Túto informáciu poskytuje nasadzujúci subjekt podľa čl. 26 ods. 7 európskeho aktu o AI a príslušného vnútroštátneho práva.',
sections: [
['Čo systém robí a na čo sa používa', ''],
['Aké rozhodnutia systém podporuje (konečné rozhodnutie prijíma človek)', ''],
['Ktoré z Vašich údajov sa spracúvajú', ''],
['Ľudský dohľad: kto na systém dohliada a ako môžete vzniesť námietky', ''],
['Vaše kontaktné osoby (odborné oddelenie, zodpovedná osoba pre ochranu údajov, zamestnanecká rada)', ''],
],
},
ro: {
title: 'Informarea angajaților cu privire la utilizarea unui sistem de IA (proiect)',
body: 'Dragi colege și colegi,\n\nprin prezenta vă informăm că în întreprinderea noastră va fi utilizat sistemul de IA descris mai jos. Această informare este furnizată de implementator conform art. 26 alin. (7) din Regulamentul european privind IA, precum și dreptului național aplicabil.',
sections: [
['Ce face sistemul și la ce este utilizat', ''],
['Ce decizii sprijină sistemul (decizia finală aparține omului)', ''],
['Care dintre datele dumneavoastră sunt prelucrate', ''],
['Supravegherea umană: cine supraveghează sistemul și cum puteți formula obiecții', ''],
['Persoanele dumneavoastră de contact (departamentul de specialitate, responsabilul cu protecția datelor, comitetul de întreprindere)', ''],
],
},
} as const;
const T = T_ALL[locale];
const lines = [head(T.title, system, pack, today, locale, profile)];
lines.push(T.body, '');
for (const [label] of T.sections) {
lines.push(`## ${label}`, '', s.todo, '');
}
return lines.join('\n');
}
/** Vordruck: Grundrechte-Folgenabschätzung (FRIA, Art. 27) — Arbeitsvorlage. */
export function friaTemplate(
system: AISystem,
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const T_ALL = {
de: {
title: 'Grundrechte-Folgenabschätzung (FRIA, Art. 27) — Arbeitsvorlage',
sections: [
'Beschreibung des Einsatzprozesses und der Zweckbestimmung',
'Zeitraum und Häufigkeit der Nutzung',
'Kategorien betroffener Personen und Gruppen',
'Spezifische Schadensrisiken für Grundrechte (Nichtdiskriminierung, Privatsphäre, Meinungsfreiheit, soziale Rechte)',
'Maßnahmen der menschlichen Aufsicht gemäß Betriebsanleitung',
'Maßnahmen bei Eintritt der Risiken (interne Governance, Beschwerdemechanismen)',
'Ergebnis und Entscheidung (Einsatz / Einsatz mit Auflagen / kein Einsatz)',
'Meldung an die Marktüberwachungsbehörde (soweit erforderlich)',
],
},
en: {
title: 'Fundamental rights impact assessment (FRIA, Art. 27) — working template',
sections: [
'Description of the deployment process and intended use',
'Period and frequency of use',
'Categories of natural persons and groups likely to be affected',
'Specific risks of harm to fundamental rights (non-discrimination, privacy, freedom of expression, social rights)',
'Human oversight measures as per instructions for use',
'Measures in case risks materialise (internal governance, complaint mechanisms)',
'Result and decision (use / use with conditions / no use)',
'Notification to the market surveillance authority (where required)',
],
},
fr: {
title: 'Analyse dimpact sur les droits fondamentaux (AIFD/FRIA, art. 27) — modèle de travail',
sections: [
'Description du processus de déploiement et de la destination prévue',
'Période et fréquence dutilisation',
'Catégories de personnes physiques et de groupes susceptibles dêtre concernés',
'Risques spécifiques datteinte aux droits fondamentaux (non-discrimination, vie privée, liberté dexpression, droits sociaux)',
'Mesures de contrôle humain conformément à la notice dutilisation',
'Mesures en cas de matérialisation des risques (gouvernance interne, mécanismes de réclamation)',
'Résultat et décision (utilisation / utilisation sous conditions / pas dutilisation)',
'Notification à lautorité de surveillance du marché (le cas échéant)',
],
},
it: {
title: 'Valutazione dimpatto sui diritti fondamentali (FRIA, art. 27) — modello di lavoro',
sections: [
'Descrizione del processo di impiego e della finalità prevista',
'Periodo e frequenza di utilizzo',
'Categorie di persone fisiche e gruppi verosimilmente interessati',
'Rischi specifici di danno ai diritti fondamentali (non discriminazione, vita privata, libertà di espressione, diritti sociali)',
'Misure di sorveglianza umana secondo le istruzioni per luso',
'Misure in caso di concretizzazione dei rischi (governance interna, meccanismi di reclamo)',
'Risultato e decisione (impiego / impiego con condizioni / nessun impiego)',
'Notifica allautorità di vigilanza del mercato (ove richiesto)',
],
},
es: {
title: 'Evaluación de impacto sobre los derechos fundamentales (FRIA, art. 27) — plantilla de trabajo',
sections: [
'Descripción del proceso de despliegue y de la finalidad prevista',
'Período y frecuencia de uso',
'Categorías de personas físicas y grupos que puedan verse afectados',
'Riesgos específicos de perjuicio para los derechos fundamentales (no discriminación, privacidad, libertad de expresión, derechos sociales)',
'Medidas de supervisión humana conforme a las instrucciones de uso',
'Medidas en caso de materialización de los riesgos (gobernanza interna, mecanismos de reclamación)',
'Resultado y decisión (uso / uso con condiciones / no uso)',
'Notificación a la autoridad de vigilancia del mercado (cuando proceda)',
],
},
pl: {
title: 'Ocena skutków dla praw podstawowych (FRIA, art. 27) — wzór roboczy',
sections: [
'Opis procesu wdrożenia i przewidzianego przeznaczenia',
'Okres i częstotliwość użytkowania',
'Kategorie osób fizycznych i grup, które mogą być dotknięte',
'Szczególne ryzyka szkody dla praw podstawowych (niedyskryminacja, prywatność, wolność wypowiedzi, prawa socjalne)',
'Środki nadzoru ludzkiego zgodnie z instrukcją obsługi',
'Środki na wypadek urzeczywistnienia się ryzyk (wewnętrzne zarządzanie, mechanizmy skargowe)',
'Wynik i decyzja (wykorzystanie / wykorzystanie pod warunkami / brak wykorzystania)',
'Powiadomienie organu nadzoru rynku (o ile wymagane)',
],
},
cs: {
title: 'Posouzení dopadů na základní práva (FRIA, čl. 27) — pracovní šablona',
sections: [
'Popis procesu nasazení a zamýšleného účelu',
'Doba a četnost používání',
'Kategorie fyzických osob a skupin, které mohou být dotčeny',
'Specifická rizika újmy na základních právech (zákaz diskriminace, soukromí, svoboda projevu, sociální práva)',
'Opatření lidského dohledu podle návodu k použití',
'Opatření pro případ naplnění rizik (interní správa a řízení, mechanismy pro stížnosti)',
'Výsledek a rozhodnutí (nasazení / nasazení s podmínkami / žádné nasazení)',
'Oznámení orgánu dozoru nad trhem (je-li vyžadováno)',
],
},
sk: {
title: 'Posúdenie vplyvu na základné práva (FRIA, čl. 27) — pracovná šablóna',
sections: [
'Opis procesu nasadenia a zamýšľaného účelu',
'Obdobie a frekvencia používania',
'Kategórie fyzických osôb a skupín, ktoré môžu byť dotknuté',
'Špecifické riziká ujmy na základných právach (nediskriminácia, súkromie, sloboda prejavu, sociálne práva)',
'Opatrenia ľudského dohľadu podľa návodu na použitie',
'Opatrenia pre prípad naplnenia rizík (interná správa a riadenie, mechanizmy podávania sťažností)',
'Výsledok a rozhodnutie (nasadenie / nasadenie s podmienkami / žiadne nasadenie)',
'Oznámenie orgánu dohľadu nad trhom (ak sa vyžaduje)',
],
},
ro: {
title: 'Evaluarea impactului asupra drepturilor fundamentale (FRIA, art. 27) — model de lucru',
sections: [
'Descrierea procesului de implementare și a scopului preconizat',
'Perioada și frecvența utilizării',
'Categoriile de persoane fizice și de grupuri susceptibile de a fi afectate',
'Riscuri specifice de prejudiciu pentru drepturile fundamentale (nediscriminare, viață privată, libertate de exprimare, drepturi sociale)',
'Măsuri de supraveghere umană conform instrucțiunilor de utilizare',
'Măsuri în cazul materializării riscurilor (guvernanță internă, mecanisme de plângere)',
'Rezultat și decizie (utilizare / utilizare cu condiții / neutilizare)',
'Notificarea autorității de supraveghere a pieței (dacă este necesar)',
],
},
} as const;
const T = T_ALL[locale];
const lines = [head(T.title, system, pack, today, locale, profile)];
T.sections.forEach((sec, i) => {
lines.push(`## ${i + 1}. ${sec}`, '', s.todo, '');
});
return lines.join('\n');
}
/** Vordruck: Meldung eines schwerwiegenden Vorfalls (Art. 73) — internes Formular. */
export function incidentReportForm(
system: AISystem,
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const T_ALL = {
de: {
title: 'Meldung eines schwerwiegenden Vorfalls (Art. 73) — internes Formular',
note: 'Fristen: Meldung an die Marktüberwachungsbehörde unverzüglich nach Feststellung des Kausalzusammenhangs, spätestens 15 Tage; Tod einer Person: 10 Tage; weitverbreiteter Verstoß / kritische Infrastruktur: 2 Tage.',
fields: [
'Datum/Uhrzeit des Vorfalls und der Kenntnisnahme',
'Beschreibung des Vorfalls und unmittelbare Folgen',
'Betroffene Personen / eingetretener Schaden (Gesundheit, Sicherheit, Grundrechte)',
'Vermutete Ursache / Zusammenhang mit dem KI-System',
'Ergriffene Sofortmaßnahmen (Eindämmung, Abschaltung)',
'Gemeldet an (Behörde, Anbieter, interne Stellen) mit Datum',
'Korrekturmaßnahmen und Lessons Learned',
'Verantwortliche Person (Name, Funktion, Unterschrift)',
],
},
en: {
title: 'Serious incident report (Art. 73) — internal form',
note: 'Deadlines: report to the market surveillance authority immediately after establishing the causal link, at the latest within 15 days; death of a person: 10 days; widespread infringement / critical infrastructure: 2 days.',
fields: [
'Date/time of the incident and of becoming aware',
'Description of the incident and immediate consequences',
'Persons affected / damage incurred (health, safety, fundamental rights)',
'Presumed cause / connection with the AI system',
'Immediate measures taken (containment, shutdown)',
'Reported to (authority, provider, internal bodies) with date',
'Corrective actions and lessons learned',
'Responsible person (name, function, signature)',
],
},
fr: {
title: 'Signalement dun incident grave (art. 73) — formulaire interne',
note: 'Délais : signalement à lautorité de surveillance du marché immédiatement après létablissement du lien de causalité, au plus tard dans un délai de 15 jours ; décès dune personne : 10 jours ; infraction de grande ampleur / infrastructure critique : 2 jours.',
fields: [
'Date/heure de lincident et de la prise de connaissance',
'Description de lincident et conséquences immédiates',
'Personnes concernées / dommages survenus (santé, sécurité, droits fondamentaux)',
'Cause présumée / lien avec le système dIA',
'Mesures immédiates prises (confinement, mise hors service)',
'Signalé à (autorité, fournisseur, services internes) avec date',
'Mesures correctives et enseignements tirés',
'Personne responsable (nom, fonction, signature)',
],
},
it: {
title: 'Segnalazione di un incidente grave (art. 73) — modulo interno',
note: 'Termini: segnalazione allautorità di vigilanza del mercato immediatamente dopo laccertamento del nesso di causalità, al più tardi entro 15 giorni; decesso di una persona: 10 giorni; violazione diffusa / infrastruttura critica: 2 giorni.',
fields: [
'Data/ora dellincidente e della presa di conoscenza',
'Descrizione dellincidente e conseguenze immediate',
'Persone interessate / danni verificatisi (salute, sicurezza, diritti fondamentali)',
'Causa presunta / collegamento con il sistema di IA',
'Misure immediate adottate (contenimento, disattivazione)',
'Segnalato a (autorità, fornitore, organi interni) con data',
'Misure correttive e lezioni apprese',
'Persona responsabile (nome, funzione, firma)',
],
},
es: {
title: 'Notificación de un incidente grave (art. 73) — formulario interno',
note: 'Plazos: notificación a la autoridad de vigilancia del mercado inmediatamente después de establecer el nexo causal, a más tardar en un plazo de 15 días; fallecimiento de una persona: 10 días; infracción generalizada / infraestructura crítica: 2 días.',
fields: [
'Fecha/hora del incidente y del momento en que se tuvo conocimiento',
'Descripción del incidente y consecuencias inmediatas',
'Personas afectadas / daños producidos (salud, seguridad, derechos fundamentales)',
'Causa presunta / relación con el sistema de IA',
'Medidas inmediatas adoptadas (contención, desconexión)',
'Notificado a (autoridad, proveedor, órganos internos) con fecha',
'Medidas correctoras y lecciones aprendidas',
'Persona responsable (nombre, cargo, firma)',
],
},
pl: {
title: 'Zgłoszenie poważnego incydentu (art. 73) — formularz wewnętrzny',
note: 'Terminy: zgłoszenie do organu nadzoru rynku niezwłocznie po ustaleniu związku przyczynowego, najpóźniej w ciągu 15 dni; śmierć osoby: 10 dni; powszechne naruszenie / infrastruktura krytyczna: 2 dni.',
fields: [
'Data/godzina incydentu i powzięcia o nim wiadomości',
'Opis incydentu i bezpośrednie skutki',
'Osoby dotknięte / powstała szkoda (zdrowie, bezpieczeństwo, prawa podstawowe)',
'Przypuszczalna przyczyna / związek z systemem AI',
'Podjęte środki natychmiastowe (ograniczenie skutków, wyłączenie)',
'Zgłoszono do (organ, dostawca, jednostki wewnętrzne) wraz z datą',
'Działania korygujące i wyciągnięte wnioski',
'Osoba odpowiedzialna (imię i nazwisko, funkcja, podpis)',
],
},
cs: {
title: 'Hlášení závažného incidentu (čl. 73) — interní formulář',
note: 'Lhůty: hlášení orgánu dozoru nad trhem neprodleně po zjištění příčinné souvislosti, nejpozději do 15 dnů; úmrtí osoby: 10 dnů; rozsáhlé porušení / kritická infrastruktura: 2 dny.',
fields: [
'Datum/čas incidentu a okamžiku, kdy jsme se o něm dozvěděli',
'Popis incidentu a bezprostřední následky',
'Dotčené osoby / vzniklá škoda (zdraví, bezpečnost, základní práva)',
'Předpokládaná příčina / souvislost se systémem AI',
'Přijatá okamžitá opatření (omezení dopadů, odstavení)',
'Nahlášeno komu (orgán, poskytovatel, interní útvary) s datem',
'Nápravná opatření a získané poznatky',
'Odpovědná osoba (jméno, funkce, podpis)',
],
},
sk: {
title: 'Hlásenie závažného incidentu (čl. 73) — interný formulár',
note: 'Lehoty: hlásenie orgánu dohľadu nad trhom bezodkladne po zistení príčinnej súvislosti, najneskôr do 15 dní; úmrtie osoby: 10 dní; rozsiahle porušenie / kritická infraštruktúra: 2 dni.',
fields: [
'Dátum/čas incidentu a okamihu, keď sme sa o ňom dozvedeli',
'Opis incidentu a bezprostredné následky',
'Dotknuté osoby / vzniknutá škoda (zdravie, bezpečnosť, základné práva)',
'Predpokladaná príčina / súvislosť so systémom AI',
'Prijaté okamžité opatrenia (obmedzenie dôsledkov, odstavenie)',
'Nahlásené komu (orgán, poskytovateľ, interné útvary) s dátumom',
'Nápravné opatrenia a získané poznatky',
'Zodpovedná osoba (meno, funkcia, podpis)',
],
},
ro: {
title: 'Raportarea unui incident grav (art. 73) — formular intern',
note: 'Termene: raportare către autoritatea de supraveghere a pieței imediat după stabilirea legăturii de cauzalitate, cel târziu în termen de 15 zile; decesul unei persoane: 10 zile; încălcare pe scară largă / infrastructură critică: 2 zile.',
fields: [
'Data/ora incidentului și a luării la cunoștință',
'Descrierea incidentului și consecințele imediate',
'Persoane afectate / prejudiciul produs (sănătate, siguranță, drepturi fundamentale)',
'Cauza prezumată / legătura cu sistemul de IA',
'Măsuri imediate luate (limitarea efectelor, oprirea sistemului)',
'Raportat către (autoritate, furnizor, structuri interne) cu data',
'Măsuri corective și lecții învățate',
'Persoana responsabilă (nume, funcție, semnătură)',
],
},
} as const;
const T = T_ALL[locale];
const lines = [head(T.title, system, pack, today, locale, profile)];
lines.push(`> ${T.note}`, '');
T.fields.forEach((f, i) => {
lines.push(`## ${i + 1}. ${f}`, '', s.todo, '');
});
return lines.join('\n');
}

View File

@ -0,0 +1,139 @@
/**
* Kern-Typen des AI-Act-Kompass.
*
* Alle Datenstrukturen sind unveränderlich gedacht (immutable)
* Funktionen geben neue Objekte zurück statt zu mutieren.
*/
/** Rolle des Unternehmens in Bezug auf das KI-System (Art. 3 AI Act). */
export type Role = 'provider' | 'deployer' | 'importer' | 'distributor';
/** Risikoklasse nach EU AI Act. */
export type RiskClass =
| 'out-of-scope'
| 'prohibited'
| 'high'
| 'limited'
| 'minimal';
/** Antworten des Bewertungs-Wizards für ein einzelnes KI-System. */
export interface AssessmentAnswers {
/** Erfüllt das System die KI-Definition nach Art. 3 Nr. 1? */
readonly isAISystem: boolean;
/** Rolle des Unternehmens für dieses System. */
readonly role: Role;
/** Handelt es sich (auch) um ein GPAI-Modell (Art. 51 ff.)? */
readonly isGPAIModel: boolean;
/** IDs der zutreffenden verbotenen Praktiken (Art. 5). */
readonly prohibitedPractices: readonly string[];
/** IDs der zutreffenden Annex-III-Hochrisiko-Bereiche. */
readonly annexIIICategories: readonly string[];
/** Greift die Ausnahme nach Art. 6 Abs. 3 (eng begrenzte Aufgabe)? */
readonly art63Exception: boolean;
/** Führt das System Profiling natürlicher Personen durch? */
readonly involvesProfiling: boolean;
/** Sicherheitsbauteil eines regulierten Produkts (Annex I)? */
readonly isAnnexISafetyComponent: boolean;
/** IDs der zutreffenden Transparenzpflichten-Auslöser (Art. 50). */
readonly transparencyTriggers: readonly string[];
}
/** Ergebnis der Risikoklassifizierung. */
export interface Classification {
readonly riskClass: RiskClass;
/** Begründungen in Prüfreihenfolge (menschenlesbar, Deutsch). */
readonly reasons: readonly string[];
/** Zusätzlich GPAI-Pflichten (Art. 53 ff.) relevant? */
readonly gpaiObligations: boolean;
/** Transparenzpflichten nach Art. 50 zusätzlich anwendbar? */
readonly transparencyDuties: boolean;
/** Dokumentationspflicht nach Art. 6 Abs. 4 (Ausnahme in Anspruch genommen)? */
readonly art64DocumentationDuty: boolean;
}
/** Eine konkrete Pflicht aus dem AI Act. */
export interface Obligation {
readonly id: string;
readonly title: string;
readonly articles: string;
readonly description: string;
/** ISO-Datum der maßgeblichen Geltungsfrist. */
readonly deadline: string;
readonly roles: readonly Role[];
readonly riskClasses: readonly RiskClass[];
}
/** Status einer Pflicht in der Umsetzung durch den Nutzer. */
export type ObligationStatus = 'open' | 'in-progress' | 'done' | 'not-applicable';
/** Ein registriertes KI-System im Inventar. */
export interface AISystem {
readonly id: string;
readonly name: string;
readonly purpose: string;
readonly vendor: string;
readonly owner: string;
readonly createdAt: string;
readonly updatedAt: string;
readonly answers: AssessmentAnswers;
readonly classification: Classification;
/** Umsetzungsstatus je Pflicht-ID. */
readonly obligationStatus: Readonly<Record<string, ObligationStatus>>;
}
/** Firmenprofil für personalisierte Berichte (Briefkopf, PDF-Druck). */
export interface CompanyProfile {
readonly name: string;
readonly street: string;
readonly zipCity: string;
readonly contactPerson: string;
readonly email: string;
readonly phone: string;
readonly website: string;
/** Logo als Data-URL (bleibt lokal im Browser), leer = kein Logo. */
readonly logoDataUrl: string;
/** ISO-Ländercodes der aktivierten nationalen Anforderungsmodule (z. B. "DE"). */
readonly countries: readonly string[];
}
/** Eintrag im regulatorischen Content-Pack (Checklisten-Item mit Rechtsgrundlage). */
export interface ContentItem {
readonly id: string;
readonly label: string;
readonly legalRef: string;
readonly hint?: string;
}
/** Wichtige Geltungsfrist des AI Act. */
export interface Deadline {
readonly id: string;
readonly date: string;
readonly label: string;
readonly description: string;
}
/** Nationales Anforderungsmodul eines EU-Mitgliedstaats. */
export interface NationalPack {
/** ISO-3166-Ländercode, z. B. "DE". */
readonly code: string;
readonly country: string;
/** Zuständige Aufsichts-/Marktüberwachungsbehörde(n). */
readonly authority: string;
/** Zusätzliche nationale Pflichten (Rechtsgrundlage im Feld articles). */
readonly items: readonly Obligation[];
}
/** Versionierter regulatorischer Content-Pack. */
export interface ContentPack {
readonly version: string;
readonly releasedAt: string;
readonly legalBasis: string;
readonly prohibitedPractices: readonly ContentItem[];
readonly annexIIICategories: readonly ContentItem[];
readonly transparencyTriggers: readonly ContentItem[];
readonly aiDefinitionCriteria: readonly ContentItem[];
readonly obligations: readonly Obligation[];
readonly deadlines: readonly Deadline[];
/** Nationale Zusatzanforderungen der EU-Mitgliedstaaten. */
readonly national: readonly NationalPack[];
}

View File

@ -0,0 +1,53 @@
import type { Locale } from '../i18n/types';
/**
* Dokument-Verifikation für Nachweise.
*
* Gedruckte Nachweise (Zertifikat, Schulungsregister) erhalten eine
* SHA-256-Prüfsumme über den Dokumentinhalt. Damit lässt sich später
* belegen, dass ein vorgelegter Ausdruck unverändert aus dem Tool
* stammt: gleiche Eingaben gleiche Prüfsumme. Hochgeladene Scans
* werden ebenfalls gehasht und im Register verankert.
*/
/** Berechnet den SHA-256-Hash eines Textes als Hex-String. */
export async function sha256Hex(text: string): Promise<string> {
const data = new TextEncoder().encode(text);
const digest = await crypto.subtle.digest('SHA-256', data);
return Array.from(new Uint8Array(digest))
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
}
/** Berechnet den SHA-256-Hash von Binärdaten (z. B. Scan-Datei) als Hex-String. */
export async function sha256HexBytes(data: ArrayBuffer): Promise<string> {
const digest = await crypto.subtle.digest('SHA-256', data);
return Array.from(new Uint8Array(digest))
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
}
const VERIFY_TEXT: Readonly<Record<'de' | 'en', { label: string; note: string }>> = {
de: {
label: 'Dokument-Prüfsumme (SHA-256)',
note: 'Verifikation: Die Prüfsumme wurde über den vorstehenden Dokumentinhalt gebildet. Ein vorgelegter Ausdruck ist unverändert, wenn die im Tool neu erzeugte Prüfsumme übereinstimmt.',
},
en: {
label: 'Document checksum (SHA-256)',
note: 'Verification: the checksum was computed over the document content above. A presented printout is unaltered if the checksum re-generated in the tool matches.',
},
};
/**
* Hängt eine Verifikations-Fußzeile (Prüfsumme über den Inhalt) an ein
* generiertes Markdown-Dokument an.
*
* @param markdown - Fertiges Dokument
* @param locale - Dokumentsprache (Fußzeile DE/EN)
* @returns Dokument mit Prüfsummen-Fußzeile
*/
export async function withVerification(markdown: string, locale: Locale): Promise<string> {
const t = locale === 'de' ? VERIFY_TEXT.de : VERIFY_TEXT.en;
const hash = await sha256Hex(markdown);
return `${markdown}\n\n**${t.label}:** \`${hash}\`\n\n> ${t.note}`;
}

View File

@ -0,0 +1,47 @@
import { createContext, useContext, useMemo, useState } from 'react';
import type { ReactNode } from 'react';
import { getContentPack } from '../content/pack';
import type { ContentPack } from '../engine/types';
import { loadLocale, saveLocale } from './types';
import type { Locale } from './types';
import { uiStrings } from './ui';
import type { UIStrings } from './ui';
interface I18nValue {
readonly locale: Locale;
readonly t: UIStrings;
/** Content-Pack in der aktuellen Sprache. */
readonly pack: ContentPack;
readonly setLocale: (locale: Locale) => void;
}
const I18nContext = createContext<I18nValue | null>(null);
/** Stellt Sprache, UI-Wörterbuch und lokalisierten Content-Pack bereit. */
export function I18nProvider({ children }: { readonly children: ReactNode }): JSX.Element {
const [locale, setLocaleState] = useState<Locale>(() => loadLocale());
const value = useMemo<I18nValue>(
() => ({
locale,
t: uiStrings(locale),
pack: getContentPack(locale),
setLocale: (next: Locale) => {
saveLocale(next);
setLocaleState(next);
},
}),
[locale],
);
return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>;
}
/** Zugriff auf Sprache, Wörterbuch und Content-Pack. */
export function useI18n(): I18nValue {
const ctx = useContext(I18nContext);
if (!ctx) {
throw new Error('useI18n muss innerhalb von <I18nProvider> verwendet werden.');
}
return ctx;
}

View File

@ -0,0 +1,78 @@
/**
* Mehrsprachigkeits-Grundlagen.
*
* Die App ist für europäische Unternehmen gedacht alle Inhalte
* (UI, Regel-Engine, Content-Pack, Dokumente) sind lokalisierbar.
* Vollständig übersetzt (UI, Content-Pack, Dokumente): DE, EN, FR,
* IT, ES, PL, CS, SK, RO. Weitere Sprachen greifen bis zur
* Fachübersetzung auf den englischen Fallback zurück.
*/
/** Unterstützte Sprachen. */
export type Locale = 'de' | 'en' | 'fr' | 'it' | 'es' | 'pl' | 'cs' | 'sk' | 'ro';
/** Alle unterstützten Sprachen in Anzeigereihenfolge. */
export const LOCALES: readonly Locale[] = ['de', 'en', 'fr', 'it', 'es', 'pl', 'cs', 'sk', 'ro'];
/** Anzeigenamen der Sprachen (Eigenbezeichnung). */
export const LOCALE_NAMES: Readonly<Record<Locale, string>> = {
de: 'Deutsch',
en: 'English',
fr: 'Français',
it: 'Italiano',
es: 'Español',
pl: 'Polski',
cs: 'Čeština',
sk: 'Slovenčina',
ro: 'Română',
};
/**
* Lokalisierter Text. Deutsch und Englisch sind Pflicht; weitere
* Sprachen optional fehlt eine Übersetzung, greift der Fallback
* auf Englisch (siehe {@link resolveText}).
*/
export interface LText {
readonly de: string;
readonly en: string;
readonly fr?: string;
readonly it?: string;
readonly es?: string;
readonly pl?: string;
readonly cs?: string;
readonly sk?: string;
readonly ro?: string;
}
/** Kurzform zum Anlegen lokalisierter Texte (DE/EN-Basis). */
export function lt(de: string, en: string): LText {
return { de, en };
}
/** Löst einen lokalisierten Text auf; Fallback: Englisch. */
export function resolveText(text: LText, locale: Locale): string {
return text[locale] ?? text.en;
}
const LOCALE_KEY = 'ai-act-kompass/locale/v1';
function isLocale(value: string | null): value is Locale {
return value !== null && (LOCALES as readonly string[]).includes(value);
}
/** Lädt die gespeicherte Sprache (Fallback: Browser-Sprache, sonst Englisch). */
export function loadLocale(): Locale {
try {
const stored = localStorage.getItem(LOCALE_KEY);
if (isLocale(stored)) return stored;
const nav = navigator.language.slice(0, 2).toLowerCase();
return isLocale(nav) ? nav : 'en';
} catch {
return 'de';
}
}
/** Persistiert die gewählte Sprache. */
export function saveLocale(locale: Locale): void {
localStorage.setItem(LOCALE_KEY, locale);
}

View File

@ -0,0 +1,211 @@
import type { UIStrings } from './ui';
/** Tschechisches UI-Wörterbuch. */
export const CS: UIStrings = {
brandTag: 'Soulad s aktem EU o umělé inteligenci pro MSP · local-first',
navDashboard: 'Přehled a inventář',
navTasks: 'Úkoly a lhůty',
navNew: 'Posoudit nový systém',
navTemplates: 'Šablony a formuláře',
navSettings: 'Nastavení a záloha',
footPrivacy: 'Žádný cloud. Žádná telemetrie.',
footLocal: 'Všechna data zůstávají na tomto zařízení.',
footNoAdvice: 'Nejde o právní poradenství.',
dashTitle: 'Přehled',
dashSub: 'Soulad s aktem EU o umělé inteligenci na první pohled. Všechna data zůstávají lokálně na tomto zařízení.',
statSystems: 'Systémy AI v inventáři',
statHigh: 'Vysoce rizikové systémy',
statProhibited: 'Zakázané praktiky',
statOpen: 'Otevřené úkoly',
deadlinesTitle: 'Lhůty použitelnosti aktu o umělé inteligenci',
inventoryTitle: 'Inventář AI',
inventoryPrint: 'Vytisknout inventář / PDF',
newSystem: '+ Posoudit systém',
emptyInventory:
'Zatím nejsou evidovány žádné systémy AI. Začněte posouzením svého prvního systému — např. chatbota, nástroje pro předvýběr uchazečů nebo zakoupeného nástroje AI.',
colSystem: 'Systém',
colRole: 'Role',
colRisk: 'Riziková třída',
colOwner: 'Odpovědná osoba',
colUpdated: 'Naposledy posouzeno',
disclaimerLine:
'AI-Act-Kompass je strukturovaná pracovní pomůcka založená na nařízení (EU) 2024/1689 — nejde o právní poradenství. Balíček obsahu v{version}.',
tasksTitle: 'Úkoly a lhůty',
tasksSub: 'Všechny povinnosti všech systémů jako odškrtávací seznam — co je hotovo, co je splatné nyní a co vás čeká.',
tasksProgress: 'Hotovo {done} z {total} úkolů',
tasksDueNow: 'Splatné nyní',
tasksUpcoming: 'Čeká vás',
tasksResolved: 'Hotovo',
tasksEmpty: 'Žádné úkoly — nejprve posuďte systém AI.',
tasksAllDone: 'V této skupině je vše hotovo.',
tasksDue: 'Lhůta',
calExport: 'Přidat do kalendáře (.ics)',
calHint: 'Exportuje všechny otevřené lhůty jako soubor kalendáře s připomínkami (30 a 7 dní předem) — lze importovat do Outlooku, kalendáře Apple i Google, v telefonu i počítači.',
navQuiz: 'Test gramotnosti v oblasti AI',
quizSub: 'Jednoduchý test základů (12 otázek) gramotnosti v oblasti AI podle čl. 4 — s tisknutelným certifikátem jako dokladem a místním registrem školení.',
quizName: 'Jméno účastníka/účastnice *',
quizNamePh: 'Jméno a příjmení',
quizSubmit: 'Vyhodnotit test',
quizAnswerAll: 'Zadejte prosím jméno a odpovězte na všechny otázky.',
quizPassed: 'Úspěšně složen',
quizFailed: 'Nesložen',
quizScoreLine: '{correct} z {total} otázek správně ({pct} %) — hranice úspěšnosti {pass} %.',
quizWhy: 'Vysvětlení',
quizCert: 'Vytisknout certifikát / PDF',
quizRetry: 'Opakovat test',
quizLogTitle: 'Registr školení (doklad podle čl. 4)',
quizLogHint: 'Každý pokus se ukládá lokálně a slouží jako doklad povinnosti gramotnosti v oblasti AI (čl. 4). Registr pravidelně tiskněte a zakládejte do dokumentace školení.',
quizLogEmpty: 'Zatím žádné pokusy.',
quizLogPrint: 'Vytisknout registr / PDF',
quizColScore: 'Výsledek',
quizColStatus: 'Stav',
quizDocsTitle: 'Tisk školicích materiálů',
quizPrintTest: 'Papírová verze testu',
quizPrintKey: 'List s řešením',
quizPrintHandout: 'Školicí materiál (12 pravidel)',
quizManualTitle: 'Přidat účastníka ručně (papírový test)',
quizManualHint: 'Pro testy na papíře: zadejte účastníka a výsledek, poté přiložte naskenovaný vyhodnocený arch — důkazní řetězec je tak úplný.',
quizManualScore: 'Správné odpovědi (z 12)',
quizManualAdd: 'Přidat do registru',
quizSourceApp: 'Aplikace',
quizSourcePaper: 'Papír',
quizColSource: 'Zdroj',
quizColEvidence: 'Doklad',
quizAttach: 'Přiložit sken',
quizAttachView: 'Otevřít sken',
quizAttachTooBig: 'Soubor je příliš velký — použijte sken do 1 MB (např. komprimovaný JPG/PDF).',
quizAttachDone: 'Sken uložen a ukotven v registru kontrolním součtem SHA-256.',
quizDeleteRecord: 'Opravdu smazat záznam „{name}"? Přiložené doklady budou ztraceny.',
wizardTitleNew: 'Posoudit nový systém AI',
wizardTitleRe: 'Nové posouzení: {name}',
wizardSub: 'Odpovězte na otázky — riziková třída se určí automaticky podle systematiky aktu o umělé inteligenci.',
stepBasics: 'Základní údaje',
stepDefinition: 'Definice AI',
stepProhibited: 'Zákazy',
stepHighRisk: 'Vysoké riziko',
stepTransparency: 'Transparentnost a GPAI',
stepResult: 'Výsledek',
fieldName: 'Název systému *',
fieldNamePh: 'např. nástroj pro předvýběr uchazečů',
fieldPurpose: 'Zamýšlený účel',
fieldPurposePh: 'K čemu se systém používá?',
fieldVendor: 'Výrobce / poskytovatel',
fieldOwner: 'Odpovědná osoba (interní)',
fieldRole: 'Role vaší společnosti',
roleHint: 'Poskytovatel = vyvíjí/uvádí systém na trh pod vlastním jménem. Zavádějící subjekt = používá systém třetí strany (nejčastější případ u MSP).',
defTitle: 'Splňuje systém definici AI (čl. 3 bod 1)?',
defHint: 'Systém spadá pod akt o umělé inteligenci pouze tehdy, jsou-li splněna všechna kritéria.',
defWarn: 'Nejsou splněna všechna kritéria → systém se nepovažuje za systém AI; akt o umělé inteligenci se nepoužije.',
prohTitle: 'Zakázané praktiky (čl. 5)',
prohHint: 'Platí-li některý z těchto bodů, je používání od 2. února 2025 zakázáno.',
hrTitle: 'Klasifikace vysokého rizika (čl. 6)',
annexILabel: 'Systém je bezpečnostní komponentou regulovaného výrobku (např. zdravotnického prostředku, stroje, výtahu), nebo je sám takovým výrobkem.',
annexIIITitle: 'Oblasti použití podle přílohy III',
exceptionTitle: 'Možná výjimka (čl. 6 odst. 3)',
profilingLabel: 'Systém provádí profilování fyzických osob.',
profilingRef: 'Profilování výjimku vylučuje — vždy vysoké riziko.',
art63Label: 'Systém plní pouze úzce vymezený procesní nebo přípravný úkol, nebo pouze zlepšuje výsledek již dokončené lidské činnosti — bez významného rizika pro zdraví, bezpečnost nebo základní práva.',
art63Ref: 'Čl. 6 odst. 3 — posouzení musí být zdokumentováno (čl. 6 odst. 4).',
trTitle: 'Povinnosti transparentnosti (čl. 50)',
gpaiTitle: 'AI pro obecné účely (GPAI)',
gpaiLabel: 'Poskytujeme vlastní model GPAI (např. samostatně natrénovaný nebo podstatně upravený základní model).',
gpaiRef: 'Čl. 51 a násl. — pouhé používání např. GPT/Claude přes API se nepočítá.',
resultTitle: 'Výsledek:',
resultGpai: 'Navíc platí povinnosti pro modely GPAI (čl. 53 a násl.).',
resultProhibited: 'Používání tohoto systému je podle čl. 5 zakázáno (pokuta až 35 mil. EUR nebo 7 % celosvětového ročního obratu). Ukončete používání a vyhledejte právní radu.',
btnCancel: 'Zrušit',
btnBack: 'Zpět',
btnNext: 'Dále',
btnSave: 'Uložit',
detailBack: '← Zpět na přehled',
detailNoPurpose: 'Zamýšlený účel nebyl zaznamenán',
detailReasons: 'Odůvodnění klasifikace',
detailReassess: 'Posoudit znovu',
detailDelete: 'Smazat systém',
detailObligations: 'Povinnosti',
detailNational: 'vč. národních modulů: {codes}',
detailDocs: 'Generovat dokumenty',
docShow: 'zobrazit',
docHide: 'skrýt',
docPrint: 'Tisk / PDF',
docRisk: 'Zpráva o riziku',
docPlan: 'Plán opatření',
docAnnexIV: 'Dokumentace podle přílohy IV',
docProcurement: 'Zadávací specifikace nákupu AI',
docConformity: 'EU prohlášení o shodě',
confirmDeleteSystem: 'Opravdu smazat „{name}“?',
systemNotFound: 'Systém nebyl nalezen.',
statusOpen: 'Otevřeno',
statusInProgress: 'V realizaci',
statusDone: 'Hotovo',
statusNA: 'Nepoužije se',
settingsTitle: 'Nastavení',
settingsSub: 'Suverenita dat: vše zůstává lokálně v tomto prohlížeči — žádná synchronizace s cloudem, žádná telemetrie.',
langTitle: 'Sprache / Language / Jazyk',
langHint: 'Rozhraní, regulační obsah a generované dokumenty jsou plně dostupné v němčině, angličtině, francouzštině, italštině, španělštině, polštině, češtině, slovenštině a rumunštině. Další jazyky EU budou následovat prostřednictvím kanálu obsahu.',
profileTitle: 'Firemní profil (hlavička pro zprávy a tisk PDF)',
profileHint: 'Tyto údaje se objevují v záhlaví a zápatí všech generovaných a tištěných dokumentů. Logo zůstává uloženo lokálně a nikdy neopustí zařízení.',
pfName: 'Název společnosti', pfStreet: 'Ulice a číslo', pfZip: 'PSČ a obec',
pfContact: 'Kontaktní osoba', pfEmail: 'E-mail', pfPhone: 'Telefon', pfWeb: 'Web',
logoNone: 'Není uloženo žádné logo.',
logoUpload: 'Nahrát logo',
logoRemove: 'Odebrat logo',
logoTaken: 'Logo bylo použito.',
logoTooBig: 'Logo je příliš velké — použijte soubor menší než 300 KB.',
logoNotImage: 'Vyberte prosím obrazový soubor (PNG, JPG nebo SVG).',
countriesTitle: 'Národní moduly (dodatečné vnitrostátní požadavky)',
countriesHint: 'Aktivujte země EU, ve kterých vaše společnost nabízí nebo provozuje systémy AI. Národní povinnosti (dozor, pracovní právo, zvláštní zákony) se pak objeví v kontrolních seznamech a dokumentech. Při přeshraniční spolupráci: aktivujte všechny zapojené země.',
authorityLabel: 'Dozor',
packTitle: 'Regulační balíček obsahu',
packStand: 'Stav k',
packHint: 'Balíček obsahu (zákazy, oblasti přílohy III, povinnosti EU, národní moduly, lhůty) je modelován jako vyměnitelný datový balíček. Aktualizace přicházejí s novými verzemi aplikace a v budoucnu přes podepsaný aktualizační kanál.',
backupTitle: 'Zálohování',
backupExport: 'Exportovat zálohu (JSON)',
backupImport: 'Importovat zálohu',
importOk: 'Import dokončen: {count} systém(y/ů){profile}.',
importProfileSuffix: ' vč. firemního profilu',
importFail: 'Import se nezdařil: {error}',
deleteTitle: 'Smazat všechna data',
deleteHint: 'Nevratně odstraní všechny evidované systémy AI a firemní profil z tohoto prohlížeče.',
deleteBtn: 'Smazat vše',
deleteConfirm: 'Opravdu nevratně smazat všechna lokální data?',
deleteDone: 'Všechna data byla smazána.',
legalGateTitle: 'Důležité právní upozornění',
legalGateBody1:
'AI-Act-Kompass je strukturovaná pracovní pomůcka, která má usnadnit provádění nařízení (EU) 2024/1689 (akt o umělé inteligenci) a příslušných vnitrostátních předpisů.',
legalGateBody2:
'Tato aplikace neposkytuje právní služby a nepředstavuje právní poradenství, právní informaci ani právně závazné poučení. Všechny klasifikace, kontrolní seznamy a generované dokumenty jsou nezávazná předběžná posouzení a návrhy bez záruky správnosti, úplnosti nebo aktuálnosti.',
legalGateBody3:
'Závazný výklad aktu EU o umělé inteligenci přísluší výhradně příslušným orgánům a soudům. Tento nástroj nenahrazuje právní posouzení vašeho konkrétního případu — obraťte se za tímto účelem na kvalifikovanou právní pomoc (advokátku/advokáta). Používání je na vlastní riziko; odpovědnost za rozhodnutí učiněná na základě tohoto nástroje je vyloučena v rozsahu povoleném zákonem.',
legalGateAccept: 'Rozumím — používat jako pracovní pomůcku',
legalNoticeTitle: 'Právní upozornění (nejde o právní poradenství)',
resultDisclaimer:
'Tato klasifikace je nezávazné, automatizované předběžné posouzení na základě vašich odpovědí — nejde o právní poradenství. Před dalekosáhlými rozhodnutími nechte výsledek právně ověřit.',
templatesTitle: 'Šablony a formuláře',
templatesSub: 'Celofiremní návrhy pro interní a externí implementaci — tisknutelné s firemní hlavičkou. Formuláře vázané na konkrétní systém (podniková rada, informace pro zaměstnance, FRIA, hlášení incidentu) najdete v zobrazení daného systému.',
templatesHint: 'Všechny šablony jsou návrhy se zástupnými poli — před použitím je upravte a nechte právně ověřit.',
tplPolicy: 'Interní směrnice pro AI',
tplPolicyDesc: 'Pravidla používání AI ve společnosti: schvalování, zákazy, dohled, transparentnost, incidenty.',
tplTraining: 'Plán školení AI gramotnosti (čl. 4)',
tplTrainingDesc: 'Matice školení a průběžná evidence — povinnost od 2. 2. 2025.',
tplWorksAgreement: 'Podniková dohoda o AI (rámcová)',
tplWorksAgreementDesc: 'Návrh podle německého práva (§ 87 odst. 1 bod 6, § 90 BetrVG): účelové omezení, žádná automatizovaná personální rozhodnutí, práva podnikové rady.',
docWorksCouncil: 'Informace pro podnikovou radu (§ 90 BetrVG)',
docEmployeeInfo: 'Informace pro zaměstnance o používání AI',
docFria: 'Šablona FRIA (čl. 27)',
docIncident: 'Hlášení incidentu (čl. 73)',
tplReporting: 'Interní směrnice pro hlášení a eskalaci',
tplReportingDesc: 'Interní ohlašovací povinnost pro incidenty AI: kanály hlášení, lhůty 24h/48h, úrovně eskalace, registr incidentů — připravuje hlášení podle čl. 73.',
tplApproval: 'Žádost o schválení systému AI',
tplApprovalDesc: 'Interní formulář schvalovacího procesu nových nástrojů AI — proti stínové AI, s polem pro rozhodnutí.',
tplAudit: 'Interní auditní kontrolní seznam souladu AI',
tplAuditDesc: 'Pravidelná sebekontrola (inventář, školení, protokoly, incidenty, podklady poskytovatelů) s podpisem.',
};

View File

@ -0,0 +1,211 @@
import type { UIStrings } from './ui';
/** Spanisches UI-Wörterbuch. */
export const ES: UIStrings = {
brandTag: 'Cumplimiento del Reglamento de IA de la UE para pymes · local-first',
navDashboard: 'Panel & inventario',
navTasks: 'Tareas & plazos',
navNew: 'Evaluar un nuevo sistema',
navTemplates: 'Plantillas & formularios',
navSettings: 'Ajustes & copia de seguridad',
footPrivacy: 'Sin nube. Sin telemetría.',
footLocal: 'Todos los datos permanecen en este dispositivo.',
footNoAdvice: 'No constituye asesoramiento jurídico.',
dashTitle: 'Panel',
dashSub: 'Su cumplimiento del Reglamento de IA de la UE de un vistazo. Todos los datos permanecen en local en este dispositivo.',
statSystems: 'Sistemas de IA en el inventario',
statHigh: 'Sistemas de alto riesgo',
statProhibited: 'Prácticas prohibidas',
statOpen: 'Tareas abiertas',
deadlinesTitle: 'Plazos de aplicación del Reglamento de IA',
inventoryTitle: 'Inventario de sistemas de IA',
inventoryPrint: 'Imprimir inventario / PDF',
newSystem: '+ Evaluar sistema',
emptyInventory:
'Aún no hay sistemas de IA registrados. Empiece evaluando su primer sistema — p. ej. su chatbot, su preselección de candidatos o una herramienta de IA adquirida.',
colSystem: 'Sistema',
colRole: 'Rol',
colRisk: 'Clase de riesgo',
colOwner: 'Responsable',
colUpdated: 'Última evaluación',
disclaimerLine:
'AI-Act-Kompass es una herramienta de trabajo estructurada basada en el Reglamento (UE) 2024/1689 — no es asesoramiento jurídico. Content pack v{version}.',
tasksTitle: 'Tareas & plazos',
tasksSub: 'Todas las obligaciones de todos los sistemas como lista de verificación — qué está hecho, qué vence ahora y qué está por venir.',
tasksProgress: '{done} de {total} tareas completadas',
tasksDueNow: 'Vence ahora',
tasksUpcoming: 'Próximamente',
tasksResolved: 'Completado',
tasksEmpty: 'No hay tareas — evalúe primero un sistema de IA.',
tasksAllDone: 'Todo hecho en este grupo.',
tasksDue: 'Plazo',
calExport: 'Añadir al calendario (.ics)',
calHint: 'Exporta todos los plazos abiertos como archivo de calendario con recordatorios (30 y 7 días antes) — importable en Outlook, Apple y Google Calendar, en el móvil y el ordenador.',
navQuiz: 'Test de alfabetización en IA',
quizSub: 'Test sencillo de fundamentos (12 preguntas) sobre alfabetización en IA según el art. 4 — con certificado imprimible como prueba y registro local de formación.',
quizName: 'Nombre del/de la participante *',
quizNamePh: 'Nombre y apellidos',
quizSubmit: 'Evaluar el test',
quizAnswerAll: 'Introduzca un nombre y responda a todas las preguntas.',
quizPassed: 'Aprobado',
quizFailed: 'No aprobado',
quizScoreLine: '{correct} de {total} preguntas correctas ({pct} %) — umbral de aprobado {pass} %.',
quizWhy: 'Explicación',
quizCert: 'Imprimir certificado / PDF',
quizRetry: 'Repetir el test',
quizLogTitle: 'Registro de formación (prueba art. 4)',
quizLogHint: 'Cada intento se guarda en local y sirve como prueba de la obligación de alfabetización en IA (art. 4). Imprima el registro periódicamente y archívelo con su documentación de formación.',
quizLogEmpty: 'Aún no hay intentos.',
quizLogPrint: 'Imprimir registro / PDF',
quizColScore: 'Resultado',
quizColStatus: 'Estado',
quizDocsTitle: 'Imprimir materiales de formación',
quizPrintTest: 'Versión en papel del test',
quizPrintKey: 'Hoja de soluciones',
quizPrintHandout: 'Material de formación (12 reglas)',
quizManualTitle: 'Registrar participante manualmente (test en papel)',
quizManualHint: 'Para tests realizados en papel: introduzca participante y resultado, y adjunte el cuestionario corregido escaneado — así la cadena de evidencia queda completa.',
quizManualScore: 'Respuestas correctas (de 12)',
quizManualAdd: 'Añadir al registro',
quizSourceApp: 'App',
quizSourcePaper: 'Papel',
quizColSource: 'Fuente',
quizColEvidence: 'Evidencia',
quizAttach: 'Adjuntar escaneo',
quizAttachView: 'Abrir escaneo',
quizAttachTooBig: 'Archivo demasiado grande — use un escaneo de menos de 1 MB (p. ej. JPG/PDF comprimido).',
quizAttachDone: 'Escaneo guardado y anclado en el registro con suma de verificación SHA-256.',
quizDeleteRecord: '¿Eliminar realmente la entrada «{name}»? Las evidencias adjuntas se perderán.',
wizardTitleNew: 'Evaluar un nuevo sistema de IA',
wizardTitleRe: 'Reevaluación: {name}',
wizardSub: 'Responda a las preguntas — la clase de riesgo se determina automáticamente según la sistemática del Reglamento de IA.',
stepBasics: 'Datos básicos',
stepDefinition: 'Definición de IA',
stepProhibited: 'Prohibiciones',
stepHighRisk: 'Alto riesgo',
stepTransparency: 'Transparencia & GPAI',
stepResult: 'Resultado',
fieldName: 'Nombre del sistema *',
fieldNamePh: 'p. ej. herramienta de cribado de candidatos',
fieldPurpose: 'Finalidad prevista',
fieldPurposePh: '¿Para qué se utiliza el sistema?',
fieldVendor: 'Fabricante / proveedor',
fieldOwner: 'Persona responsable (interna)',
fieldRole: 'Rol de su empresa',
roleHint: 'Proveedor = desarrolla/comercializa el sistema con su propio nombre. Responsable del despliegue = utiliza un sistema de terceros (caso más frecuente en pymes).',
defTitle: '¿Cumple el sistema la definición de IA (art. 3, punto 1)?',
defHint: 'El sistema solo entra en el Reglamento de IA si se cumplen todos los criterios.',
defWarn: 'No se cumplen todos los criterios → el sistema no es un sistema de IA; el Reglamento de IA no se aplica.',
prohTitle: 'Prácticas prohibidas (art. 5)',
prohHint: 'Si alguno de estos puntos se aplica, el uso está prohibido desde el 2 de febrero de 2025.',
hrTitle: 'Clasificación de alto riesgo (art. 6)',
annexILabel: 'El sistema es un componente de seguridad de un producto regulado (p. ej. producto sanitario, máquina, ascensor) o es él mismo dicho producto.',
annexIIITitle: 'Ámbitos de uso según el anexo III',
exceptionTitle: 'Posible excepción (art. 6, apdo. 3)',
profilingLabel: 'El sistema realiza elaboración de perfiles de personas físicas.',
profilingRef: 'La elaboración de perfiles excluye la excepción — siempre alto riesgo.',
art63Label: 'El sistema solo realiza una tarea procedimental limitada o preparatoria, o únicamente mejora el resultado de una actividad humana ya concluida — sin riesgo significativo para la salud, la seguridad o los derechos fundamentales.',
art63Ref: 'Art. 6, apdo. 3 — la evaluación debe documentarse (art. 6, apdo. 4).',
trTitle: 'Obligaciones de transparencia (art. 50)',
gpaiTitle: 'IA de uso general (GPAI)',
gpaiLabel: 'Proporcionamos nuestro propio modelo GPAI (p. ej. modelo base autoentrenado o sustancialmente modificado).',
gpaiRef: 'Art. 51 y ss. — el mero uso de GPT/Claude vía API no cuenta.',
resultTitle: 'Resultado:',
resultGpai: 'Se aplican además las obligaciones de los modelos GPAI (art. 53 y ss.).',
resultProhibited: 'El uso de este sistema está prohibido según el art. 5 (multa de hasta 35 M€ o el 7 % de la facturación anual mundial). Cese el uso y consulte a un abogado.',
btnCancel: 'Cancelar',
btnBack: 'Atrás',
btnNext: 'Siguiente',
btnSave: 'Guardar',
detailBack: '← Volver al panel',
detailNoPurpose: 'Sin finalidad registrada',
detailReasons: 'Motivación de la clasificación',
detailReassess: 'Reevaluar',
detailDelete: 'Eliminar sistema',
detailObligations: 'Obligaciones',
detailNational: 'incl. módulos nacionales: {codes}',
detailDocs: 'Generar documentos',
docShow: 'ver',
docHide: 'ocultar',
docPrint: 'Imprimir / PDF',
docRisk: 'Informe de riesgo',
docPlan: 'Plan de acción',
docAnnexIV: 'Documentación anexo IV',
docProcurement: 'Pliego de compra de IA',
docConformity: 'Declaración UE de conformidad',
confirmDeleteSystem: '¿Eliminar realmente «{name}»?',
systemNotFound: 'Sistema no encontrado.',
statusOpen: 'Abierto',
statusInProgress: 'En curso',
statusDone: 'Hecho',
statusNA: 'No aplicable',
settingsTitle: 'Ajustes',
settingsSub: 'Soberanía de los datos: todo permanece en local en este navegador — sin sincronización en la nube, sin telemetría.',
langTitle: 'Sprache / Language / Idioma',
langHint: 'Interfaz, contenidos normativos y documentos generados íntegramente disponibles en 9 idiomas europeos (DE, EN, FR, IT, ES, PL, CS, SK, RO). Más idiomas de la UE llegarán mediante el content feed.',
profileTitle: 'Perfil de empresa (membrete para informes & impresión PDF)',
profileHint: 'Estos datos aparecen en el encabezado y pie de página de todos los documentos generados e impresos. El logotipo se guarda en local y nunca sale del dispositivo.',
pfName: 'Razón social', pfStreet: 'Calle & número', pfZip: 'CP & ciudad',
pfContact: 'Persona de contacto', pfEmail: 'Correo electrónico', pfPhone: 'Teléfono', pfWeb: 'Sitio web',
logoNone: 'Sin logotipo guardado.',
logoUpload: 'Subir logotipo',
logoRemove: 'Quitar logotipo',
logoTaken: 'Logotipo aplicado.',
logoTooBig: 'Logotipo demasiado grande — use un archivo de menos de 300 KB.',
logoNotImage: 'Elija un archivo de imagen (PNG, JPG o SVG).',
countriesTitle: 'Módulos nacionales (requisitos adicionales)',
countriesHint: 'Active los países de la UE en los que su empresa ofrece u opera sistemas de IA. Las obligaciones nacionales (autoridades, derecho laboral, leyes especiales) aparecerán en las listas y documentos. Cooperación transfronteriza: active todos los países implicados.',
authorityLabel: 'Autoridad',
packTitle: 'Content pack normativo',
packStand: 'Actualizado a',
packHint: 'El content pack (prohibiciones, ámbitos del anexo III, obligaciones UE, módulos nacionales, plazos) está modelado como paquete de datos sustituible. Las actualizaciones llegan con nuevas versiones de la app y, en el futuro, mediante un feed firmado.',
backupTitle: 'Copia de seguridad',
backupExport: 'Exportar copia (JSON)',
backupImport: 'Importar copia',
importOk: 'Importación completada: {count} sistema(s){profile}.',
importProfileSuffix: ' incl. perfil de empresa',
importFail: 'Error de importación: {error}',
deleteTitle: 'Eliminar todos los datos',
deleteHint: 'Elimina irrevocablemente de este navegador todos los sistemas de IA registrados y el perfil de empresa.',
deleteBtn: 'Eliminar todo',
deleteConfirm: '¿Eliminar realmente y de forma irrevocable todos los datos locales?',
deleteDone: 'Todos los datos han sido eliminados.',
legalGateTitle: 'Aviso legal importante',
legalGateBody1:
'AI-Act-Kompass es una herramienta de trabajo estructurada destinada a facilitar la aplicación del Reglamento (UE) 2024/1689 (Reglamento de IA) y de las disposiciones nacionales pertinentes.',
legalGateBody2:
'Esta aplicación no presta servicios jurídicos y no constituye asesoramiento jurídico, información jurídica ni instrucción jurídicamente vinculante. Todas las clasificaciones, listas y documentos generados son evaluaciones preliminares no vinculantes y borradores, sin garantía de exactitud, integridad o actualidad.',
legalGateBody3:
'La interpretación vinculante del Reglamento de IA corresponde exclusivamente a las autoridades y tribunales competentes. Esta herramienta no sustituye la valoración jurídica de su caso concreto — consulte a un asesor jurídico cualificado. El uso es bajo su propio riesgo; se excluye la responsabilidad por decisiones basadas en esta herramienta en la medida permitida por la ley.',
legalGateAccept: 'Entendido — usar como herramienta de trabajo',
legalNoticeTitle: 'Aviso legal (no es asesoramiento jurídico)',
resultDisclaimer:
'Esta clasificación es una evaluación preliminar automatizada y no vinculante basada en sus respuestas — no es asesoramiento jurídico. Haga revisar el resultado por un jurista antes de decisiones importantes.',
templatesTitle: 'Plantillas & formularios',
templatesSub: 'Borradores a nivel de empresa para la implementación interna y externa — imprimibles con membrete. Los formularios específicos de sistema (comité de empresa, información a empleados, FRIA, notificación de incidentes) están en la vista de cada sistema.',
templatesHint: 'Todas las plantillas son borradores con campos por completar — adáptelas y hágalas revisar jurídicamente antes de usarlas.',
tplPolicy: 'Política interna de IA',
tplPolicyDesc: 'Reglas de uso de la IA en la empresa: aprobaciones, prohibiciones, supervisión, transparencia, incidentes.',
tplTraining: 'Plan de formación en competencia de IA (art. 4)',
tplTrainingDesc: 'Matriz de formación y registro continuo — obligatorio desde el 02/02/2025.',
tplWorksAgreement: 'Acuerdo de empresa sobre IA (marco)',
tplWorksAgreementDesc: 'Borrador según el derecho alemán (§ 87, § 90 BetrVG): limitación de finalidad, sin decisiones de RR. HH. automatizadas, derechos del comité de empresa.',
docWorksCouncil: 'Información al comité de empresa (§ 90 BetrVG)',
docEmployeeInfo: 'Información a los empleados sobre el uso de IA',
docFria: 'Plantilla FRIA (art. 27)',
docIncident: 'Notificación de incidente (art. 73)',
tplReporting: 'Política interna de notificación & escalado',
tplReportingDesc: 'Obligación interna de notificar incidentes de IA: canales, plazos de 24 h/48 h, niveles de escalado, registro — prepara la notificación del art. 73.',
tplApproval: 'Solicitud de aprobación de sistema de IA',
tplApprovalDesc: 'Formulario interno para aprobar nuevas herramientas de IA — contra la shadow AI, con bloque de decisión.',
tplAudit: 'Lista de auditoría interna de cumplimiento de IA',
tplAuditDesc: 'Autoevaluación periódica (inventario, formaciones, registros, incidentes, documentos de proveedores) con firma.',
};

View File

@ -0,0 +1,211 @@
import type { UIStrings } from './ui';
/** Französisches UI-Wörterbuch. */
export const FR: UIStrings = {
brandTag: 'Conformité au règlement IA de lUE pour PME · local-first',
navDashboard: 'Tableau de bord & inventaire',
navTasks: 'Tâches & échéances',
navNew: 'Évaluer un nouveau système',
navTemplates: 'Modèles & formulaires',
navSettings: 'Paramètres & sauvegarde',
footPrivacy: 'Pas de cloud. Pas de télémétrie.',
footLocal: 'Toutes les données restent sur cet appareil.',
footNoAdvice: 'Ne constitue pas un conseil juridique.',
dashTitle: 'Tableau de bord',
dashSub: 'Votre conformité au règlement IA de lUE en un coup dœil. Toutes les données restent en local sur cet appareil.',
statSystems: 'Systèmes dIA à linventaire',
statHigh: 'Systèmes à haut risque',
statProhibited: 'Pratiques interdites',
statOpen: 'Tâches ouvertes',
deadlinesTitle: 'Échéances dapplication du règlement IA',
inventoryTitle: 'Inventaire des systèmes dIA',
inventoryPrint: 'Imprimer linventaire / PDF',
newSystem: '+ Évaluer un système',
emptyInventory:
'Aucun système dIA enregistré. Commencez par évaluer votre premier système — p. ex. votre chatbot, votre présélection de candidatures ou un outil dIA acheté.',
colSystem: 'Système',
colRole: 'Rôle',
colRisk: 'Classe de risque',
colOwner: 'Responsable',
colUpdated: 'Dernière évaluation',
disclaimerLine:
'AI-Act-Kompass est une aide de travail structurée fondée sur le règlement (UE) 2024/1689 — pas un conseil juridique. Pack de contenu v{version}.',
tasksTitle: 'Tâches & échéances',
tasksSub: 'Toutes les obligations de tous les systèmes sous forme de liste à cocher — ce qui est fait, ce qui est dû maintenant et ce qui arrive.',
tasksProgress: '{done} tâches sur {total} accomplies',
tasksDueNow: 'À traiter maintenant',
tasksUpcoming: 'À venir',
tasksResolved: 'Accompli',
tasksEmpty: 'Aucune tâche — évaluez dabord un système dIA.',
tasksAllDone: 'Tout est fait dans ce groupe.',
tasksDue: 'Échéance',
calExport: 'Ajouter au calendrier (.ics)',
calHint: 'Exporte toutes les échéances ouvertes sous forme de fichier calendrier avec rappels (30 et 7 jours avant) — importable dans Outlook, Apple et Google Agenda, sur téléphone et ordinateur.',
navQuiz: 'Test de maîtrise de lIA',
quizSub: 'Test simple des fondamentaux (12 questions) sur la maîtrise de lIA selon lart. 4 — avec certificat imprimable comme preuve et registre local de formation.',
quizName: 'Nom du participant / de la participante *',
quizNamePh: 'Prénom et nom',
quizSubmit: 'Évaluer le test',
quizAnswerAll: 'Veuillez saisir un nom et répondre à toutes les questions.',
quizPassed: 'Réussi',
quizFailed: 'Non réussi',
quizScoreLine: '{correct} questions sur {total} correctes ({pct} %) — seuil de réussite {pass} %.',
quizWhy: 'Explication',
quizCert: 'Imprimer le certificat / PDF',
quizRetry: 'Repasser le test',
quizLogTitle: 'Registre de formation (preuve art. 4)',
quizLogHint: 'Chaque passage est enregistré en local et sert de preuve de lobligation de maîtrise de lIA (art. 4). Imprimez régulièrement le registre et classez-le avec votre documentation de formation.',
quizLogEmpty: 'Aucun passage pour linstant.',
quizLogPrint: 'Imprimer le registre / PDF',
quizColScore: 'Résultat',
quizColStatus: 'Statut',
quizDocsTitle: 'Imprimer les supports de formation',
quizPrintTest: 'Version papier du test',
quizPrintKey: 'Corrigé',
quizPrintHandout: 'Support de formation (12 règles)',
quizManualTitle: 'Saisir un participant manuellement (test papier)',
quizManualHint: 'Pour les tests réalisés sur papier : saisissez le participant et le résultat, puis joignez le questionnaire corrigé numérisé — la chaîne de preuve est ainsi complète.',
quizManualScore: 'Réponses correctes (sur 12)',
quizManualAdd: 'Ajouter au registre',
quizSourceApp: 'App',
quizSourcePaper: 'Papier',
quizColSource: 'Source',
quizColEvidence: 'Preuve',
quizAttach: 'Joindre un scan',
quizAttachView: 'Ouvrir le scan',
quizAttachTooBig: 'Fichier trop volumineux — utilisez un scan de moins de 1 Mo (p. ex. JPG/PDF compressé).',
quizAttachDone: 'Scan enregistré et ancré dans le registre avec une somme de contrôle SHA-256.',
quizDeleteRecord: 'Supprimer vraiment lentrée « {name} » ? Les preuves jointes seront perdues.',
wizardTitleNew: 'Évaluer un nouveau système dIA',
wizardTitleRe: 'Réévaluation : {name}',
wizardSub: 'Répondez aux questions — la classe de risque est déterminée automatiquement selon la systématique du règlement IA.',
stepBasics: 'Données de base',
stepDefinition: 'Définition de lIA',
stepProhibited: 'Interdictions',
stepHighRisk: 'Haut risque',
stepTransparency: 'Transparence & GPAI',
stepResult: 'Résultat',
fieldName: 'Nom du système *',
fieldNamePh: 'p. ex. outil de présélection de candidatures',
fieldPurpose: 'Destination',
fieldPurposePh: 'À quoi sert le système ?',
fieldVendor: 'Fabricant / fournisseur',
fieldOwner: 'Personne responsable (interne)',
fieldRole: 'Rôle de votre entreprise',
roleHint: 'Fournisseur = développe/commercialise le système sous son propre nom. Déployeur = utilise un système tiers (cas le plus fréquent pour les PME).',
defTitle: 'Le système répond-il à la définition de lIA (art. 3, point 1) ?',
defHint: 'Le système ne relève du règlement IA que si tous les critères sappliquent.',
defWarn: 'Tous les critères ne sont pas remplis → le système nest pas un système dIA ; le règlement IA ne sapplique pas.',
prohTitle: 'Pratiques interdites (art. 5)',
prohHint: 'Si lun de ces points sapplique, lutilisation est interdite depuis le 2 février 2025.',
hrTitle: 'Classification à haut risque (art. 6)',
annexILabel: 'Le système est un composant de sécurité dun produit réglementé (p. ex. dispositif médical, machine, ascenseur) ou un tel produit lui-même.',
annexIIITitle: 'Domaines dutilisation selon lannexe III',
exceptionTitle: 'Exception possible (art. 6, par. 3)',
profilingLabel: 'Le système effectue un profilage de personnes physiques.',
profilingRef: 'Le profilage exclut lexception — toujours haut risque.',
art63Label: 'Le système naccomplit quune tâche procédurale étroite ou préparatoire, ou ne fait quaméliorer le résultat dune activité humaine déjà achevée — sans risque important pour la santé, la sécurité ou les droits fondamentaux.',
art63Ref: 'Art. 6, par. 3 — lappréciation doit être documentée (art. 6, par. 4).',
trTitle: 'Obligations de transparence (art. 50)',
gpaiTitle: 'IA à usage général (GPAI)',
gpaiLabel: 'Nous fournissons notre propre modèle GPAI (p. ex. modèle de base auto-entraîné ou substantiellement modifié).',
gpaiRef: 'Art. 51 et s. — la simple utilisation de GPT/Claude via API ne compte pas.',
resultTitle: 'Résultat :',
resultGpai: 'Les obligations relatives aux modèles GPAI (art. 53 et s.) sappliquent en outre.',
resultProhibited: 'Lutilisation de ce système est interdite en vertu de lart. 5 (amende jusquà 35 M€ ou 7 % du chiffre daffaires annuel mondial). Cessez lutilisation et consultez un juriste.',
btnCancel: 'Annuler',
btnBack: 'Retour',
btnNext: 'Suivant',
btnSave: 'Enregistrer',
detailBack: '← Retour au tableau de bord',
detailNoPurpose: 'Aucune destination renseignée',
detailReasons: 'Motivation de la classification',
detailReassess: 'Réévaluer',
detailDelete: 'Supprimer le système',
detailObligations: 'Obligations',
detailNational: 'incl. modules nationaux : {codes}',
detailDocs: 'Générer des documents',
docShow: 'afficher',
docHide: 'masquer',
docPrint: 'Imprimer / PDF',
docRisk: 'Rapport de risque',
docPlan: 'Plan daction',
docAnnexIV: 'Documentation annexe IV',
docProcurement: 'Cahier des charges achat dIA',
docConformity: 'Déclaration UE de conformité',
confirmDeleteSystem: 'Supprimer vraiment « {name} » ?',
systemNotFound: 'Système introuvable.',
statusOpen: 'Ouvert',
statusInProgress: 'En cours',
statusDone: 'Fait',
statusNA: 'Non applicable',
settingsTitle: 'Paramètres',
settingsSub: 'Souveraineté des données : tout reste en local dans ce navigateur — pas de synchronisation cloud, pas de télémétrie.',
langTitle: 'Sprache / Language / Langue',
langHint: 'Interface, contenus réglementaires et documents générés entièrement disponibles en 9 langues européennes (DE, EN, FR, IT, ES, PL, CS, SK, RO). Dautres langues de lUE suivront via le flux de contenu.',
profileTitle: 'Profil dentreprise (en-tête pour rapports & impression PDF)',
profileHint: 'Ces informations apparaissent dans len-tête et le pied de page de tous les documents générés et imprimés. Le logo reste stocké en local et ne quitte jamais lappareil.',
pfName: 'Raison sociale', pfStreet: 'Rue & numéro', pfZip: 'Code postal & ville',
pfContact: 'Personne de contact', pfEmail: 'E-mail', pfPhone: 'Téléphone', pfWeb: 'Site web',
logoNone: 'Aucun logo enregistré.',
logoUpload: 'Téléverser un logo',
logoRemove: 'Supprimer le logo',
logoTaken: 'Logo appliqué.',
logoTooBig: 'Logo trop volumineux — utilisez un fichier de moins de 300 Ko.',
logoNotImage: 'Veuillez choisir un fichier image (PNG, JPG ou SVG).',
countriesTitle: 'Modules nationaux (exigences supplémentaires)',
countriesHint: 'Activez les pays de lUE dans lesquels votre entreprise propose ou exploite des systèmes dIA. Les obligations nationales (autorités, droit du travail, lois spéciales) apparaissent alors dans les checklists et documents. Coopération transfrontalière : activez tous les pays concernés.',
authorityLabel: 'Autorité',
packTitle: 'Pack de contenu réglementaire',
packStand: 'État',
packHint: 'Le pack de contenu (interdictions, domaines annexe III, obligations UE, modules nationaux, échéances) est modélisé comme un paquet de données remplaçable. Les mises à jour arrivent avec les nouvelles versions de lapp et, à lavenir, via un flux signé.',
backupTitle: 'Sauvegarde',
backupExport: 'Exporter la sauvegarde (JSON)',
backupImport: 'Importer une sauvegarde',
importOk: 'Import terminé : {count} système(s){profile}.',
importProfileSuffix: ' incl. profil dentreprise',
importFail: 'Échec de limport : {error}',
deleteTitle: 'Supprimer toutes les données',
deleteHint: 'Supprime irrévocablement tous les systèmes dIA enregistrés et le profil dentreprise de ce navigateur.',
deleteBtn: 'Tout supprimer',
deleteConfirm: 'Supprimer vraiment et irrévocablement toutes les données locales ?',
deleteDone: 'Toutes les données ont été supprimées.',
legalGateTitle: 'Avertissement juridique important',
legalGateBody1:
'AI-Act-Kompass est une aide de travail structurée destinée à faciliter la mise en œuvre du règlement (UE) 2024/1689 (règlement IA) et des dispositions nationales pertinentes.',
legalGateBody2:
'Cette application ne fournit pas de services juridiques et ne constitue ni un conseil juridique, ni un renseignement juridique, ni une instruction juridiquement contraignante. Toutes les classifications, checklists et documents générés sont des évaluations préliminaires non contraignantes et des projets, sans garantie dexactitude, dexhaustivité ou dactualité.',
legalGateBody3:
'Linterprétation contraignante du règlement IA appartient exclusivement aux autorités et juridictions compétentes. Cet outil ne remplace pas lappréciation juridique de votre cas particulier — consultez un conseil juridique qualifié. Lutilisation se fait à vos risques ; toute responsabilité pour des décisions fondées sur cet outil est exclue dans la mesure permise par la loi.',
legalGateAccept: 'Compris — utiliser comme aide de travail',
legalNoticeTitle: 'Avertissement juridique (pas un conseil juridique)',
resultDisclaimer:
'Cette classification est une évaluation préliminaire automatisée et non contraignante fondée sur vos réponses — pas un conseil juridique. Faites vérifier le résultat par un juriste avant toute décision importante.',
templatesTitle: 'Modèles & formulaires',
templatesSub: 'Projets à léchelle de lentreprise pour la mise en œuvre interne et externe — imprimables avec en-tête. Les formulaires liés à un système (comité dentreprise, information des salariés, FRIA, signalement dincident) se trouvent dans la vue du système concerné.',
templatesHint: 'Tous les modèles sont des projets avec des champs à compléter — à adapter et à faire vérifier juridiquement avant utilisation.',
tplPolicy: 'Politique interne dIA',
tplPolicyDesc: 'Règles dutilisation de lIA dans lentreprise : validations, interdictions, supervision, transparence, incidents.',
tplTraining: 'Plan de formation à la maîtrise de lIA (art. 4)',
tplTrainingDesc: 'Matrice de formation et registre continu — obligatoire depuis le 02/02/2025.',
tplWorksAgreement: 'Accord dentreprise sur lIA (cadre)',
tplWorksAgreementDesc: 'Projet selon le droit allemand (§ 87, § 90 BetrVG) : limitation des finalités, pas de décisions RH automatisées, droits du comité dentreprise.',
docWorksCouncil: 'Information du comité dentreprise (§ 90 BetrVG)',
docEmployeeInfo: 'Information des salariés sur lusage de lIA',
docFria: 'Modèle FRIA (art. 27)',
docIncident: 'Signalement dincident (art. 73)',
tplReporting: 'Politique interne de signalement & escalade',
tplReportingDesc: 'Obligation interne de signalement des incidents dIA : canaux, délais 24 h/48 h, niveaux descalade, registre — prépare le signalement art. 73.',
tplApproval: 'Demande de validation dun système dIA',
tplApprovalDesc: 'Formulaire interne de validation des nouveaux outils dIA — contre lIA fantôme, avec bloc de décision.',
tplAudit: 'Checklist daudit interne de conformité IA',
tplAuditDesc: 'Auto-contrôle périodique (inventaire, formations, journaux, incidents, documents fournisseurs) avec visa.',
};

View File

@ -0,0 +1,211 @@
import type { UIStrings } from './ui';
/** Italienisches UI-Wörterbuch. */
export const IT: UIStrings = {
brandTag: 'Conformità al regolamento IA dellUE per PMI · local-first',
navDashboard: 'Dashboard & inventario',
navTasks: 'Attività & scadenze',
navNew: 'Valutare un nuovo sistema',
navTemplates: 'Modelli & moduli',
navSettings: 'Impostazioni & backup',
footPrivacy: 'Nessun cloud. Nessuna telemetria.',
footLocal: 'Tutti i dati restano su questo dispositivo.',
footNoAdvice: 'Non costituisce consulenza legale.',
dashTitle: 'Dashboard',
dashSub: 'La conformità al regolamento IA dellUE a colpo docchio. Tutti i dati restano in locale su questo dispositivo.',
statSystems: 'Sistemi di IA in inventario',
statHigh: 'Sistemi ad alto rischio',
statProhibited: 'Pratiche vietate',
statOpen: 'Attività aperte',
deadlinesTitle: 'Scadenze di applicazione del regolamento IA',
inventoryTitle: 'Inventario dei sistemi di IA',
inventoryPrint: 'Stampare linventario / PDF',
newSystem: '+ Valutare un sistema',
emptyInventory:
'Nessun sistema di IA registrato. Iniziate valutando il vostro primo sistema — p. es. il vostro chatbot, la preselezione dei candidati o uno strumento di IA acquistato.',
colSystem: 'Sistema',
colRole: 'Ruolo',
colRisk: 'Classe di rischio',
colOwner: 'Responsabile',
colUpdated: 'Ultima valutazione',
disclaimerLine:
'AI-Act-Kompass è uno strumento di lavoro strutturato basato sul regolamento (UE) 2024/1689 — non è consulenza legale. Content pack v{version}.',
tasksTitle: 'Attività & scadenze',
tasksSub: 'Tutti gli obblighi di tutti i sistemi come lista da spuntare — cosa è fatto, cosa scade ora e cosa arriverà.',
tasksProgress: '{done} attività su {total} completate',
tasksDueNow: 'In scadenza ora',
tasksUpcoming: 'In arrivo',
tasksResolved: 'Completato',
tasksEmpty: 'Nessuna attività — valutate prima un sistema di IA.',
tasksAllDone: 'Tutto fatto in questo gruppo.',
tasksDue: 'Scadenza',
calExport: 'Aggiungi al calendario (.ics)',
calHint: 'Esporta tutte le scadenze aperte come file di calendario con promemoria (30 e 7 giorni prima) — importabile in Outlook, Apple e Google Calendar, su telefono e computer.',
navQuiz: 'Test di alfabetizzazione IA',
quizSub: 'Test semplice sulle basi (12 domande) dellalfabetizzazione IA ai sensi dellart. 4 — con certificato stampabile come prova e registro locale della formazione.',
quizName: 'Nome del/della partecipante *',
quizNamePh: 'Nome e cognome',
quizSubmit: 'Valuta il test',
quizAnswerAll: 'Inserite un nome e rispondete a tutte le domande.',
quizPassed: 'Superato',
quizFailed: 'Non superato',
quizScoreLine: '{correct} domande su {total} corrette ({pct} %) — soglia di superamento {pass} %.',
quizWhy: 'Spiegazione',
quizCert: 'Stampa certificato / PDF',
quizRetry: 'Ripeti il test',
quizLogTitle: 'Registro formazione (prova art. 4)',
quizLogHint: 'Ogni esecuzione viene salvata in locale e serve come prova dellobbligo di alfabetizzazione IA (art. 4). Stampate regolarmente il registro e archiviatelo con la documentazione formativa.',
quizLogEmpty: 'Nessuna esecuzione finora.',
quizLogPrint: 'Stampa registro / PDF',
quizColScore: 'Risultato',
quizColStatus: 'Stato',
quizDocsTitle: 'Stampa materiali formativi',
quizPrintTest: 'Versione cartacea del test',
quizPrintKey: 'Foglio delle soluzioni',
quizPrintHandout: 'Dispensa formativa (12 regole)',
quizManualTitle: 'Registrare manualmente un partecipante (test cartaceo)',
quizManualHint: 'Per i test svolti su carta: inserite partecipante e risultato, poi allegate il foglio corretto scansionato — la catena probatoria è così completa.',
quizManualScore: 'Risposte corrette (su 12)',
quizManualAdd: 'Aggiungi al registro',
quizSourceApp: 'App',
quizSourcePaper: 'Carta',
quizColSource: 'Fonte',
quizColEvidence: 'Prova',
quizAttach: 'Allega scansione',
quizAttachView: 'Apri scansione',
quizAttachTooBig: 'File troppo grande — usate una scansione sotto 1 MB (p. es. JPG/PDF compresso).',
quizAttachDone: 'Scansione salvata e ancorata nel registro con checksum SHA-256.',
quizDeleteRecord: 'Eliminare davvero la voce «{name}»? Le prove allegate andranno perse.',
wizardTitleNew: 'Valutare un nuovo sistema di IA',
wizardTitleRe: 'Rivalutazione: {name}',
wizardSub: 'Rispondete alle domande — la classe di rischio viene determinata automaticamente secondo la sistematica del regolamento IA.',
stepBasics: 'Dati di base',
stepDefinition: 'Definizione di IA',
stepProhibited: 'Divieti',
stepHighRisk: 'Alto rischio',
stepTransparency: 'Trasparenza & GPAI',
stepResult: 'Risultato',
fieldName: 'Nome del sistema *',
fieldNamePh: 'p. es. strumento di screening dei candidati',
fieldPurpose: 'Finalità prevista',
fieldPurposePh: 'A cosa serve il sistema?',
fieldVendor: 'Produttore / fornitore',
fieldOwner: 'Persona responsabile (interna)',
fieldRole: 'Ruolo della vostra azienda',
roleHint: 'Fornitore = sviluppa/commercializza il sistema con il proprio nome. Deployer = utilizza un sistema di terzi (caso più frequente per le PMI).',
defTitle: 'Il sistema soddisfa la definizione di IA (art. 3, punto 1)?',
defHint: 'Il sistema rientra nel regolamento IA solo se tutti i criteri sono soddisfatti.',
defWarn: 'Non tutti i criteri sono soddisfatti → il sistema non è un sistema di IA; il regolamento IA non si applica.',
prohTitle: 'Pratiche vietate (art. 5)',
prohHint: 'Se uno di questi punti si applica, luso è vietato dal 2 febbraio 2025.',
hrTitle: 'Classificazione ad alto rischio (art. 6)',
annexILabel: 'Il sistema è un componente di sicurezza di un prodotto regolamentato (p. es. dispositivo medico, macchina, ascensore) o è esso stesso un tale prodotto.',
annexIIITitle: 'Ambiti di utilizzo secondo lallegato III',
exceptionTitle: 'Possibile eccezione (art. 6, par. 3)',
profilingLabel: 'Il sistema effettua profilazione di persone fisiche.',
profilingRef: 'La profilazione esclude leccezione — sempre alto rischio.',
art63Label: 'Il sistema svolge solo un compito procedurale ristretto o preparatorio, oppure migliora soltanto il risultato di unattività umana già conclusa — senza rischio significativo per salute, sicurezza o diritti fondamentali.',
art63Ref: 'Art. 6, par. 3 — la valutazione deve essere documentata (art. 6, par. 4).',
trTitle: 'Obblighi di trasparenza (art. 50)',
gpaiTitle: 'IA per finalità generali (GPAI)',
gpaiLabel: 'Forniamo un nostro modello GPAI (p. es. modello di base auto-addestrato o sostanzialmente modificato).',
gpaiRef: 'Art. 51 e segg. — il semplice uso di GPT/Claude via API non conta.',
resultTitle: 'Risultato:',
resultGpai: 'Si applicano inoltre gli obblighi per i modelli GPAI (art. 53 e segg.).',
resultProhibited: 'Luso di questo sistema è vietato ai sensi dellart. 5 (sanzione fino a 35 mln € o al 7 % del fatturato annuo mondiale). Cessate luso e consultate un legale.',
btnCancel: 'Annulla',
btnBack: 'Indietro',
btnNext: 'Avanti',
btnSave: 'Salva',
detailBack: '← Torna alla dashboard',
detailNoPurpose: 'Nessuna finalità registrata',
detailReasons: 'Motivazione della classificazione',
detailReassess: 'Rivalutare',
detailDelete: 'Eliminare il sistema',
detailObligations: 'Obblighi',
detailNational: 'incl. moduli nazionali: {codes}',
detailDocs: 'Generare documenti',
docShow: 'mostra',
docHide: 'nascondi',
docPrint: 'Stampa / PDF',
docRisk: 'Rapporto di rischio',
docPlan: 'Piano dazione',
docAnnexIV: 'Documentazione allegato IV',
docProcurement: 'Capitolato acquisto IA',
docConformity: 'Dichiarazione UE di conformità',
confirmDeleteSystem: 'Eliminare davvero «{name}»?',
systemNotFound: 'Sistema non trovato.',
statusOpen: 'Aperto',
statusInProgress: 'In corso',
statusDone: 'Fatto',
statusNA: 'Non applicabile',
settingsTitle: 'Impostazioni',
settingsSub: 'Sovranità dei dati: tutto resta in locale in questo browser — nessuna sincronizzazione cloud, nessuna telemetria.',
langTitle: 'Sprache / Language / Lingua',
langHint: 'Interfaccia, contenuti normativi e documenti generati interamente disponibili in 9 lingue europee (DE, EN, FR, IT, ES, PL, CS, SK, RO). Altre lingue UE seguiranno tramite il content feed.',
profileTitle: 'Profilo aziendale (intestazione per report & stampa PDF)',
profileHint: 'Questi dati compaiono nellintestazione e nel piè di pagina di tutti i documenti generati e stampati. Il logo resta salvato in locale e non lascia mai il dispositivo.',
pfName: 'Ragione sociale', pfStreet: 'Via & numero civico', pfZip: 'CAP & città',
pfContact: 'Referente', pfEmail: 'E-mail', pfPhone: 'Telefono', pfWeb: 'Sito web',
logoNone: 'Nessun logo salvato.',
logoUpload: 'Caricare un logo',
logoRemove: 'Rimuovere il logo',
logoTaken: 'Logo applicato.',
logoTooBig: 'Logo troppo grande — usate un file sotto i 300 KB.',
logoNotImage: 'Scegliete un file immagine (PNG, JPG o SVG).',
countriesTitle: 'Moduli nazionali (requisiti aggiuntivi)',
countriesHint: 'Attivate i paesi UE in cui la vostra azienda offre o utilizza sistemi di IA. Gli obblighi nazionali (autorità, diritto del lavoro, leggi speciali) compariranno in checklist e documenti. Cooperazione transfrontaliera: attivate tutti i paesi coinvolti.',
authorityLabel: 'Autorità',
packTitle: 'Content pack normativo',
packStand: 'Aggiornato al',
packHint: 'Il content pack (divieti, ambiti allegato III, obblighi UE, moduli nazionali, scadenze) è modellato come pacchetto dati sostituibile. Gli aggiornamenti arrivano con le nuove versioni dellapp e, in futuro, tramite un feed firmato.',
backupTitle: 'Backup',
backupExport: 'Esportare il backup (JSON)',
backupImport: 'Importare un backup',
importOk: 'Import completato: {count} sistema/i{profile}.',
importProfileSuffix: ' incl. profilo aziendale',
importFail: 'Import non riuscito: {error}',
deleteTitle: 'Eliminare tutti i dati',
deleteHint: 'Rimuove irrevocabilmente da questo browser tutti i sistemi di IA registrati e il profilo aziendale.',
deleteBtn: 'Eliminare tutto',
deleteConfirm: 'Eliminare davvero e irrevocabilmente tutti i dati locali?',
deleteDone: 'Tutti i dati sono stati eliminati.',
legalGateTitle: 'Avvertenza legale importante',
legalGateBody1:
'AI-Act-Kompass è uno strumento di lavoro strutturato inteso a facilitare lattuazione del regolamento (UE) 2024/1689 (regolamento IA) e delle pertinenti disposizioni nazionali.',
legalGateBody2:
'Questa applicazione non fornisce servizi legali e non costituisce consulenza legale, informazione legale né istruzione giuridicamente vincolante. Tutte le classificazioni, checklist e i documenti generati sono valutazioni preliminari non vincolanti e bozze, senza garanzia di correttezza, completezza o attualità.',
legalGateBody3:
'Linterpretazione vincolante del regolamento IA spetta esclusivamente alle autorità e ai giudici competenti. Questo strumento non sostituisce la valutazione legale del vostro caso specifico — rivolgetevi a una consulenza legale qualificata. Luso avviene a proprio rischio; la responsabilità per decisioni basate su questo strumento è esclusa nella misura consentita dalla legge.',
legalGateAccept: 'Capito — usare come strumento di lavoro',
legalNoticeTitle: 'Avvertenza legale (non è consulenza legale)',
resultDisclaimer:
'Questa classificazione è una valutazione preliminare automatizzata e non vincolante basata sulle vostre risposte — non è consulenza legale. Fate verificare il risultato da un legale prima di decisioni importanti.',
templatesTitle: 'Modelli & moduli',
templatesSub: 'Bozze a livello aziendale per lattuazione interna ed esterna — stampabili con intestazione. I moduli specifici di sistema (consiglio aziendale, informazione ai dipendenti, FRIA, segnalazione incidenti) si trovano nella vista del rispettivo sistema.',
templatesHint: 'Tutti i modelli sono bozze con segnaposto — adattare e far verificare legalmente prima delluso.',
tplPolicy: 'Policy interna sullIA',
tplPolicyDesc: 'Regole duso dellIA in azienda: approvazioni, divieti, supervisione, trasparenza, incidenti.',
tplTraining: 'Piano di formazione allalfabetizzazione IA (art. 4)',
tplTrainingDesc: 'Matrice formativa e registro continuo — obbligatorio dal 02/02/2025.',
tplWorksAgreement: 'Accordo aziendale sullIA (quadro)',
tplWorksAgreementDesc: 'Bozza secondo il diritto tedesco (§ 87, § 90 BetrVG): vincolo di finalità, nessuna decisione HR automatizzata, diritti del consiglio aziendale.',
docWorksCouncil: 'Informazione al consiglio aziendale (§ 90 BetrVG)',
docEmployeeInfo: 'Informazione ai dipendenti sulluso dellIA',
docFria: 'Modello FRIA (art. 27)',
docIncident: 'Segnalazione di incidente (art. 73)',
tplReporting: 'Policy interna di segnalazione & escalation',
tplReportingDesc: 'Obbligo interno di segnalazione degli incidenti IA: canali, termini 24 h/48 h, livelli di escalation, registro — prepara la segnalazione ex art. 73.',
tplApproval: 'Richiesta di approvazione sistema IA',
tplApprovalDesc: 'Modulo interno per lapprovazione di nuovi strumenti di IA — contro la shadow AI, con blocco decisionale.',
tplAudit: 'Checklist di audit interno conformità IA',
tplAuditDesc: 'Autoverifica periodica (inventario, formazioni, log, incidenti, documenti dei fornitori) con firma.',
};

View File

@ -0,0 +1,211 @@
import type { UIStrings } from './ui';
/** Polnisches UI-Wörterbuch. */
export const PL: UIStrings = {
brandTag: 'Zgodność z rozporządzeniem UE w sprawie AI dla MŚP · local-first',
navDashboard: 'Pulpit i inwentarz',
navTasks: 'Zadania i terminy',
navNew: 'Oceń nowy system',
navTemplates: 'Szablony i formularze',
navSettings: 'Ustawienia i kopia zapasowa',
footPrivacy: 'Bez chmury. Bez telemetrii.',
footLocal: 'Wszystkie dane pozostają na tym urządzeniu.',
footNoAdvice: 'To nie jest porada prawna.',
dashTitle: 'Pulpit',
dashSub: 'Zgodność z rozporządzeniem UE w sprawie AI w skrócie. Wszystkie dane pozostają lokalnie na tym urządzeniu.',
statSystems: 'Systemy AI w inwentarzu',
statHigh: 'Systemy wysokiego ryzyka',
statProhibited: 'Zakazane praktyki',
statOpen: 'Otwarte zadania',
deadlinesTitle: 'Terminy stosowania rozporządzenia w sprawie AI',
inventoryTitle: 'Inwentarz AI',
inventoryPrint: 'Drukuj inwentarz / PDF',
newSystem: '+ Oceń system',
emptyInventory:
'Nie zarejestrowano jeszcze żadnych systemów AI. Zacznij od oceny pierwszego systemu — np. chatbota, narzędzia do wstępnej selekcji kandydatów lub zakupionego narzędzia AI.',
colSystem: 'System',
colRole: 'Rola',
colRisk: 'Klasa ryzyka',
colOwner: 'Osoba odpowiedzialna',
colUpdated: 'Ostatnia ocena',
disclaimerLine:
'AI-Act-Kompass to ustrukturyzowane narzędzie pomocnicze oparte na rozporządzeniu (UE) 2024/1689 — nie stanowi porady prawnej. Pakiet treści v{version}.',
tasksTitle: 'Zadania i terminy',
tasksSub: 'Wszystkie obowiązki wszystkich systemów jako lista do odhaczenia — co jest zrobione, co jest teraz wymagalne i co nadchodzi.',
tasksProgress: 'Wykonano {done} z {total} zadań',
tasksDueNow: 'Wymagalne teraz',
tasksUpcoming: 'Nadchodzące',
tasksResolved: 'Zrobione',
tasksEmpty: 'Brak zadań — najpierw oceń system AI.',
tasksAllDone: 'Wszystko zrobione w tej grupie.',
tasksDue: 'Termin',
calExport: 'Dodaj do kalendarza (.ics)',
calHint: 'Eksportuje wszystkie otwarte terminy jako plik kalendarza z przypomnieniami (30 i 7 dni wcześniej) — do zaimportowania w Outlooku, kalendarzu Apple i Google, na telefonie i komputerze.',
navQuiz: 'Test kompetencji AI',
quizSub: 'Prosty test podstaw (12 pytań) z kompetencji w zakresie AI zgodnie z art. 4 — z drukowanym certyfikatem jako dowodem i lokalnym rejestrem szkoleń.',
quizName: 'Imię i nazwisko uczestnika/uczestniczki *',
quizNamePh: 'Imię i nazwisko',
quizSubmit: 'Oceń test',
quizAnswerAll: 'Proszę podać imię i nazwisko oraz odpowiedzieć na wszystkie pytania.',
quizPassed: 'Zaliczony',
quizFailed: 'Niezaliczony',
quizScoreLine: '{correct} z {total} pytań poprawnie ({pct} %) — próg zaliczenia {pass} %.',
quizWhy: 'Wyjaśnienie',
quizCert: 'Drukuj certyfikat / PDF',
quizRetry: 'Powtórz test',
quizLogTitle: 'Rejestr szkoleń (dowód z art. 4)',
quizLogHint: 'Każde podejście jest zapisywane lokalnie i służy jako dowód obowiązku kompetencji w zakresie AI (art. 4). Regularnie drukuj rejestr i dołączaj do dokumentacji szkoleniowej.',
quizLogEmpty: 'Brak podejść.',
quizLogPrint: 'Drukuj rejestr / PDF',
quizColScore: 'Wynik',
quizColStatus: 'Status',
quizDocsTitle: 'Drukuj materiały szkoleniowe',
quizPrintTest: 'Wersja papierowa testu',
quizPrintKey: 'Arkusz odpowiedzi',
quizPrintHandout: 'Materiał szkoleniowy (12 zasad)',
quizManualTitle: 'Dodaj uczestnika ręcznie (test papierowy)',
quizManualHint: 'Dla testów na papierze: wpisz uczestnika i wynik, a następnie załącz zeskanowany, oceniony arkusz — łańcuch dowodowy będzie kompletny.',
quizManualScore: 'Poprawne odpowiedzi (z 12)',
quizManualAdd: 'Dodaj do rejestru',
quizSourceApp: 'Aplikacja',
quizSourcePaper: 'Papier',
quizColSource: 'Źródło',
quizColEvidence: 'Dowód',
quizAttach: 'Załącz skan',
quizAttachView: 'Otwórz skan',
quizAttachTooBig: 'Plik za duży — użyj skanu poniżej 1 MB (np. skompresowany JPG/PDF).',
quizAttachDone: 'Skan zapisany i powiązany z rejestrem sumą kontrolną SHA-256.',
quizDeleteRecord: 'Czy na pewno usunąć wpis „{name}"? Załączone dowody zostaną utracone.',
wizardTitleNew: 'Oceń nowy system AI',
wizardTitleRe: 'Ponowna ocena: {name}',
wizardSub: 'Odpowiedz na pytania — klasa ryzyka zostanie ustalona automatycznie zgodnie z systematyką rozporządzenia w sprawie AI.',
stepBasics: 'Dane podstawowe',
stepDefinition: 'Definicja AI',
stepProhibited: 'Zakazy',
stepHighRisk: 'Wysokie ryzyko',
stepTransparency: 'Przejrzystość i GPAI',
stepResult: 'Wynik',
fieldName: 'Nazwa systemu *',
fieldNamePh: 'np. narzędzie do wstępnej selekcji kandydatów',
fieldPurpose: 'Przeznaczenie',
fieldPurposePh: 'Do czego system jest wykorzystywany?',
fieldVendor: 'Producent / dostawca',
fieldOwner: 'Osoba odpowiedzialna (wewnętrznie)',
fieldRole: 'Rola Twojego przedsiębiorstwa',
roleHint: 'Dostawca = rozwija/wprowadza system do obrotu pod własną nazwą. Podmiot stosujący = korzysta z systemu strony trzeciej (najczęstszy przypadek w MŚP).',
defTitle: 'Czy system spełnia definicję AI (art. 3 pkt 1)?',
defHint: 'System podlega rozporządzeniu w sprawie AI tylko wtedy, gdy spełnione są wszystkie kryteria.',
defWarn: 'Nie wszystkie kryteria są spełnione → system nie jest uznawany za system AI; rozporządzenie w sprawie AI nie ma zastosowania.',
prohTitle: 'Zakazane praktyki (art. 5)',
prohHint: 'Jeśli którykolwiek z tych punktów ma zastosowanie, korzystanie jest zakazane od 2 lutego 2025 r.',
hrTitle: 'Klasyfikacja wysokiego ryzyka (art. 6)',
annexILabel: 'System jest związanym z bezpieczeństwem elementem produktu podlegającego regulacjom (np. wyrobu medycznego, maszyny, dźwigu) lub sam jest takim produktem.',
annexIIITitle: 'Obszary zastosowania według załącznika III',
exceptionTitle: 'Możliwy wyjątek (art. 6 ust. 3)',
profilingLabel: 'System dokonuje profilowania osób fizycznych.',
profilingRef: 'Profilowanie wyklucza wyjątek — zawsze wysokie ryzyko.',
art63Label: 'System wykonuje jedynie wąskie zadanie proceduralne lub przygotowawcze albo tylko poprawia wynik zakończonej wcześniej czynności człowieka — bez istotnego ryzyka dla zdrowia, bezpieczeństwa lub praw podstawowych.',
art63Ref: 'Art. 6 ust. 3 — ocenę należy udokumentować (art. 6 ust. 4).',
trTitle: 'Obowiązki w zakresie przejrzystości (art. 50)',
gpaiTitle: 'AI ogólnego przeznaczenia (GPAI)',
gpaiLabel: 'Udostępniamy własny model GPAI (np. samodzielnie wytrenowany lub istotnie zmodyfikowany model bazowy).',
gpaiRef: 'Art. 51 i nast. — samo korzystanie np. z GPT/Claude przez API się nie liczy.',
resultTitle: 'Wynik:',
resultGpai: 'Dodatkowo obowiązują obowiązki dotyczące modeli GPAI (art. 53 i nast.).',
resultProhibited: 'Korzystanie z tego systemu jest zakazane na mocy art. 5 (kara do 35 mln EUR lub 7 % rocznego światowego obrotu). Zaprzestań korzystania i zasięgnij porady prawnej.',
btnCancel: 'Anuluj',
btnBack: 'Wstecz',
btnNext: 'Dalej',
btnSave: 'Zapisz',
detailBack: '← Powrót do pulpitu',
detailNoPurpose: 'Nie zarejestrowano przeznaczenia',
detailReasons: 'Uzasadnienie klasyfikacji',
detailReassess: 'Oceń ponownie',
detailDelete: 'Usuń system',
detailObligations: 'Obowiązki',
detailNational: 'w tym moduły krajowe: {codes}',
detailDocs: 'Generuj dokumenty',
docShow: 'pokaż',
docHide: 'ukryj',
docPrint: 'Drukuj / PDF',
docRisk: 'Raport ryzyka',
docPlan: 'Plan działań',
docAnnexIV: 'Dokumentacja wg załącznika IV',
docProcurement: 'Specyfikacja zakupu AI',
docConformity: 'Deklaracja zgodności UE',
confirmDeleteSystem: 'Czy na pewno usunąć „{name}”?',
systemNotFound: 'Nie znaleziono systemu.',
statusOpen: 'Otwarte',
statusInProgress: 'W realizacji',
statusDone: 'Zrobione',
statusNA: 'Nie dotyczy',
settingsTitle: 'Ustawienia',
settingsSub: 'Suwerenność danych: wszystko pozostaje lokalnie w tej przeglądarce — bez synchronizacji z chmurą, bez telemetrii.',
langTitle: 'Sprache / Language / Język',
langHint: 'Interfejs, treści regulacyjne i generowane dokumenty w pełni dostępne w językach: niemieckim, angielskim, francuskim, włoskim, hiszpańskim, polskim, czeskim, słowackim i rumuńskim. Kolejne języki UE pojawią się za pośrednictwem kanału treści.',
profileTitle: 'Profil firmy (nagłówek firmowy do raportów i wydruku PDF)',
profileHint: 'Te dane pojawiają się w nagłówku i stopce wszystkich generowanych i drukowanych dokumentów. Logo pozostaje zapisane lokalnie i nie opuszcza urządzenia.',
pfName: 'Nazwa firmy', pfStreet: 'Ulica i numer', pfZip: 'Kod pocztowy i miejscowość',
pfContact: 'Osoba kontaktowa', pfEmail: 'E-mail', pfPhone: 'Telefon', pfWeb: 'Strona internetowa',
logoNone: 'Nie zapisano logo.',
logoUpload: 'Prześlij logo',
logoRemove: 'Usuń logo',
logoTaken: 'Logo zastosowano.',
logoTooBig: 'Logo jest za duże — użyj pliku mniejszego niż 300 KB.',
logoNotImage: 'Wybierz plik graficzny (PNG, JPG lub SVG).',
countriesTitle: 'Moduły krajowe (dodatkowe wymogi krajowe)',
countriesHint: 'Aktywuj kraje UE, w których Twoje przedsiębiorstwo oferuje lub eksploatuje systemy AI. Krajowe obowiązki (nadzór, prawo pracy, przepisy szczególne) pojawią się wtedy w listach kontrolnych i dokumentach. Przy współpracy transgranicznej: aktywuj wszystkie zaangażowane kraje.',
authorityLabel: 'Nadzór',
packTitle: 'Regulacyjny pakiet treści',
packStand: 'Stan na',
packHint: 'Pakiet treści (zakazy, obszary załącznika III, obowiązki UE, moduły krajowe, terminy) jest zamodelowany jako wymienny pakiet danych. Aktualizacje pojawiają się wraz z nowymi wersjami aplikacji, a w przyszłości przez podpisany kanał aktualizacji.',
backupTitle: 'Kopia zapasowa',
backupExport: 'Eksportuj kopię zapasową (JSON)',
backupImport: 'Importuj kopię zapasową',
importOk: 'Import zakończony: {count} system(y/ów){profile}.',
importProfileSuffix: ' wraz z profilem firmy',
importFail: 'Import nie powiódł się: {error}',
deleteTitle: 'Usuń wszystkie dane',
deleteHint: 'Nieodwracalnie usuwa wszystkie zarejestrowane systemy AI oraz profil firmy z tej przeglądarki.',
deleteBtn: 'Usuń wszystko',
deleteConfirm: 'Czy na pewno nieodwracalnie usunąć wszystkie lokalne dane?',
deleteDone: 'Wszystkie dane zostały usunięte.',
legalGateTitle: 'Ważna informacja prawna',
legalGateBody1:
'AI-Act-Kompass to ustrukturyzowane narzędzie pomocnicze, które ma ułatwiać wdrożenie rozporządzenia (UE) 2024/1689 (rozporządzenie w sprawie AI) oraz właściwych przepisów krajowych.',
legalGateBody2:
'Ta aplikacja nie świadczy usług prawnych i nie stanowi porady prawnej, informacji prawnej ani prawnie wiążącego pouczenia. Wszystkie klasyfikacje, listy kontrolne i generowane dokumenty są niewiążącymi wstępnymi ocenami i projektami, bez gwarancji poprawności, kompletności ani aktualności.',
legalGateBody3:
'Wiążąca wykładnia rozporządzenia UE w sprawie AI należy wyłącznie do właściwych organów i sądów. To narzędzie nie zastępuje prawnej oceny Twojego indywidualnego przypadku — skorzystaj w tym celu z wykwalifikowanej pomocy prawnej (radca prawny/adwokat). Korzystanie odbywa się na własne ryzyko; odpowiedzialność za decyzje podjęte na podstawie tego narzędzia jest wyłączona w zakresie dozwolonym przez prawo.',
legalGateAccept: 'Rozumiem — używać jako narzędzia pomocniczego',
legalNoticeTitle: 'Informacja prawna (nie stanowi porady prawnej)',
resultDisclaimer:
'Ta klasyfikacja jest niewiążącą, zautomatyzowaną wstępną oceną opartą na Twoich odpowiedziach — nie stanowi porady prawnej. Przed daleko idącymi decyzjami zleć prawną weryfikację wyniku.',
templatesTitle: 'Szablony i formularze',
templatesSub: 'Ogólnofirmowe projekty do wdrożenia wewnętrznego i zewnętrznego — do druku z nagłówkiem firmowym. Formularze dotyczące konkretnego systemu (rada zakładowa, informacja dla pracowników, FRIA, zgłoszenie incydentu) znajdziesz w widoku danego systemu.',
templatesHint: 'Wszystkie szablony to projekty z polami do uzupełnienia — przed użyciem dostosuj je i zleć weryfikację prawną.',
tplPolicy: 'Wewnętrzna polityka AI',
tplPolicyDesc: 'Zasady korzystania z AI w przedsiębiorstwie: zatwierdzenia, zakazy, nadzór, przejrzystość, incydenty.',
tplTraining: 'Plan szkoleń z kompetencji w zakresie AI (art. 4)',
tplTrainingDesc: 'Matryca szkoleń i ciągła ewidencja — obowiązek od 02.02.2025.',
tplWorksAgreement: 'Porozumienie zakładowe w sprawie AI (ramowe)',
tplWorksAgreementDesc: 'Projekt wg prawa niemieckiego (§ 87 ust. 1 pkt 6, § 90 BetrVG): ograniczenie celu, brak zautomatyzowanych decyzji kadrowych, prawa rady zakładowej.',
docWorksCouncil: 'Informacja dla rady zakładowej (§ 90 BetrVG)',
docEmployeeInfo: 'Informacja dla pracowników o wykorzystaniu AI',
docFria: 'Szablon FRIA (art. 27)',
docIncident: 'Zgłoszenie incydentu (art. 73)',
tplReporting: 'Wewnętrzna polityka zgłaszania i eskalacji',
tplReportingDesc: 'Wewnętrzny obowiązek zgłaszania incydentów AI: kanały zgłoszeń, terminy 24h/48h, poziomy eskalacji, rejestr incydentów — przygotowuje zgłoszenie z art. 73.',
tplApproval: 'Wniosek o zatwierdzenie systemu AI',
tplApprovalDesc: 'Wewnętrzny formularz procesu zatwierdzania nowych narzędzi AI — przeciw „shadow AI”, z polem decyzji.',
tplAudit: 'Wewnętrzna lista kontrolna audytu zgodności AI',
tplAuditDesc: 'Okresowa samokontrola (inwentarz, szkolenia, logi, incydenty, dokumenty dostawców) z podpisem.',
};

View File

@ -0,0 +1,211 @@
import type { UIStrings } from './ui';
/** Rumänisches UI-Wörterbuch. */
export const RO: UIStrings = {
brandTag: 'Conformitate cu Regulamentul UE privind IA pentru IMM-uri · local-first',
navDashboard: 'Tablou de bord și inventar',
navTasks: 'Sarcini și termene',
navNew: 'Evaluează un sistem nou',
navTemplates: 'Modele și formulare',
navSettings: 'Setări și backup',
footPrivacy: 'Fără cloud. Fără telemetrie.',
footLocal: 'Toate datele rămân pe acest dispozitiv.',
footNoAdvice: 'Nu constituie consultanță juridică.',
dashTitle: 'Tablou de bord',
dashSub: 'Conformitatea cu Regulamentul UE privind IA dintr-o privire. Toate datele rămân local pe acest dispozitiv.',
statSystems: 'Sisteme de IA în inventar',
statHigh: 'Sisteme cu risc ridicat',
statProhibited: 'Practici interzise',
statOpen: 'Sarcini deschise',
deadlinesTitle: 'Termenele de aplicare ale Regulamentului privind IA',
inventoryTitle: 'Inventar IA',
inventoryPrint: 'Tipărește inventarul / PDF',
newSystem: '+ Evaluează un sistem',
emptyInventory:
'Niciun sistem de IA înregistrat încă. Începeți cu evaluarea primului dumneavoastră sistem — de ex. chatbotul, instrumentul de preselecție a candidaților sau un instrument de IA achiziționat.',
colSystem: 'Sistem',
colRole: 'Rol',
colRisk: 'Clasă de risc',
colOwner: 'Responsabil',
colUpdated: 'Ultima evaluare',
disclaimerLine:
'AI-Act-Kompass este un instrument de lucru structurat bazat pe Regulamentul (UE) 2024/1689 — nu constituie consultanță juridică. Pachet de conținut v{version}.',
tasksTitle: 'Sarcini și termene',
tasksSub: 'Toate obligațiile tuturor sistemelor sub forma unei liste de bifat — ce este finalizat, ce este scadent acum și ce urmează.',
tasksProgress: '{done} din {total} sarcini finalizate',
tasksDueNow: 'Scadente acum',
tasksUpcoming: 'Urmează',
tasksResolved: 'Finalizate',
tasksEmpty: 'Nicio sarcină — evaluați mai întâi un sistem de IA.',
tasksAllDone: 'Totul este finalizat în acest grup.',
tasksDue: 'Termen',
calExport: 'Adaugă în calendar (.ics)',
calHint: 'Exportă toate termenele deschise ca fișier de calendar cu mementouri (cu 30 și 7 zile înainte) — importabil în Outlook, Apple și Google Calendar, pe telefon și pe computer.',
navQuiz: 'Test de alfabetizare în IA',
quizSub: 'Test simplu de bază (12 întrebări) privind alfabetizarea în domeniul IA conform art. 4 — cu certificat imprimabil ca dovadă și registru local de formare.',
quizName: 'Numele participantului/participantei *',
quizNamePh: 'Prenume și nume',
quizSubmit: 'Evaluează testul',
quizAnswerAll: 'Vă rugăm să introduceți numele și să răspundeți la toate întrebările.',
quizPassed: 'Promovat',
quizFailed: 'Nepromovat',
quizScoreLine: '{correct} din {total} întrebări corecte ({pct} %) — prag de promovare {pass} %.',
quizWhy: 'Explicație',
quizCert: 'Tipărește certificatul / PDF',
quizRetry: 'Repetă testul',
quizLogTitle: 'Registrul de formare (dovadă art. 4)',
quizLogHint: 'Fiecare încercare este salvată local și servește drept dovadă a obligației de alfabetizare în IA (art. 4). Tipăriți regulat registrul și arhivați-l cu documentația de formare.',
quizLogEmpty: 'Nicio încercare până acum.',
quizLogPrint: 'Tipărește registrul / PDF',
quizColScore: 'Rezultat',
quizColStatus: 'Stare',
quizDocsTitle: 'Tipărește materialele de formare',
quizPrintTest: 'Versiunea pe hârtie a testului',
quizPrintKey: 'Foaia de răspunsuri',
quizPrintHandout: 'Material de formare (12 reguli)',
quizManualTitle: 'Adaugă participant manual (test pe hârtie)',
quizManualHint: 'Pentru testele pe hârtie: introduceți participantul și rezultatul, apoi atașați foaia corectată scanată — lanțul probatoriu este astfel complet.',
quizManualScore: 'Răspunsuri corecte (din 12)',
quizManualAdd: 'Adaugă în registru',
quizSourceApp: 'Aplicație',
quizSourcePaper: 'Hârtie',
quizColSource: 'Sursă',
quizColEvidence: 'Dovadă',
quizAttach: 'Atașează scanarea',
quizAttachView: 'Deschide scanarea',
quizAttachTooBig: 'Fișier prea mare — folosiți o scanare sub 1 MB (de ex. JPG/PDF comprimat).',
quizAttachDone: 'Scanare salvată și ancorată în registru cu sumă de control SHA-256.',
quizDeleteRecord: 'Chiar ștergeți intrarea „{name}"? Dovezile atașate se vor pierde.',
wizardTitleNew: 'Evaluează un sistem de IA nou',
wizardTitleRe: 'Reevaluare: {name}',
wizardSub: 'Răspundeți la întrebări — clasa de risc este determinată automat conform sistematicii Regulamentului privind IA.',
stepBasics: 'Date de bază',
stepDefinition: 'Definiția IA',
stepProhibited: 'Interdicții',
stepHighRisk: 'Risc ridicat',
stepTransparency: 'Transparență și GPAI',
stepResult: 'Rezultat',
fieldName: 'Numele sistemului *',
fieldNamePh: 'de ex. instrument de preselecție a candidaților',
fieldPurpose: 'Scopul preconizat',
fieldPurposePh: 'La ce este utilizat sistemul?',
fieldVendor: 'Producător / furnizor',
fieldOwner: 'Persoană responsabilă (internă)',
fieldRole: 'Rolul companiei dumneavoastră',
roleHint: 'Furnizor = dezvoltă/comercializează sistemul sub nume propriu. Implementator = utilizează un sistem al unui terț (cel mai frecvent caz pentru IMM-uri).',
defTitle: 'Îndeplinește sistemul definiția IA (art. 3 pct. 1)?',
defHint: 'Sistemul intră sub incidența Regulamentului privind IA numai dacă toate criteriile sunt îndeplinite.',
defWarn: 'Nu toate criteriile sunt îndeplinite → sistemul nu este considerat sistem de IA; Regulamentul privind IA nu se aplică.',
prohTitle: 'Practici interzise (art. 5)',
prohHint: 'Dacă se aplică oricare dintre aceste puncte, utilizarea este interzisă începând cu 2 februarie 2025.',
hrTitle: 'Clasificarea ca risc ridicat (art. 6)',
annexILabel: 'Sistemul este o componentă de siguranță a unui produs reglementat (de ex. dispozitiv medical, mașină industrială, ascensor) sau este el însuși un astfel de produs.',
annexIIITitle: 'Domenii de utilizare conform anexei III',
exceptionTitle: 'Excepție posibilă (art. 6 alin. 3)',
profilingLabel: 'Sistemul realizează crearea de profiluri ale persoanelor fizice.',
profilingRef: 'Crearea de profiluri exclude excepția — întotdeauna risc ridicat.',
art63Label: 'Sistemul îndeplinește doar o sarcină procedurală restrânsă sau pregătitoare, ori doar îmbunătățește rezultatul unei activități umane deja încheiate — fără risc semnificativ pentru sănătate, siguranță sau drepturile fundamentale.',
art63Ref: 'Art. 6 alin. 3 — evaluarea trebuie documentată (art. 6 alin. 4).',
trTitle: 'Obligații de transparență (art. 50)',
gpaiTitle: 'IA de uz general (GPAI)',
gpaiLabel: 'Punem la dispoziție propriul model GPAI (de ex. model de bază antrenat de noi sau modificat substanțial).',
gpaiRef: 'Art. 51 și urm. — simpla utilizare a GPT/Claude prin API, de exemplu, nu se ia în calcul.',
resultTitle: 'Rezultat:',
resultGpai: 'Se aplică suplimentar obligațiile privind modelele GPAI (art. 53 și urm.).',
resultProhibited: 'Utilizarea acestui sistem este interzisă conform art. 5 (amendă de până la 35 mil. EUR sau 7 % din cifra de afaceri anuală mondială). Încetați utilizarea și solicitați consultanță juridică.',
btnCancel: 'Anulează',
btnBack: 'Înapoi',
btnNext: 'Continuă',
btnSave: 'Salvează',
detailBack: '← Înapoi la tabloul de bord',
detailNoPurpose: 'Niciun scop preconizat înregistrat',
detailReasons: 'Motivarea clasificării',
detailReassess: 'Reevaluează',
detailDelete: 'Șterge sistemul',
detailObligations: 'Obligații',
detailNational: 'incl. module naționale: {codes}',
detailDocs: 'Generează documente',
docShow: 'afișează',
docHide: 'ascunde',
docPrint: 'Tipărire / PDF',
docRisk: 'Raport de risc',
docPlan: 'Plan de măsuri',
docAnnexIV: 'Documentație conform anexei IV',
docProcurement: 'Caiet de sarcini pentru achiziția de IA',
docConformity: 'Declarație UE de conformitate',
confirmDeleteSystem: 'Sigur ștergeți „{name}”?',
systemNotFound: 'Sistemul nu a fost găsit.',
statusOpen: 'Deschis',
statusInProgress: 'În implementare',
statusDone: 'Finalizat',
statusNA: 'Nu se aplică',
settingsTitle: 'Setări',
settingsSub: 'Suveranitatea datelor: totul rămâne local în acest browser — fără sincronizare în cloud, fără telemetrie.',
langTitle: 'Sprache / Language / Limbă',
langHint: 'Interfața, conținutul de reglementare și documentele generate sunt disponibile integral în germană, engleză, franceză, italiană, spaniolă, polonă, cehă, slovacă și română. Alte limbi ale UE vor urma prin fluxul de conținut.',
profileTitle: 'Profilul companiei (antet pentru rapoarte și tipărire PDF)',
profileHint: 'Aceste informații apar în antetul și subsolul tuturor documentelor generate și tipărite. Logoul rămâne stocat local și nu părăsește niciodată dispozitivul.',
pfName: 'Numele companiei', pfStreet: 'Strada și numărul', pfZip: 'Cod poștal și localitate',
pfContact: 'Persoană de contact', pfEmail: 'E-mail', pfPhone: 'Telefon', pfWeb: 'Site web',
logoNone: 'Niciun logo stocat.',
logoUpload: 'Încarcă logo',
logoRemove: 'Elimină logoul',
logoTaken: 'Logo aplicat.',
logoTooBig: 'Logoul este prea mare — folosiți un fișier sub 300 KB.',
logoNotImage: 'Alegeți un fișier imagine (PNG, JPG sau SVG).',
countriesTitle: 'Module naționale (cerințe naționale suplimentare)',
countriesHint: 'Activați țările UE în care compania dumneavoastră oferă sau operează sisteme de IA. Obligațiile naționale (supraveghere, dreptul muncii, legi speciale) apar apoi în listele de verificare și în documente. Pentru cooperare transfrontalieră: activați toate țările implicate.',
authorityLabel: 'Supraveghere',
packTitle: 'Pachet de conținut de reglementare',
packStand: 'Actualizat la',
packHint: 'Pachetul de conținut (interdicții, domenii din anexa III, obligații UE, module naționale, termene) este modelat ca pachet de date înlocuibil. Actualizările sosesc odată cu noile versiuni ale aplicației și, pe viitor, printr-un flux de actualizare semnat.',
backupTitle: 'Backup',
backupExport: 'Exportă backup (JSON)',
backupImport: 'Importă backup',
importOk: 'Import finalizat: {count} sistem(e){profile}.',
importProfileSuffix: ' incl. profilul companiei',
importFail: 'Importul a eșuat: {error}',
deleteTitle: 'Șterge toate datele',
deleteHint: 'Elimină ireversibil toate sistemele de IA înregistrate și profilul companiei din acest browser.',
deleteBtn: 'Șterge tot',
deleteConfirm: 'Sigur ștergeți ireversibil toate datele locale?',
deleteDone: 'Toate datele au fost șterse.',
legalGateTitle: 'Aviz juridic important',
legalGateBody1:
'AI-Act-Kompass este un instrument de lucru structurat menit să faciliteze punerea în aplicare a Regulamentului (UE) 2024/1689 (Regulamentul privind IA) și a dispozițiilor naționale relevante.',
legalGateBody2:
'Această aplicație nu prestează servicii juridice și nu constituie consultanță juridică, informare juridică sau instrucțiune cu caracter juridic obligatoriu. Toate clasificările, listele de verificare și documentele generate sunt evaluări preliminare neobligatorii și proiecte, fără garanție privind corectitudinea, caracterul complet sau actualitatea.',
legalGateBody3:
'Interpretarea obligatorie a Regulamentului UE privind IA revine exclusiv autorităților și instanțelor competente. Acest instrument nu înlocuiește evaluarea juridică a cazului dumneavoastră concret — apelați în acest scop la consultanță juridică calificată (avocat). Utilizarea se face pe propriul risc; răspunderea pentru deciziile luate pe baza acestui instrument este exclusă în măsura permisă de lege.',
legalGateAccept: 'Am înțeles — folosesc ca instrument de lucru',
legalNoticeTitle: 'Aviz juridic (nu constituie consultanță juridică)',
resultDisclaimer:
'Această clasificare este o evaluare preliminară automatizată, fără caracter obligatoriu, bazată pe răspunsurile dumneavoastră — nu constituie consultanță juridică. Solicitați o verificare juridică a rezultatului înainte de decizii cu consecințe majore.',
templatesTitle: 'Modele și formulare',
templatesSub: 'Proiecte la nivel de companie pentru implementarea internă și externă — tipăribile cu antetul companiei. Formularele specifice unui sistem (consiliul de întreprindere, informarea angajaților, FRIA, raportarea incidentelor) se găsesc în vizualizarea sistemului respectiv.',
templatesHint: 'Toate modelele sunt proiecte cu câmpuri de completat — adaptați-le și solicitați verificarea juridică înainte de utilizare.',
tplPolicy: 'Politică internă privind IA',
tplPolicyDesc: 'Reguli de utilizare a IA în companie: aprobări, interdicții, supraveghere, transparență, incidente.',
tplTraining: 'Plan de instruire pentru alfabetizarea în domeniul IA (art. 4)',
tplTrainingDesc: 'Matrice de instruire și evidență continuă — obligatoriu din 02.02.2025.',
tplWorksAgreement: 'Acord de întreprindere privind IA (cadru)',
tplWorksAgreementDesc: 'Proiect conform dreptului german (§ 87 alin. 1 pct. 6, § 90 BetrVG): limitarea scopului, fără decizii de personal automatizate, drepturile consiliului de întreprindere.',
docWorksCouncil: 'Informarea consiliului de întreprindere (§ 90 BetrVG)',
docEmployeeInfo: 'Informarea angajaților privind utilizarea IA',
docFria: 'Model FRIA (art. 27)',
docIncident: 'Raportare incident (art. 73)',
tplReporting: 'Politică internă de raportare și escaladare',
tplReportingDesc: 'Obligație internă de raportare a incidentelor de IA: canale de raportare, termene de 24h/48h, niveluri de escaladare, registru de incidente — pregătește raportarea conform art. 73.',
tplApproval: 'Cerere de aprobare a unui sistem de IA',
tplApprovalDesc: 'Formular intern pentru procesul de aprobare a noilor instrumente de IA — împotriva IA „din umbră”, cu secțiune de decizie.',
tplAudit: 'Listă internă de verificare pentru auditul conformității IA',
tplAuditDesc: 'Autoverificare periodică (inventar, instruiri, jurnale, incidente, documente ale furnizorilor) cu semnătură.',
};

View File

@ -0,0 +1,211 @@
import type { UIStrings } from './ui';
/** Slowakisches UI-Wörterbuch. */
export const SK: UIStrings = {
brandTag: 'Súlad s aktom EÚ o umelej inteligencii pre MSP · local-first',
navDashboard: 'Prehľad a inventár',
navTasks: 'Úlohy a lehoty',
navNew: 'Posúdiť nový systém',
navTemplates: 'Šablóny a formuláre',
navSettings: 'Nastavenia a záloha',
footPrivacy: 'Žiadny cloud. Žiadna telemetria.',
footLocal: 'Všetky údaje zostávajú na tomto zariadení.',
footNoAdvice: 'Nejde o právne poradenstvo.',
dashTitle: 'Prehľad',
dashSub: 'Súlad s aktom EÚ o umelej inteligencii na prvý pohľad. Všetky údaje zostávajú lokálne na tomto zariadení.',
statSystems: 'Systémy AI v inventári',
statHigh: 'Vysokorizikové systémy',
statProhibited: 'Zakázané praktiky',
statOpen: 'Otvorené úlohy',
deadlinesTitle: 'Lehoty uplatňovania aktu o umelej inteligencii',
inventoryTitle: 'Inventár AI',
inventoryPrint: 'Vytlačiť inventár / PDF',
newSystem: '+ Posúdiť systém',
emptyInventory:
'Zatiaľ nie sú evidované žiadne systémy AI. Začnite posúdením svojho prvého systému — napr. chatbota, nástroja na predvýber uchádzačov alebo zakúpeného nástroja AI.',
colSystem: 'Systém',
colRole: 'Rola',
colRisk: 'Riziková trieda',
colOwner: 'Zodpovedná osoba',
colUpdated: 'Naposledy posúdené',
disclaimerLine:
'AI-Act-Kompass je štruktúrovaná pracovná pomôcka založená na nariadení (EÚ) 2024/1689 — nejde o právne poradenstvo. Balík obsahu v{version}.',
tasksTitle: 'Úlohy a lehoty',
tasksSub: 'Všetky povinnosti všetkých systémov ako odškrtávací zoznam — čo je hotové, čo je splatné teraz a čo vás čaká.',
tasksProgress: 'Hotových {done} z {total} úloh',
tasksDueNow: 'Splatné teraz',
tasksUpcoming: 'Čaká vás',
tasksResolved: 'Hotové',
tasksEmpty: 'Žiadne úlohy — najprv posúďte systém AI.',
tasksAllDone: 'V tejto skupine je všetko hotové.',
tasksDue: 'Lehota',
calExport: 'Pridať do kalendára (.ics)',
calHint: 'Exportuje všetky otvorené lehoty ako súbor kalendára s pripomienkami (30 a 7 dní vopred) — možno importovať do Outlooku, kalendára Apple aj Google, v telefóne aj počítači.',
navQuiz: 'Test gramotnosti v oblasti AI',
quizSub: 'Jednoduchý test základov (12 otázok) gramotnosti v oblasti AI podľa čl. 4 — s tlačiteľným certifikátom ako dokladom a lokálnym registrom školení.',
quizName: 'Meno účastníka/účastníčky *',
quizNamePh: 'Meno a priezvisko',
quizSubmit: 'Vyhodnotiť test',
quizAnswerAll: 'Zadajte, prosím, meno a odpovedzte na všetky otázky.',
quizPassed: 'Úspešne absolvovaný',
quizFailed: 'Neabsolvovaný',
quizScoreLine: '{correct} z {total} otázok správne ({pct} %) — hranica úspešnosti {pass} %.',
quizWhy: 'Vysvetlenie',
quizCert: 'Vytlačiť certifikát / PDF',
quizRetry: 'Zopakovať test',
quizLogTitle: 'Register školení (doklad podľa čl. 4)',
quizLogHint: 'Každý pokus sa ukladá lokálne a slúži ako doklad povinnosti gramotnosti v oblasti AI (čl. 4). Register pravidelne tlačte a zakladajte do dokumentácie školení.',
quizLogEmpty: 'Zatiaľ žiadne pokusy.',
quizLogPrint: 'Vytlačiť register / PDF',
quizColScore: 'Výsledok',
quizColStatus: 'Stav',
quizDocsTitle: 'Tlač školiacich materiálov',
quizPrintTest: 'Papierová verzia testu',
quizPrintKey: 'Hárok s riešeniami',
quizPrintHandout: 'Školiaci materiál (12 pravidiel)',
quizManualTitle: 'Pridať účastníka ručne (papierový test)',
quizManualHint: 'Pre testy na papieri: zadajte účastníka a výsledok, potom priložte naskenovaný vyhodnotený hárok — dôkazová reťaz je tak úplná.',
quizManualScore: 'Správne odpovede (z 12)',
quizManualAdd: 'Pridať do registra',
quizSourceApp: 'Aplikácia',
quizSourcePaper: 'Papier',
quizColSource: 'Zdroj',
quizColEvidence: 'Doklad',
quizAttach: 'Priložiť sken',
quizAttachView: 'Otvoriť sken',
quizAttachTooBig: 'Súbor je príliš veľký — použite sken do 1 MB (napr. komprimovaný JPG/PDF).',
quizAttachDone: 'Sken uložený a ukotvený v registri kontrolným súčtom SHA-256.',
quizDeleteRecord: 'Naozaj vymazať záznam „{name}"? Priložené doklady sa stratia.',
wizardTitleNew: 'Posúdiť nový systém AI',
wizardTitleRe: 'Opätovné posúdenie: {name}',
wizardSub: 'Odpovedzte na otázky — riziková trieda sa určí automaticky podľa systematiky aktu o umelej inteligencii.',
stepBasics: 'Základné údaje',
stepDefinition: 'Definícia AI',
stepProhibited: 'Zákazy',
stepHighRisk: 'Vysoké riziko',
stepTransparency: 'Transparentnosť a GPAI',
stepResult: 'Výsledok',
fieldName: 'Názov systému *',
fieldNamePh: 'napr. nástroj na predvýber uchádzačov',
fieldPurpose: 'Zamýšľaný účel',
fieldPurposePh: 'Na čo sa systém používa?',
fieldVendor: 'Výrobca / poskytovateľ',
fieldOwner: 'Zodpovedná osoba (interná)',
fieldRole: 'Rola vašej spoločnosti',
roleHint: 'Poskytovateľ = vyvíja/uvádza systém na trh pod vlastným menom. Nasadzujúci subjekt = používa systém tretej strany (najčastejší prípad MSP).',
defTitle: 'Spĺňa systém definíciu AI (čl. 3 bod 1)?',
defHint: 'Systém spadá pod akt o umelej inteligencii iba vtedy, ak sú splnené všetky kritériá.',
defWarn: 'Nie sú splnené všetky kritériá → systém sa nepovažuje za systém AI; akt o umelej inteligencii sa neuplatňuje.',
prohTitle: 'Zakázané praktiky (čl. 5)',
prohHint: 'Ak platí niektorý z týchto bodov, používanie je od 2. februára 2025 zakázané.',
hrTitle: 'Klasifikácia vysokého rizika (čl. 6)',
annexILabel: 'Systém je bezpečnostným komponentom regulovaného výrobku (napr. zdravotníckej pomôcky, stroja, výťahu), alebo je sám takýmto výrobkom.',
annexIIITitle: 'Oblasti použitia podľa prílohy III',
exceptionTitle: 'Možná výnimka (čl. 6 ods. 3)',
profilingLabel: 'Systém vykonáva profilovanie fyzických osôb.',
profilingRef: 'Profilovanie výnimku vylučuje — vždy vysoké riziko.',
art63Label: 'Systém plní iba úzko vymedzenú procesnú alebo prípravnú úlohu, alebo iba zlepšuje výsledok už ukončenej ľudskej činnosti — bez významného rizika pre zdravie, bezpečnosť alebo základné práva.',
art63Ref: 'Čl. 6 ods. 3 — posúdenie sa musí zdokumentovať (čl. 6 ods. 4).',
trTitle: 'Povinnosti transparentnosti (čl. 50)',
gpaiTitle: 'AI na všeobecné účely (GPAI)',
gpaiLabel: 'Poskytujeme vlastný model GPAI (napr. samostatne natrénovaný alebo podstatne upravený základný model).',
gpaiRef: 'Čl. 51 a nasl. — samotné používanie napr. GPT/Claude cez API sa nepočíta.',
resultTitle: 'Výsledok:',
resultGpai: 'Navyše platia povinnosti pre modely GPAI (čl. 53 a nasl.).',
resultProhibited: 'Používanie tohto systému je podľa čl. 5 zakázané (pokuta do 35 mil. EUR alebo 7 % celosvetového ročného obratu). Ukončite používanie a vyhľadajte právnu radu.',
btnCancel: 'Zrušiť',
btnBack: 'Späť',
btnNext: 'Ďalej',
btnSave: 'Uložiť',
detailBack: '← Späť na prehľad',
detailNoPurpose: 'Zamýšľaný účel nebol zaznamenaný',
detailReasons: 'Odôvodnenie klasifikácie',
detailReassess: 'Posúdiť znova',
detailDelete: 'Vymazať systém',
detailObligations: 'Povinnosti',
detailNational: 'vrát. národných modulov: {codes}',
detailDocs: 'Generovať dokumenty',
docShow: 'zobraziť',
docHide: 'skryť',
docPrint: 'Tlač / PDF',
docRisk: 'Správa o riziku',
docPlan: 'Plán opatrení',
docAnnexIV: 'Dokumentácia podľa prílohy IV',
docProcurement: 'Špecifikácia obstarávania AI',
docConformity: 'EÚ vyhlásenie o zhode',
confirmDeleteSystem: 'Naozaj vymazať „{name}“?',
systemNotFound: 'Systém sa nenašiel.',
statusOpen: 'Otvorené',
statusInProgress: 'V realizácii',
statusDone: 'Hotové',
statusNA: 'Neuplatňuje sa',
settingsTitle: 'Nastavenia',
settingsSub: 'Suverenita údajov: všetko zostáva lokálne v tomto prehliadači — žiadna synchronizácia s cloudom, žiadna telemetria.',
langTitle: 'Sprache / Language / Jazyk',
langHint: 'Rozhranie, regulačný obsah a generované dokumenty sú plne dostupné v nemčine, angličtine, francúzštine, taliančine, španielčine, poľštine, češtine, slovenčine a rumunčine. Ďalšie jazyky EÚ budú nasledovať prostredníctvom kanála obsahu.',
profileTitle: 'Firemný profil (hlavička pre správy a tlač PDF)',
profileHint: 'Tieto údaje sa zobrazujú v hlavičke a päte všetkých generovaných a tlačených dokumentov. Logo zostáva uložené lokálne a nikdy neopustí zariadenie.',
pfName: 'Názov spoločnosti', pfStreet: 'Ulica a číslo', pfZip: 'PSČ a obec',
pfContact: 'Kontaktná osoba', pfEmail: 'E-mail', pfPhone: 'Telefón', pfWeb: 'Web',
logoNone: 'Nie je uložené žiadne logo.',
logoUpload: 'Nahrať logo',
logoRemove: 'Odstrániť logo',
logoTaken: 'Logo bolo použité.',
logoTooBig: 'Logo je príliš veľké — použite súbor menší ako 300 KB.',
logoNotImage: 'Vyberte prosím obrazový súbor (PNG, JPG alebo SVG).',
countriesTitle: 'Národné moduly (dodatočné vnútroštátne požiadavky)',
countriesHint: 'Aktivujte krajiny EÚ, v ktorých vaša spoločnosť ponúka alebo prevádzkuje systémy AI. Národné povinnosti (dozor, pracovné právo, osobitné zákony) sa potom objavia v kontrolných zoznamoch a dokumentoch. Pri cezhraničnej spolupráci: aktivujte všetky zúčastnené krajiny.',
authorityLabel: 'Dozor',
packTitle: 'Regulačný balík obsahu',
packStand: 'Stav k',
packHint: 'Balík obsahu (zákazy, oblasti prílohy III, povinnosti EÚ, národné moduly, lehoty) je modelovaný ako vymeniteľný dátový balík. Aktualizácie prichádzajú s novými verziami aplikácie a v budúcnosti cez podpísaný aktualizačný kanál.',
backupTitle: 'Zálohovanie',
backupExport: 'Exportovať zálohu (JSON)',
backupImport: 'Importovať zálohu',
importOk: 'Import dokončený: {count} systém(y/ov){profile}.',
importProfileSuffix: ' vrát. firemného profilu',
importFail: 'Import zlyhal: {error}',
deleteTitle: 'Vymazať všetky údaje',
deleteHint: 'Nenávratne odstráni všetky evidované systémy AI a firemný profil z tohto prehliadača.',
deleteBtn: 'Vymazať všetko',
deleteConfirm: 'Naozaj nenávratne vymazať všetky lokálne údaje?',
deleteDone: 'Všetky údaje boli vymazané.',
legalGateTitle: 'Dôležité právne upozornenie',
legalGateBody1:
'AI-Act-Kompass je štruktúrovaná pracovná pomôcka, ktorá má uľahčiť vykonávanie nariadenia (EÚ) 2024/1689 (akt o umelej inteligencii) a príslušných vnútroštátnych predpisov.',
legalGateBody2:
'Táto aplikácia neposkytuje právne služby a nepredstavuje právne poradenstvo, právnu informáciu ani právne záväzné poučenie. Všetky klasifikácie, kontrolné zoznamy a generované dokumenty sú nezáväzné predbežné posúdenia a návrhy bez záruky správnosti, úplnosti alebo aktuálnosti.',
legalGateBody3:
'Záväzný výklad aktu EÚ o umelej inteligencii prislúcha výlučne príslušným orgánom a súdom. Tento nástroj nenahrádza právne posúdenie vášho konkrétneho prípadu — obráťte sa na kvalifikovanú právnu pomoc (advokátku/advokáta). Používanie je na vlastné riziko; zodpovednosť za rozhodnutia prijaté na základe tohto nástroja je vylúčená v rozsahu povolenom zákonom.',
legalGateAccept: 'Rozumiem — používať ako pracovnú pomôcku',
legalNoticeTitle: 'Právne upozornenie (nejde o právne poradenstvo)',
resultDisclaimer:
'Táto klasifikácia je nezáväzné, automatizované predbežné posúdenie na základe vašich odpovedí — nejde o právne poradenstvo. Pred ďalekosiahlymi rozhodnutiami si nechajte výsledok právne overiť.',
templatesTitle: 'Šablóny a formuláre',
templatesSub: 'Celofiremné návrhy pre internú a externú implementáciu — tlačiteľné s firemnou hlavičkou. Formuláre viazané na konkrétny systém (zamestnanecká rada, informácia pre zamestnancov, FRIA, hlásenie incidentu) nájdete v zobrazení daného systému.',
templatesHint: 'Všetky šablóny sú návrhy so zástupnými poľami — pred použitím ich upravte a nechajte právne overiť.',
tplPolicy: 'Interná smernica pre AI',
tplPolicyDesc: 'Pravidlá používania AI v spoločnosti: schvaľovanie, zákazy, dohľad, transparentnosť, incidenty.',
tplTraining: 'Plán školení gramotnosti v oblasti AI (čl. 4)',
tplTrainingDesc: 'Matica školení a priebežná evidencia — povinnosť od 2. 2. 2025.',
tplWorksAgreement: 'Podniková dohoda o AI (rámcová)',
tplWorksAgreementDesc: 'Návrh podľa nemeckého práva (§ 87 ods. 1 bod 6, § 90 BetrVG): účelové obmedzenie, žiadne automatizované personálne rozhodnutia, práva zamestnaneckej rady.',
docWorksCouncil: 'Informácia pre zamestnaneckú radu (§ 90 BetrVG)',
docEmployeeInfo: 'Informácia pre zamestnancov o používaní AI',
docFria: 'Šablóna FRIA (čl. 27)',
docIncident: 'Hlásenie incidentu (čl. 73)',
tplReporting: 'Interná smernica pre hlásenie a eskaláciu',
tplReportingDesc: 'Interná ohlasovacia povinnosť pre incidenty AI: kanály hlásenia, lehoty 24 h/48 h, úrovne eskalácie, register incidentov — pripravuje hlásenie podľa čl. 73.',
tplApproval: 'Žiadosť o schválenie systému AI',
tplApprovalDesc: 'Interný formulár schvaľovacieho procesu nových nástrojov AI — proti tieňovej AI, s poľom pre rozhodnutie.',
tplAudit: 'Interný auditný kontrolný zoznam súladu AI',
tplAuditDesc: 'Pravidelná samokontrola (inventár, školenia, protokoly, incidenty, podklady poskytovateľov) s podpisom.',
};

View File

@ -0,0 +1,443 @@
import type { Locale } from './types';
/* eslint-disable max-lines */
const DE = {
brandTag: 'EU AI Act Compliance für KMU · local-first',
navDashboard: 'Dashboard & Inventar',
navTasks: 'Aufgaben & Fristen',
navNew: 'Neues System bewerten',
navSettings: 'Einstellungen & Backup',
footPrivacy: 'Keine Cloud. Keine Telemetrie.',
footLocal: 'Alle Daten bleiben auf diesem Gerät.',
footNoAdvice: 'Keine Rechtsberatung.',
dashTitle: 'Dashboard',
dashSub: 'EU-AI-Act-Compliance auf einen Blick. Alle Daten bleiben lokal auf diesem Gerät.',
statSystems: 'KI-Systeme im Inventar',
statHigh: 'Hochrisiko-Systeme',
statProhibited: 'Verbotene Praktiken',
statOpen: 'Offene Aufgaben',
deadlinesTitle: 'Geltungsfristen des AI Act',
inventoryTitle: 'KI-Inventar',
inventoryPrint: 'Inventar drucken / PDF',
newSystem: '+ System bewerten',
emptyInventory:
'Noch keine KI-Systeme erfasst. Starten Sie mit der Bewertung Ihres ersten Systems — z. B. Ihres Chatbots, Ihres Bewerber-Screenings oder eines eingekauften KI-Tools.',
colSystem: 'System',
colRole: 'Rolle',
colRisk: 'Risikoklasse',
colOwner: 'Verantwortlich',
colUpdated: 'Zuletzt bewertet',
disclaimerLine:
'Der AI-Act-Kompass ist eine strukturierte Arbeitshilfe auf Basis der Verordnung (EU) 2024/1689 — keine Rechtsberatung. Content-Pack v{version}.',
tasksTitle: 'Aufgaben & Fristen',
tasksSub: 'Alle Pflichten aller Systeme als abhakbare Liste — was erledigt ist, was jetzt fällig ist und was noch kommt.',
tasksProgress: '{done} von {total} Aufgaben erledigt',
tasksDueNow: 'Jetzt fällig',
tasksUpcoming: 'Kommt auf Sie zu',
tasksResolved: 'Erledigt',
tasksEmpty: 'Keine Aufgaben — bewerten Sie zuerst ein KI-System.',
tasksAllDone: 'Alles erledigt in dieser Gruppe.',
tasksDue: 'Frist',
calExport: 'In Kalender übernehmen (.ics)',
calHint: 'Exportiert alle offenen Fristen als Kalenderdatei mit Erinnerungen (30 und 7 Tage vorher) — importierbar in Outlook, Apple- und Google-Kalender auf Handy und Rechner.',
navQuiz: 'KI-Kompetenztest',
quizSub: 'Einfacher Grundlagentest (12 Fragen) zur KI-Kompetenz nach Art. 4 — mit druckbarem Zertifikat als Nachweis und lokalem Schulungsregister.',
quizName: 'Name der Teilnehmerin / des Teilnehmers *',
quizNamePh: 'Vor- und Nachname',
quizSubmit: 'Test auswerten',
quizAnswerAll: 'Bitte Namen eintragen und alle Fragen beantworten.',
quizPassed: 'Bestanden',
quizFailed: 'Nicht bestanden',
quizScoreLine: '{correct} von {total} Fragen richtig ({pct} %) — Bestehensgrenze {pass} %.',
quizWhy: 'Erklärung',
quizCert: 'Zertifikat drucken / PDF',
quizRetry: 'Test wiederholen',
quizLogTitle: 'Schulungsregister (Art.-4-Nachweis)',
quizLogHint: 'Jeder Testdurchlauf wird lokal gespeichert und dient als Nachweis der KI-Kompetenzpflicht (Art. 4). Register regelmäßig drucken und zur Schulungsdokumentation nehmen.',
quizLogEmpty: 'Noch keine Testdurchläufe.',
quizLogPrint: 'Register drucken / PDF',
quizColScore: 'Ergebnis',
quizColStatus: 'Status',
quizDocsTitle: 'Schulungsunterlagen drucken',
quizPrintTest: 'Papierfassung des Tests',
quizPrintKey: 'Lösungsbogen',
quizPrintHandout: 'Schulungshandout (12 Regeln)',
quizManualTitle: 'Teilnehmer manuell erfassen (Papier-Test)',
quizManualHint: 'Für auf Papier durchgeführte Tests: Teilnehmer/in und Ergebnis eintragen, danach den ausgewerteten Bogen als Scan anhängen — so ist die Nachweiskette vollständig.',
quizManualScore: 'Richtige Antworten (von 12)',
quizManualAdd: 'In Register aufnehmen',
quizSourceApp: 'App',
quizSourcePaper: 'Papier',
quizColSource: 'Quelle',
quizColEvidence: 'Beleg',
quizAttach: 'Scan anhängen',
quizAttachView: 'Scan öffnen',
quizAttachTooBig: 'Datei zu groß — bitte Scan unter 1 MB verwenden (z. B. als komprimiertes JPG/PDF).',
quizAttachDone: 'Scan gespeichert und mit SHA-256-Prüfsumme im Register verankert.',
quizDeleteRecord: 'Eintrag „{name}" wirklich löschen? Belege gehen mit verloren.',
wizardTitleNew: 'Neues KI-System bewerten',
wizardTitleRe: 'Neubewertung: {name}',
wizardSub: 'Beantworten Sie die Fragen — die Risikoklasse wird automatisch nach der Systematik des AI Act ermittelt.',
stepBasics: 'Grunddaten',
stepDefinition: 'KI-Definition',
stepProhibited: 'Verbote',
stepHighRisk: 'Hochrisiko',
stepTransparency: 'Transparenz & GPAI',
stepResult: 'Ergebnis',
fieldName: 'Name des Systems *',
fieldNamePh: 'z. B. Bewerber-Screening-Tool',
fieldPurpose: 'Zweckbestimmung',
fieldPurposePh: 'Wofür wird das System eingesetzt?',
fieldVendor: 'Hersteller / Anbieter',
fieldOwner: 'Verantwortliche Person (intern)',
fieldRole: 'Rolle Ihres Unternehmens',
roleHint: 'Anbieter = entwickelt/vertreibt das System unter eigenem Namen. Betreiber = setzt ein fremdes System ein (häufigster KMU-Fall).',
defTitle: 'Erfüllt das System die KI-Definition (Art. 3 Nr. 1)?',
defHint: 'Nur wenn alle Kriterien zutreffen, fällt das System unter den AI Act.',
defWarn: 'Nicht alle Kriterien erfüllt → das System gilt nicht als KI-System, der AI Act ist nicht anwendbar.',
prohTitle: 'Verbotene Praktiken (Art. 5)',
prohHint: 'Trifft einer dieser Punkte zu, ist der Einsatz seit 2. Februar 2025 verboten.',
hrTitle: 'Hochrisiko-Einstufung (Art. 6)',
annexILabel: 'Das System ist Sicherheitsbauteil eines regulierten Produkts (z. B. Medizinprodukt, Maschine, Aufzug) oder selbst ein solches Produkt.',
annexIIITitle: 'Einsatzbereiche nach Annex III',
exceptionTitle: 'Mögliche Ausnahme (Art. 6 Abs. 3)',
profilingLabel: 'Das System führt Profiling natürlicher Personen durch.',
profilingRef: 'Profiling schließt die Ausnahme aus — immer Hochrisiko.',
art63Label: 'Das System erfüllt nur eine eng begrenzte verfahrenstechnische oder vorbereitende Aufgabe bzw. verbessert lediglich das Ergebnis einer zuvor abgeschlossenen menschlichen Tätigkeit — ohne wesentliches Risiko für Gesundheit, Sicherheit oder Grundrechte.',
art63Ref: 'Art. 6 Abs. 3 — die Einschätzung muss dokumentiert werden (Art. 6 Abs. 4).',
trTitle: 'Transparenzpflichten (Art. 50)',
gpaiTitle: 'General-Purpose AI',
gpaiLabel: 'Wir stellen ein eigenes GPAI-Modell bereit (z. B. selbst trainiertes oder wesentlich verändertes Basismodell).',
gpaiRef: 'Art. 51 ff. — die bloße Nutzung von z. B. GPT/Claude über API zählt nicht.',
resultTitle: 'Ergebnis:',
resultGpai: 'Zusätzlich gelten GPAI-Modellpflichten (Art. 53 ff.).',
resultProhibited: 'Der Einsatz dieses Systems ist nach Art. 5 verboten (Bußgeld bis 35 Mio. € oder 7 % des weltweiten Jahresumsatzes). Einsatz einstellen und rechtlichen Rat einholen.',
btnCancel: 'Abbrechen',
btnBack: 'Zurück',
btnNext: 'Weiter',
btnSave: 'Speichern',
detailBack: '← Zurück zum Dashboard',
detailNoPurpose: 'Keine Zweckbestimmung erfasst',
detailReasons: 'Begründung der Einstufung',
detailReassess: 'Neu bewerten',
detailDelete: 'System löschen',
detailObligations: 'Pflichten',
detailNational: 'inkl. Länder-Module: {codes}',
detailDocs: 'Dokumente generieren',
docShow: 'ansehen',
docHide: 'ausblenden',
docPrint: 'Drucken / PDF',
docRisk: 'Risikobericht',
docPlan: 'Maßnahmenplan',
docAnnexIV: 'Annex-IV-Dokumentation',
docProcurement: 'Lastenheft KI-Beschaffung',
docConformity: 'EU-Konformitätserklärung',
confirmDeleteSystem: '„{name}" wirklich löschen?',
systemNotFound: 'System nicht gefunden.',
statusOpen: 'Offen',
statusInProgress: 'In Umsetzung',
statusDone: 'Erledigt',
statusNA: 'Nicht anwendbar',
settingsTitle: 'Einstellungen',
settingsSub: 'Datenhoheit: Alles liegt lokal in diesem Browser — kein Cloud-Sync, keine Telemetrie.',
langTitle: 'Sprache / Language',
langHint: 'Oberfläche, regulatorische Inhalte und generierte Dokumente vollständig in 9 europäischen Sprachen (DE, EN, FR, IT, ES, PL, CS, SK, RO). Weitere EU-Sprachen folgen über den Content-Feed.',
profileTitle: 'Firmenprofil (Briefkopf für Berichte & PDF-Druck)',
profileHint: 'Diese Angaben erscheinen im Kopf und in der Fußzeile aller generierten und gedruckten Dokumente. Das Logo bleibt lokal gespeichert und verlässt das Gerät nicht.',
pfName: 'Firmenname', pfStreet: 'Straße & Hausnummer', pfZip: 'PLZ & Ort',
pfContact: 'Ansprechpartner', pfEmail: 'E-Mail', pfPhone: 'Telefon', pfWeb: 'Website',
logoNone: 'Kein Logo hinterlegt.',
logoUpload: 'Logo hochladen',
logoRemove: 'Logo entfernen',
logoTaken: 'Logo übernommen.',
logoTooBig: 'Logo zu groß — bitte eine Datei unter 300 KB verwenden.',
logoNotImage: 'Bitte eine Bilddatei wählen (PNG, JPG oder SVG).',
countriesTitle: 'Länder-Module (nationale Zusatzanforderungen)',
countriesHint: 'Aktivieren Sie die EU-Länder, in denen Ihr Unternehmen KI-Systeme anbietet oder betreibt. Die nationalen Pflichten (Aufsicht, Arbeitsrecht, Sondergesetze) erscheinen dann in Checklisten und Dokumenten. Bei grenzüberschreitender Zusammenarbeit: alle beteiligten Länder aktivieren.',
authorityLabel: 'Aufsicht',
packTitle: 'Regulatorischer Content-Pack',
packStand: 'Stand',
packHint: 'Der Content-Pack (Verbote, Annex-III-Bereiche, EU-Pflichten, Länder-Module, Fristen) ist als austauschbares Datenpaket modelliert. Updates erscheinen mit neuen App-Versionen bzw. künftig über einen signierten Update-Feed.',
backupTitle: 'Datensicherung',
backupExport: 'Backup exportieren (JSON)',
backupImport: 'Backup importieren',
importOk: 'Import abgeschlossen: {count} System(e){profile}.',
importProfileSuffix: ' inkl. Firmenprofil',
importFail: 'Import fehlgeschlagen: {error}',
deleteTitle: 'Alle Daten löschen',
deleteHint: 'Entfernt alle erfassten KI-Systeme und das Firmenprofil unwiderruflich aus diesem Browser.',
deleteBtn: 'Alles löschen',
deleteConfirm: 'Wirklich alle lokalen Daten unwiderruflich löschen?',
deleteDone: 'Alle Daten gelöscht.',
legalGateTitle: 'Wichtiger rechtlicher Hinweis',
legalGateBody1:
'Der AI-Act-Kompass ist eine strukturierte Arbeitshilfe, die die Umsetzung der Verordnung (EU) 2024/1689 (EU AI Act) und einschlägiger nationaler Vorschriften erleichtern soll.',
legalGateBody2:
'Diese Anwendung erbringt keine Rechtsdienstleistung im Sinne des Rechtsdienstleistungsgesetzes (RDG) und stellt keine Rechtsberatung, Rechtsauskunft oder rechtsverbindliche Belehrung dar. Alle Einstufungen, Checklisten und generierten Dokumente sind unverbindliche Ersteinschätzungen und Entwürfe ohne Gewähr für Richtigkeit, Vollständigkeit oder Aktualität.',
legalGateBody3:
'Die verbindliche Auslegung des EU AI Act obliegt allein den zuständigen Behörden und Gerichten. Die rechtliche Bewertung Ihres Einzelfalls ersetzt dieses Tool nicht — ziehen Sie hierfür qualifizierte Rechtsberatung (Rechtsanwältin/Rechtsanwalt) hinzu. Die Nutzung erfolgt auf eigenes Risiko; eine Haftung für Entscheidungen auf Grundlage dieses Tools ist ausgeschlossen, soweit gesetzlich zulässig.',
legalGateAccept: 'Verstanden — als Arbeitshilfe nutzen',
legalNoticeTitle: 'Rechtlicher Hinweis (keine Rechtsberatung)',
resultDisclaimer:
'Diese Einstufung ist eine unverbindliche, automatisierte Ersteinschätzung auf Basis Ihrer Angaben — keine Rechtsberatung. Lassen Sie das Ergebnis vor weitreichenden Entscheidungen rechtlich prüfen.',
navTemplates: 'Vorlagen & Vordrucke',
templatesTitle: 'Vorlagen & Vordrucke',
templatesSub: 'Unternehmensweite Entwürfe für die interne und externe Umsetzung — mit Firmen-Briefkopf druckbar. Systembezogene Vordrucke (Betriebsrat, Mitarbeiterinfo, FRIA, Vorfallmeldung) finden Sie in der jeweiligen Systemansicht.',
templatesHint: 'Alle Vorlagen sind Entwürfe mit Platzhaltern — vor Verwendung anpassen und rechtlich prüfen lassen.',
tplPolicy: 'Interne KI-Richtlinie',
tplPolicyDesc: 'Nutzungsregeln für KI im Unternehmen: Freigaben, Verbote, Aufsicht, Transparenz, Vorfälle.',
tplTraining: 'Schulungsplan KI-Kompetenz (Art. 4)',
tplTrainingDesc: 'Schulungsmatrix und fortlaufender Nachweis — Pflicht seit 02.02.2025.',
tplWorksAgreement: 'Betriebsvereinbarung KI (Rahmen)',
tplWorksAgreementDesc: 'Entwurf nach § 87 Abs. 1 Nr. 6, § 90 BetrVG: Zweckbindung, keine automatisierten Personalentscheidungen, Rechte des Betriebsrats.',
docWorksCouncil: 'Betriebsrats-Information (§ 90 BetrVG)',
docEmployeeInfo: 'Mitarbeiterinformation KI-Einsatz',
docFria: 'FRIA-Vorlage (Art. 27)',
docIncident: 'Vorfallmeldung (Art. 73)',
tplReporting: 'Interne Melde- & Eskalationsrichtlinie',
tplReportingDesc: 'Interne Meldepflicht für KI-Vorfälle: Meldewege, 24h-/48h-Fristen, Eskalationsstufen, Vorfallregister — bereitet die Art.-73-Meldung vor.',
tplApproval: 'Freigabeantrag KI-System',
tplApprovalDesc: 'Internes Formular für den Genehmigungsprozess neuer KI-Tools — gegen Schatten-KI, mit Entscheidungsfeld.',
tplAudit: 'Interne Audit-Checkliste KI-Compliance',
tplAuditDesc: 'Periodische Selbstprüfung (Inventar, Schulungen, Logs, Vorfälle, Anbieterunterlagen) mit Abzeichnung.',
};
export type UIStrings = typeof DE;
const EN: UIStrings = {
brandTag: 'EU AI Act compliance for SMEs · local-first',
navDashboard: 'Dashboard & inventory',
navTasks: 'Tasks & deadlines',
navNew: 'Assess new system',
navSettings: 'Settings & backup',
footPrivacy: 'No cloud. No telemetry.',
footLocal: 'All data stays on this device.',
footNoAdvice: 'Not legal advice.',
dashTitle: 'Dashboard',
dashSub: 'EU AI Act compliance at a glance. All data stays locally on this device.',
statSystems: 'AI systems in inventory',
statHigh: 'High-risk systems',
statProhibited: 'Prohibited practices',
statOpen: 'Open tasks',
deadlinesTitle: 'AI Act application deadlines',
inventoryTitle: 'AI inventory',
inventoryPrint: 'Print inventory / PDF',
newSystem: '+ Assess system',
emptyInventory:
'No AI systems recorded yet. Start by assessing your first system — e.g. your chatbot, your applicant screening or a purchased AI tool.',
colSystem: 'System',
colRole: 'Role',
colRisk: 'Risk class',
colOwner: 'Responsible',
colUpdated: 'Last assessed',
disclaimerLine:
'AI-Act-Kompass is a structured working aid based on Regulation (EU) 2024/1689 — not legal advice. Content pack v{version}.',
tasksTitle: 'Tasks & deadlines',
tasksSub: 'All obligations of all systems as a checkable list — what is done, what is due now and what is coming up.',
tasksProgress: '{done} of {total} tasks done',
tasksDueNow: 'Due now',
tasksUpcoming: 'Coming up',
tasksResolved: 'Done',
tasksEmpty: 'No tasks — assess an AI system first.',
tasksAllDone: 'Everything done in this group.',
tasksDue: 'Deadline',
calExport: 'Add to calendar (.ics)',
calHint: 'Exports all open deadlines as a calendar file with reminders (30 and 7 days ahead) — importable into Outlook, Apple and Google Calendar on phone and desktop.',
navQuiz: 'AI literacy test',
quizSub: 'Simple basics test (12 questions) on AI literacy under Art. 4 — with printable certificate as evidence and a local training register.',
quizName: 'Participant name *',
quizNamePh: 'First and last name',
quizSubmit: 'Evaluate test',
quizAnswerAll: 'Please enter a name and answer all questions.',
quizPassed: 'Passed',
quizFailed: 'Not passed',
quizScoreLine: '{correct} of {total} questions correct ({pct} %) — pass threshold {pass} %.',
quizWhy: 'Explanation',
quizCert: 'Print certificate / PDF',
quizRetry: 'Retake test',
quizLogTitle: 'Training register (Art. 4 evidence)',
quizLogHint: 'Each test run is stored locally and serves as evidence of the AI literacy duty (Art. 4). Print the register regularly and file it with your training documentation.',
quizLogEmpty: 'No test runs yet.',
quizLogPrint: 'Print register / PDF',
quizColScore: 'Score',
quizColStatus: 'Status',
quizDocsTitle: 'Print training materials',
quizPrintTest: 'Paper version of the test',
quizPrintKey: 'Answer key',
quizPrintHandout: 'Training handout (12 rules)',
quizManualTitle: 'Add participant manually (paper test)',
quizManualHint: 'For tests taken on paper: enter participant and score, then attach the marked sheet as a scan — completing the evidence chain.',
quizManualScore: 'Correct answers (of 12)',
quizManualAdd: 'Add to register',
quizSourceApp: 'App',
quizSourcePaper: 'Paper',
quizColSource: 'Source',
quizColEvidence: 'Evidence',
quizAttach: 'Attach scan',
quizAttachView: 'Open scan',
quizAttachTooBig: 'File too large — please use a scan under 1 MB (e.g. compressed JPG/PDF).',
quizAttachDone: 'Scan stored and anchored in the register with a SHA-256 checksum.',
quizDeleteRecord: 'Really delete entry “{name}”? Attached evidence will be lost.',
wizardTitleNew: 'Assess a new AI system',
wizardTitleRe: 'Reassessment: {name}',
wizardSub: 'Answer the questions — the risk class is determined automatically following the AI Acts system.',
stepBasics: 'Basics',
stepDefinition: 'AI definition',
stepProhibited: 'Prohibitions',
stepHighRisk: 'High-risk',
stepTransparency: 'Transparency & GPAI',
stepResult: 'Result',
fieldName: 'System name *',
fieldNamePh: 'e.g. applicant screening tool',
fieldPurpose: 'Intended purpose',
fieldPurposePh: 'What is the system used for?',
fieldVendor: 'Manufacturer / provider',
fieldOwner: 'Responsible person (internal)',
fieldRole: 'Your companys role',
roleHint: 'Provider = develops/markets the system under its own name. Deployer = uses a third-party system (most common SME case).',
defTitle: 'Does the system meet the AI definition (Art. 3(1))?',
defHint: 'Only if all criteria apply does the system fall under the AI Act.',
defWarn: 'Not all criteria met → the system does not qualify as an AI system; the AI Act does not apply.',
prohTitle: 'Prohibited practices (Art. 5)',
prohHint: 'If any of these apply, use has been prohibited since 2 February 2025.',
hrTitle: 'High-risk classification (Art. 6)',
annexILabel: 'The system is a safety component of a regulated product (e.g. medical device, machine, lift) or such a product itself.',
annexIIITitle: 'Areas of use under Annex III',
exceptionTitle: 'Possible exception (Art. 6(3))',
profilingLabel: 'The system performs profiling of natural persons.',
profilingRef: 'Profiling excludes the exception — always high-risk.',
art63Label: 'The system only performs a narrow procedural or preparatory task, or merely improves the result of a previously completed human activity — without significant risk to health, safety or fundamental rights.',
art63Ref: 'Art. 6(3) — the assessment must be documented (Art. 6(4)).',
trTitle: 'Transparency obligations (Art. 50)',
gpaiTitle: 'General-purpose AI',
gpaiLabel: 'We provide our own GPAI model (e.g. self-trained or substantially modified base model).',
gpaiRef: 'Art. 51 et seq. — merely using e.g. GPT/Claude via API does not count.',
resultTitle: 'Result:',
resultGpai: 'GPAI model obligations (Art. 53 et seq.) apply additionally.',
resultProhibited: 'Use of this system is prohibited under Art. 5 (fines up to €35m or 7% of global annual turnover). Cease use and seek legal advice.',
btnCancel: 'Cancel',
btnBack: 'Back',
btnNext: 'Next',
btnSave: 'Save',
detailBack: '← Back to dashboard',
detailNoPurpose: 'No intended purpose recorded',
detailReasons: 'Reasoning for the classification',
detailReassess: 'Reassess',
detailDelete: 'Delete system',
detailObligations: 'Obligations',
detailNational: 'incl. country modules: {codes}',
detailDocs: 'Generate documents',
docShow: 'view',
docHide: 'hide',
docPrint: 'Print / PDF',
docRisk: 'Risk report',
docPlan: 'Action plan',
docAnnexIV: 'Annex IV documentation',
docProcurement: 'AI procurement specification',
docConformity: 'EU declaration of conformity',
confirmDeleteSystem: 'Really delete “{name}”?',
systemNotFound: 'System not found.',
statusOpen: 'Open',
statusInProgress: 'In progress',
statusDone: 'Done',
statusNA: 'Not applicable',
settingsTitle: 'Settings',
settingsSub: 'Data sovereignty: everything stays locally in this browser — no cloud sync, no telemetry.',
langTitle: 'Sprache / Language',
langHint: 'Interface, regulatory content and generated documents fully available in 9 European languages (DE, EN, FR, IT, ES, PL, CS, SK, RO). More EU languages will follow via the content feed.',
profileTitle: 'Company profile (letterhead for reports & PDF printing)',
profileHint: 'These details appear in the header and footer of all generated and printed documents. The logo is stored locally and never leaves the device.',
pfName: 'Company name', pfStreet: 'Street & number', pfZip: 'Postcode & city',
pfContact: 'Contact person', pfEmail: 'Email', pfPhone: 'Phone', pfWeb: 'Website',
logoNone: 'No logo stored.',
logoUpload: 'Upload logo',
logoRemove: 'Remove logo',
logoTaken: 'Logo applied.',
logoTooBig: 'Logo too large — please use a file under 300 KB.',
logoNotImage: 'Please choose an image file (PNG, JPG or SVG).',
countriesTitle: 'Country modules (national additional requirements)',
countriesHint: 'Activate the EU countries in which your company offers or operates AI systems. National obligations (supervision, labour law, special laws) then appear in checklists and documents. For cross-border cooperation: activate all countries involved.',
authorityLabel: 'Supervision',
packTitle: 'Regulatory content pack',
packStand: 'As of',
packHint: 'The content pack (prohibitions, Annex III areas, EU obligations, country modules, deadlines) is modelled as a replaceable data package. Updates ship with new app versions and, in future, via a signed update feed.',
backupTitle: 'Backup',
backupExport: 'Export backup (JSON)',
backupImport: 'Import backup',
importOk: 'Import completed: {count} system(s){profile}.',
importProfileSuffix: ' incl. company profile',
importFail: 'Import failed: {error}',
deleteTitle: 'Delete all data',
deleteHint: 'Irreversibly removes all recorded AI systems and the company profile from this browser.',
deleteBtn: 'Delete everything',
deleteConfirm: 'Really delete all local data irreversibly?',
deleteDone: 'All data deleted.',
legalGateTitle: 'Important legal notice',
legalGateBody1:
'AI-Act-Kompass is a structured working aid intended to facilitate the implementation of Regulation (EU) 2024/1689 (EU AI Act) and relevant national provisions.',
legalGateBody2:
'This application does not provide legal services and does not constitute legal advice, legal information or legally binding instruction. All classifications, checklists and generated documents are non-binding preliminary assessments and drafts, without warranty as to accuracy, completeness or currency.',
legalGateBody3:
'The binding interpretation of the EU AI Act rests solely with the competent authorities and courts. This tool does not replace the legal assessment of your individual case — consult qualified legal counsel for that purpose. Use is at your own risk; liability for decisions based on this tool is excluded to the extent permitted by law.',
legalGateAccept: 'Understood — use as a working aid',
legalNoticeTitle: 'Legal notice (not legal advice)',
resultDisclaimer:
'This classification is a non-binding, automated preliminary assessment based on your input — not legal advice. Have the result legally reviewed before far-reaching decisions.',
navTemplates: 'Templates & forms',
templatesTitle: 'Templates & forms',
templatesSub: 'Company-wide drafts for internal and external implementation — printable with company letterhead. System-specific forms (works council, employee info, FRIA, incident report) are in the respective system view.',
templatesHint: 'All templates are drafts with placeholders — adapt and have them legally reviewed before use.',
tplPolicy: 'Internal AI policy',
tplPolicyDesc: 'Usage rules for AI in the company: approvals, prohibitions, oversight, transparency, incidents.',
tplTraining: 'AI literacy training plan (Art. 4)',
tplTrainingDesc: 'Training matrix and continuous record — mandatory since 2 Feb 2025.',
tplWorksAgreement: 'Works agreement on AI (framework)',
tplWorksAgreementDesc: 'Draft per Sec. 87(1) No. 6, Sec. 90 BetrVG: purpose limitation, no automated personnel decisions, works council rights.',
docWorksCouncil: 'Works council information (Sec. 90 BetrVG)',
docEmployeeInfo: 'Employee information on AI use',
docFria: 'FRIA template (Art. 27)',
docIncident: 'Incident report (Art. 73)',
tplReporting: 'Internal reporting & escalation policy',
tplReportingDesc: 'Internal reporting duty for AI incidents: channels, 24h/48h deadlines, escalation levels, incident register — prepares the Art. 73 report.',
tplApproval: 'AI system approval request',
tplApprovalDesc: 'Internal form for approving new AI tools — against shadow AI, with decision section.',
tplAudit: 'Internal AI compliance audit checklist',
tplAuditDesc: 'Periodic self-review (inventory, trainings, logs, incidents, provider documents) with sign-off.',
};
import { CS } from './ui.cs';
import { ES } from './ui.es';
import { FR } from './ui.fr';
import { IT } from './ui.it';
import { PL } from './ui.pl';
import { RO } from './ui.ro';
import { SK } from './ui.sk';
const DICTS: Readonly<Record<Locale, UIStrings>> = { de: DE, en: EN, fr: FR, it: IT, es: ES, pl: PL, cs: CS, sk: SK, ro: RO };
/** Liefert das UI-Wörterbuch für die Sprache. */
export function uiStrings(locale: Locale): UIStrings {
return DICTS[locale];
}
/** Ersetzt {platzhalter} in einem UI-String. */
export function fmt(template: string, params: Readonly<Record<string, string | number>>): string {
return template.replace(/\{(\w+)\}/g, (_, key: string) => String(params[key] ?? ''));
}

View File

@ -0,0 +1,27 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { I18nProvider } from './i18n/context';
import { App } from './ui/App';
import './styles.css';
const container = document.getElementById('root');
if (!container) {
throw new Error('Root-Element #root nicht gefunden.');
}
createRoot(container).render(
<StrictMode>
<I18nProvider>
<App />
</I18nProvider>
</StrictMode>,
);
// PWA: Offline-Fähigkeit und Installierbarkeit auf Handy/Mac.
if ('serviceWorker' in navigator && import.meta.env.PROD) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('./sw.js').catch(() => {
// Ohne Service Worker läuft die App normal weiter — nur nicht offline.
});
});
}

View File

@ -0,0 +1,112 @@
import type { CompanyProfile } from '../engine/types';
import { renderMarkdown } from './render';
/** Maskiert HTML-Sonderzeichen für den Briefkopf. */
function esc(text: string): string {
return text
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;');
}
/** Baut den Briefkopf (Logo, Firmenname, Kontaktdaten) als HTML. */
function letterhead(profile: CompanyProfile): string {
const addressLines = [profile.street, profile.zipCity].filter((l) => l.trim() !== '');
const contactLines = [
profile.contactPerson,
profile.email,
profile.phone,
profile.website,
].filter((l) => l.trim() !== '');
if (profile.name.trim() === '' && profile.logoDataUrl === '' && contactLines.length === 0) {
return '';
}
const logo = profile.logoDataUrl
? `<img class="lh-logo" src="${profile.logoDataUrl}" alt="Logo">`
: '';
return `
<header class="letterhead">
<div class="lh-company">
<div class="lh-name">${esc(profile.name)}</div>
<div class="lh-lines">${addressLines.map(esc).join('<br>')}</div>
<div class="lh-lines">${contactLines.map(esc).join(' · ')}</div>
</div>
${logo}
</header>`;
}
/** Fußzeile mit Kontaktdaten für jede gedruckte Seite. */
function footer(profile: CompanyProfile): string {
const parts = [profile.name, profile.street, profile.zipCity, profile.email, profile.phone]
.filter((p) => p.trim() !== '')
.map(esc);
return parts.length > 0 ? `<footer class="pagefoot">${parts.join(' · ')}</footer>` : '';
}
const PRINT_CSS = `
@page { size: A4; margin: 22mm 20mm; }
* { box-sizing: border-box; }
body {
font-family: 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, 'Times New Roman', serif;
color: #14120e; margin: 0; font-size: 11.5pt; line-height: 1.55; background: #fff;
}
.letterhead { display: flex; justify-content: space-between; align-items: flex-start;
border-bottom: 2.5pt solid #14120e; padding-bottom: 10pt; margin-bottom: 18pt; }
.lh-name { font-size: 15pt; font-weight: 700; letter-spacing: 0.02em; }
.lh-lines { font-size: 9pt; color: #444; margin-top: 3pt;
font-family: ui-monospace, 'Courier New', monospace; }
.lh-logo { max-height: 52pt; max-width: 160pt; object-fit: contain; }
h1 { font-size: 17pt; margin: 0 0 12pt; line-height: 1.25;
border-bottom: 1pt solid #14120e; padding-bottom: 6pt; }
h2 { font-size: 13pt; margin: 16pt 0 6pt; }
h3 { font-size: 11.5pt; margin: 12pt 0 4pt; }
p { margin: 0 0 8pt; }
ul { margin: 0 0 8pt; padding-left: 16pt; }
li { margin-bottom: 3pt; }
blockquote { margin: 10pt 0; padding: 6pt 10pt; border-left: 2.5pt solid #a3271e;
font-size: 9.5pt; color: #444; }
table { width: 100%; border-collapse: collapse; margin: 6pt 0 12pt; font-size: 9.5pt; }
th { text-align: left; border-bottom: 1.5pt solid #14120e; padding: 4pt 6pt;
font-family: ui-monospace, 'Courier New', monospace; font-size: 8pt;
text-transform: uppercase; letter-spacing: 0.06em; }
td { border-bottom: 0.5pt solid #999; padding: 4pt 6pt; vertical-align: top; }
em { color: #a3271e; font-style: italic; }
.pagefoot { margin-top: 24pt; padding-top: 6pt; border-top: 0.75pt solid #14120e;
font-size: 7.5pt; color: #555; font-family: ui-monospace, 'Courier New', monospace; }
`;
/**
* Öffnet ein Dokument als druckfertige Ansicht mit Firmen-Briefkopf und
* startet den Druckdialog (PDF via "Als PDF speichern" des Browsers).
* Alles läuft lokal keine Server-Roundtrips.
*
* @param title - Fenstertitel (wird auch Standard-PDF-Dateiname)
* @param markdown - Vom Dokumenten-Generator erzeugtes Markdown
* @param profile - Firmenprofil für Briefkopf und Fußzeile
*/
export function printDocument(title: string, markdown: string, profile: CompanyProfile): void {
const win = window.open('', '_blank', 'width=900,height=1000');
if (!win) {
window.alert('Popup blockiert — bitte Popups für diese Seite erlauben, um drucken zu können.');
return;
}
win.document.write(`<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>${esc(title)}</title>
<style>${PRINT_CSS}</style>
</head>
<body>
${letterhead(profile)}
${renderMarkdown(markdown)}
${footer(profile)}
<script>window.addEventListener('load', function () { window.print(); });</script>
</body>
</html>`);
win.document.close();
}

View File

@ -0,0 +1,42 @@
import { describe, expect, it } from 'vitest';
import { renderMarkdown } from './render';
describe('renderMarkdown', () => {
it('rendert Überschriften aller Ebenen', () => {
const html = renderMarkdown('# H1\n\n## H2\n\n### H3');
expect(html).toContain('<h1>H1</h1>');
expect(html).toContain('<h2>H2</h2>');
expect(html).toContain('<h3>H3</h3>');
});
it('rendert Tabellen mit Kopfzeile', () => {
const html = renderMarkdown('| Pflicht | Frist |\n|---|---|\n| QMS | 2027 |');
expect(html).toContain('<th>Pflicht</th>');
expect(html).toContain('<td>QMS</td>');
expect(html).not.toContain('---');
});
it('rendert Meta-Tabellen mit leerer Kopfzeile', () => {
const html = renderMarkdown('| | |\n|---|---|\n| **KI-System** | Chatbot |');
expect(html).toContain('<strong>KI-System</strong>');
expect(html).toContain('<td>Chatbot</td>');
});
it('rendert Listen und Blockquotes', () => {
const html = renderMarkdown('- Punkt eins\n- Punkt zwei\n\n> Hinweis');
expect(html).toContain('<li>Punkt eins</li>');
expect(html).toContain('<blockquote>Hinweis</blockquote>');
});
it('rendert Inline-Formatierung', () => {
const html = renderMarkdown('Das ist **wichtig** und _offen_.');
expect(html).toContain('<strong>wichtig</strong>');
expect(html).toContain('<em>offen</em>');
});
it('maskiert HTML in Eingaben (kein Injection über Systemnamen)', () => {
const html = renderMarkdown('# <script>alert(1)</script>');
expect(html).not.toContain('<script>');
expect(html).toContain('&lt;script&gt;');
});
});

View File

@ -0,0 +1,125 @@
/**
* Minimaler Markdown-Renderer für die intern erzeugten Dokumente.
*
* Unterstützt genau die Konstrukte, die der Dokumenten-Generator ausgibt:
* Überschriften (#/##/###), Tabellen, Listen, Blockquotes, Absätze sowie
* **fett** und _kursiv_. Kein externer Parser bewusst klein und auditierbar.
*/
/** Maskiert HTML-Sonderzeichen. */
function escapeHtml(text: string): string {
return text
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;');
}
/** Wandelt Inline-Markdown (**fett**, _kursiv_) in HTML um. */
function inline(text: string): string {
return escapeHtml(text)
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
.replace(/_(.+?)_/g, '<em>$1</em>');
}
function isTableRow(line: string): boolean {
return line.trimStart().startsWith('|');
}
function isSeparatorRow(line: string): boolean {
return /^\s*\|[\s\-|:]+\|\s*$/.test(line);
}
function splitCells(line: string): readonly string[] {
const trimmed = line.trim().replace(/^\|/, '').replace(/\|$/, '');
return trimmed.split('|').map((c) => c.trim());
}
function renderTable(rows: readonly string[]): string {
const [first, second] = rows;
const hasHeader = first !== undefined && second !== undefined && isSeparatorRow(second);
const bodyRows = hasHeader ? rows.slice(2) : rows.filter((r) => !isSeparatorRow(r));
const parts: string[] = ['<table>'];
if (hasHeader) {
const headerCells = splitCells(first)
.map((c) => `<th>${inline(c)}</th>`)
.join('');
parts.push(`<thead><tr>${headerCells}</tr></thead>`);
}
parts.push('<tbody>');
for (const row of bodyRows) {
const cells = splitCells(row)
.map((c) => `<td>${inline(c)}</td>`)
.join('');
parts.push(`<tr>${cells}</tr>`);
}
parts.push('</tbody></table>');
return parts.join('');
}
/**
* Rendert die intern erzeugten Markdown-Dokumente als HTML.
*
* @param markdown - Vom Dokumenten-Generator erzeugtes Markdown
* @returns HTML-Fragment (ohne umgebendes Dokument)
*/
export function renderMarkdown(markdown: string): string {
const lines = markdown.split('\n');
const out: string[] = [];
let i = 0;
while (i < lines.length) {
const line = lines[i] ?? '';
if (line.trim() === '') {
i += 1;
continue;
}
if (line.startsWith('### ')) {
out.push(`<h3>${inline(line.slice(4))}</h3>`);
i += 1;
continue;
}
if (line.startsWith('## ')) {
out.push(`<h2>${inline(line.slice(3))}</h2>`);
i += 1;
continue;
}
if (line.startsWith('# ')) {
out.push(`<h1>${inline(line.slice(2))}</h1>`);
i += 1;
continue;
}
if (line.startsWith('> ')) {
const quote: string[] = [];
while (i < lines.length && (lines[i] ?? '').startsWith('> ')) {
quote.push(inline((lines[i] ?? '').slice(2)));
i += 1;
}
out.push(`<blockquote>${quote.join('<br>')}</blockquote>`);
continue;
}
if (line.startsWith('- ')) {
const items: string[] = [];
while (i < lines.length && (lines[i] ?? '').startsWith('- ')) {
items.push(`<li>${inline((lines[i] ?? '').slice(2))}</li>`);
i += 1;
}
out.push(`<ul>${items.join('')}</ul>`);
continue;
}
if (isTableRow(line)) {
const rows: string[] = [];
while (i < lines.length && isTableRow(lines[i] ?? '')) {
rows.push(lines[i] ?? '');
i += 1;
}
out.push(renderTable(rows));
continue;
}
out.push(`<p>${inline(line)}</p>`);
i += 1;
}
return out.join('\n');
}

View File

@ -0,0 +1,156 @@
import type { TrainingRecord } from '../engine/quiz';
import type { AISystem, CompanyProfile } from '../engine/types';
const STORAGE_KEY = 'ai-act-kompass/systems/v1';
const PROFILE_KEY = 'ai-act-kompass/profile/v1';
const TRAINING_KEY = 'ai-act-kompass/training/v1';
/** Lädt das Schulungsregister aus dem lokalen Speicher (fail-safe). */
export function loadTraining(): readonly TrainingRecord[] {
try {
const raw = localStorage.getItem(TRAINING_KEY);
if (!raw) return [];
const parsed: unknown = JSON.parse(raw);
return Array.isArray(parsed) ? (parsed as TrainingRecord[]) : [];
} catch {
return [];
}
}
/** Persistiert das Schulungsregister im lokalen Speicher. */
export function saveTraining(records: readonly TrainingRecord[]): void {
localStorage.setItem(TRAINING_KEY, JSON.stringify(records));
}
/** Format der Export-/Import-Datei. */
export interface ExportFile {
readonly app: 'ai-act-kompass';
readonly schemaVersion: 1 | 2 | 3;
readonly exportedAt: string;
readonly systems: readonly AISystem[];
/** Ab schemaVersion 2 enthalten. */
readonly profile?: CompanyProfile;
/** Ab schemaVersion 3 enthalten: Schulungsregister inkl. Scan-Belegen. */
readonly training?: readonly TrainingRecord[];
}
/** Ergebnis eines Imports (ältere Backups haben kein Profil/Register). */
export interface ImportResult {
readonly systems: readonly AISystem[];
readonly profile: CompanyProfile | null;
readonly training: readonly TrainingRecord[] | null;
}
/** Leeres Firmenprofil (Default). */
export function emptyProfile(): CompanyProfile {
return {
name: '',
street: '',
zipCity: '',
contactPerson: '',
email: '',
phone: '',
website: '',
logoDataUrl: '',
countries: [],
};
}
/**
* Lädt alle registrierten KI-Systeme aus dem lokalen Speicher.
* Bei defekten Daten wird eine leere Liste zurückgegeben (fail-safe).
*/
export function loadSystems(): readonly AISystem[] {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return [];
const parsed: unknown = JSON.parse(raw);
return Array.isArray(parsed) ? (parsed as AISystem[]) : [];
} catch {
return [];
}
}
/**
* Persistiert die Systemliste im lokalen Speicher des Browsers.
* Es verlassen keine Daten das Gerät.
*/
export function saveSystems(systems: readonly AISystem[]): void {
localStorage.setItem(STORAGE_KEY, JSON.stringify(systems));
}
/** Lädt das Firmenprofil aus dem lokalen Speicher (fail-safe). */
export function loadProfile(): CompanyProfile {
try {
const raw = localStorage.getItem(PROFILE_KEY);
if (!raw) return emptyProfile();
const parsed: unknown = JSON.parse(raw);
return typeof parsed === 'object' && parsed !== null
? { ...emptyProfile(), ...(parsed as Partial<CompanyProfile>) }
: emptyProfile();
} catch {
return emptyProfile();
}
}
/** Persistiert das Firmenprofil im lokalen Speicher des Browsers. */
export function saveProfile(profile: CompanyProfile): void {
localStorage.setItem(PROFILE_KEY, JSON.stringify(profile));
}
/**
* Serialisiert alle Daten als Export-Datei (JSON) für Backup/Umzug.
*
* @param systems - Zu exportierende Systeme
* @param profile - Firmenprofil
* @param exportedAt - Zeitstempel im ISO-Format
*/
export function exportData(
systems: readonly AISystem[],
profile: CompanyProfile,
exportedAt: string,
training: readonly TrainingRecord[] = [],
): string {
const file: ExportFile = {
app: 'ai-act-kompass',
schemaVersion: 3,
exportedAt,
systems,
profile,
training,
};
return JSON.stringify(file, null, 2);
}
/**
* Liest eine Export-Datei ein und validiert das Grundformat.
* Versteht schemaVersion 1 (ohne Profil) und 2 (mit Profil).
*
* @param json - Inhalt der Export-Datei
* @returns Systeme und ggf. Firmenprofil aus der Datei
* @throws Error bei unbekanntem oder defektem Format
*/
export function importData(json: string): ImportResult {
const parsed: unknown = JSON.parse(json);
if (
typeof parsed !== 'object' ||
parsed === null ||
(parsed as ExportFile).app !== 'ai-act-kompass' ||
!Array.isArray((parsed as ExportFile).systems)
) {
throw new Error('Unbekanntes Dateiformat — keine gültige AI-Act-Kompass-Exportdatei.');
}
const file = parsed as ExportFile;
return {
systems: file.systems,
profile: file.profile ? { ...emptyProfile(), ...file.profile } : null,
training: Array.isArray(file.training) ? file.training : null,
};
}
/** Löscht alle lokal gespeicherten Daten unwiderruflich. */
export function clearAll(): void {
localStorage.removeItem(STORAGE_KEY);
localStorage.removeItem(PROFILE_KEY);
localStorage.removeItem(TRAINING_KEY);
}

View File

@ -0,0 +1,377 @@
/*
* AI-Act-Kompass Anti-AI-Design.
* Gestaltungsprinzip: technisches Druckwerk statt SaaS-Dashboard.
* Papierton, Serifenschrift, Hairlines, rechteckige "Stempel"
* keine Verläufe, keine Schatten, keine Rundungen, keine Emojis.
*/
:root {
--paper: #f4f1ea;
--panel: #fdfcf8;
--ink: #14120e;
--muted: #6b675e;
--line: #14120e;
--hairline: #c9c4b8;
--accent: #a3271e;
--ok: #2d5d3a;
--warn: #8a6d1a;
--serif: 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, 'Times New Roman', serif;
--mono: ui-monospace, 'SF Mono', Menlo, Consolas, 'Courier New', monospace;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--paper);
color: var(--ink);
font-family: var(--serif);
}
.layout { display: flex; min-height: 100vh; }
/* ── Seitenleiste: Kolumnentitel eines Fachblatts ─────────────────── */
.sidebar {
width: 250px;
flex-shrink: 0;
background: var(--paper);
border-right: 2px solid var(--ink);
padding: 26px 18px;
display: flex;
flex-direction: column;
}
.sidebar .brand {
font-size: 21px;
font-weight: 700;
letter-spacing: 0.01em;
border-bottom: 3px double var(--ink);
padding-bottom: 12px;
}
.sidebar .brand small {
display: block;
font-family: var(--mono);
font-size: 10px;
font-weight: 400;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--muted);
margin-top: 8px;
}
.sidebar nav { display: flex; flex-direction: column; margin-top: 22px; }
.sidebar button {
text-align: left;
background: none;
border: none;
border-bottom: 1px solid var(--hairline);
color: var(--ink);
padding: 12px 4px;
font-family: var(--serif);
font-size: 15px;
cursor: pointer;
}
.sidebar button:hover { color: var(--accent); }
.sidebar button.active {
font-weight: 700;
border-left: 4px solid var(--accent);
padding-left: 10px;
}
.sidebar .foot {
margin-top: auto;
font-family: var(--mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--muted);
line-height: 1.8;
border-top: 1px solid var(--ink);
padding-top: 12px;
}
.main { flex: 1; padding: 32px 40px; max-width: 1060px; }
h1 { font-size: 26px; margin: 0 0 6px; font-weight: 700; }
h2 { font-size: 16px; margin: 22px 0 10px; }
.sub { color: var(--muted); font-size: 15px; margin: 0 0 22px; font-style: italic; }
.panel {
background: var(--panel);
border: 1px solid var(--ink);
padding: 20px 22px;
margin-bottom: 18px;
}
/* ── Kennzahlen ───────────────────────────────────────────────────── */
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0; }
.grid .stat { padding: 0 18px; border-left: 1px solid var(--hairline); }
.grid .stat:first-child { border-left: none; padding-left: 0; }
.stat .num { font-size: 34px; font-weight: 700; font-variant-numeric: tabular-nums; }
.stat .lbl {
font-family: var(--mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--muted);
margin-top: 2px;
}
/* ── Tabellen ─────────────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
text-align: left;
font-family: var(--mono);
color: var(--ink);
font-weight: 600;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.07em;
border-bottom: 2px solid var(--ink);
}
th, td { padding: 10px; }
td { border-bottom: 1px solid var(--hairline); vertical-align: top; }
tr.clickable { cursor: pointer; }
tr.clickable:hover td { background: #efe9dc; }
/* ── Risiko-Stempel ───────────────────────────────────────────────── */
.badge {
display: inline-block;
padding: 2px 9px;
border: 1.5px solid currentColor;
font-family: var(--mono);
font-size: 10.5px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.07em;
white-space: nowrap;
background: transparent;
}
.badge.high { color: var(--accent); }
.badge.prohibited { color: var(--panel); background: var(--accent); border-color: var(--accent); }
.badge.limited { color: var(--warn); }
.badge.minimal { color: var(--ok); }
.badge.out-of-scope { color: var(--muted); }
/* ── Buttons: Stempelkissen-Optik ─────────────────────────────────── */
button.primary, button.ghost, button.danger {
padding: 9px 16px;
font-family: var(--mono);
font-size: 11.5px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
cursor: pointer;
border: 1.5px solid var(--ink);
background: var(--panel);
color: var(--ink);
}
button.primary { background: var(--ink); color: var(--paper); }
button.primary:hover { background: var(--accent); border-color: var(--accent); }
button.primary:disabled { opacity: 0.4; cursor: not-allowed; }
button.ghost:hover { border-color: var(--accent); color: var(--accent); }
button.danger { border-color: var(--accent); color: var(--accent); }
button.danger:hover { background: var(--accent); color: var(--paper); }
/* ── Formulare ────────────────────────────────────────────────────── */
label.field { display: block; margin-bottom: 14px; font-size: 14px; }
label.field span {
display: block;
font-family: var(--mono);
font-size: 10.5px;
text-transform: uppercase;
letter-spacing: 0.06em;
margin-bottom: 5px;
}
input[type='text'], select, textarea {
width: 100%;
padding: 9px 11px;
border: 1px solid var(--ink);
font-size: 14px;
font-family: var(--serif);
background: #fff;
color: var(--ink);
border-radius: 0;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.profile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0 22px; }
.logo-row { display: flex; align-items: center; gap: 16px; margin-top: 6px; flex-wrap: wrap; }
.logo-preview {
max-height: 56px;
max-width: 180px;
object-fit: contain;
border: 1px solid var(--hairline);
padding: 6px;
background: #fff;
}
.check {
display: flex;
gap: 10px;
align-items: flex-start;
padding: 11px 13px;
border: 1px solid var(--hairline);
border-left: 3px solid var(--ink);
margin-bottom: 8px;
cursor: pointer;
font-size: 14.5px;
background: var(--panel);
}
.check:hover { border-left-color: var(--accent); }
.check input { margin-top: 4px; accent-color: var(--accent); }
.check .ref {
display: block;
font-family: var(--mono);
font-size: 11px;
color: var(--muted);
margin-top: 3px;
}
/* ── Wizard ───────────────────────────────────────────────────────── */
.wizard-steps { display: flex; gap: 0; margin-bottom: 20px; flex-wrap: wrap; border: 1px solid var(--ink); }
.wizard-steps .step {
font-family: var(--mono);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 7px 12px;
border-right: 1px solid var(--hairline);
color: var(--muted);
background: var(--panel);
}
.wizard-steps .step:last-child { border-right: none; }
.wizard-steps .step.current { background: var(--ink); color: var(--paper); }
.wizard-steps .step.done { color: var(--ink); font-weight: 700; }
.wizard-nav { display: flex; justify-content: space-between; margin-top: 20px; }
.reasons li { margin-bottom: 7px; font-size: 14.5px; }
.hint { font-size: 13px; color: var(--muted); }
.disclaimer {
font-family: var(--mono);
font-size: 11px;
color: var(--muted);
border-left: 3px solid var(--accent);
padding: 9px 13px;
background: var(--panel);
margin-top: 22px;
}
/* ── Fristen ──────────────────────────────────────────────────────── */
.deadline-list { list-style: none; padding: 0; margin: 0; }
.deadline-list li {
display: flex;
gap: 14px;
padding: 10px 0;
border-bottom: 1px solid var(--hairline);
font-size: 14.5px;
align-items: baseline;
}
.deadline-list li:last-child { border-bottom: none; }
.deadline-list .date {
font-family: var(--mono);
font-weight: 700;
font-size: 13px;
white-space: nowrap;
min-width: 96px;
}
.deadline-list .past { color: var(--muted); text-decoration: line-through; }
/* ── Dokumentvorschau ─────────────────────────────────────────────── */
.doc-preview {
background: #fff;
color: var(--ink);
border: 1px solid var(--ink);
padding: 18px;
font-family: var(--mono);
font-size: 12px;
overflow-x: auto;
white-space: pre-wrap;
max-height: 420px;
overflow-y: auto;
}
.toolbar { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0 16px; }
.empty { text-align: center; color: var(--muted); padding: 44px 0; font-size: 14.5px; font-style: italic; }
.panel-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.table-scroll { overflow-x: auto; }
/* ── Sprachumschalter ─────────────────────────────────────────────── */
.lang-switch { display: flex; gap: 0; margin-top: 18px; border: 1px solid var(--ink); align-self: flex-start; }
.lang-switch button {
border: none; border-right: 1px solid var(--ink); border-radius: 0;
padding: 6px 12px; background: var(--panel); color: var(--ink);
font-family: var(--mono); font-size: 11px; font-weight: 700; letter-spacing: 0.06em; cursor: pointer;
}
.lang-switch button:last-child { border-right: none; }
.lang-switch button.active { background: var(--ink); color: var(--paper); }
/* ── Aufgabenliste (abhakbar) ─────────────────────────────────────── */
.task-list { list-style: none; padding: 0; margin: 0; }
.task {
display: flex; gap: 12px; align-items: flex-start;
padding: 11px 4px; border-bottom: 1px solid var(--hairline);
}
.task:last-child { border-bottom: none; }
.task.done .task-title { text-decoration: line-through; color: var(--muted); }
.task-check input { width: 19px; height: 19px; margin-top: 2px; accent-color: var(--accent); cursor: pointer; }
.task-body { flex: 1; min-width: 0; }
.task-title { font-size: 14.5px; font-weight: 600; }
.task-meta {
display: flex; gap: 12px; flex-wrap: wrap; margin-top: 3px;
font-family: var(--mono); font-size: 11px; color: var(--muted);
}
.task-system {
border: none; background: none; padding: 0; cursor: pointer;
font-family: var(--mono); font-size: 11px; color: var(--accent);
text-decoration: underline; text-underline-offset: 2px;
}
.progress-label { font-family: var(--mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 8px; }
.progress-track { height: 12px; border: 1px solid var(--ink); background: var(--panel); }
.progress-fill { height: 100%; background: var(--ink); transition: width 0.3s ease; }
/* ── Rechtlicher Hinweis (Erststart) ──────────────────────────────── */
.gate-backdrop {
position: fixed; inset: 0; z-index: 100;
background: rgba(20, 18, 14, 0.6);
display: flex; align-items: center; justify-content: center; padding: 20px;
}
.gate {
background: var(--paper); border: 2px solid var(--ink);
max-width: 620px; max-height: 90vh; overflow-y: auto; padding: 26px 28px;
}
.gate h1 { border-bottom: 3px double var(--ink); padding-bottom: 10px; }
.gate p { font-size: 14.5px; line-height: 1.6; }
.gate button { margin-top: 10px; }
/* ── Responsiv: Tablet & Handy ────────────────────────────────────── */
@media (max-width: 900px) {
.layout { flex-direction: column; }
.sidebar {
width: 100%; border-right: none; border-bottom: 2px solid var(--ink);
padding: 14px 16px; flex-direction: column;
}
.sidebar .brand { font-size: 17px; padding-bottom: 8px; }
.sidebar nav {
flex-direction: row; overflow-x: auto; margin-top: 10px; gap: 0;
-webkit-overflow-scrolling: touch;
}
.sidebar nav button {
white-space: nowrap; border-bottom: none; border-right: 1px solid var(--hairline);
padding: 9px 12px; font-size: 13.5px;
}
.sidebar button.active { border-left: none; padding-left: 12px; background: var(--ink); color: var(--paper); }
.sidebar .foot { display: none; }
.lang-switch { position: absolute; top: 14px; right: 16px; margin-top: 0; }
.sidebar { position: relative; }
.main { padding: 18px 14px; }
h1 { font-size: 21px; }
.panel { padding: 14px 14px; }
.grid { grid-template-columns: repeat(2, 1fr); gap: 12px 0; }
.grid .stat:nth-child(odd) { border-left: none; padding-left: 0; }
.grid .stat:nth-child(even) { padding-left: 14px; }
.stat .num { font-size: 26px; }
.wizard-steps { border: none; gap: 4px; }
.wizard-steps .step { border: 1px solid var(--hairline); }
.deadline-list li { flex-direction: column; gap: 2px; }
button.primary, button.ghost, button.danger { padding: 10px 14px; }
.task { padding: 12px 2px; }
.task-check input { width: 22px; height: 22px; }
}

View File

@ -0,0 +1,230 @@
import { useEffect, useState } from 'react';
import type { TrainingRecord } from '../engine/quiz';
import type { AISystem, CompanyProfile, ObligationStatus } from '../engine/types';
import { useI18n } from '../i18n/context';
import { LOCALES } from '../i18n/types';
import { fmt } from '../i18n/ui';
import { loadProfile, loadSystems, loadTraining, saveProfile, saveSystems, saveTraining } from '../store/storage';
import { ChecklistView } from './ChecklistView';
import { Dashboard } from './Dashboard';
import { DisclaimerGate } from './DisclaimerGate';
import { QuizView } from './QuizView';
import { SettingsView } from './SettingsView';
import { SystemDetail } from './SystemDetail';
import { TemplatesView } from './TemplatesView';
import { Wizard } from './Wizard';
type View =
| { readonly kind: 'dashboard' }
| { readonly kind: 'tasks' }
| { readonly kind: 'templates' }
| { readonly kind: 'quiz' }
| { readonly kind: 'wizard'; readonly systemId: string | null }
| { readonly kind: 'detail'; readonly systemId: string }
| { readonly kind: 'settings' };
/** App-Shell: Navigation, State-Verwaltung und Persistenz. */
export function App(): JSX.Element {
const { t, locale, setLocale } = useI18n();
const [systems, setSystems] = useState<readonly AISystem[]>(() => loadSystems());
const [profile, setProfile] = useState<CompanyProfile>(() => loadProfile());
const [training, setTraining] = useState<readonly TrainingRecord[]>(() => loadTraining());
const [view, setView] = useState<View>({ kind: 'dashboard' });
useEffect(() => {
saveSystems(systems);
}, [systems]);
useEffect(() => {
saveProfile(profile);
}, [profile]);
useEffect(() => {
saveTraining(training);
}, [training]);
const findSystem = (id: string): AISystem | undefined => systems.find((s) => s.id === id);
const upsert = (system: AISystem): void => {
setSystems((prev) => {
const exists = prev.some((s) => s.id === system.id);
return exists ? prev.map((s) => (s.id === system.id ? system : s)) : [...prev, system];
});
};
const remove = (id: string): void => {
setSystems((prev) => prev.filter((s) => s.id !== id));
setView({ kind: 'dashboard' });
};
const setObligationStatus = (
systemId: string,
obligationId: string,
status: ObligationStatus,
): void => {
const system = findSystem(systemId);
if (!system) return;
upsert({
...system,
updatedAt: new Date().toISOString(),
obligationStatus: { ...system.obligationStatus, [obligationId]: status },
});
};
return (
<div className="layout">
<DisclaimerGate />
<aside className="sidebar">
<div className="brand">
AI-Act-Kompass
<small>{t.brandTag}</small>
</div>
<nav>
<button
className={view.kind === 'dashboard' ? 'active' : ''}
onClick={() => setView({ kind: 'dashboard' })}
>
{t.navDashboard}
</button>
<button
className={view.kind === 'tasks' ? 'active' : ''}
onClick={() => setView({ kind: 'tasks' })}
>
{t.navTasks}
</button>
<button
className={view.kind === 'wizard' ? 'active' : ''}
onClick={() => setView({ kind: 'wizard', systemId: null })}
>
{t.navNew}
</button>
<button
className={view.kind === 'templates' ? 'active' : ''}
onClick={() => setView({ kind: 'templates' })}
>
{t.navTemplates}
</button>
<button
className={view.kind === 'quiz' ? 'active' : ''}
onClick={() => setView({ kind: 'quiz' })}
>
{t.navQuiz}
</button>
<button
className={view.kind === 'settings' ? 'active' : ''}
onClick={() => setView({ kind: 'settings' })}
>
{t.navSettings}
</button>
</nav>
<div className="lang-switch">
{LOCALES.map((l) => (
<button
key={l}
className={l === locale ? 'active' : ''}
onClick={() => setLocale(l)}
aria-label={`Sprache ${l}`}
>
{l.toUpperCase()}
</button>
))}
</div>
<div className="foot">
{t.footPrivacy}
<br />
{t.footLocal}
<br />
<br />
{t.footNoAdvice}
</div>
</aside>
<main className="main">
{view.kind === 'dashboard' && (
<Dashboard
systems={systems}
profile={profile}
onOpen={(id) => setView({ kind: 'detail', systemId: id })}
onNew={() => setView({ kind: 'wizard', systemId: null })}
/>
)}
{view.kind === 'tasks' && (
<ChecklistView
systems={systems}
profile={profile}
onToggle={(systemId, obligationId, done) =>
setObligationStatus(systemId, obligationId, done ? 'done' : 'open')
}
onOpenSystem={(id) => setView({ kind: 'detail', systemId: id })}
/>
)}
{view.kind === 'templates' && <TemplatesView systems={systems} profile={profile} />}
{view.kind === 'quiz' && (
<QuizView
profile={profile}
records={training}
onRecord={(record) => setTraining((prev) => [record, ...prev])}
onUpdateRecord={(record) =>
setTraining((prev) => prev.map((r) => (r.id === record.id ? record : r)))
}
onDeleteRecord={(id) => setTraining((prev) => prev.filter((r) => r.id !== id))}
/>
)}
{view.kind === 'wizard' && (
<Wizard
existing={view.systemId ? (findSystem(view.systemId) ?? null) : null}
onSave={(system) => {
upsert(system);
setView({ kind: 'detail', systemId: system.id });
}}
onCancel={() => setView({ kind: 'dashboard' })}
/>
)}
{view.kind === 'detail' &&
(() => {
const system = findSystem(view.systemId);
if (!system) {
return <div className="empty">{t.systemNotFound}</div>;
}
return (
<SystemDetail
system={system}
profile={profile}
onUpdate={upsert}
onReassess={() => setView({ kind: 'wizard', systemId: system.id })}
onDelete={() => {
if (window.confirm(fmt(t.confirmDeleteSystem, { name: system.name }))) {
remove(system.id);
}
}}
onBack={() => setView({ kind: 'dashboard' })}
/>
);
})()}
{view.kind === 'settings' && (
<SettingsView
systems={systems}
profile={profile}
training={training}
onProfileChange={setProfile}
onImport={(imported, importedProfile, importedTraining) => {
setSystems(imported);
if (importedProfile) setProfile(importedProfile);
if (importedTraining) setTraining(importedTraining);
}}
onClear={() => {
setSystems([]);
setTraining([]);
}}
/>
)}
</main>
</div>
);
}

View File

@ -0,0 +1,157 @@
import { useMemo } from 'react';
import { buildChecklist } from '../engine/checklist';
import type { ChecklistEntry } from '../engine/checklist';
import { checklistIcs } from '../engine/ics';
import type { AISystem, CompanyProfile } from '../engine/types';
import { useI18n } from '../i18n/context';
import { fmt } from '../i18n/ui';
import { downloadText, todayISO, uiDate } from './common';
interface ChecklistViewProps {
readonly systems: readonly AISystem[];
readonly profile: CompanyProfile;
readonly onToggle: (systemId: string, obligationId: string, done: boolean) => void;
readonly onOpenSystem: (systemId: string) => void;
}
function Group({
title,
entries,
emptyText,
onToggle,
onOpenSystem,
}: {
readonly title: string;
readonly entries: readonly ChecklistEntry[];
readonly emptyText: string;
readonly onToggle: (systemId: string, obligationId: string, done: boolean) => void;
readonly onOpenSystem: (systemId: string) => void;
}): JSX.Element {
const { locale, t } = useI18n();
return (
<div className="panel">
<h2 style={{ marginTop: 0 }}>
{title} ({entries.length})
</h2>
{entries.length === 0 ? (
<p className="hint">{emptyText}</p>
) : (
<ul className="task-list">
{entries.map((e) => (
<li key={`${e.systemId}:${e.obligation.id}`} className={e.resolved ? 'task done' : 'task'}>
<label className="task-check">
<input
type="checkbox"
checked={e.resolved}
onChange={(ev) => onToggle(e.systemId, e.obligation.id, ev.target.checked)}
/>
</label>
<div className="task-body">
<div className="task-title">{e.obligation.title}</div>
<div className="task-meta">
<button className="task-system" onClick={() => onOpenSystem(e.systemId)}>
{e.systemName}
</button>
<span>{e.obligation.articles}</span>
<span>
{t.tasksDue}: {uiDate(e.obligation.deadline, locale)}
</span>
</div>
</div>
</li>
))}
</ul>
)}
</div>
);
}
/**
* Systemübergreifende, abhakbare Aufgabenliste: was erledigt ist,
* was jetzt fällig ist und was noch kommt mobiltauglich.
*/
export function ChecklistView({
systems,
profile,
onToggle,
onOpenSystem,
}: ChecklistViewProps): JSX.Element {
const { t, pack } = useI18n();
const today = todayISO();
const checklist = useMemo(
() => buildChecklist(systems, pack, profile.countries, today),
[systems, pack, profile.countries, today],
);
const pct = checklist.total === 0 ? 0 : Math.round((checklist.resolvedCount / checklist.total) * 100);
return (
<div>
<h1>{t.tasksTitle}</h1>
<p className="sub">{t.tasksSub}</p>
{checklist.total === 0 ? (
<div className="panel">
<div className="empty">{t.tasksEmpty}</div>
</div>
) : (
<>
<div className="panel">
<div className="progress-label">
{fmt(t.tasksProgress, { done: checklist.resolvedCount, total: checklist.total })} {pct} %
</div>
<div className="progress-track">
<div className="progress-fill" style={{ width: `${pct}%` }} />
</div>
<div className="toolbar" style={{ margin: '14px 0 0' }}>
<button
className="ghost"
onClick={() =>
downloadText(
`ai-act-fristen-${today}.ics`,
checklistIcs({
entries: [...checklist.dueNow, ...checklist.upcoming],
deadlines: pack.deadlines,
today,
timestamp: new Date().toISOString(),
calendarName: 'AI-Act-Kompass',
}),
'text/calendar',
)
}
>
{t.calExport}
</button>
</div>
<p className="hint" style={{ marginBottom: 0 }}>
{t.calHint}
</p>
</div>
<Group
title={t.tasksDueNow}
entries={checklist.dueNow}
emptyText={t.tasksAllDone}
onToggle={onToggle}
onOpenSystem={onOpenSystem}
/>
<Group
title={t.tasksUpcoming}
entries={checklist.upcoming}
emptyText={t.tasksAllDone}
onToggle={onToggle}
onOpenSystem={onOpenSystem}
/>
<Group
title={t.tasksResolved}
entries={checklist.resolved}
emptyText="—"
onToggle={onToggle}
onOpenSystem={onOpenSystem}
/>
</>
)}
</div>
);
}

View File

@ -0,0 +1,137 @@
import { buildChecklist } from '../engine/checklist';
import { inventoryReport } from '../engine/documents';
import type { AISystem, CompanyProfile } from '../engine/types';
import { useI18n } from '../i18n/context';
import { fmt } from '../i18n/ui';
import { printDocument } from '../print/print';
import { downloadText, RiskBadge, ROLE_UI, todayISO, uiDate } from './common';
interface DashboardProps {
readonly systems: readonly AISystem[];
readonly profile: CompanyProfile;
readonly onOpen: (id: string) => void;
readonly onNew: () => void;
}
/** Übersichtsseite: Kennzahlen, Fristen und das KI-Inventar. */
export function Dashboard({ systems, profile, onOpen, onNew }: DashboardProps): JSX.Element {
const { t, locale, pack } = useI18n();
const today = todayISO();
const count = (risk: string): number =>
systems.filter((s) => s.classification.riskClass === risk).length;
const checklist = buildChecklist(systems, pack, profile.countries, today);
const openTasks = checklist.total - checklist.resolvedCount;
return (
<div>
<h1>{t.dashTitle}</h1>
<p className="sub">{t.dashSub}</p>
<div className="panel grid">
<div className="stat">
<div className="num">{systems.length}</div>
<div className="lbl">{t.statSystems}</div>
</div>
<div className="stat">
<div className="num">{count('high')}</div>
<div className="lbl">{t.statHigh}</div>
</div>
<div className="stat">
<div className="num">{count('prohibited')}</div>
<div className="lbl">{t.statProhibited}</div>
</div>
<div className="stat">
<div className="num">{openTasks}</div>
<div className="lbl">{t.statOpen}</div>
</div>
</div>
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.deadlinesTitle}</h2>
<ul className="deadline-list">
{pack.deadlines.map((d) => (
<li key={d.id}>
<span className={`date ${d.date < today ? 'past' : ''}`}>{uiDate(d.date, locale)}</span>
<span>
<strong>{d.label}</strong> {d.description}
</span>
</li>
))}
</ul>
</div>
<div className="panel">
<div className="panel-head">
<h2 style={{ margin: 0 }}>{t.inventoryTitle}</h2>
<div className="toolbar" style={{ margin: 0 }}>
{systems.length > 0 && (
<>
<button
className="ghost"
onClick={() =>
printDocument(
`ki-inventar-${today}`,
inventoryReport(systems, pack, today, profile, locale),
profile,
)
}
>
{t.inventoryPrint}
</button>
<button
className="ghost"
onClick={() =>
downloadText(
`ki-inventar-${today}.md`,
inventoryReport(systems, pack, today, profile, locale),
)
}
>
.md
</button>
</>
)}
<button className="primary" onClick={onNew}>
{t.newSystem}
</button>
</div>
</div>
{systems.length === 0 ? (
<div className="empty">{t.emptyInventory}</div>
) : (
<div className="table-scroll">
<table>
<thead>
<tr>
<th>{t.colSystem}</th>
<th>{t.colRole}</th>
<th>{t.colRisk}</th>
<th>{t.colOwner}</th>
<th>{t.colUpdated}</th>
</tr>
</thead>
<tbody>
{systems.map((s) => (
<tr key={s.id} className="clickable" onClick={() => onOpen(s.id)}>
<td>
<strong>{s.name}</strong>
</td>
<td>{ROLE_UI[locale][s.answers.role]}</td>
<td>
<RiskBadge risk={s.classification.riskClass} />
</td>
<td>{s.owner || '—'}</td>
<td>{uiDate(s.updatedAt.slice(0, 10), locale)}</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
<p className="disclaimer">{fmt(t.disclaimerLine, { version: pack.version })}</p>
</div>
);
}

View File

@ -0,0 +1,47 @@
import { useState } from 'react';
import { useI18n } from '../i18n/context';
const ACK_KEY = 'ai-act-kompass/legal-ack/v1';
function hasAcknowledged(): boolean {
try {
return localStorage.getItem(ACK_KEY) !== null;
} catch {
return false;
}
}
/**
* Rechtlicher Hinweis beim ersten Start: Die Nutzung ist erst nach
* ausdrücklicher Bestätigung möglich, dass das Tool nur eine Arbeitshilfe
* und keine Rechtsberatung ist. Die Bestätigung wird mit Zeitstempel
* lokal gespeichert.
*/
export function DisclaimerGate(): JSX.Element | null {
const { t } = useI18n();
const [acknowledged, setAcknowledged] = useState<boolean>(() => hasAcknowledged());
if (acknowledged) return null;
return (
<div className="gate-backdrop" role="dialog" aria-modal="true" aria-label={t.legalGateTitle}>
<div className="gate">
<h1>{t.legalGateTitle}</h1>
<p>{t.legalGateBody1}</p>
<p>
<strong>{t.legalGateBody2}</strong>
</p>
<p>{t.legalGateBody3}</p>
<button
className="primary"
onClick={() => {
localStorage.setItem(ACK_KEY, new Date().toISOString());
setAcknowledged(true);
}}
>
{t.legalGateAccept}
</button>
</div>
</div>
);
}

View File

@ -0,0 +1,389 @@
import { useMemo, useRef, useState } from 'react';
import {
answerKeyDoc,
certificateDoc,
getQuiz,
handoutDoc,
printableTestDoc,
scoreQuiz,
trainingLogDoc,
} from '../engine/quiz';
import type { QuizScore, TrainingRecord } from '../engine/quiz';
import { QUIZ_PASS_PCT, QUIZ_QUESTIONS } from '../engine/quizContent';
import type { CompanyProfile } from '../engine/types';
import { sha256HexBytes, withVerification } from '../engine/verify';
import { useI18n } from '../i18n/context';
import { fmt } from '../i18n/ui';
import { printDocument } from '../print/print';
import { todayISO, uiDate } from './common';
interface QuizViewProps {
readonly profile: CompanyProfile;
readonly records: readonly TrainingRecord[];
readonly onRecord: (record: TrainingRecord) => void;
readonly onUpdateRecord: (record: TrainingRecord) => void;
readonly onDeleteRecord: (id: string) => void;
}
const MAX_SCAN_BYTES = 1_000_000;
/**
* KI-Kompetenztest (Art. 4): Test mit Auswertung, druckbaren
* Schulungsunterlagen, manueller Teilnehmer-Erfassung (Papier-Tests),
* Scan-Belegen mit SHA-256-Prüfsumme und Schulungsregister.
*/
export function QuizView({
profile,
records,
onRecord,
onUpdateRecord,
onDeleteRecord,
}: QuizViewProps): JSX.Element {
const { t, locale, pack } = useI18n();
const today = todayISO();
const questions = useMemo(() => getQuiz(locale), [locale]);
const [name, setName] = useState('');
const [answers, setAnswers] = useState<readonly (number | null)[]>(() =>
questions.map(() => null),
);
const [result, setResult] = useState<QuizScore | null>(null);
const [lastRecordId, setLastRecordId] = useState<string | null>(null);
const [manualName, setManualName] = useState('');
const [manualCorrect, setManualCorrect] = useState('');
const [attachTarget, setAttachTarget] = useState<string | null>(null);
const [attachMessage, setAttachMessage] = useState('');
const scanInput = useRef<HTMLInputElement>(null);
const complete = name.trim() !== '' && answers.every((a) => a !== null);
const printVerified = (file: string, markdown: string): void => {
void withVerification(markdown, locale).then((verified) =>
printDocument(file, verified, profile),
);
};
const submit = (): void => {
const score = scoreQuiz(answers);
const id = crypto.randomUUID();
setResult(score);
setLastRecordId(id);
onRecord({
id,
name: name.trim(),
date: today,
scorePct: score.pct,
passed: score.passed,
source: 'app',
});
};
const addManual = (): void => {
const correct = Number(manualCorrect);
if (manualName.trim() === '' || !Number.isInteger(correct) || correct < 0 || correct > QUIZ_QUESTIONS.length) {
return;
}
const pct = Math.round((correct / QUIZ_QUESTIONS.length) * 100);
onRecord({
id: crypto.randomUUID(),
name: manualName.trim(),
date: today,
scorePct: pct,
passed: pct >= QUIZ_PASS_PCT,
source: 'paper',
});
setManualName('');
setManualCorrect('');
};
const attachScan = async (file: File): Promise<void> => {
const record = records.find((r) => r.id === attachTarget);
if (!record) return;
if (file.size > MAX_SCAN_BYTES) {
setAttachMessage(t.quizAttachTooBig);
return;
}
const buffer = await file.arrayBuffer();
const sha256 = await sha256HexBytes(buffer);
const dataUrl = await new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(typeof reader.result === 'string' ? reader.result : '');
reader.onerror = () => reject(new Error('read failed'));
reader.readAsDataURL(file);
});
onUpdateRecord({ ...record, attachment: { fileName: file.name, sha256, dataUrl } });
setAttachMessage(t.quizAttachDone);
};
const openScan = (record: TrainingRecord): void => {
if (!record.attachment) return;
const win = window.open('', '_blank');
if (!win) return;
if (record.attachment.dataUrl.startsWith('data:application/pdf')) {
win.document.write(
`<iframe src="${record.attachment.dataUrl}" style="border:0;width:100vw;height:100vh"></iframe>`,
);
} else {
win.document.write(`<img src="${record.attachment.dataUrl}" style="max-width:100%">`);
}
win.document.close();
};
return (
<div>
<h1>{t.navQuiz}</h1>
<p className="sub">{t.quizSub}</p>
{result === null ? (
<>
<div className="panel">
<label className="field">
<span>{t.quizName}</span>
<input
type="text"
value={name}
placeholder={t.quizNamePh}
onChange={(e) => setName(e.target.value)}
/>
</label>
</div>
{questions.map((q, qi) => (
<div key={q.id} className="panel">
<h2 style={{ marginTop: 0 }}>
{qi + 1}. {q.question}
</h2>
{q.options.map((option, oi) => (
<label key={oi} className="check">
<input
type="radio"
name={q.id}
checked={answers[qi] === oi}
onChange={() => setAnswers(answers.map((a, i) => (i === qi ? oi : a)))}
/>
<span>{option}</span>
</label>
))}
</div>
))}
<div className="wizard-nav">
<span className="hint">{!complete ? t.quizAnswerAll : ''}</span>
<button className="primary" disabled={!complete} onClick={submit}>
{t.quizSubmit}
</button>
</div>
</>
) : (
<div className="panel">
<h2 style={{ marginTop: 0 }}>
<span className={`badge ${result.passed ? 'minimal' : 'high'}`}>
{result.passed ? t.quizPassed : t.quizFailed}
</span>
</h2>
<p>
{fmt(t.quizScoreLine, {
correct: result.correct,
total: result.total,
pct: result.pct,
pass: QUIZ_PASS_PCT,
})}
</p>
<div className="toolbar">
<button
className="primary"
onClick={() =>
printVerified(
`ki-kompetenz-${name.trim()}-${today}`,
certificateDoc(name.trim(), result, pack, today, profile, locale, lastRecordId ?? undefined),
)
}
>
{t.quizCert}
</button>
<button
className="ghost"
onClick={() => {
setAnswers(questions.map(() => null));
setResult(null);
setLastRecordId(null);
}}
>
{t.quizRetry}
</button>
</div>
<h2>{t.quizWhy}</h2>
<ul className="reasons">
{questions.map((q, qi) => (
<li key={q.id}>
<strong>
{answers[qi] === q.correctIndex ? '✓' : '✗'} {qi + 1}.
</strong>{' '}
{q.explanation}
</li>
))}
</ul>
</div>
)}
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.quizDocsTitle}</h2>
<div className="toolbar" style={{ marginBottom: 0 }}>
<button
className="ghost"
onClick={() =>
printDocument(`ki-test-papier-${today}`, printableTestDoc(pack, today, profile, locale), profile)
}
>
{t.quizPrintTest}
</button>
<button
className="ghost"
onClick={() =>
printDocument(`ki-test-loesungen-${today}`, answerKeyDoc(pack, today, profile, locale), profile)
}
>
{t.quizPrintKey}
</button>
<button
className="ghost"
onClick={() =>
printDocument(`ki-schulungshandout-${today}`, handoutDoc(pack, today, profile, locale), profile)
}
>
{t.quizPrintHandout}
</button>
</div>
</div>
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.quizManualTitle}</h2>
<p className="hint">{t.quizManualHint}</p>
<div className="profile-grid">
<label className="field">
<span>{t.quizName}</span>
<input
type="text"
value={manualName}
placeholder={t.quizNamePh}
onChange={(e) => setManualName(e.target.value)}
/>
</label>
<label className="field">
<span>{t.quizManualScore}</span>
<input
type="text"
inputMode="numeric"
value={manualCorrect}
placeholder={`0${QUIZ_QUESTIONS.length}`}
onChange={(e) => setManualCorrect(e.target.value)}
/>
</label>
</div>
<button className="primary" onClick={addManual}>
{t.quizManualAdd}
</button>
</div>
<div className="panel">
<div className="panel-head">
<h2 style={{ margin: 0 }}>{t.quizLogTitle}</h2>
{records.length > 0 && (
<button
className="ghost"
onClick={() =>
printVerified(
`schulungsregister-${today}`,
trainingLogDoc(records, pack, today, profile, locale),
)
}
>
{t.quizLogPrint}
</button>
)}
</div>
<p className="hint">{t.quizLogHint}</p>
{attachMessage && <p className="hint">{attachMessage}</p>}
<input
ref={scanInput}
type="file"
accept="image/*,application/pdf"
style={{ display: 'none' }}
onChange={(e) => {
const file = e.target.files?.[0];
if (file) void attachScan(file);
e.target.value = '';
}}
/>
{records.length === 0 ? (
<p className="hint">{t.quizLogEmpty}</p>
) : (
<div className="table-scroll">
<table>
<thead>
<tr>
<th>{t.colUpdated}</th>
<th>{t.colOwner}</th>
<th>{t.quizColSource}</th>
<th>{t.quizColScore}</th>
<th>{t.quizColStatus}</th>
<th>{t.quizColEvidence}</th>
</tr>
</thead>
<tbody>
{records.map((r) => (
<tr key={r.id}>
<td>{uiDate(r.date, locale)}</td>
<td>{r.name}</td>
<td>{(r.source ?? 'app') === 'paper' ? t.quizSourcePaper : t.quizSourceApp}</td>
<td>{r.scorePct} %</td>
<td>
<span className={`badge ${r.passed ? 'minimal' : 'high'}`}>
{r.passed ? t.quizPassed : t.quizFailed}
</span>
</td>
<td>
<div className="toolbar" style={{ margin: 0 }}>
{r.attachment ? (
<button
className="ghost"
title={`SHA-256: ${r.attachment.sha256}`}
onClick={() => openScan(r)}
>
{t.quizAttachView}
</button>
) : (
<button
className="ghost"
onClick={() => {
setAttachTarget(r.id);
scanInput.current?.click();
}}
>
{t.quizAttach}
</button>
)}
<button
className="danger"
onClick={() => {
if (window.confirm(fmt(t.quizDeleteRecord, { name: r.name }))) {
onDeleteRecord(r.id);
}
}}
>
</button>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
</div>
);
}

View File

@ -0,0 +1,252 @@
import { useRef, useState } from 'react';
import type { TrainingRecord } from '../engine/quiz';
import type { AISystem, CompanyProfile } from '../engine/types';
import { useI18n } from '../i18n/context';
import { LOCALE_NAMES, LOCALES } from '../i18n/types';
import { fmt } from '../i18n/ui';
import { clearAll, exportData, importData } from '../store/storage';
import { downloadText, todayISO } from './common';
interface SettingsViewProps {
readonly systems: readonly AISystem[];
readonly profile: CompanyProfile;
readonly training: readonly TrainingRecord[];
readonly onProfileChange: (profile: CompanyProfile) => void;
readonly onImport: (
systems: readonly AISystem[],
profile: CompanyProfile | null,
training: readonly TrainingRecord[] | null,
) => void;
readonly onClear: () => void;
}
const MAX_LOGO_BYTES = 300_000;
type ProfileTextKey = Exclude<keyof CompanyProfile, 'logoDataUrl' | 'countries'>;
/** Einstellungen: Sprache, Firmenprofil, Länder-Module, Backup, Rechtshinweis. */
export function SettingsView({
systems,
profile,
training,
onProfileChange,
onImport,
onClear,
}: SettingsViewProps): JSX.Element {
const { t, locale, pack, setLocale } = useI18n();
const fileInput = useRef<HTMLInputElement>(null);
const logoInput = useRef<HTMLInputElement>(null);
const [message, setMessage] = useState<string>('');
const [logoMessage, setLogoMessage] = useState<string>('');
const profileFields: readonly { key: ProfileTextKey; label: string; placeholder: string }[] = [
{ key: 'name', label: t.pfName, placeholder: 'Muster GmbH' },
{ key: 'street', label: t.pfStreet, placeholder: 'Musterstraße 1' },
{ key: 'zipCity', label: t.pfZip, placeholder: '60311 Frankfurt am Main' },
{ key: 'contactPerson', label: t.pfContact, placeholder: 'Max Mustermann' },
{ key: 'email', label: t.pfEmail, placeholder: 'compliance@muster.de' },
{ key: 'phone', label: t.pfPhone, placeholder: '+49 69 000000' },
{ key: 'website', label: t.pfWeb, placeholder: 'www.muster.de' },
];
const handleImport = async (file: File): Promise<void> => {
try {
const result = importData(await file.text());
onImport(result.systems, result.profile, result.training);
setMessage(
fmt(t.importOk, {
count: result.systems.length,
profile: result.profile ? t.importProfileSuffix : '',
}),
);
} catch (err) {
setMessage(fmt(t.importFail, { error: err instanceof Error ? err.message : String(err) }));
}
};
const handleLogo = (file: File): void => {
if (!file.type.startsWith('image/')) {
setLogoMessage(t.logoNotImage);
return;
}
const reader = new FileReader();
reader.onload = () => {
const dataUrl = typeof reader.result === 'string' ? reader.result : '';
if (dataUrl.length > MAX_LOGO_BYTES * 1.4) {
setLogoMessage(t.logoTooBig);
return;
}
onProfileChange({ ...profile, logoDataUrl: dataUrl });
setLogoMessage(t.logoTaken);
};
reader.readAsDataURL(file);
};
const toggleCountry = (code: string): void => {
const countries = profile.countries.includes(code)
? profile.countries.filter((c) => c !== code)
: [...profile.countries, code];
onProfileChange({ ...profile, countries });
};
return (
<div>
<h1>{t.settingsTitle}</h1>
<p className="sub">{t.settingsSub}</p>
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.langTitle}</h2>
<div className="toolbar">
{LOCALES.map((l) => (
<button
key={l}
className={l === locale ? 'primary' : 'ghost'}
onClick={() => setLocale(l)}
>
{LOCALE_NAMES[l]}
</button>
))}
</div>
<p className="hint">{t.langHint}</p>
</div>
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.countriesTitle}</h2>
<p className="hint">{t.countriesHint}</p>
{pack.national.map((n) => (
<label key={n.code} className="check">
<input
type="checkbox"
checked={profile.countries.includes(n.code)}
onChange={() => toggleCountry(n.code)}
/>
<span>
<strong>
{n.code} {n.country}
</strong>
<span className="ref">
{t.authorityLabel}: {n.authority}
</span>
</span>
</label>
))}
</div>
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.profileTitle}</h2>
<p className="hint">{t.profileHint}</p>
<div className="profile-grid">
{profileFields.map((f) => (
<label key={f.key} className="field">
<span>{f.label}</span>
<input
type="text"
value={profile[f.key]}
placeholder={f.placeholder}
onChange={(e) => onProfileChange({ ...profile, [f.key]: e.target.value })}
/>
</label>
))}
</div>
<div className="logo-row">
{profile.logoDataUrl ? (
<img className="logo-preview" src={profile.logoDataUrl} alt="Logo" />
) : (
<span className="hint">{t.logoNone}</span>
)}
<div className="toolbar" style={{ margin: 0 }}>
<button className="ghost" onClick={() => logoInput.current?.click()}>
{t.logoUpload}
</button>
{profile.logoDataUrl && (
<button className="danger" onClick={() => onProfileChange({ ...profile, logoDataUrl: '' })}>
{t.logoRemove}
</button>
)}
</div>
<input
ref={logoInput}
type="file"
accept="image/*"
style={{ display: 'none' }}
onChange={(e) => {
const file = e.target.files?.[0];
if (file) handleLogo(file);
e.target.value = '';
}}
/>
</div>
{logoMessage && <p className="hint">{logoMessage}</p>}
</div>
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.packTitle}</h2>
<p style={{ fontSize: 14 }}>
Version <strong>{pack.version}</strong> · {t.packStand} {pack.releasedAt}
<br />
<span className="hint">{pack.legalBasis}</span>
</p>
<p className="hint">{t.packHint}</p>
</div>
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.backupTitle}</h2>
<div className="toolbar">
<button
className="primary"
onClick={() =>
downloadText(
`ai-act-kompass-backup-${todayISO()}.json`,
exportData(systems, profile, new Date().toISOString(), training),
'application/json',
)
}
>
{t.backupExport}
</button>
<button className="ghost" onClick={() => fileInput.current?.click()}>
{t.backupImport}
</button>
<input
ref={fileInput}
type="file"
accept="application/json"
style={{ display: 'none' }}
onChange={(e) => {
const file = e.target.files?.[0];
if (file) void handleImport(file);
e.target.value = '';
}}
/>
</div>
{message && <p className="hint">{message}</p>}
</div>
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.legalNoticeTitle}</h2>
<p className="hint">{t.legalGateBody1}</p>
<p className="hint">
<strong>{t.legalGateBody2}</strong>
</p>
<p className="hint">{t.legalGateBody3}</p>
</div>
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.deleteTitle}</h2>
<p className="hint">{t.deleteHint}</p>
<button
className="danger"
onClick={() => {
if (window.confirm(t.deleteConfirm)) {
clearAll();
onClear();
setMessage(t.deleteDone);
}
}}
>
{t.deleteBtn}
</button>
</div>
</div>
);
}

View File

@ -0,0 +1,241 @@
import { useMemo, useState } from 'react';
import { docStrings } from '../engine/docStrings';
import { actionPlan, annexIVSkeleton, riskReport } from '../engine/documents';
import { conformityDeclaration, procurementSpec } from '../engine/extraDocs';
import { deriveObligations } from '../engine/obligations';
import {
employeeInfo,
friaTemplate,
incidentReportForm,
worksCouncilInfo,
} from '../engine/templatesSystem';
import type { AISystem, CompanyProfile, ObligationStatus } from '../engine/types';
import { useI18n } from '../i18n/context';
import { fmt } from '../i18n/ui';
import { printDocument } from '../print/print';
import { downloadText, RiskBadge, ROLE_UI, todayISO, uiDate } from './common';
interface SystemDetailProps {
readonly system: AISystem;
readonly profile: CompanyProfile;
readonly onUpdate: (system: AISystem) => void;
readonly onReassess: () => void;
readonly onDelete: () => void;
readonly onBack: () => void;
}
type DocKind =
| 'report'
| 'plan'
| 'annexIV'
| 'procurement'
| 'conformity'
| 'worksCouncil'
| 'employeeInfo'
| 'fria'
| 'incident';
/** Detailansicht eines Systems: Klassifizierung, Pflichten-Checkliste, Dokumente. */
export function SystemDetail({
system,
profile,
onUpdate,
onReassess,
onDelete,
onBack,
}: SystemDetailProps): JSX.Element {
const { t, locale, pack } = useI18n();
const today = todayISO();
const [preview, setPreview] = useState<DocKind | null>(null);
const obligations = useMemo(
() => deriveObligations(system.classification, system.answers, pack, profile.countries),
[system, pack, profile.countries],
);
const statusOptions: readonly { value: ObligationStatus; label: string }[] = [
{ value: 'open', label: t.statusOpen },
{ value: 'in-progress', label: t.statusInProgress },
{ value: 'done', label: t.statusDone },
{ value: 'not-applicable', label: t.statusNA },
];
const setStatus = (obligationId: string, status: ObligationStatus): void => {
onUpdate({
...system,
updatedAt: new Date().toISOString(),
obligationStatus: { ...system.obligationStatus, [obligationId]: status },
});
};
const docs: Record<DocKind, { label: string; file: string; render: () => string }> = {
report: {
label: t.docRisk,
file: `risikobericht-${system.name}-${today}.md`,
render: () => riskReport(system, pack, today, profile, locale),
},
plan: {
label: t.docPlan,
file: `massnahmenplan-${system.name}-${today}.md`,
render: () => actionPlan(system, obligations, pack, today, profile, locale),
},
annexIV: {
label: t.docAnnexIV,
file: `annex-iv-${system.name}-${today}.md`,
render: () => annexIVSkeleton(system, pack, today, profile, locale),
},
procurement: {
label: t.docProcurement,
file: `lastenheft-${system.name}-${today}.md`,
render: () => procurementSpec(system, pack, today, profile, locale),
},
conformity: {
label: t.docConformity,
file: `konformitaetserklaerung-${system.name}-${today}.md`,
render: () => conformityDeclaration(system, pack, today, profile, locale),
},
worksCouncil: {
label: t.docWorksCouncil,
file: `betriebsrat-info-${system.name}-${today}.md`,
render: () => worksCouncilInfo(system, pack, today, profile, locale),
},
employeeInfo: {
label: t.docEmployeeInfo,
file: `mitarbeiterinfo-${system.name}-${today}.md`,
render: () => employeeInfo(system, pack, today, profile, locale),
},
fria: {
label: t.docFria,
file: `fria-${system.name}-${today}.md`,
render: () => friaTemplate(system, pack, today, profile, locale),
},
incident: {
label: t.docIncident,
file: `vorfallmeldung-${system.name}-${today}.md`,
render: () => incidentReportForm(system, pack, today, profile, locale),
},
};
const isProvider = system.answers.role === 'provider';
const isDeployer = system.answers.role === 'deployer';
const isHigh = system.classification.riskClass === 'high';
const visibleDocs = (Object.keys(docs) as DocKind[]).filter((kind) => {
if (kind === 'annexIV' || kind === 'conformity') return isHigh && isProvider;
if (kind === 'procurement') return isDeployer;
if (kind === 'worksCouncil') return isDeployer && profile.countries.includes('DE');
if (kind === 'employeeInfo') return isDeployer;
if (kind === 'fria') return isDeployer && isHigh;
if (kind === 'incident') return isHigh;
return true;
});
const nationalCodes = profile.countries.filter((code) =>
pack.national.some((n) => n.code === code),
);
return (
<div>
<button className="ghost" onClick={onBack}>
{t.detailBack}
</button>
<h1 style={{ marginTop: 14 }}>
{system.name} <RiskBadge risk={system.classification.riskClass} />
</h1>
<p className="sub">
{ROLE_UI[locale][system.answers.role]} · {system.purpose || t.detailNoPurpose}
</p>
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.detailReasons}</h2>
<ul className="reasons">
{system.classification.reasons.map((r) => (
<li key={r}>{r}</li>
))}
</ul>
<div className="toolbar">
<button className="ghost" onClick={onReassess}>
{t.detailReassess}
</button>
<button className="danger" onClick={onDelete}>
{t.detailDelete}
</button>
</div>
</div>
{obligations.length > 0 && (
<div className="panel">
<h2 style={{ marginTop: 0 }}>
{t.detailObligations} ({obligations.length})
{nationalCodes.length > 0 && (
<span className="hint"> {fmt(t.detailNational, { codes: nationalCodes.join(', ') })}</span>
)}
</h2>
<div className="table-scroll">
<table>
<thead>
<tr>
<th>{docStrings(locale).plan.colObligation}</th>
<th>{docStrings(locale).plan.colLegal}</th>
<th>{docStrings(locale).plan.colDeadline}</th>
<th>{docStrings(locale).plan.colStatus}</th>
</tr>
</thead>
<tbody>
{obligations.map((ob) => {
const status = system.obligationStatus[ob.id] ?? 'open';
return (
<tr key={ob.id}>
<td>
<strong>{ob.title}</strong>
<div className="hint">{ob.description}</div>
</td>
<td>{ob.articles}</td>
<td>{uiDate(ob.deadline, locale)}</td>
<td>
<select
value={status}
onChange={(e) => setStatus(ob.id, e.target.value as ObligationStatus)}
>
{statusOptions.map((o) => (
<option key={o.value} value={o.value}>
{o.label}
</option>
))}
</select>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
)}
<div className="panel">
<h2 style={{ marginTop: 0 }}>{t.detailDocs}</h2>
<div className="toolbar">
{visibleDocs.map((kind) => (
<span key={kind} style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
<button className="ghost" onClick={() => setPreview(preview === kind ? null : kind)}>
{docs[kind].label} {preview === kind ? t.docHide : t.docShow}
</button>
<button
className="primary"
onClick={() =>
printDocument(docs[kind].file.replace(/\.md$/, ''), docs[kind].render(), profile)
}
>
{t.docPrint}
</button>
<button className="ghost" onClick={() => downloadText(docs[kind].file, docs[kind].render())}>
.md
</button>
</span>
))}
</div>
{preview && <pre className="doc-preview">{docs[preview].render()}</pre>}
</div>
</div>
);
}

View File

@ -0,0 +1,105 @@
import { useState } from 'react';
import { aiPolicy, trainingPlan, worksAgreement } from '../engine/templatesCompany';
import { approvalRequest, auditChecklist, reportingPolicy } from '../engine/templatesInternal';
import type { AISystem, CompanyProfile } from '../engine/types';
import { useI18n } from '../i18n/context';
import { printDocument } from '../print/print';
import { downloadText, todayISO } from './common';
interface TemplatesViewProps {
readonly systems: readonly AISystem[];
readonly profile: CompanyProfile;
}
type TplKind = 'policy' | 'reporting' | 'approval' | 'audit' | 'training' | 'worksAgreement';
/** Unternehmensweite Vorlagen: KI-Richtlinie, Schulungsplan, Betriebsvereinbarung. */
export function TemplatesView({ systems, profile }: TemplatesViewProps): JSX.Element {
const { t, locale, pack } = useI18n();
const today = todayISO();
const [preview, setPreview] = useState<TplKind | null>(null);
const templates: Record<
TplKind,
{ label: string; desc: string; file: string; render: () => string }
> = {
policy: {
label: t.tplPolicy,
desc: t.tplPolicyDesc,
file: `ki-richtlinie-${today}.md`,
render: () => aiPolicy(pack, today, profile, locale),
},
reporting: {
label: t.tplReporting,
desc: t.tplReportingDesc,
file: `melde-richtlinie-${today}.md`,
render: () => reportingPolicy(pack, today, profile, locale),
},
approval: {
label: t.tplApproval,
desc: t.tplApprovalDesc,
file: `freigabeantrag-ki-${today}.md`,
render: () => approvalRequest(pack, today, profile, locale),
},
audit: {
label: t.tplAudit,
desc: t.tplAuditDesc,
file: `audit-checkliste-ki-${today}.md`,
render: () => auditChecklist(pack, today, profile, locale),
},
training: {
label: t.tplTraining,
desc: t.tplTrainingDesc,
file: `schulungsplan-${today}.md`,
render: () => trainingPlan(systems, pack, today, profile, locale),
},
worksAgreement: {
label: t.tplWorksAgreement,
desc: t.tplWorksAgreementDesc,
file: `betriebsvereinbarung-ki-${today}.md`,
render: () => worksAgreement(pack, today, profile, locale),
},
};
return (
<div>
<h1>{t.templatesTitle}</h1>
<p className="sub">{t.templatesSub}</p>
{(Object.keys(templates) as TplKind[]).map((kind) => (
<div key={kind} className="panel">
<div className="panel-head">
<div>
<h2 style={{ margin: 0 }}>{templates[kind].label}</h2>
<p className="hint" style={{ margin: '4px 0 0' }}>
{templates[kind].desc}
</p>
</div>
<div className="toolbar" style={{ margin: 0 }}>
<button className="ghost" onClick={() => setPreview(preview === kind ? null : kind)}>
{preview === kind ? t.docHide : t.docShow}
</button>
<button
className="primary"
onClick={() =>
printDocument(templates[kind].file.replace(/\.md$/, ''), templates[kind].render(), profile)
}
>
{t.docPrint}
</button>
<button
className="ghost"
onClick={() => downloadText(templates[kind].file, templates[kind].render())}
>
.md
</button>
</div>
</div>
{preview === kind && <pre className="doc-preview">{templates[kind].render()}</pre>}
</div>
))}
<p className="disclaimer">{t.templatesHint}</p>
</div>
);
}

View File

@ -0,0 +1,346 @@
import { useMemo, useState } from 'react';
import { classify } from '../engine/classify';
import type { AISystem, AssessmentAnswers, ContentItem, Role } from '../engine/types';
import { useI18n } from '../i18n/context';
import { fmt } from '../i18n/ui';
import { RiskBadge, ROLE_UI } from './common';
interface WizardProps {
/** Bestehendes System bei Neubewertung, sonst null. */
readonly existing: AISystem | null;
readonly onSave: (system: AISystem) => void;
readonly onCancel: () => void;
}
interface Draft {
name: string;
purpose: string;
vendor: string;
owner: string;
role: Role;
defCriteria: readonly string[];
isGPAIModel: boolean;
prohibitedPractices: readonly string[];
annexIIICategories: readonly string[];
art63Exception: boolean;
involvesProfiling: boolean;
isAnnexISafetyComponent: boolean;
transparencyTriggers: readonly string[];
}
function initialDraft(existing: AISystem | null, allDefIds: readonly string[]): Draft {
if (!existing) {
return {
name: '', purpose: '', vendor: '', owner: '',
role: 'deployer',
defCriteria: allDefIds,
isGPAIModel: false,
prohibitedPractices: [],
annexIIICategories: [],
art63Exception: false,
involvesProfiling: false,
isAnnexISafetyComponent: false,
transparencyTriggers: [],
};
}
const a = existing.answers;
return {
name: existing.name,
purpose: existing.purpose,
vendor: existing.vendor,
owner: existing.owner,
role: a.role,
defCriteria: a.isAISystem ? allDefIds : [],
isGPAIModel: a.isGPAIModel,
prohibitedPractices: a.prohibitedPractices,
annexIIICategories: a.annexIIICategories,
art63Exception: a.art63Exception,
involvesProfiling: a.involvesProfiling,
isAnnexISafetyComponent: a.isAnnexISafetyComponent,
transparencyTriggers: a.transparencyTriggers,
};
}
function toggle(list: readonly string[], id: string): readonly string[] {
return list.includes(id) ? list.filter((x) => x !== id) : [...list, id];
}
function CheckList({
items,
selected,
onToggle,
}: {
readonly items: readonly ContentItem[];
readonly selected: readonly string[];
readonly onToggle: (id: string) => void;
}): JSX.Element {
return (
<div>
{items.map((item) => (
<label key={item.id} className="check">
<input
type="checkbox"
checked={selected.includes(item.id)}
onChange={() => onToggle(item.id)}
/>
<span>
{item.label}
<span className="ref">
{item.legalRef}
{item.hint ? `${item.hint}` : ''}
</span>
</span>
</label>
))}
</div>
);
}
/** Mehrstufiger Bewertungs-Wizard: erfasst ein KI-System und klassifiziert es. */
export function Wizard({ existing, onSave, onCancel }: WizardProps): JSX.Element {
const { t, locale, pack } = useI18n();
const steps = [t.stepBasics, t.stepDefinition, t.stepProhibited, t.stepHighRisk, t.stepTransparency, t.stepResult];
const allDefIds = useMemo(() => pack.aiDefinitionCriteria.map((c) => c.id), [pack]);
const [step, setStep] = useState(0);
const [draft, setDraft] = useState<Draft>(() => initialDraft(existing, allDefIds));
const isAISystem = draft.defCriteria.length === allDefIds.length;
const answers: AssessmentAnswers = useMemo(
() => ({
isAISystem,
role: draft.role,
isGPAIModel: draft.isGPAIModel,
prohibitedPractices: draft.prohibitedPractices,
annexIIICategories: draft.annexIIICategories,
art63Exception: draft.art63Exception,
involvesProfiling: draft.involvesProfiling,
isAnnexISafetyComponent: draft.isAnnexISafetyComponent,
transparencyTriggers: draft.transparencyTriggers,
}),
[draft, isAISystem],
);
const classification = useMemo(() => classify(answers, pack, locale), [answers, pack, locale]);
const canNext = step !== 0 || draft.name.trim().length > 0;
const save = (): void => {
const now = new Date().toISOString();
onSave({
id: existing?.id ?? crypto.randomUUID(),
name: draft.name.trim(),
purpose: draft.purpose.trim(),
vendor: draft.vendor.trim(),
owner: draft.owner.trim(),
createdAt: existing?.createdAt ?? now,
updatedAt: now,
answers,
classification,
obligationStatus: existing?.obligationStatus ?? {},
});
};
return (
<div>
<h1>{existing ? fmt(t.wizardTitleRe, { name: existing.name }) : t.wizardTitleNew}</h1>
<p className="sub">{t.wizardSub}</p>
<div className="wizard-steps">
{steps.map((label, i) => (
<span key={label} className={`step ${i === step ? 'current' : i < step ? 'done' : ''}`}>
{i + 1}. {label}
</span>
))}
</div>
<div className="panel">
{step === 0 && (
<>
<label className="field">
<span>{t.fieldName}</span>
<input
type="text"
value={draft.name}
placeholder={t.fieldNamePh}
onChange={(e) => setDraft({ ...draft, name: e.target.value })}
/>
</label>
<label className="field">
<span>{t.fieldPurpose}</span>
<textarea
rows={2}
value={draft.purpose}
placeholder={t.fieldPurposePh}
onChange={(e) => setDraft({ ...draft, purpose: e.target.value })}
/>
</label>
<label className="field">
<span>{t.fieldVendor}</span>
<input type="text" value={draft.vendor} onChange={(e) => setDraft({ ...draft, vendor: e.target.value })} />
</label>
<label className="field">
<span>{t.fieldOwner}</span>
<input type="text" value={draft.owner} onChange={(e) => setDraft({ ...draft, owner: e.target.value })} />
</label>
<label className="field">
<span>{t.fieldRole}</span>
<select value={draft.role} onChange={(e) => setDraft({ ...draft, role: e.target.value as Role })}>
{(Object.keys(ROLE_UI[locale]) as Role[]).map((r) => (
<option key={r} value={r}>
{ROLE_UI[locale][r]}
</option>
))}
</select>
<span className="hint">{t.roleHint}</span>
</label>
</>
)}
{step === 1 && (
<>
<h2>{t.defTitle}</h2>
<p className="hint">{t.defHint}</p>
<CheckList
items={pack.aiDefinitionCriteria}
selected={draft.defCriteria}
onToggle={(id) => setDraft({ ...draft, defCriteria: toggle(draft.defCriteria, id) })}
/>
{!isAISystem && <p className="hint"> {t.defWarn}</p>}
</>
)}
{step === 2 && (
<>
<h2>{t.prohTitle}</h2>
<p className="hint">{t.prohHint}</p>
<CheckList
items={pack.prohibitedPractices}
selected={draft.prohibitedPractices}
onToggle={(id) => setDraft({ ...draft, prohibitedPractices: toggle(draft.prohibitedPractices, id) })}
/>
</>
)}
{step === 3 && (
<>
<h2>{t.hrTitle}</h2>
<label className="check">
<input
type="checkbox"
checked={draft.isAnnexISafetyComponent}
onChange={(e) => setDraft({ ...draft, isAnnexISafetyComponent: e.target.checked })}
/>
<span>
{t.annexILabel}
<span className="ref">Art. 6 Abs. 1, Annex I</span>
</span>
</label>
<h2>{t.annexIIITitle}</h2>
<CheckList
items={pack.annexIIICategories}
selected={draft.annexIIICategories}
onToggle={(id) => setDraft({ ...draft, annexIIICategories: toggle(draft.annexIIICategories, id) })}
/>
{draft.annexIIICategories.length > 0 && (
<>
<h2>{t.exceptionTitle}</h2>
<label className="check">
<input
type="checkbox"
checked={draft.involvesProfiling}
onChange={(e) => setDraft({ ...draft, involvesProfiling: e.target.checked })}
/>
<span>
{t.profilingLabel}
<span className="ref">{t.profilingRef}</span>
</span>
</label>
<label className="check">
<input
type="checkbox"
checked={draft.art63Exception}
onChange={(e) => setDraft({ ...draft, art63Exception: e.target.checked })}
/>
<span>
{t.art63Label}
<span className="ref">{t.art63Ref}</span>
</span>
</label>
</>
)}
</>
)}
{step === 4 && (
<>
<h2>{t.trTitle}</h2>
<CheckList
items={pack.transparencyTriggers}
selected={draft.transparencyTriggers}
onToggle={(id) => setDraft({ ...draft, transparencyTriggers: toggle(draft.transparencyTriggers, id) })}
/>
<h2>{t.gpaiTitle}</h2>
<label className="check">
<input
type="checkbox"
checked={draft.isGPAIModel}
onChange={(e) => setDraft({ ...draft, isGPAIModel: e.target.checked })}
/>
<span>
{t.gpaiLabel}
<span className="ref">{t.gpaiRef}</span>
</span>
</label>
</>
)}
{step === 5 && (
<>
<h2>
{t.resultTitle} <RiskBadge risk={classification.riskClass} />
</h2>
<ul className="reasons">
{classification.reasons.map((r) => (
<li key={r}>{r}</li>
))}
</ul>
{classification.gpaiObligations && <p className="hint">{t.resultGpai}</p>}
{classification.riskClass === 'prohibited' && <p className="hint"> {t.resultProhibited}</p>}
<p className="disclaimer">{t.resultDisclaimer}</p>
</>
)}
</div>
<div className="wizard-nav">
<div>
<button className="ghost" onClick={onCancel}>
{t.btnCancel}
</button>
</div>
<div style={{ display: 'flex', gap: 8 }}>
{step > 0 && (
<button className="ghost" onClick={() => setStep(step - 1)}>
{t.btnBack}
</button>
)}
{step < steps.length - 1 && (
<button
className="primary"
disabled={!canNext}
onClick={() => setStep(isAISystem || step === 0 ? step + 1 : steps.length - 1)}
>
{t.btnNext}
</button>
)}
{step === steps.length - 1 && (
<button className="primary" disabled={draft.name.trim().length === 0} onClick={save}>
{t.btnSave}
</button>
)}
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,119 @@
import { useI18n } from '../i18n/context';
import type { Locale } from '../i18n/types';
import type { RiskClass, Role } from '../engine/types';
/** Kurze UI-Labels für Risikoklassen je Sprache. */
export const RISK_UI: Readonly<Record<Locale, Readonly<Record<RiskClass, string>>>> = {
de: {
'out-of-scope': 'Nicht anwendbar',
prohibited: 'Verboten',
high: 'Hochrisiko',
limited: 'Begrenztes Risiko',
minimal: 'Minimales Risiko',
},
en: {
'out-of-scope': 'Out of scope',
prohibited: 'Prohibited',
high: 'High-risk',
limited: 'Limited risk',
minimal: 'Minimal risk',
},
fr: {
'out-of-scope': 'Hors champ',
prohibited: 'Interdit',
high: 'Haut risque',
limited: 'Risque limité',
minimal: 'Risque minimal',
},
it: {
'out-of-scope': 'Fuori ambito',
prohibited: 'Vietato',
high: 'Alto rischio',
limited: 'Rischio limitato',
minimal: 'Rischio minimo',
},
es: {
'out-of-scope': 'Fuera de ámbito',
prohibited: 'Prohibido',
high: 'Alto riesgo',
limited: 'Riesgo limitado',
minimal: 'Riesgo mínimo',
},
pl: {
'out-of-scope': 'Poza zakresem',
prohibited: 'Zakazane',
high: 'Wysokie ryzyko',
limited: 'Ograniczone ryzyko',
minimal: 'Minimalne ryzyko',
},
cs: {
'out-of-scope': 'Mimo působnost',
prohibited: 'Zakázáno',
high: 'Vysoké riziko',
limited: 'Omezené riziko',
minimal: 'Minimální riziko',
},
sk: {
'out-of-scope': 'Mimo pôsobnosti',
prohibited: 'Zakázané',
high: 'Vysoké riziko',
limited: 'Obmedzené riziko',
minimal: 'Minimálne riziko',
},
ro: {
'out-of-scope': 'În afara domeniului',
prohibited: 'Interzis',
high: 'Risc ridicat',
limited: 'Risc limitat',
minimal: 'Risc minim',
},
};
/** Kurze UI-Labels für Rollen je Sprache. */
export const ROLE_UI: Readonly<Record<Locale, Readonly<Record<Role, string>>>> = {
de: { provider: 'Anbieter', deployer: 'Betreiber', importer: 'Einführer', distributor: 'Händler' },
en: { provider: 'Provider', deployer: 'Deployer', importer: 'Importer', distributor: 'Distributor' },
fr: { provider: 'Fournisseur', deployer: 'Déployeur', importer: 'Importateur', distributor: 'Distributeur' },
it: { provider: 'Fornitore', deployer: 'Deployer', importer: 'Importatore', distributor: 'Distributore' },
es: { provider: 'Proveedor', deployer: 'Responsable del despliegue', importer: 'Importador', distributor: 'Distribuidor' },
pl: { provider: 'Dostawca', deployer: 'Podmiot stosujący', importer: 'Importer', distributor: 'Dystrybutor' },
cs: { provider: 'Poskytovatel', deployer: 'Zavádějící subjekt', importer: 'Dovozce', distributor: 'Distributor' },
sk: { provider: 'Poskytovateľ', deployer: 'Nasadzujúci subjekt', importer: 'Dovozca', distributor: 'Distribútor' },
ro: { provider: 'Furnizor', deployer: 'Implementator', importer: 'Importator', distributor: 'Distribuitor' },
};
/** Farbiges Stempel-Badge für die Risikoklasse eines Systems. */
export function RiskBadge({ risk }: { readonly risk: RiskClass }): JSX.Element {
const { locale } = useI18n();
return <span className={`badge ${risk}`}>{RISK_UI[locale][risk]}</span>;
}
/**
* Löst einen Browser-Download für generierten Text aus.
*
* @param filename - Zieldateiname
* @param content - Dateiinhalt
* @param mime - MIME-Type (Default: Markdown)
*/
export function downloadText(filename: string, content: string, mime = 'text/markdown'): void {
const blob = new Blob([content], { type: `${mime};charset=utf-8` });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
/** Heutiges Datum im ISO-Format (YYYY-MM-DD). */
export function todayISO(): string {
return new Date().toISOString().slice(0, 10);
}
/** Formatiert ein ISO-Datum für die UI (DE/PL/CS/SK/RO: TT.MM.JJJJ, FR/IT/ES: TT/MM/JJJJ, EN: ISO). */
export function uiDate(iso: string, locale: Locale): string {
if (locale === 'en') return iso;
const dotLocales: readonly Locale[] = ['de', 'pl', 'cs', 'sk', 'ro'];
const sep = dotLocales.includes(locale) ? '.' : '/';
return iso.split('-').reverse().join(sep);
}

View File

@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"skipLibCheck": true,
"isolatedModules": true,
"resolveJsonModule": true,
"noEmit": true,
"types": ["vite/client"]
},
"include": ["src"]
}

View File

@ -0,0 +1,15 @@
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
base: './',
build: {
outDir: 'dist',
sourcemap: false,
},
test: {
environment: 'node',
include: ['src/**/*.test.ts'],
},
});