---
name: documentation
description: |
  Automatically generates technical documentation for SmartStack.
  Use this skill when:
  - User asks to create/generate documentation
  - User mentions "document", "documentation", "doc", "ERD", "schema"
  - User wants to document a module, table, tool, or test
  - After implementing a feature to generate its documentation
  Types: user module, developer tools, database ERD, testing tools
argument-hint: "<module-name> [--type user|developer|database|testing] [--tech]"
allowed-tools: [Read, Glob, Grep, Bash]  # Bash: CLI invocation
---

<objective>
Generate and maintain technical documentation integrated into the SmartStack web app.

Two colocated CLIs do the deterministic work (`cli/extract-doc`, `cli/scaffold-doc`)
and the ui-polish CLI enforces theme tokens; you author the faithful Mock UI in between.
</objective>

<quick_start>
## WHEN THIS SKILL ACTIVATES

### PREREQUISITE — ONLY post-implementation
This skill requires the feature page to already exist (generated by /ba-develop).
It reads real TSX pages, controllers, and entities. Without them, nothing to document.

→ For reviewing/editing the analysis BEFORE implementation: use `/ba-audit-pre-dev`

Claude automatically invokes this skill when it detects:

| Trigger | Example |
|---------|---------|
| ❌ NEVER during BA | Before /ba-develop — feature page does not exist yet |
| Explicit request | "Document the SLA module" |
| Documentation mention | "We should create the doc for..." |
| After implementation | "The feature is done, generate the doc" |
| Structure question | "How is the documentation organized?" |
| Keywords | "ERD", "schema", "diagram", "document" |
| **Update request** | "Update the doc", "refresh documentation", "doc is outdated" |
| **Drift detected** | "The SLA documentation is stale" |
</quick_start>

<parameters>
## DOCUMENTATION TYPES

| Type | Description | Output |
|------|-------------|--------|
| `user` | User module (Mock UI) | `docs/business/{group}/{application}/{module}/index.tsx` (standalone TSX with Mock UI) |
| `developer` | Development tool guide | `docs/developer/tools/{Tool}Page.tsx` |
| `database` | Schema with ERD diagram | `docs/developer/database/{Schema}SchemaPage.tsx` |
| `testing` | Testing tool | `docs/developer/testing/{Tool}TestingPage.tsx` |

> **Updating an existing doc = re-run the skill with the SAME type** — the CLIs
> are idempotent (there is NO `update` type; the Zod schemas reject it).
>
> **`--tech` (opt-in, OFF by default)**: also generate the Section 9
> « Référence technique » appendix (API endpoints + business-rules tables).
> Without it a `user` doc has 8 sections — permissions live in Section 2
> (« Accès & rôles »). A re-run without `--tech` NEVER removes an existing
> technical section.

### Available Developer tools

| Category | Tools |
|----------|-------|
| Local Environment | Docker Compose, MailDev, VS Code, Environment variables |
| API Testing | Postman, REST Client, Swagger/OpenAPI |
| E2E Testing | Microsoft Playwright, Inspector, Trace Viewer |
| Load Testing | NBomber (.NET), k6, Azure Load Testing |
| Security Testing | OWASP ZAP, Security Code Scan, Snyk, OWASP ASVS |
</parameters>

<workflow>
## WORKFLOW EXECUTION SEQUENCE

Two colocated CLIs do the deterministic work; you author the faithful Mock UI in between.

1. **[Step 00: Init](steps/step-00-init.md)** — Detect type + target + application
2. **[Step 01: Scan](steps/step-01-scan.md)** — run **`extract-doc`** (real page, chart types, endpoints, rules, entity props)
3. **[Step 02: Generate](steps/step-02-generate.md)** — author the page + i18n content, then run **`scaffold-doc`** (writes i18n + manifest, returns a wiring plan you apply)
4. **[Step 03: Validate](steps/step-03-validate.md)** — run **ui-polish** (theme tokens) + verify wiring + typecheck

### CLIs

| CLI | Role |
|-----|------|
| `cli/extract-doc` | Read-only report: **frontend mode (source monorepo vs client package)**, real page TSX, chart→Mock-UI mapping, API endpoints (resolved permissions), business rules, entity props, namespace/routes (**kebab namespace in client mode**), **+ `accessRoles` (the « Accès & rôles » join: code permissions × core-seed state roles × rbac.md portée — code is the source of truth, drift → warnings)**, **+ structure scan of the existing doc (`existingDoc.forbiddenSections` to strip, `existingDoc.missingRequired` = objective + header `summary` tagline to add; NON-blocking: `adviseRolesTable`, `overflowRisks`)** |
| `cli/scaffold-doc` | **Bimodal.** Source: writes 4 i18n files (FLAT for user / nested for DocRenderer) + upserts `docs-manifest.json` + emits the wiring plan (config.ts / DocRoutes.tsx / DocPanelContext.tsx / UserIndexPage.tsx). Client: writes 4 i18n files (kebab namespace) + `src/extensions/<kebab>Registry.ts` (`docs.*` PageRegistry seam) + creates/upserts the manifest + instructs re-running aggregate-component-registry. **Fails loudly (exit 1) on any missing wiring target or violated client invariant.** |
| `development/frontend/ui-polish` | Enforces theme tokens (zero hardcoded colours) — replaces the old manual colour rules |

### Deployment modes (auto-detected by the CLIs)

| | `source` (SmartStack.app monorepo) | `client` (generated project on `@atlashub/smartstack`) |
|---|---|---|
| Detection | web `package.json` **is** the package / DocRoutes.tsx + i18n config.ts in-tree | web `package.json` **depends on** the package / componentRegistry.generated.ts |
| Types supported | user, developer, database, testing | **user ONLY** (DocRenderer is not exported by the package) |
| Namespace | camelCase (`docsAdministrationUsers`) | **kebab** (`docs-administration-users`) — file name = namespace (moduleResources contract) |
| Page folder | `src/pages/docs/business/{platform\|personal}/{app}/{module}/` | `src/pages/docs/business/{app}/{module}/` (no group segment) |
| Routing | static `<Route>` in DocRoutes.tsx | `PageRegistry.register('docs.{app}.{module}', …)` → the package's `buildExtensionDocRoutes()` |
| Doc panel button | docMapping edit in DocPanelContext.tsx | **package-owned** — falls back to the user-docs root until the package derives client mappings from `docs.*` keys (reported as `panel-limitation`) |

> Invoke CLIs with `npx --prefer-offline tsx skills/documentation/cli/<cli>/index.ts --spec '<JSON>'`.
> On Windows PowerShell, call through the Bash tool (single-quoted JSON) or escape `"` as `\"`.

### Quick Reference

| Scenario | Key Actions |
|------|-----------|
| `user` | extract-doc → read real page → author standalone annotated Mock UI (Section 2 = « Accès & rôles » table from `report.accessRoles`) + FLAT i18n → scaffold-doc → apply wiring → ui-polish |
| `developer\|database\|testing` | extract-doc (thin) + tool/schema data → author doc-data.ts + DocRenderer wrapper + FLAT i18n → scaffold-doc → apply wiring → ui-polish |
| re-run on an existing doc | extract-doc (+ **strip any `existingDoc.forbiddenSections`, add any `existingDoc.missingRequired` = objective / header `summary`; follow the NON-blocking `adviseRolesTable` / `overflowRisks` advice**) → refresh Mock UI / endpoints / rules → re-run scaffold-doc (idempotent) → ui-polish → §0 structure gate |
</workflow>

<entry_point>
## SKILL ENTRY POINT

**Start with:** [steps/step-00-init.md](steps/step-00-init.md)

All execution flows through this progressive loading architecture. Each step file contains:
- Clear execution sequence
- Success metrics
- Next step reference
</entry_point>

<execution_rules>
## ABSOLUTE RULES

1. **NEVER** hardcoded text → `useTranslation('<namespace>')`
2. **NEVER** ASCII art → React/HTML components for ERD
3. **ALWAYS** read the REAL page TSX (located by `extract-doc`) before writing Mock UI
4. **ALWAYS** use the real endpoints / business rules from the `extract-doc` report (curated, not dumped verbatim)
5. **ALWAYS** annotate every Mock UI section with the canonical `Annotation` component
6. **ALWAYS** author i18n in ALL 4 languages (FR, EN, DE, IT)
7. **i18n shape depends on type:** `user` = FLAT (no root key; resolved via `t('title')`); `developer/database/testing` = NESTED under the namespace key (resolved via `t('<namespace>.path')`). Author FLAT content — `scaffold-doc` wraps it for the DocRenderer types.
8. **ALWAYS** run `scaffold-doc` (i18n files + manifest), then apply its wiring plan — **bimodal**: source = in-place TSX edits (config.ts, DocRoutes.tsx, DocPanelContext.tsx, UserIndexPage.tsx); client = execute the `aggregate` instruction (re-run aggregate-component-registry) and report the `panel-limitation` info. A scaffold-doc failure (exit 1) STOPS the flow — fix its `errors[]`, never ship an unrouted page. **NEVER edit files under `node_modules/`.**
9. **ALWAYS** run the ui-polish CLI before finishing (theme-token enforcement)
10. **For `user` type:** standalone annotated Mock UI TSX page. **DO NOT use DocRenderer.**
11. **For `developer|database|testing` types:** DocRenderer with `doc-data.ts` + `index.tsx` wrapper + `i18nNamespace` prop.
12. **ALWAYS** lead with **Objectif** as Section 1 — a factual description of what the module does, as its own numbered section (never folded into the header subtitle). **NEVER** include problème/solution, "Bénéfices" or "Avant/Après" sections — this is documentation, not sales. Both sides are enforced by the step-03 §0 structure gate.
13. **Section 2 = « Accès & rôles »** (`user` type): the Rôle | Peut faire | Portée table authored from `report.accessRoles.rows` ONLY — the code is the source of truth, NEVER invent a grant; join warnings are REPORTED to the user, never published. `source === 'ba'` → render the `access.unverified` caveat; `unmappedCodePermissions` → render as a caveat. Fallback `source === 'none'` → the plain access card (URL + required-permissions list). No breadcrumb — the doc opens as a panel on the page itself; keep only the URL.
14. **Section 9 « Référence technique » is opt-in (`--tech`), OFF by default** — 8 sections without it. A re-run without `--tech` NEVER removes an existing technical section. Header stats (`businessRules` + `apiEndpoints`) stay in BOTH cases.

### Theme / colour — delegated to the ui-polish CLI

15. **Colour & token compliance is enforced by the ui-polish CLI**, not by hand. After the page exists, run it (step-03) in apply mode (`--regenerate-threshold 0`). Do NOT hand-map Tailwind colours or maintain a mapping table — the CLI maps hardcoded colours → theme tokens deterministically. See `development/frontend/ui-polish`.

### Doc-specific intent the CLI can't infer (keep while authoring)

16. **Dashboard chart series / KPI use the `--dataviz-*` palette** (`--dataviz-accent`, `--dataviz-cat-1..12`, `--dataviz-trend-*`) — never `--color-accent-*`/`--color-primary-*` for data series. Mirrors the real `DashboardPage.tsx`.
17. **Brand colour = the themeable `--color-accent-*` ramp**, never the frozen `--color-primary-*` indigo.
18. **Highlight blocks (Annotation, Tip, "Avec la fonctionnalité")** use the discreet accent pattern `border-l-2 border-[var(--color-accent-500)] bg-[var(--bg-secondary)]` — never `--info/success/warning/error-bg` (reserved for real alerts).

### Mock UI fidelity + layout (user type — detail in templates.md)

19. **Faithful reproduction**: match the real page's layout family + each chart's recharts type (`extract-doc` `charts[]`). Never a generic KPI/table substitute.
20. **Expressive chart data**: ratio max/min(>0) ≥ 5x, visible peak + valley, height ≥ `h-24` (page) / `h-20` (DocPanel), real metric + unit (not abstract 0-100%).
21. **Annotations** sit INSIDE the same padded container as the Mock UI they explain; compact (`px-3 py-2 text-xs`).
22. **No DocPanel overflow**: `overflow-hidden` on chart cards, `min-w-0` on flex children, no fixed px bar widths; root container `space-y-8 max-w-5xl mx-auto pb-12` (no horizontal padding).
23. **Official card pattern**: `p-N bg-[var(--bg-card)] border border-[var(--border-color)] rounded-[var(--radius-card)]` — not `className="card"`, not `rounded-lg`, not `bg-white`/`bg-gray-*`.
24. **Fixed header block** (identical across pages): title + icon → **required accent tagline `t('summary')`** (`text-xl text-[var(--color-accent-600)] font-medium`) → `t('subtitle')` → inline stats line `<span>{N} {t('header.x')}</span>` (count as sibling text, **never** pills, **never** `t('header.x', {count})`). Missing tagline fails the §0 gate (`missingRequired` = `['summary']`).
</execution_rules>

<step_files>
## Step Files

| Step | File | Purpose |
|------|------|---------|
| 00 | [steps/step-00-init.md](steps/step-00-init.md) | Detect documentation type, target, application |
| 01 | [steps/step-01-scan.md](steps/step-01-scan.md) | Run `extract-doc` → report |
| 02 | [steps/step-02-generate.md](steps/step-02-generate.md) | Author content, run `scaffold-doc`, apply wiring plan |
| 03 | [steps/step-03-validate.md](steps/step-03-validate.md) | Run ui-polish, verify wiring, typecheck |
</step_files>

<success_criteria>
- Documentation page renders correctly in the React app
- Mock UI faithfully reproduces the real page interface (not generic KPI/table)
- Every Mock UI section has `Annotation` components explaining each visual element
- i18n files created in ALL 4 languages (FR, EN, DE, IT) — FLAT for `user`, nested under the namespace key for DocRenderer types
- ui-polish reports 0 colour errors on the generated page
- Wiring applied per mode — **source**: route in `DocRoutes.tsx`, namespace in `i18n/config.ts`, `docs-manifest.json` entry, `DocPanelContext.tsx` mapping (+ `UserIndexPage.tsx` for user type); **client**: `src/extensions/<kebab>Registry.ts` emitted, aggregator re-run (`componentRegistry.generated.ts` imports it, `moduleResources.generated.ts` registers the kebab namespace), manifest entry, page reachable at `/docs/business/{app}/{module}`, `panel-limitation` reported to the user
- Web app typechecks/builds
- Header is the fixed block: title + **accent tagline `t('summary')`** + subtitle + inline stats line (counts as sibling text, not pills) — consistent across pages
- Section 1 is **Objectif** (factual description of what the module does) AND no problème/solution, "Bénéfices" or "Avant/Après" framing — `extract-doc`'s `existingDoc.forbiddenSections` AND `existingDoc.missingRequired` (`objective`, `summary`) are all empty (step-03 §0 blocking gate)
- Section 2 is **« Accès & rôles »** (`user` type): the Rôle | Peut faire | Portée table built from `report.accessRoles.rows` only, `access.unverified` caveat when `source === 'ba'`, unmapped code permissions surfaced — or the plain access card when `source === 'none'`. Join warnings reported to the user, never published
- 8 sections by default; the Section 9 « Référence technique » appendix only with `--tech` (and never removed from an existing doc by a re-run without it)
- The NON-blocking advice (`existingDoc.adviseRolesTable`, `existingDoc.overflowRisks`) is surfaced to the user (never gated)
</success_criteria>
