Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Architecture

## Four-Layer Design

```text
┌─────────────────────────────────────────┐
│ CLI (cli/main.py) │ deploy --target selfhosted|atlassian|m365
└────────────────┬────────────────────────┘
┌────────────────▼────────────────────────┐
│ Adapter (adapters/<target>/) │ 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/<target>.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 <t> --config <f>`).
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)).
49 changes: 49 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -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/<target>.yaml` | Tool overlay template — copy and fill per client |
| `config/clients/<client>.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) |
Loading