From b55799685ed5d374bed241a8154ce5d631ad5303 Mon Sep 17 00:00:00 2001 From: Gerald Fruhmann Date: Sat, 4 Jul 2026 19:26:40 +0200 Subject: [PATCH] docs: translate project-brief to English and add doc stubs - docs/project-brief.md: full English translation of original German brief - docs/setup.md: quick-start guide stub - docs/configuration.md: config reference stub (core keys + env vars) - docs/architecture.md: four-layer diagram + self-hosted stack overview - docs/redmine-setup.md: manual custom field setup guide (API limitation) - docs/templates.md: Jinja2 template reference with all variables Co-Authored-By: Claude Sonnet 4.6 --- docs/architecture.md | 82 +++++++++++++++++++++++ docs/configuration.md | 49 ++++++++++++++ docs/project-brief.md | 150 ++++++++++++++++++++---------------------- docs/redmine-setup.md | 82 +++++++++++++++++++++++ docs/setup.md | 37 +++++++++++ docs/templates.md | 68 +++++++++++++++++++ 6 files changed, 390 insertions(+), 78 deletions(-) create mode 100644 docs/architecture.md create mode 100644 docs/configuration.md create mode 100644 docs/redmine-setup.md create mode 100644 docs/setup.md create mode 100644 docs/templates.md diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..7a7034e --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,82 @@ +# Architecture + +## Four-Layer Design + +```text +┌─────────────────────────────────────────┐ +│ CLI (cli/main.py) │ deploy --target selfhosted|atlassian|m365 +└────────────────┬────────────────────────┘ + │ +┌────────────────▼────────────────────────┐ +│ Adapter (adapters//) │ translates config + rendered templates +│ selfhosted: XWiki + Redmine modules │ into real objects in the target platform +│ atlassian: Confluence + Jira [Ph. 2] │ +│ m365: SharePoint + PA [Ph. 3] │ +└────────────────┬────────────────────────┘ + │ +┌────────────────▼────────────────────────┐ +│ Core (core/) │ +│ config.py — YAML loader + Pydantic │ +│ renderer.py — Jinja2 template engine │ +└────────────────┬────────────────────────┘ + │ +┌────────────────▼────────────────────────┐ +│ Config + Templates │ +│ config/core.yaml — QMS substance │ +│ config/.yaml — tool overlay │ +│ templates/*.md.j2 — doc templates │ +└─────────────────────────────────────────┘ +``` + +## Layer Responsibilities + +### Config layer + +Declarative QMS substance in YAML. Contains clauses 4–10, document definitions, roles, +record types, KPIs, and CAPA states. Tool-specific details live in overlay files. +This is the only file a consultant touches when adapting the kit for a new client. + +### Template layer + +Jinja2 (`.md.j2`) text blocks with `{{ variable }}` placeholders. Rendered at deploy +time using values from the merged config (core + overlay). Output is written to the +target platform as pages or documents. + +### Adapter layer + +One module per platform. Reads the rendered output and creates real objects: + +| Adapter | What it creates | +|---------|----------------| +| `selfhosted/xwiki.py` | XWiki spaces, pages, parent hierarchy | +| `selfhosted/redmine.py` | Redmine projects, trackers, issues | +| `atlassian/` | Confluence spaces/pages, Jira projects/issue types [Phase 2] | +| `m365/` | SharePoint sites/libraries, Power Automate flows [Phase 3] | + +**Idempotency:** each adapter checks whether an object already exists before creating it. +Running `deploy` twice produces the same result without duplicates. + +### CLI layer + +Single entry point (`python -m cli deploy --target --config `). +Orchestrates: load config → merge overlay → render templates → call adapter. + +## Self-hosted Stack + +```text + ┌──────────────┐ + Browser ───▶ │ Reverse Proxy│ (e.g. Caddy / nginx) + └──────┬───────┘ + ┌───────────┴───────────┐ + ▼ ▼ + ┌──────────┐ ┌──────────┐ + │ XWiki │ │ Redmine │ + │ :8080 │ │ :3000 │ + └──────────┘ └──────────┘ + Documents, policies, NCs, CAPAs, + procedures, templates audits, KPIs +``` + +XWiki and Redmine run as separate Docker containers seeded by the Python generator. +Custom field **definitions** in Redmine must be created once manually +(API limitation — see [Redmine Setup](redmine-setup.md)). diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..a608d46 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,49 @@ +# Configuration Reference + +> TODO: Full reference will be written once the core config loader (Pydantic schema) is complete. + +## Overview + +Configuration is split into two layers: + +| File | Purpose | +|------|---------| +| `config/core.yaml` | Tool-neutral QMS substance — clauses, documents, roles, records, KPIs | +| `config/.yaml` | Tool overlay template — copy and fill per client | +| `config/clients/.yaml` | Per-client filled overlay (gitignored, not in this repo) | + +## Core Config Keys + +See [`config/core.yaml`](../config/core.yaml) — all keys are documented inline. + +## Overlay Keys + +| Key | Description | +|-----|-------------| +| `target` | `selfhosted` / `atlassian` / `m365` | +| `organisation.name` | Full legal name of the client organisation | +| `organisation.short` | Short identifier used in document IDs | +| `organisation.quality_officer` | Full name of the QMO | +| `organisation.management` | Full name of the approving manager | + +### Self-hosted specific + +| Key | Description | +|-----|-------------| +| `xwiki.base_url` | XWiki instance URL | +| `xwiki.space_key` | XWiki space key for the QMS (default: `QMS`) | +| `redmine.base_url` | Redmine instance URL | +| `redmine.project_key` | Redmine project identifier | +| `redmine.tracker_mapping` | Maps record type IDs to Redmine tracker names | + +## Environment Variables + +Secrets are never stored in config files — pass them as environment variables: + +| Variable | Used by | +|----------|---------| +| `XWIKI_PASSWORD` | XWiki REST authentication | +| `REDMINE_API_KEY` | Redmine REST authentication | +| `CONFLUENCE_API_TOKEN` | Confluence REST authentication (Phase 2) | +| `JIRA_API_TOKEN` | Jira REST authentication (Phase 2) | +| `SHAREPOINT_CLIENT_SECRET` | SharePoint Graph API (Phase 3) | diff --git a/docs/project-brief.md b/docs/project-brief.md index b075e47..3aeb647 100644 --- a/docs/project-brief.md +++ b/docs/project-brief.md @@ -1,125 +1,119 @@ -# Projekt-Brief: Wiederverwendbarer ISO-9001-QMS-Deployment-Generator +# Project Brief: Reusable ISO 9001 QMS Deployment Generator -> **Kennzeichnungslegende** +> **Notation legend** > -> * **(bestätigt)** = vom Auftraggeber ausdrücklich vorgegeben. -> * **[Schlussfolgerung]** = Vorschlag/Ableitung, nicht final bestätigt. -> * **[Nicht verifiziert]** = nicht überprüfbar in diesem Rahmen. -> * **(belegt)** = in der vorangegangenen Recherche mit Quellen (u. a. Microsoft Learn, Atlassian-Doku, Zertifizierungsstellen wie NQA) belegt. -> -> Da Teile dieses Dokuments Vorschläge sind, gilt die Kennzeichnung für das gesamte Dokument. Die offenen Entscheidungen (Abschnitt 9) sind bewusst nicht gefüllt. +> * **(confirmed)** = explicitly specified by the client. +> * **[conclusion]** = proposal / inference, not finally confirmed. +> * **[not verified]** = could not be verified in this context. +> * **(evidenced)** = supported by prior research with sources (Microsoft Learn, Atlassian docs, certification bodies such as NQA). --- -## 1. Ziel / Use Case (bestätigt) +## 1. Goal / Use Case (confirmed) -* Ein **wiederverwendbares Framework**, das ein ISO-9001-QMS-**Gerüst** automatisiert in Ziel-Tools deployt („Tag 1"). -* Danach werden die organisationsspezifischen Inhalte (Prozesse, Kontext, Risikoregister, Ziele) über ca. 2 Wochen ausgefüllt. -* Ergebnis: ein vollständig dokumentiertes, **audit-fähiges** QMS im Sinne von **interner Reife bzw. Kunden-/Zweitparteien-Audit** (Bedeutung 1, bestätigt). -* Einsatzkontext: Beratung kleiner Kanzleien/Firmen; das Framework soll **pro Kunde wiederverwendbar** sein. +* A **reusable framework** that automatically deploys an ISO 9001 QMS **scaffold** into target tools on day one. +* Afterwards, organisation-specific content (processes, context, risk register, objectives) is filled in over approximately two weeks. +* Result: a fully documented, **audit-ready** QMS in the sense of **internal maturity or customer/second-party audit** (confirmed). +* Context: consulting small law firms / companies; the framework shall be **reusable per client**. -## 2. Scope-Abgrenzung +## 2. Scope -* **Allgemeines ISO 9001** (branchenneutral), **keine** Medizinprodukte (kein ISO 13485 / IEC 62304). (bestätigt) -* Zielzustand ist Dokumentations-/interne Reife, **nicht** die akkreditierte Zertifizierung. (bestätigt) -* **(belegt)** Grenze: Eine akkreditierte Zertifizierung setzt zusätzlich eine Betriebsphase voraus (üblich ~3 Monate inkl. einem vollständigen internen Audit-Zyklus und einem Management-Review). Diese Zeit lässt sich nicht wegkonfigurieren und liegt außerhalb dessen, was das Deployment leistet. +* **General ISO 9001** (sector-neutral), **no** medical devices (no ISO 13485 / IEC 62304). (confirmed) +* Target state is documentation / internal maturity, **not** accredited certification. (confirmed) +* **(evidenced)** Limit: accredited certification additionally requires an operating phase (typically ~3 months including a full internal audit cycle and a management review). This time cannot be configured away and is outside the scope of what the deployment delivers. -## 3. Funktionaler Umfang – „voller Umfang" (bestätigt) +## 3. Functional Scope — "full scope" (confirmed) -Pro Ziel-Tool soll deployt werden: +Per target tool to be deployed: -* **Struktur**: Space/Site/Projekt, Dokumentenbaum, Namenskonventionen. -* **Dokument-Templates** mit Platzhaltern: Qualitätspolitik, Verfahren, Management-Review-Agenda, internes Audit-Checklist, CAPA-/NC-Formular. -* **Record-Container**: Listen-/Issue-Schemata für NC, CAPA, Audits, Ziele/KPIs. -* **Workflows**: Freigabe/Review, CAPA-Routing, Review-Erinnerungen. -* **Dashboards**: KPI-/Status-Übersicht. -* Abdeckung der ISO-9001-Klauseln 4–10 als Gliederungslogik. +* **Structure**: space / site / project, document tree, naming conventions. +* **Document templates** with placeholders: quality policy, procedures, management review agenda, internal audit checklist, CAPA / NC form. +* **Record containers**: list / issue schemas for NC, CAPA, audits, objectives / KPIs. +* **Workflows**: approval / review, CAPA routing, review reminders. +* **Dashboards**: KPI / status overview. +* Coverage of ISO 9001 clauses 4–10 as the structuring logic. -## 4. Zielplattformen + Reihenfolge (bestätigt) +## 4. Target Platforms + Priority (confirmed) -Priorität: **1. self-hosted → 2. Atlassian (Confluence + Jira) → 3. Microsoft 365 (SharePoint)**. +Priority: **1. self-hosted → 2. Atlassian (Confluence + Jira) → 3. Microsoft 365 (SharePoint)**. -Plattform-Constraints **(belegt)**, die beim Adapter-Bau zu beachten sind: +Platform constraints **(evidenced)** to consider when building adapters: -* **Atlassian**: Provisioning über Confluence-/Jira-REST-API bzw. Forge. Freigabe-Workflow + Versionierung sind in Confluence Cloud **nicht nativ** → Marketplace-App nötig (z. B. Comala); dieser Teil ist nur **teil-automatisierbar**. Kein offizieller First-Party-Terraform-Provider für Atlassian Cloud. -* **M365**: Template-basiertes Provisioning (PnP) ist **PowerShell-/.NET-nativ**; Site Scripts (JSON) und Power Automate für Freigabe/Erinnerungen. Python kann die REST-/Graph-API bedienen, hat aber **keine gepflegte PnP-Provisioning-Template-Engine**. -* **self-hosted**: end-to-end skriptbar (Docker/Compose + Seed über REST/DB); Betrieb/Wartung liegt beim Betreiber. +* **Atlassian**: provisioning via Confluence / Jira REST API or Forge. Approval workflow + versioning are **not native** in Confluence Cloud → Marketplace app required (e.g. Comala); this part is **only partially automatable**. No official first-party Terraform provider for Atlassian Cloud. +* **M365**: template-based provisioning (PnP) is **PowerShell / .NET-native**; Site Scripts (JSON) and Power Automate for approval / reminders. Python can use the REST / Graph API but has **no maintained PnP provisioning template engine**. +* **Self-hosted**: end-to-end scriptable (Docker / Compose + seed via REST / DB); operation / maintenance is the operator's responsibility. -## 5. Architektur — [Schlussfolgerung] +## 5. Architecture — [conclusion] -[Schlussfolgerung] Vier Schichten, konfig-getrieben, idempotent: +Four layers, config-driven, idempotent: -``` +```text qms-kit/ ├─ config/ -│ ├─ core.yaml # tool-neutral: Klauseln 4–10, Dok-Liste, Record-Typen, Rollen, KPIs, CAPA-States -│ ├─ selfhosted.yaml # Overlay: DB/Host, Modul-Mapping des OSS-Tools -│ ├─ atlassian.yaml # Overlay: Space-Keys, Jira-Projekt/Issue-Types, App-Konfig -│ └─ m365.yaml # Overlay: Site-URLs, Listen-Mapping, Flow-IDs -├─ templates/ # Textbausteine mit Platzhaltern (Jinja2) +│ ├─ core.yaml # tool-neutral: clauses 4–10, doc list, record types, roles, KPIs, CAPA states +│ ├─ selfhosted.yaml # overlay: DB/host, module mapping for the OSS tool +│ ├─ atlassian.yaml # overlay: space keys, Jira project/issue types, app config +│ └─ m365.yaml # overlay: site URLs, list mapping, flow IDs +├─ templates/ # text blocks with placeholders (Jinja2) │ ├─ policy.md.j2 │ ├─ procedure.md.j2 │ ├─ mgmt_review_agenda.md.j2 │ ├─ internal_audit_checklist.md.j2 │ └─ capa_form.md.j2 -├─ core/ # Config-Loader, Schema-Validierung, Template-Renderer +├─ core/ # config loader, schema validation, template renderer ├─ adapters/ -│ ├─ selfhosted/ # XWiki (Docs) + Redmine (Records): Docker-Compose + Seed via REST -│ ├─ atlassian/ # REST-Skripte (Spaces/Seiten/Jira-Issues/Dashboards) -│ └─ m365/ # PnP-PowerShell-Skripte + Site Scripts (JSON) + Power-Automate-Export -├─ cli/ # Einstieg: deploy --target selfhosted|atlassian|m365 +│ ├─ selfhosted/ # XWiki (docs) + Redmine (records): Docker Compose + seed via REST +│ ├─ atlassian/ # REST scripts (spaces / pages / Jira issues / dashboards) +│ └─ m365/ # PnP PowerShell scripts + site scripts (JSON) + Power Automate export +├─ cli/ # entry point: deploy --target selfhosted|atlassian|m365 ├─ docs/ └─ tests/ ``` -Schichtbeschreibung [Schlussfolgerung]: +Layer description [conclusion]: -1. **Config-Layer** – deklarative QMS-Substanz + Tool-Overlays. -2. **Template-Layer** – Textbausteine mit Variablen; beim Deployment gerendert und in die Zielplattform geschrieben. -3. **Adapter-Layer** – pro Tool ein Übersetzer von Config+Templates in echte Objekte. -4. **CLI-Layer** – ein Einstiegspunkt, idempotent. +1. **Config layer** — declarative QMS substance + tool overlays. The file touched when extending. +2. **Template layer** — text blocks with variables; rendered at deployment time and written to the target platform. +3. **Adapter layer** — one translator per tool from config + templates into real objects (see constraints in section 4). +4. **CLI layer** — single entry point, idempotent (M365 Site Scripts are natively non-destructive per Microsoft; idempotency for self-hosted / Atlassian must be implemented). -## 6. Technische Entscheidungen +## 6. Technical Decisions -* **Config-Format: YAML** (bestätigt). -* **Sprache: Python als Kern/Orchestrator + im M365-Adapter PnP PowerShell per shell-out** (bestätigt). -* **Config-Struktur: tool-neutrale Kern-Config + Tool-Overlays** (bestätigt). +* **Config format: YAML** (confirmed). +* **Language: Python as core / orchestrator + PnP PowerShell in the M365 adapter via shell-out** (confirmed). +* **Config structure: tool-neutral core config + tool overlays** (confirmed). -## 7. Wiederverwendbarkeit (bestätigt) +## 7. Reusability (confirmed) -* Multi-Tenant: gleiche QMS-Substanz, pro Kunde ein Overlay/Instanz. -* Versioniert (Semver + Changelog), Adapter als austauschbare Module. -* Erweiterbar: neue Dokumente/Prozesse ergänzen, ohne Adapter zu ändern. +* Multi-tenant: same QMS substance, one overlay / instance per client. +* Versioned (Semver + changelog), adapters as interchangeable modules. +* Extensible: add new documents / processes without changing adapters. -## 8. Nicht-Ziele / Grenzen +## 8. Non-Goals / Limits -* Kein Erzeugen der akkreditierten Zertifizierungs-Reife (Betriebs-/Nachweisphase, s. Abschnitt 2). -* Auf Atlassian: Freigabe/Versionierung nur teil-automatisiert (App-abhängig). -* Der Generator liefert ein audit-*fähiges Gerüst*; die inhaltliche Prozessarbeit bleibt manuell. +* Does not produce accredited certification readiness (operating / evidence phase, see section 2). +* On Atlassian: approval / versioning only partially automated (app-dependent). +* The generator delivers an audit-*ready scaffold*; the substantive process work remains manual. -## 9. Getroffene Entscheidungen +## 9. Decisions Made -### 9.1 Self-hosted-Zielzustand (bestätigt): XWiki + Redmine +### 9.1 Self-hosted target (confirmed): XWiki + Redmine as the "solution" (analogous to Confluence + Jira) -* **XWiki** = Dokumenten-Ebene (QM-Handbuch, Policy, Prozeduren, Templates). LGPL-2.1, automatische Versionierung, REST-API, offizielles Docker-Image. **[Nicht verifiziert]:** exakte Ausprägung des Approval-/Publication-Workflows. -* **Redmine** = Record-/Tracking-Ebene (CAPA, NC, Audits, Ziele/KPIs). GNU GPL v2, REST-API, Docker Official Image. -* **Verifizierte API-Grenze (Redmine):** Custom-Field-Definitionen sind per API nur lesbar; das Anlegen neuer Felder ist per API nicht möglich. Der Generator seedet Projekte/Issues/Feldwerte; die Felddefinitionen müssen einmalig manuell eingerichtet werden. +* **XWiki** = document layer (QM manual, policy, procedures, templates). Verified: LGPL-2.1 (OSI-approved), automatic **versioning** and **REST API**; **official Docker image** (`xwiki`) + Docker Compose setups (MySQL / MariaDB / PostgreSQL on Tomcat). **[Not verified]:** exact form of the approval / publication workflow (extension vs. out-of-the-box). +* **Redmine** = record / tracking layer (trackable items: CAPA, NC, audits, objectives / KPIs). Verified: **GNU GPL v2** (open source, free licence), REST API can set **custom field values** via POST / PUT; **Docker official image** `redmine` + Docker Compose example on the official Docker Hub page. Note: the Docker image is maintained by docker-library (not Redmine upstream). +* **Verified API limit (Redmine):** custom field **definitions** are **read-only** via API (GET only); **creating** new fields via API is not possible. [Conclusion] The generator seeds projects / issues / field **values**; field **definitions** (e.g. Root Cause, Effectiveness Check, Status) must be set up **once manually or via plugin**. +* **Deployment (confirmed / verified):** both as separate Docker containers connected via reverse proxy; both REST APIs can be seeded from the Python generator. [Conclusion] XWiki's REST API is advantageous for seeding. -### 9.2 Config-Struktur (bestätigt): tool-neutrale Kern-Config + Tool-Overlays. +### 9.2 Config structure (confirmed): tool-neutral core config + tool overlays -### 9.3 Sprache (bestätigt): Python-Kern + PnP-PowerShell im M365-Adapter. +### 9.3 Language (confirmed): Python core + PnP PowerShell in the M365 adapter -### 9.4 Prozesszeichnung (bestätigt): Fallback draw.io (Docker-self-hostbar), PNG/SVG-Export in XWiki-Seite einfügen. +### 9.4 Process diagrams (confirmed): draw.io embedded as PNG in XWiki -## 10. Lieferreihenfolge (bestätigt) +draw.io is Docker-self-hostable, supports BPMN, and exports PNG / SVG. [Conclusion] PNG is a static image; the editable source stays in draw.io. -**self-hosted-Adapter zuerst**, dann Atlassian, dann M365. Kern-Config + Templates zuerst (tool-neutral). - ---- +**Scope note:** The self-hosted target is therefore a **two-tool stack** (XWiki + Redmine). The adapter `adapters/selfhosted/` is split into an XWiki module and a Redmine module. -## Anhang: Auftrag an Claude Code +## 10. Delivery Order (confirmed) -* Erzeuge das Repo-Gerüst gemäß Abschnitt 5, beginnend mit Kern-Config + Templates + **self-hosted-Adapter**. -* Halte die Plattform-Constraints aus Abschnitt 4 ein. -* Fülle **keine** der offenen Entscheidungen selbstständig – frage nach oder markiere als TODO. -* Kennzeichne im Code/Docs, was Annahme vs. bestätigte Vorgabe ist. +Following the priority: **self-hosted adapter first**, then Atlassian, then M365. Core config + templates first as they are tool-neutral. diff --git a/docs/redmine-setup.md b/docs/redmine-setup.md new file mode 100644 index 0000000..5fc10ae --- /dev/null +++ b/docs/redmine-setup.md @@ -0,0 +1,82 @@ +# Redmine Setup — Manual Custom Field Definitions + +## Why Manual? + +The Redmine REST API supports reading custom field definitions (`GET /custom_fields.json`) +but **cannot create them**. This is a verified API limitation. + +The qms-kit deployer seeds projects, issues, and field *values* automatically. +Field *definitions* must be created once manually before the first deployment. + +## Required Custom Fields + +Create the following fields in **Administration → Custom Fields** in Redmine. +Assign each field to the appropriate tracker. + +### Nonconformity (NC) tracker + +| Field name | Type | Required | +|------------|------|----------| +| Detected By | Text | Yes | +| Severity | List: Low / Medium / High / Critical | Yes | +| Root Cause | Long text | No | +| Correction | Long text | No | +| Correction Date | Date | No | + +### CAPA tracker + +| Field name | Type | Required | +|------------|------|----------| +| NC Reference | Text | No | +| Root Cause | Long text | Yes | +| Corrective Action | Long text | Yes | +| Effectiveness Check | Long text | No | +| Effectiveness Check Date | Date | No | + +### Internal Audit tracker + +| Field name | Type | Required | +|------------|------|----------| +| Auditor | Text | Yes | +| Audit Scope | Text | Yes | +| Findings | Long text | No | +| Observations | Long text | No | +| Follow-up Date | Date | No | + +### KPI Measurement tracker + +| Field name | Type | Required | +|------------|------|----------| +| KPI ID | Text | Yes | +| Period | Text | Yes | +| Target | Text | Yes | +| Actual | Text | Yes | +| Trend | List: Up / Stable / Down | No | +| Action Required | Boolean | No | + +## Tracker Names + +The tracker names in Redmine must match the values in your overlay config +(`config/clients/.yaml` → `redmine.tracker_mapping`). + +Default mapping from `config/selfhosted.yaml`: + +```yaml +tracker_mapping: + nc: "Nonconformity" + capa: "CAPA" + audit: "Internal Audit" + kpi: "KPI Measurement" +``` + +Create trackers in **Administration → Trackers** before creating custom fields. + +## After Manual Setup + +Once fields and trackers exist, run the deployer normally: + +```bash +python -m cli deploy --target selfhosted --config config/clients/.yaml +``` + +The deployer will find the trackers by name and seed issues with the correct field values. diff --git a/docs/setup.md b/docs/setup.md new file mode 100644 index 0000000..36f502d --- /dev/null +++ b/docs/setup.md @@ -0,0 +1,37 @@ +# Setup Guide + +> TODO: Full installation walkthrough will be written once the self-hosted adapter is complete. + +## Prerequisites + +- Docker and Docker Compose installed +- Python 3.12+ +- `uv` package manager (`pip install uv`) + +## Quick Start (Self-hosted) + +```bash +# 1. Clone the repository +git clone https://github.com/gerfru/qms-kit.git +cd qms-kit + +# 2. Install dependencies +uv sync + +# 3. Copy and fill in the client overlay +cp config/selfhosted.yaml config/clients/acme.yaml +# edit config/clients/acme.yaml with your org details, XWiki URL, Redmine URL + +# 4. Start the self-hosted stack +docker compose -f adapters/selfhosted/docker-compose.yml up -d + +# 5. Run the one-time Redmine manual setup (custom field definitions) +# See docs/redmine-setup.md + +# 6. Deploy the QMS scaffold +python -m cli deploy --target selfhosted --config config/clients/acme.yaml +``` + +## Next Steps + +See [Configuration Reference](configuration.md) for all available options. diff --git a/docs/templates.md b/docs/templates.md new file mode 100644 index 0000000..0a4c29e --- /dev/null +++ b/docs/templates.md @@ -0,0 +1,68 @@ +# Template Reference + +## Overview + +All templates are [Jinja2](https://jinja.palletsprojects.com/) files located in `templates/`. +They use `{{ variable }}` syntax for placeholders and are rendered by `core/renderer.py` +at deployment time. + +## Available Templates + +| File | Document | ISO Clause | +|------|----------|------------| +| `policy.md.j2` | Quality Policy | 5.2 | +| `procedure.md.j2` | Generic Procedure | 7.5 / 8.x / 9.x / 10.x | +| `mgmt_review_agenda.md.j2` | Management Review Agenda + Minutes | 9.3 | +| `internal_audit_checklist.md.j2` | Internal Audit Checklist | 9.2 | +| `capa_form.md.j2` | CAPA Form | 10.2 | + +## Common Variables + +All templates receive the following variables from the merged config: + +| Variable | Source | Description | +|----------|--------|-------------| +| `org_name` | `organisation.name` | Full legal name of the organisation | +| `org_short` | `organisation.short` | Short identifier | +| `quality_officer` | `organisation.quality_officer` | QMO full name | +| `management` | `organisation.management` | Approving manager full name | +| `date` | injected at render time | ISO 8601 date string | +| `version` | `meta.version` | Document version | + +## Template-specific Variables + +### `procedure.md.j2` + +| Variable | Description | +|----------|-------------| +| `procedure_title` | Title of this specific procedure | +| `doc_id` | Unique document identifier (e.g. `QMS-P-7.5-001`) | +| `owner_role` | Role responsible for this procedure | +| `approver` | Name or role of the approving person | +| `clause` | ISO 9001 clause number | +| `author` | Author of the initial version | + +### `internal_audit_checklist.md.j2` + +| Variable | Description | +|----------|-------------| +| `audit_date` | Date of the audit | +| `auditor` | Name of the auditor | +| `audit_scope` | Area / process being audited | +| `contact` | Auditee contact person | + +### `capa_form.md.j2` + +| Variable | Description | +|----------|-------------| +| `capa_id` | Unique CAPA identifier (e.g. `CAPA-2024-001`) | +| `opened_date` | Date the CAPA was opened | +| `opened_by` | Person who opened the CAPA | +| `source_ref` | Reference to triggering NC, audit finding, etc. | + +## Adding a New Template + +1. Create `templates/.md.j2` with `{{ variable }}` placeholders. +2. Register it in `config/core.yaml` under the relevant document's `template:` key. +3. Add any new variables to `core/renderer.py` context building. +4. No adapter changes needed — adapters receive the rendered string.