diff --git a/SoW/.mermaid.json b/SoW/.mermaid.json new file mode 100644 index 0000000..1bcd778 --- /dev/null +++ b/SoW/.mermaid.json @@ -0,0 +1,18 @@ +{ + "theme": "base", + "themeVariables": { + "fontFamily": "Segoe UI, system-ui, -apple-system, Roboto, sans-serif", + "fontSize": "15px", + "primaryColor": "#e9eef8", + "primaryBorderColor": "#2a4c8f", + "primaryTextColor": "#18202e", + "lineColor": "#5a6478", + "secondaryColor": "#f2f4f8", + "tertiaryColor": "#ffffff", + "clusterBkg": "#fbfcfd", + "clusterBorder": "#c9d6ee", + "edgeLabelBackground": "#ffffff" + }, + "flowchart": { "curve": "basis", "htmlLabels": true, "padding": 16, "nodeSpacing": 45, "rankSpacing": 55 }, + "sequence": { "actorMargin": 40, "mirrorActors": false } +} diff --git a/SoW/.puppeteer.json b/SoW/.puppeteer.json new file mode 100644 index 0000000..b911f25 --- /dev/null +++ b/SoW/.puppeteer.json @@ -0,0 +1 @@ +{ "executablePath": "/opt/pw-browsers/chromium", "args": ["--no-sandbox", "--disable-setuid-sandbox"] } diff --git a/SoW/README.md b/SoW/README.md new file mode 100644 index 0000000..a82534a --- /dev/null +++ b/SoW/README.md @@ -0,0 +1,35 @@ +# SoW — Atlas PPM + +Statement-of-Work deliverables for the Atlas PPM engagement. + +## Contents + +| File | What | +|---|---| +| `STATEMENT-OF-WORK.md` / `.html` | **Canonical SoW** in the Birgma house format (17 sections; mirrors `GovernancePortal_Latest/docs/STATEMENT-OF-WORK.md`) | +| `SoW-Atlas-PPM-Product-Build.md` | Detailed build SoW (Markdown, Confluence-ready) | +| `SoW-Atlas-PPM-Remediation.md` | SoW for the code-review remediation engagement (Epic #106) | +| `sow-atlas-ppm-product-build.html` | Product-build SoW as a styled, printable HTML page | +| `flows.md` | Index of all flow diagrams (live Mermaid + image links) | +| `flows-gallery.html` | Self-contained HTML gallery of every rendered flow | +| `flows/*.mmd` | Mermaid source (20 system + 8 user + 9 dev = 37 flows) | +| `images/*.png` | Static rendered images of each flow | + +## Three views of the flows + +- **System & data flows** (`NN-*.mmd`) — how the platform moves data and enforces rules. +- **User journeys** (`user-*.mmd`) — persona → goal, step by step. +- **Software-development interaction** (`dev-*.mmd`) — SDLC + how the pieces interact at build/run/deploy. + +## Regenerating the images + +Rendered with `@mermaid-js/mermaid-cli` against the repo's Chromium (not an app dependency — install on demand): + +```bash +for f in flows/*.mmd; do + b=$(basename "$f" .mmd) + npx @mermaid-js/mermaid-cli -i "$f" -o "images/$b.png" -p .puppeteer.json -c .mermaid.json -b white -s 2 +done +``` + +`.mermaid.json` carries the Atlas theme; `.puppeteer.json` points at the pre-installed Chromium with `--no-sandbox`. diff --git a/SoW/STATEMENT-OF-WORK.html b/SoW/STATEMENT-OF-WORK.html new file mode 100644 index 0000000..c2eab46 --- /dev/null +++ b/SoW/STATEMENT-OF-WORK.html @@ -0,0 +1,350 @@ + + +
+
+

Statement of Work

+

Atlas PPM

+

Portfolio & Project Management platform — Birgma / Biltema Group

+

How to use this document. The scope, deliverables, acceptance criteria and security/compliance commitments below are grounded in the delivered system. Fields in [brackets] — parties, dates, effort and commercials — are for the contracting parties to complete; they are intentionally not pre-filled.

+
+
Project
Atlas — Portfolio & Project Management (PPM) platform
+
Client / Sponsor
[Birgma / Biltema — sponsor name]
+
Supplier / Delivery
[Delivery team / vendor]
+
SoW version
1.0 · [date]
+
Effective period
[start] – [end]
+
Document owner
[name, role]
+
+
+ +
+

1 Purpose

+

This Statement of Work defines the scope, deliverables, approach, acceptance criteria and responsibilities for the design, build and hand-over of Atlas — a Portfolio & Project Management web application that runs the Biltema Group portfolio end to end: demand intake and scoring, projects with stage-gate governance, programs and products, OKRs, timeline/Gantt planning, resource and financial management, delivery reporting, and a security/compliance module — with identity federated to Microsoft Entra ID and authorization enforced server-side. The frontend is reproduced pixel-faithful to the approved prototype (design/Atlas PPM.dc.html) and wired to the .NET 10 minimal API.

+
+ +
+

2 Background

+

Portfolio governance today is spread across spreadsheets and disconnected trackers, so demand, delivery, resourcing and financials cannot be seen or governed in one place, and stage-gate/architecture decisions are not auditable. Atlas replaces that with a single, role-aware platform: a controlled object model (demands → projects → programs/products/OKRs), server-authoritative RBAC, real-time collaboration, connector-fed work-item sync, and an ISO 27001 / GDPR-aware governance module — deployable on-premise and air-gapped.

+
+ +
+

3 Objectives

+ +
+ +
+

4 Scope of work

+

4.1 In scope (work packages)

+
+ + + + + + + + + + + + + + + +
WPWork packageSummary
WP1Identity & accessEntra SSO (MSAL); RS256 token validation; server-authoritative RBAC capability matrix (6 canonical roles; 9 cosmetic identities); idle logout; anonymous-in-production boot fuses
WP2Portfolio & demand intakePortfolio (projects + blockers); Demand Pipeline value-vs-effort funnel; Programs (stakeholder matrix); Products; OKRs
WP3Project deliveryProject Detail — Overview · Tasks (board+list) · Epics · RAID · Artifacts(+versions) · Costs · Gates (G0–G5) · Security (ISO 27001 SoA); delivery roles
WP4Planning & timelineTimeline / Gantt (project & program); phases, bars, milestones; cross-entity dependency arrows (manual / jira / project)
WP5Resources & financialsEntra-synced roster; period-windowed utilisation (shared time-phased engine + date range); budget vs actual, CapEx/OpEx, forecast-at-completion, ROI
WP6Reporting & assuranceDashboard (Executive/Operational/Compact/Custom); Delivery status; Releases; Weekly Updates; branded Reports (PDF/Excel/PPTX); audit log
WP7IntegrationsJira & Azure DevOps sync behind one IWorkItemConnector (shared queue/worker, 202+poll, delta watermark); Teams notifications; connector catalogue
WP8Real-time collaborationSingle SignalR room hub — presence, cursors, live sync, off-screen peers; PI board, demand funnel, task board; Freeform Whiteboard co-editing
WP9Governance & complianceStage gates + gate reviews; ADR log; TOGAF ADM, domains/waivers/ARB; ISO 27001 SoA; compliance module (GDPR/PCI-DSS/ISO 27001/EU AI Act/SOC 2/NIS2)
WP10People, teams & methodologyMy Team — skills matrix, Team SWOT, individual development plans (manager-scoped, governance-gated); Methodologies + create-project wizard
WP11Platform quality & CIGenerated API type contract (OpenAPI→TS) + drift check; module-boundary ratchet (ADR-0072); xUnit·Vitest·Playwright/axe·k6 with coverage floors; Semgrep + Trivy; SHA-pinned Actions
WP12Air-gapped operations & docsSelf-hosted assets; nginx same-origin (/api/v1, /hubs); OpenTelemetry; backups/restore; audit trail; secret rotation; HLD/LLD/ADRs/ABB-SBB, guides
+

4.2 Out of scope

+ +
+ +
+

5 Deliverables

+
+ + + + + + + + + + + + +
#DeliverableFormAcceptance evidence
D1Web application (SPA + API + database)Running same-origin stackServes behind nginx; npm run build green; /health·/readyz healthy
D2Source code + CI pipelinesGit repositoryCI green: frontend, API, type-contract drift, axe, Semgrep + Trivy
D3Automated test suiteCodexUnit + Vitest + Playwright/axe + k6; coverage floors (backend line ≥ 65 %, frontend ≥ 6 %)
D4Architecture & design docsMarkdownhld.md, lld.md, adr/ (+ ALL-ADRS.md), building-blocks.md
D5Requirements & user storiesMarkdownrequirements.md (FR/NFR/TR), user-stories.md
D6Security & compliance packMarkdown + codethreat-model.md, security-hardening.md, pentest-scope.md, per-project ISO 27001 SoA
D7GDPR / personnel-data packMarkdowndpia-personnel-data.md, compliance-sweden.md, retention.md
D8Operations runbooksMarkdownSETUP.md, DOCKER.md, sso-setup.md, secrets.md, observability.md, connector guides
D9User & functional documentationMarkdown + HTMLuser-stories.md, accessibility.md, and the flow package (SoW/flows.md + gallery — 39 diagrams)
+
+ +
+

6 Approach & delivery phases

+

Iterative delivery; each phase is independently shippable and CI-gated. (Phases reflect the documented delivery state and forward plan; see the ADRs.)

+
+ + + + + + + + + + + + +
PhaseFocusStatus
P0 — Shell & SSOApp shell, routing, theme, Entra SSO, RBAC capability matrixDelivered
P1 — Core objectsDashboard, Portfolio (+ Blockers), Project Detail, Demands funnelDelivered
P2 — Planning & breadthGantt, Programs, Products, OKRs, Resources, FinancialsDelivered
P3 — ReportingDelivery status, Releases, Weekly Updates, branded ReportsDelivered
P4 — Integrations & real-timeJira/ADO connector abstraction, Teams notifications, SignalR roomsDelivered
P5 — Governance & complianceStage gates, gate reviews, ADR log, TOGAF ADM, ISO 27001 SoA, compliance moduleDelivered
P6 — Approved extensionsWhiteboard, Team SWOT & dev plans, timeline dependencies, brand themes, quality/Jira ingestDelivered (CLAUDE.md §2 + ADRs)
P7 — Engineering-quality remediationSecurity hardening, generated API types, connector abstraction, cleanup (Epic #106; ADRs 0080–0084)Delivered
P8 — Azure-native / production migrationManaged identity, Key Vault, managed Postgres (PITR), private networking, WAFPlanned (separate SoW)
+
+ +
+

7 Milestones & acceptance criteria

+
+ + + + + + + + + +
MilestoneAcceptance criteria
M1 Functional acceptanceAll in-scope screens demonstrable against requirements.md (FR-*) and user-stories.md; real data with loading/empty/error; integration tests green
M2 Security acceptanceThreat model reviewed; server-authoritative RBAC verified by tests; no High findings in npm audit --omit=dev / Trivy; Semgrep + secrets clean; nginx CSP/TLS hardening
M3 Operational acceptanceSame-origin deployment per SETUP.md / DOCKER.md; /health·/readyz pass; backup + restore rehearsed; air-gapped build verified
M4 Compliance acceptancePer-project ISO 27001 SoA populated; GDPR / personnel-data pack reviewed by [DPO]; DPIA + MBL §11 sign-off; audit trail verified
M5 Documentation & hand-overD4–D9 delivered; knowledge-transfer session held
M6 Live sign-offA real Entra interactive sign-in verified in [staging/production]; go-live approved by [sponsor]
+

Definition of Done (per work package): code merged to main behind green CI (one issue → one PR); tests for the behaviour; docs/ADR updated; no High/Critical security findings; module-boundary ratchet and API type-contract drift both green.

+
+ +
+

8 Roles & responsibilities (RACI)

+
+ + + + + + + + + + +
ActivityDelivery teamClient / ITSponsorDPO
Build & test the applicationR/ACII
Entra tenant + app registrations, MFA/CACR/AII
Host / network / TLS certificatesCR/AI
Connector setup + consent (Jira/ADO/Teams/Graph)CR/AI
Security & compliance artefactsR/ACIC
Personnel-data sign-off (DPIA / MBL §11)CCIR/A
Acceptance & go-live approvalCCR/AC
+

R = Responsible · A = Accountable · C = Consulted · I = Informed. Names: [to complete].

+
+ +
+

9 Assumptions & dependencies

+ +
+ +
+

10 Constraints

+ +
+ +
+

11 Environment & technical requirements

+

Technical requirements are specified in requirements.md (TR-*): platform, frontend, identity, API/data, storage, messaging, security, observability, i18n, CI and compatibility. Setup steps are in SETUP.md / DOCKER.md; identity in sso-setup.md; connectors in jira-setup.md, azure-devops-setup.md, teams-setup.md, email-graph-setup.md.

+
+ +
+

12 Security & compliance obligations

+

The supplier will deliver and maintain: a threat model (threat-model.md) and hardening record (security-hardening.md); server-authoritative RBAC (capability matrix, ADR-0004); a per-project ISO 27001:2022 Statement of Applicability (ADR-0066); a compliance module mapping controls across GDPR / PCI-DSS / ISO 27001 / EU AI Act / SOC 2 / NIS2; and a GDPR / personnel-data pack (dpia-personnel-data.md, compliance-sweden.md, retention.md) — DSAR export, evidence-preserving erasure and retention purge. CI enforces SAST (Semgrep), Trivy, an axe sweep, coverage floors, an API type-contract drift check and the ADR-0072 module-boundary ratchet; GitHub Actions are pinned to commit SHAs. Personnel-data features stay gated off until DPIA + MBL §11 sign-off (ADR-0063).

+
+ +
+

13 Change control & governance

+

Changes to scope, deliverables or acceptance criteria are handled by written change request: description, rationale, impact on schedule/effort, and sign-off by [sponsor] and [delivery lead]. Day-to-day delivery is tracked on main with green-CI gating, one issue → one PR, and an ADR for every significant decision (architecture/adr/, ALL-ADRS.md). Product-owner-approved deviations from the frozen prototype are recorded in CLAUDE.md §2 and an ADR.

+
+ +
+

14 Risks

+

Key delivery/operational risks and mitigations are catalogued in threat-model.md and the ADRs. Highest residual items are organisation-side: enabling MFA / Conditional Access, at-rest encryption and SIEM forwarding. Delivery-side watch items: prototype-fidelity acceptance (mitigated by side-by-side review), the air-gapped no-CDN constraint (self-hosted assets, offline build verified), and the staged migration of legacy display-string date columns (ADR-0082, per-module).

+
+ +
+

15 Commercials

+

[To be completed by the parties — pricing model (fixed-price / capped T&M / T&M), total or not-to-exceed, rate card, effort estimate, payment schedule (tied to the milestones in §7), expenses, warranty and any support/maintenance terms. Not pre-filled.]

+
+ +
+

16 Acceptance & sign-off

+

Acceptance is granted per milestone (§7). Final acceptance follows M6 (live sign-off). This Statement of Work is agreed and authorised by:

+
+ + + + + + +
PartyNameSignatureDate
Client / Sponsor[ ]
Delivery lead[ ]
DPO (compliance)[ ]
+

Effective date: [on last signature] · SoW version: 1.0 · Supersedes: [none / prior].

+
+ +
+

17 References

+

requirements.md · user-stories.md · architecture/hld.md · architecture/lld.md · architecture/adr/ (+ ALL-ADRS.md) · architecture/building-blocks.md · threat-model.md · security-hardening.md · pentest-scope.md · compliance-sweden.md · dpia-personnel-data.md · retention.md · accessibility.md · observability.md · SETUP.md · DOCKER.md · sso-setup.md · secrets.md · connector guides · SoW/flows.md (functional flows).

+ +
+
+

A Appendix — Functional flows

+

The complete flow library (39 diagrams), also maintained as editable Mermaid in SoW/flows/ and indexed in SoW/flows.md.

+

A.1 System & data flows

+
Application map & navigation
Application map & navigation
Authentication & RBAC gate
Authentication & RBAC gate
Dashboard layouts & data
Dashboard layouts & data
Demand funnel
Demand funnel
Portfolio → Project
Portfolio → Project
Stage gates G0–G5
Stage gates G0–G5
Task board (realtime)
Task board (realtime)
Gantt & dependencies
Gantt & dependencies
Resource utilisation
Resource utilisation
Financials roll-up
Financials roll-up
Program detail
Program detail
Products → Releases
Products → Releases
OKRs linkage
OKRs linkage
Delivery status
Delivery status
News wall
News wall
Connector sync (Jira/ADO)
Connector sync (Jira/ADO)
Whiteboard co-editing
Whiteboard co-editing
Reports & export
Reports & export
Administration
Administration
Governance & compliance
Governance & compliance
+

A.2 User journeys (per role)

+
Executive — portfolio review
Executive — portfolio review
PMO — approve a demand
PMO — approve a demand
PM — create a project (wizard)
PM — create a project (wizard)
PM — manage tasks & Jira sync
PM — manage tasks & Jira sync
PM — stage-gate review
PM — stage-gate review
Team member — update my work
Team member — update my work
Stakeholder — check my status
Stakeholder — check my status
Manager — My Team
Manager — My Team
Platform Admin — administration
Platform Admin — administration
Chief Architect — governance
Chief Architect — governance
+

A.3 Software-development interaction flows

+
Change lifecycle
Change lifecycle
CI pipeline
CI pipeline
API type contract + drift
API type contract + drift
Module-boundary ratchet
Module-boundary ratchet
Test strategy
Test strategy
Local dev loop
Local dev loop
Build & air-gapped deploy
Build & air-gapped deploy
Runtime topology
Runtime topology
Extending a connector
Extending a connector
+
+ +
\ No newline at end of file diff --git a/SoW/STATEMENT-OF-WORK.md b/SoW/STATEMENT-OF-WORK.md new file mode 100644 index 0000000..e54b9a9 --- /dev/null +++ b/SoW/STATEMENT-OF-WORK.md @@ -0,0 +1,419 @@ +# Statement of Work — Atlas PPM + +> **How to use this document.** The scope, deliverables, acceptance criteria and +> security/compliance commitments below are grounded in the delivered system. +> Fields in **[brackets]** — parties, dates, effort and commercials — are for the +> contracting parties to complete; they are intentionally not pre-filled. + +| | | +|---|---| +| **Project** | Atlas — Portfolio & Project Management (PPM) platform | +| **Client / Sponsor** | [Birgma / Biltema — sponsor name] | +| **Supplier / Delivery** | [Delivery team / vendor] | +| **SoW version** | 1.0 · [date] | +| **Effective period** | [start] – [end] | +| **Document owner** | [name, role] | + +--- + +## 1. Purpose + +This Statement of Work defines the scope, deliverables, approach, acceptance +criteria and responsibilities for the design, build and hand-over of **Atlas** — +a Portfolio & Project Management web application that runs the Biltema Group +portfolio end to end: demand intake and scoring, projects with stage-gate +governance, programs and products, OKRs, timeline/Gantt planning, resource and +financial management, delivery reporting, and a security/compliance module — +with identity federated to **Microsoft Entra ID** and authorization enforced +server-side. The frontend is reproduced **pixel-faithful to the approved +prototype** (`design/Atlas PPM.dc.html`) and wired to the **.NET 10 minimal API**. + +## 2. Background + +Portfolio governance today is spread across spreadsheets and disconnected +trackers, so demand, delivery, resourcing and financials cannot be seen or +governed in one place, and stage-gate/architecture decisions are not auditable. +Atlas replaces that with a single, role-aware platform: a controlled object +model (demands → projects → programs/products/OKRs), server-authoritative RBAC, +real-time collaboration, connector-fed work-item sync, and an ISO 27001 / +GDPR-aware governance module — deployable **on-premise and air-gapped**. + +## 3. Objectives + +1. Federated single sign-on and least-privilege authorisation (Entra ID; 6 + canonical roles enforced server-side via a capability matrix). +2. A faithful reproduction of every approved screen, **data-driven** with + first-class loading / empty / error states (empty by default — no seed data). +3. A controlled **demand → project → gate** lifecycle with stage gates (G0–G5) + and architecture/security gate reviews. +4. **Planning & resourcing**: timeline/Gantt with cross-entity dependencies; + time-phased resource utilisation; financials (budget vs actual, FaC, ROI). +5. **Integration**: idempotent work-item sync from Jira and Azure DevOps behind + one connector abstraction; Teams notifications. +6. **Real-time collaboration**: presence, cursors and live change-sync; PI board, + task board, demand funnel and a freeform whiteboard. +7. **Governance & compliance by design**: decision log (ADR), TOGAF ADM, ISO + 27001 Statement of Applicability, and GDPR handling of personnel data. +8. **Portability & assurance**: container-first, same-origin behind nginx, an + air-gapped build, observability, backups and a continuously green CI gate. + +## 4. Scope of work + +### 4.1 In scope (work packages) + +| WP | Work package | Summary | +|----|--------------|---------| +| WP1 | Identity & access | Entra SSO (MSAL); RS256 token validation (issuer/audience/tenant); server-authoritative RBAC capability matrix (6 canonical roles; 9 cosmetic header identities); idle logout; anonymous-in-production boot fuses | +| WP2 | Portfolio & demand intake | Portfolio (projects + blockers); Demand Pipeline value-vs-effort scored funnel; Programs (stakeholder power/interest matrix); Products; OKRs linked to projects/programs/products | +| WP3 | Project delivery | Project Detail — Overview, Tasks (board + list, drag), Epics, RAID, Artifacts (+versions), Costs (labor/license/PaaS/IaaS/SaaS), Gates (G0–G5), Security (ISO 27001 SoA); People & roles incl. delivery roles (Tech Lead / Scrum Master) | +| WP4 | Planning & timeline | Timeline / Gantt (project & program scope); phases, bars, milestones; cross-entity dependency arrows (`manual` / `jira` / `project`) | +| WP5 | Resources & financials | Resource roster (Entra-synced); period-windowed utilisation with a shared time-phased engine + date-range filter; Financials — budget vs actual, CapEx/OpEx, forecast-at-completion, savings/benefit, portfolio ROI | +| WP6 | Reporting & assurance | Dashboard (Executive / Operational / Compact / drag-and-drop Custom); Delivery status by period; Releases calendar; Weekly Updates (news wall); branded Reports with PDF / Excel / PPTX export; audit log | +| WP7 | Integrations | Jira & Azure DevOps work-item sync behind one `IWorkItemConnector` (shared background queue/worker, 202 + poll, delta watermark); Microsoft Teams notifications; connector catalogue (ServiceNow, ManageEngine SDP, GitHub, Confluence, Slack, Power BI) | +| WP8 | Real-time collaboration | Single SignalR "room" hub — presence, shared cursors, live change-sync, off-screen peer indicators; PI Program Board, demand funnel, task board; Freeform Whiteboard with granular authorized co-editing | +| WP9 | Governance & compliance | Stage gates + gate reviews (architecture/security); decision log (ADR); TOGAF ADM phases, architecture domains/waivers/ARB; ISO 27001 SoA; security/compliance module (GDPR, PCI-DSS, ISO 27001, EU AI Act, SOC 2, NIS2) with control mappings | +| WP10 | People, teams & methodology | My Team — members & skills matrix, Team SWOT, individual development plans (manager-scoped, governance-gated); Methodologies library + create-project wizard | +| WP11 | Platform quality & CI | Generated API type contract (OpenAPI → TypeScript) with drift check; module-boundary ratchet (ADR-0072); tests (xUnit · Vitest · Playwright + axe · k6) with coverage floors; SAST (Semgrep) + Trivy; SHA-pinned GitHub Actions | +| WP12 | Air-gapped operations & docs | Self-hosted fonts/assets; nginx same-origin (`/api/v1`, `/hubs`); OpenTelemetry observability; backups/restore; audit trail; secret rotation; architecture (HLD/LLD/ADRs/ABB-SBB), requirements, install/integration guides | + +### 4.2 Out of scope + +- Hosting, network and identity-tenant administration beyond configuration + guidance (Entra tenant, Windows/VMware host, corporate network, firewalls, TLS). +- Organisation-side security controls (MFA / Conditional Access enablement, + at-rest disk encryption, SIEM ingestion) — the application supports them; + enabling them is an operator/IT action. +- Data migration from legacy PPM tools (unless added by change request). +- Editing the design reference (`design/`) — regenerated by the design team. +- **Jira bidirectional write-back** (Proposed, ADR-0080 — pending sign-off). +- **Full screen-body internationalisation** — the product is English content with + localised chrome (ADR-0084) until a product decision widens it. +- Personnel-data features (Team SWOT / development plans) remain **gated off** + until DPIA + MBL §11 sign-off (ADR-0063). + +## 5. Deliverables + +| # | Deliverable | Form | Acceptance evidence | +|---|-------------|------|---------------------| +| D1 | Web application (SPA + API + database) | Running same-origin stack | Builds & serves behind nginx; frontend `npm run build` green; API `/health`·`/readyz` healthy | +| D2 | Source code + CI pipelines | Git repository | CI green: frontend (lint/test/build + coverage floor), API (build/test + coverage floor), API type-contract drift, accessibility (axe), SAST (Semgrep) + Trivy | +| D3 | Automated test suite | Code | Backend xUnit (incl. fixtures + architecture-boundary tests) + frontend Vitest + Playwright/axe + k6; coverage floors gated in CI (backend line ≥ 65 %, frontend line ≥ 6 %, raised as screens gain tests) | +| D4 | Architecture & design docs | Markdown | `architecture/hld.md`, `architecture/lld.md`, `architecture/adr/` (+ `ALL-ADRS.md`), `architecture/building-blocks.md` (ABB/SBB) | +| D5 | Requirements & user stories | Markdown | `requirements.md` (FR/NFR/TR), `user-stories.md` | +| D6 | Security & compliance pack | Markdown + code | `threat-model.md`, `security-hardening.md`, `pentest-scope.md`, per-project ISO 27001 SoA (ADR-0066), control mappings | +| D7 | GDPR / personnel-data pack | Markdown | `dpia-personnel-data.md`, `compliance-sweden.md`, `retention.md` (DSAR export, evidence-preserving erasure, retention purge) | +| D8 | Operations runbooks | Markdown | `SETUP.md`, `DOCKER.md`, `sso-setup.md`, `secrets.md`, `observability.md`, `postgres-cert-auth.md`, connector setup guides | +| D9 | User & functional documentation | Markdown + HTML | `user-stories.md`, `accessibility.md`, and the flow package — `SoW/flows.md` + gallery (39 diagrams: system · per-role journeys · development) | + +## 6. Approach & delivery phases + +Iterative delivery; each phase is independently shippable and CI-gated. (Phases +reflect the documented delivery state and forward plan; see the ADRs.) + +| Phase | Focus | Status | +|-------|-------|--------| +| P0 — Shell & SSO | App shell, routing, theme tokens, Entra SSO, RBAC capability matrix | Delivered | +| P1 — Core objects | Dashboard, Portfolio (+ Blockers), Project Detail, Demands funnel | Delivered | +| P2 — Planning & portfolio breadth | Gantt/timeline, Programs, Products, OKRs, Resources, Financials | Delivered | +| P3 — Reporting | Delivery status, Releases, Weekly Updates (news), branded Reports | Delivered | +| P4 — Integrations & real-time | Jira/ADO connector abstraction, Teams notifications, SignalR rooms | Delivered | +| P5 — Governance & compliance | Stage gates, gate reviews, ADR log, TOGAF ADM, ISO 27001 SoA, compliance module | Delivered | +| P6 — Approved extensions | Whiteboard, Team SWOT & dev plans, timeline dependencies, brand themes, quality/Jira ingest | Delivered (CLAUDE.md §2 + ADRs) | +| P7 — Engineering-quality remediation | Security hardening, generated API types, connector abstraction, comment/god-object cleanup (Epic #106; ADRs 0080–0084) | Delivered | +| P8 — Azure-native / production migration | Managed identity, Key Vault, managed Postgres (PITR), private networking, WAF | Planned (separate SoW) | + +## 7. Milestones & acceptance criteria + +| Milestone | Acceptance criteria | +|-----------|---------------------| +| M1 Functional acceptance | All in-scope screens demonstrable against `requirements.md` (FR-*) and `user-stories.md`; each view shows real data with loading/empty/error; integration tests green | +| M2 Security acceptance | Threat model reviewed; server-authoritative RBAC verified by tests; no High findings in `npm audit --omit=dev` / Trivy; Semgrep + secrets scan clean; nginx CSP/TLS hardening in place | +| M3 Operational acceptance | Same-origin deployment per `SETUP.md` / `DOCKER.md`; `/health`·`/readyz` pass; **backup + restore rehearsed**; air-gapped build verified (no runtime egress) | +| M4 Compliance acceptance | Per-project ISO 27001 SoA populated; GDPR / personnel-data pack reviewed by [DPO]; DPIA + MBL §11 sign-off for personnel features; audit trail verified | +| M5 Documentation & hand-over | D4–D9 delivered; knowledge-transfer session held | +| M6 Live sign-off | A real Entra interactive sign-in verified in [staging/production]; go-live approved by [sponsor] | + +**Definition of Done (per work package):** code merged to `main` behind green CI +(one issue → one PR); tests for the behaviour; docs/ADR updated; no High/Critical +security findings; module-boundary ratchet and API type-contract drift both green. + +## 8. Roles & responsibilities (RACI) + +| Activity | Delivery team | Client / IT | Sponsor | DPO | +|---|---|---|---|---| +| Build & test the application | R/A | C | I | I | +| Entra tenant + app registrations, MFA/CA | C | R/A | I | I | +| Host / network / TLS certificates | C | R/A | I | — | +| Connector setup + consent (Jira/ADO/Teams/Graph) | C | R/A | I | — | +| Security & compliance artefacts | R/A | C | I | C | +| Personnel-data sign-off (DPIA / MBL §11) | C | C | I | R/A | +| Acceptance & go-live approval | C | C | R/A | C | + +_R = Responsible · A = Accountable · C = Consulted · I = Informed. Names: [to complete]._ + +## 9. Assumptions & dependencies + +- An **Entra ID tenant** is available with rights to create app registrations and + grant admin consent; **MFA / Conditional Access** is enabled organisation-side. +- A **Windows / VMware host** (or the agreed target) is provisioned with the + runtime; **TLS certificates** are supplied; the site is served same-origin + behind nginx. +- **PostgreSQL 16** is provisioned; off-host, access-controlled **backup storage** + is available. +- Directory data is provided via **Entra**; the client nominates admins, approvers + and connector credentials (Jira / Azure DevOps / Teams / Graph). +- The environment is **air-gapped** at runtime — all assets are self-hosted; build + tooling runs in CI, not on the target. + +## 10. Constraints + +- Single-instance, same-origin on-premise deployment; the value is auditability + and durability of portfolio evidence, not high availability. +- **No runtime internet egress** — no CDNs; fonts/assets bundled (ADR-0078). +- Deployment is by **downloading built artefacts to a Windows server** (no git on + the target); artefacts must be self-contained. +- Authorization is **server-authoritative**; the client is never a security + boundary. UI role checks are cosmetic. +- Stack: React 18 / TypeScript / Vite · .NET 10 minimal API / EF Core 10 · + PostgreSQL 16 · modern evergreen browsers. + +## 11. Environment & technical requirements + +Technical requirements are specified in `requirements.md` (TR-*): platform, +frontend, identity, API/data, storage, messaging, security, observability, i18n, +CI and compatibility. Setup steps are in `SETUP.md` / `DOCKER.md`; identity in +`sso-setup.md`; connectors in `jira-setup.md`, `azure-devops-setup.md`, +`teams-setup.md`, `email-graph-setup.md`. + +## 12. Security & compliance obligations + +The supplier will deliver and maintain: a **threat model** (`threat-model.md`) and +security-hardening record (`security-hardening.md`); **server-authoritative RBAC** +(capability matrix, ADR-0004); a per-project **ISO 27001:2022 Statement of +Applicability** (ADR-0066); a security/compliance module mapping controls across +GDPR / PCI-DSS / ISO 27001 / EU AI Act / SOC 2 / NIS2; and a **GDPR / personnel-data +pack** (`dpia-personnel-data.md`, `compliance-sweden.md`, `retention.md`) — DSAR +export, evidence-preserving erasure and retention purge. CI enforces SAST +(Semgrep), dependency/secret/IaC scanning (Trivy), an accessibility (axe) sweep, +coverage floors, an API type-contract drift check and the ADR-0072 module-boundary +ratchet; GitHub Actions are pinned to commit SHAs. Personnel-data features stay +gated off until DPIA + MBL §11 sign-off (ADR-0063). + +## 13. Change control & governance + +Changes to scope, deliverables or acceptance criteria are handled by written +**change request**: description, rationale, impact on schedule/effort, and sign-off +by [sponsor] and [delivery lead]. Day-to-day delivery is tracked on `main` with +green-CI gating, **one issue → one PR**, and an ADR for every significant +decision (see `architecture/adr/` and `ALL-ADRS.md`). Product-owner-approved +deviations from the frozen prototype are recorded in `CLAUDE.md §2` and an ADR. + +## 14. Risks + +Key delivery/operational risks and mitigations are catalogued in `threat-model.md` +and the ADRs. Highest residual items are organisation-side: enabling MFA / +Conditional Access, at-rest encryption and SIEM forwarding. Delivery-side watch +items: prototype-fidelity acceptance (mitigated by side-by-side review), the +air-gapped no-CDN constraint (self-hosted assets, offline build verified), and the +staged migration of legacy display-string date columns (ADR-0082, per-module). + +## 15. Commercials + +[To be completed by the parties — pricing model (fixed-price / capped T&M / T&M), +total or not-to-exceed, rate card, effort estimate, payment schedule (tied to the +milestones in §7), expenses, warranty and any support/maintenance terms. Not +pre-filled.] + +## 16. Acceptance & sign-off + +Acceptance is granted per milestone (§7). Final acceptance follows M6 (live +sign-off). This Statement of Work is agreed and authorised by: + +| Party | Name | Signature | Date | +|---|---|---|---| +| Client / Sponsor | [ ] | | | +| Delivery lead | [ ] | | | +| DPO (compliance) | [ ] | | | + +_Effective date: [on last signature] · SoW version: 1.0 · Supersedes: [none / prior]._ + +## 17. References + +`requirements.md` · `user-stories.md` · `architecture/hld.md` · +`architecture/lld.md` · `architecture/adr/` (+ `ALL-ADRS.md`) · +`architecture/building-blocks.md` · `threat-model.md` · `security-hardening.md` · +`pentest-scope.md` · `compliance-sweden.md` · `dpia-personnel-data.md` · +`retention.md` · `accessibility.md` · `observability.md` · `SETUP.md` · +`DOCKER.md` · `sso-setup.md` · `secrets.md` · connector guides (`jira-setup.md`, +`azure-devops-setup.md`, `teams-setup.md`, `email-graph-setup.md`) · +`SoW/flows.md` (functional flows). Companion SoWs: `SoW-Atlas-PPM-Product-Build.md` +(detailed build) and `SoW-Atlas-PPM-Remediation.md` (Epic #106 remediation). + +--- + +## Appendix A — Functional flows + +The complete flow library (39 diagrams); editable Mermaid in `flows/`, indexed in `flows.md`. The HTML edition embeds these inline. + +### A.1 System & data flows + +**Application map & navigation** + +![Application map & navigation](images/00-app-sitemap.png) + +**Authentication & RBAC gate** + +![Authentication & RBAC gate](images/01-auth-rbac.png) + +**Dashboard layouts & data** + +![Dashboard layouts & data](images/02-dashboard.png) + +**Demand funnel** + +![Demand funnel](images/03-demands.png) + +**Portfolio → Project** + +![Portfolio → Project](images/04-portfolio-project.png) + +**Stage gates G0–G5** + +![Stage gates G0–G5](images/05-project-gates.png) + +**Task board (realtime)** + +![Task board (realtime)](images/06-tasks-board.png) + +**Gantt & dependencies** + +![Gantt & dependencies](images/07-gantt.png) + +**Resource utilisation** + +![Resource utilisation](images/08-resources.png) + +**Financials roll-up** + +![Financials roll-up](images/09-financials.png) + +**Program detail** + +![Program detail](images/10-programs.png) + +**Products → Releases** + +![Products → Releases](images/11-products-releases.png) + +**OKRs linkage** + +![OKRs linkage](images/12-okrs.png) + +**Delivery status** + +![Delivery status](images/13-delivery.png) + +**News wall** + +![News wall](images/14-news.png) + +**Connector sync (Jira/ADO)** + +![Connector sync (Jira/ADO)](images/15-integrations-sync.png) + +**Whiteboard co-editing** + +![Whiteboard co-editing](images/16-whiteboard.png) + +**Reports & export** + +![Reports & export](images/17-reports.png) + +**Administration** + +![Administration](images/18-admin.png) + +**Governance & compliance** + +![Governance & compliance](images/19-governance-compliance.png) + +### A.2 User journeys (per role) + +**Executive — portfolio review** + +![Executive — portfolio review](images/user-01-executive-review.png) + +**PMO — approve a demand** + +![PMO — approve a demand](images/user-02-pmo-demand-approval.png) + +**PM — create a project (wizard)** + +![PM — create a project (wizard)](images/user-03-pm-create-project.png) + +**PM — manage tasks & Jira sync** + +![PM — manage tasks & Jira sync](images/user-04-pm-manage-tasks.png) + +**PM — stage-gate review** + +![PM — stage-gate review](images/user-05-pm-stage-gate.png) + +**Team member — update my work** + +![Team member — update my work](images/user-06-team-member-update.png) + +**Stakeholder — check my status** + +![Stakeholder — check my status](images/user-07-stakeholder-status.png) + +**Manager — My Team** + +![Manager — My Team](images/user-08-manager-team.png) + +**Platform Admin — administration** + +![Platform Admin — administration](images/user-09-platform-admin.png) + +**Chief Architect — governance** + +![Chief Architect — governance](images/user-10-architect-governance.png) + +### A.3 Software-development interaction flows + +**Change lifecycle** + +![Change lifecycle](images/dev-01-change-lifecycle.png) + +**CI pipeline** + +![CI pipeline](images/dev-02-ci-pipeline.png) + +**API type contract + drift** + +![API type contract + drift](images/dev-03-api-type-contract.png) + +**Module-boundary ratchet** + +![Module-boundary ratchet](images/dev-04-module-boundary.png) + +**Test strategy** + +![Test strategy](images/dev-05-test-strategy.png) + +**Local dev loop** + +![Local dev loop](images/dev-06-local-dev.png) + +**Build & air-gapped deploy** + +![Build & air-gapped deploy](images/dev-07-build-deploy.png) + +**Runtime topology** + +![Runtime topology](images/dev-08-runtime-topology.png) + +**Extending a connector** + +![Extending a connector](images/dev-09-connector-extension.png) + diff --git a/SoW/SoW-Atlas-PPM-Product-Build.md b/SoW/SoW-Atlas-PPM-Product-Build.md new file mode 100644 index 0000000..8d45202 --- /dev/null +++ b/SoW/SoW-Atlas-PPM-Product-Build.md @@ -0,0 +1,340 @@ +# Statement of Work — Atlas PPM Product Build + +| Field | Value | +|---|---| +| **Project** | Atlas — Portfolio & Project Management platform | +| **Client** | Birgma / Biltema Group (Nordic retail) | +| **Repository** | `nicpozent/ATLASPPM_AdditionalFeatures` | +| **Prepared for** | nicolas.pozza@birgma.com | +| **Date** | 2026-08-07 | +| **Document type** | Statement of Work — for signature (v1.0 draft) | + +--- + +## 1. Background & objectives + +Atlas is a Portfolio & Project Management web application for Birgma / Biltema +Group. This engagement delivers the **full application** — every screen and all +functionality — **pixel-faithful to the approved prototype** +(`design/Atlas PPM.dc.html`), wired to the **.NET 10 minimal API** backend, and +hardened for an **on-premise, air-gapped** deployment. + +Primary objectives: + +1. Reproduce every prototype screen 1:1 (layout, typography, colour, components, + states, copy) with no redesign or additions beyond approved extensions. +2. Data-drive every screen from the `/api/v1/*` API via TanStack Query, with + first-class **loading / empty / error** states (empty by default — no + fabricated seed data). +3. Enforce **server-authoritative** role-based access control; the client is + never a security boundary. +4. Meet the non-functional bar: accessibility (WCAG AA), localised chrome, + security/compliance modules, and a continuously green automated build. + +--- + +## 2. Scope of work + +### 2.1 Workspace screens +- **Dashboard** — four layouts via a segmented control: Executive + (portfolio-health donut, budget-burn, KPI cards w/ sparklines, + active-projects table, needs-attention, demand pipeline, recent activity), + Operational, Compact, and a drag-and-drop **Custom** builder. +- **Portfolio** — Projects (filter chips + cards/table) and Blockers (list + + side panel); drill-through to Project Detail. +- **Programs** — list + detail (stakeholder power/interest matrix, linked + projects, status); create-program modal. +- **Products** — product portfolio; Jira/ADO tasks mapped to releases. +- **OKRs** — objectives with key results linked to projects/programs/products. +- **Demands** — value-vs-effort scored intake **funnel**; drag across stages; + create/approve modals. +- **Timeline / Gantt** — Project / Program scope; phases, bars, milestones, + dependency arrows, month grid, export. +- **Project Detail** — tabs: Overview, Tasks (board + list, drag), Epics, RAID, + Artifacts (+ versions), Costs (labor/license/PaaS/IaaS/SaaS), Gates (G0–G5), + Security (ISO 27001 SoA), plus people, linked products, change requests. +- **Resources** — people synced from Entra ID; allocation vs availability; + period-windowed utilisation with a date-range filter. +- **Financials** — budget vs actual, CapEx/OpEx, forecast-at-completion, + savings/benefit, portfolio ROI, source toggle. +- **Delivery Status** — stakeholder report by period; velocity, on-time %, + blockers, budget burn. +- **Releases** — release calendar & deployment tracking. +- **Weekly Updates (News)** — editable news wall (masonry, themes, edit mode). + +### 2.2 Configuration screens +- **My Team** — members & skills, per-team SWOT, individual development plans + (manager-scoped; governance-gated). +- **Methodologies** — methodology library + create-project wizard. +- **Integrations** — connectors (Jira, Azure DevOps, ServiceNow, ManageEngine + SDP, GitHub, Confluence, Teams, Slack, Power BI), SSO, email, directory sync. +- **Reports** — branded portfolio/demand/blocker/audit reports; export formats. +- **Administration** — roles & permissions matrix, backups/restore, audit log, + AD sync, install/integration guides, deletion requests. +- **Help** — role-based guides, articles, contact. + +### 2.3 Stakeholder experience +- Reduced navigation: **My Projects**, **My Demands** + Delivery, Releases, + News, Help. + +### 2.4 Governance modules +- Stage gates G0–G5, gate reviews (architecture/security), decision log (ADR), + TOGAF ADM phases, architecture domains/waivers/ARB, and a security/compliance + module (GDPR, PCI-DSS, ISO 27001, EU AI Act, SOC 2, NIS2) with control + mappings, reproduced where the prototype places them. + +### 2.5 Approved extensions (beyond the frozen prototype) +Built in the existing design language and recorded per `CLAUDE.md §2` + an ADR: +Microsoft Teams notifications; real-time collaboration (SignalR rooms — PI +Program Board, demand funnel, task board, live presence/cursors/off-screen +peers); Freeform Whiteboard (co-editing, templates, export); Team SWOT and +individual development plans; ISO 27001 Statement of Applicability; cross-entity +timeline dependencies; period-windowed resource utilisation; quality test tasks ++ Jira board ingest; project delivery roles (Tech Lead / Scrum Master); and the +three Atlas brand themes (Command / Daylight / Carbon). + +### 2.6 Platform & cross-cutting +- Entra ID (MSAL) SSO with route guards; server-authoritative RBAC (6 canonical + roles; 9 cosmetic header identities). +- Generated API type contract (OpenAPI → TypeScript) with CI drift protection. +- Self-hosted fonts/assets for air-gapped operation; nginx same-origin serving. +- Observability (OpenTelemetry), backups/restore, audit trail, secret rotation. + +### 2.7 Out of scope +- Any redesign, restyling, or screens/sections not in the prototype (except the + §2.5 approved extensions). +- New CSS frameworks or global stylesheets (inline theme tokens only). +- Client-side authorization as a security control. +- Full screen-body internationalisation (chrome-only per ADR-0084 until a + product decision widens it). +- Jira bidirectional write-back (Proposed, ADR-0080 — pending sign-off). +- Editing the design reference (`design/`) — regenerated by the design team. + +### 2.8 User roles & journeys + +Authorization is enforced server-side on **6 canonical roles**; the header's +**9 identities** are cosmetic (they change the visible nav, not access). Each +role's primary journey is captured as a flow diagram in the flow package +(`SoW/flows/user-*`, rendered in `SoW/images/` and the gallery). + +| Role (enforced) | Header identity(ies) | Primary journeys | Flow | +|---|---|---|---| +| **Platform Admin** | Platform Admin | Administration — RBAC matrix, backups/restore, audit log, AD sync, deletion requests | `user-09` | +| **PMO** | PMO | Triage & approve demands; portfolio oversight | `user-02` (+ `user-01`) | +| **Project Manager** | PM (· PM Lead / delivery leads) | Create project (wizard); manage tasks & Jira sync; request a stage-gate review | `user-03`, `user-04`, `user-05` | +| **Team Member** | Engineering / Service / Dev / Infra Manager (& members) | Update my work; My Team — skills, SWOT, development plans | `user-06`, `user-08` | +| **Executive** | (leadership) | Portfolio review | `user-01` | +| **Stakeholder** | Stakeholder | Check my projects / demands / delivery (reduced nav) | `user-07` | +| **Architecture** | Chief Architect | Governance — ADR log, architecture gate reviews, TOGAF ADM, ISO 27001 SoA | `user-10` | + +The four **Manager** identities (Engineering / Service / Dev / Infra) differ only +cosmetically and share the Team Member / *My Team* journeys. Beyond these +role journeys, the flow package also documents **system & data flows** (20) and +**software-development interaction flows** (9) — see `SoW/flows.md` and the +gallery. + +--- + +## 3. Deliverables + +1. The complete, prototype-faithful Atlas PPM **frontend** (React 18 + TS + + Vite), one screen component per route, split into local sub-components. +2. The supporting **.NET 10 minimal API** endpoints each screen consumes + (extended where a screen needs an endpoint not yet present), EF Core 10 / + PostgreSQL 16. +3. **Entra SSO** wiring (login/redirect handling, route guards) and the RBAC + capability matrix. +4. **Generated API types** + `api.ts` client; TanStack Query hooks with + loading/empty/error states. +5. **Automated test suites** — backend (xUnit, incl. fixtures + architecture + boundary tests), frontend (Vitest), accessibility (Playwright + axe), + performance (k6) — all gated in CI with coverage floors. +6. **Flow diagrams** (`SoW/flows`) — 39 diagrams in three views: system & data + flows (20), per-role user journeys (10), and software-development interaction + flows (9), with rendered images and an index/gallery. +7. **Architecture Decision Records** for every architectural choice, plus a + consolidated `ALL-ADRS.md`. +8. **Deployment artefacts** for the air-gapped Windows on-prem target + (self-contained build output, nginx config, setup/integration guides). + +--- + +## 4. Approach & methodology + +- **Prototype is the source of truth.** Inline styles lifted from the prototype; + `theme.ts` tokens and the three fonts only; computed visuals (charts, donuts, + sparklines, gantt geometry) ported faithfully. +- **Empty by default.** Real layout with tasteful empty states until the API + returns data; never fabricated seed data. +- **Server-authoritative security.** The API is the authority for authorization; + UI role checks are cosmetic affordances only. +- **Typed, tested, accessible.** TypeScript strict; generated API types; + ≥44px hit targets, real controls, focus styles, `aria-*`; every data view has + loading/empty/error. +- **Build one screen fully** (visually faithful + data-wired + empty state) + before the next; compare side-by-side with the prototype. +- **ADR-driven + one-change-one-PR**, each verified green in CI before merge. + +--- + +## 5. Technical architecture + +| Layer | Technology | +|---|---| +| Frontend | React 18, TypeScript (strict), Vite, react-router v6, TanStack Query, @azure/msal-browser, SignalR client | +| Styling | Inline styles + `theme.ts` tokens (CSS-variable themes; 5 palettes); self-hosted fonts | +| Backend | .NET 10 minimal API, modular monolith (per-domain `Atlas.Api.`), EF Core 10 | +| Data | PostgreSQL 16 (`date`/`timestamptz` typed dates per ADR-0082) | +| Realtime | SignalR "room" hub (presence, cursors, live sync) | +| Serving | nginx, same-origin, `/api/v1/*`; on-prem air-gapped | +| Quality gates | Module-boundary ratchet (NetArchTest), coverage floors, OpenAPI type-contract drift, axe a11y, Semgrep/Trivy | + +--- + +## 6. Milestones (build order) + +| # | Phase | Contents | +|---|---|---| +| M1 | Dashboard | Executive layout first (tokens, cards, charts, tables), then Operational/Compact/Custom | +| M2 | Core object | Portfolio (+ Blockers) and Project Detail drill-in | +| M3 | Flow & time | Demands funnel, Gantt timeline | +| M4 | Portfolio breadth | Programs, Products, OKRs, Resources, Financials | +| M5 | Reporting | Delivery Status, Releases, News | +| M6 | Configuration | Methodologies (+ wizard), Integrations, Reports, Admin, Help | +| M7 | Stakeholder | My Projects / My Demands + role-based nav & affordances | +| M8 | Governance | Gates, decisions, TOGAF ADM, security/compliance | +| M9 | Platform hardening | Entra SSO, real API wiring, loading/empty/error finalisation, air-gapped packaging | + +*Milestones are delivery groupings, not a fixed calendar; sequencing may be +reprioritised with the product owner.* + +--- + +## 7. Acceptance criteria + +- **Visual fidelity**: each screen matches the prototype 1:1 on side-by-side + review (layout, spacing, type, colour, components, states, copy). +- **Data-wired**: every view reads real data via TanStack Query with + loading/empty/error states; empty by default. +- **Security**: authorization enforced server-side; verified by backend tests. +- **Accessibility**: axe sweep passes (structural); WCAG AA colour contrast on + all themes. +- **Quality gates green**: frontend + backend suites, coverage floors, OpenAPI + contract-drift, module-boundary ratchet, SAST/Trivy. +- **Deployable**: a clean build runs on the air-gapped Windows target from the + provided artefacts. + +--- + +## 8. Assumptions & constraints + +- **On-prem, air-gapped**: no runtime internet egress; all fonts/assets + self-hosted (ADR-0078); dev-only tooling runs in CI, never ships. +- **Deployment**: client downloads built files to a Windows server; no git on + target — artefacts must be self-contained. +- **Identity**: Entra ID (Azure AD) tenant available for SSO; directory sync for + Resources. +- **Prototype freeze**: `design/Atlas PPM.dc.html` is authoritative and not + edited; approved deviations recorded in `CLAUDE.md §2` + an ADR, and flagged + for the design team to regenerate `design/`. +- **Roles**: six canonical backend roles enforce access; the nine-identity + header switcher is cosmetic. + +--- + +## 9. Roles & responsibilities + +| Party | Responsibility | +|---|---| +| Engineering (delivery) | Frontend + API implementation, tests, ADRs, CI, deployment artefacts | +| Product Owner (Birgma) | Prototype sign-off, approval of extensions & Proposed ADRs, milestone prioritisation | +| Design team | Own `design/`; regenerate to reflect approved extensions | +| Platform / IT (Birgma) | Entra tenant, on-prem/nginx environment, DB provisioning, deploy windows | +| Security / Compliance | DPIA / MBL §11 sign-off for personnel-data features; governance module review | + +--- + +## 10. Non-functional requirements + +- **Accessibility** — WCAG AA; keyboard + AT support; axe-gated in CI. +- **Internationalisation** — six-locale chrome catalogue (en/sv/fi/da/no/fr) + + completeness test; English screen content (ADR-0084). +- **Security & compliance** — RBAC capability matrix; GDPR/ISO 27001/PCI-DSS/EU + AI Act/SOC 2/NIS2 modules; audit trail; secret rotation; CSP + TLS hardening. +- **Performance** — k6 performance budget; time-phased resource engine shared + across roster/report/export to prevent drift. +- **Observability** — OpenTelemetry traces/metrics/logs (OTLP, opt-in). +- **Data integrity** — typed dates (`date`/`timestamptz`); no display-string + date columns (ADR-0082). + +--- + +## 11. Risks & dependencies + +| Risk / dependency | Mitigation | +|---|---| +| Prototype fidelity disputes | Side-by-side review as an explicit acceptance gate | +| Air-gapped runtime (no CDNs) | Self-host all assets; verify offline build | +| Entra tenant / directory access | Confirm tenant + app registration early (M9 depends on it) | +| Personnel-data features (SWOT / dev plans) | Gated off until DPIA + MBL §11 sign-off (ADR-0063) | +| External connector availability (Jira/ADO/etc.) | Empty/degraded states; connectors dormant until configured | +| Compliance-module accuracy | Review with Security/Compliance before acceptance | + +--- + +## 12. Commercials & timeline + +> **To be completed by the parties.** The Atlas engineering scope, milestones and +> acceptance are fixed by this document; pricing, rates and calendar dates are +> commercial terms to be agreed and filled in before signature. + +| Term | Value | +|---|---| +| Pricing model | ‹fixed-price / capped T&M / T&M — to be agreed› | +| Total price / not-to-exceed | ‹to be agreed› | +| Rate card (if T&M) | ‹to be agreed› | +| Estimated effort | ‹to be agreed› | +| Payment schedule | On acceptance of each milestone (M1–M9, §6) · ‹split % to be agreed› | +| Expenses & travel | ‹to be agreed› | +| Start date | ‹TBD› | +| Target completion | ‹TBD› (milestone dates per §6) | +| Warranty / support | ‹to be agreed› | +| Governing agreement | This SoW is issued under ‹MSA / framework agreement ref — TBD› | + +Change control: any change to the fixed scope (§2) is handled by a written +change request priced against the agreed model before work proceeds. + +## 13. Acceptance & sign-off + +Work is accepted milestone-by-milestone against the criteria in §7. This +Statement of Work is agreed and authorised by the undersigned. + +**For Birgma / Biltema Group (Client)** + +| | | +|---|---| +| Name | ______________________________ | +| Title | ______________________________ | +| Signature | ______________________________ | +| Date | ______________________________ | + +**For the Supplier** — ‹supplier legal name — TBD› + +| | | +|---|---| +| Name | ______________________________ | +| Title | ______________________________ | +| Signature | ______________________________ | +| Date | ______________________________ | + +Effective date: ‹on last signature› · SoW version: v1.0 (draft) · Supersedes: ‹none / prior version› + +--- + +*Companion document: a separate SoW covers the **code-review remediation +engagement** (Epic #106) — security hardening, structural refactors, and the +ADRs 0080–0084 — with per-item delivery status.* + +*The 39 flow diagrams (system · user journeys · development) are embedded in the +HTML edition and indexed in `flows.md`; the HTML edition is the self-contained, +signable version.* diff --git a/SoW/SoW-Atlas-PPM-Remediation.md b/SoW/SoW-Atlas-PPM-Remediation.md new file mode 100644 index 0000000..ddf28e4 --- /dev/null +++ b/SoW/SoW-Atlas-PPM-Remediation.md @@ -0,0 +1,198 @@ +# Statement of Work — Atlas PPM Code-Review Remediation + +| Field | Value | +|---|---| +| **Project** | Atlas PPM — Code-Review Remediation (Epic #106) | +| **System** | Atlas — Portfolio & Project Management web app (React/TS + .NET 10 minimal API, PostgreSQL 16) | +| **Client** | Birgma / Biltema Group | +| **Repository** | `nicpozent/ATLASPPM_AdditionalFeatures` | +| **Prepared for** | nicolas.pozza@birgma.com | +| **Date** | 2026-08-07 | +| **Status** | In progress — the majority of scope delivered; remainder tracked below | + +--- + +## 1. Background & objectives + +A structured code review of the Atlas PPM codebase produced a remediation +backlog (findings **R1–R19**, organised into six waves in Epic #106). The +objective of this engagement is to resolve those findings — closing security +gaps, removing structural drift, and recording the architectural decisions — +**without changing product behaviour or the approved visual prototype**, and +while keeping the build continuously green. + +Guiding principles applied throughout: + +- **One finding → one pull request**, each rebased to a single clean commit. +- **Server-authoritative decisions recorded as ADRs** (Architecture Decision + Records) before or alongside the code. +- **Test-gated**: every change verified by the full automated suite before merge. +- **No behaviour or visual regression**; inline-styled theme tokens only. + +--- + +## 2. Scope of work + +### 2.1 In scope — by wave + +| Wave | Findings | Theme | +|---|---|---| +| 1 | R1–R5 | Security gate hoist & connector logging; frontend error-surface hardening; docs/config accuracy | +| 2–3 | R6–R10 | Coverage measurement + floors; ESLint ratchets; server module-folder materialisation; single `Auth:Enabled` reader; entity-hue palette unification | +| 4 | R11–R13 | Generated API type contract; whiteboard shape registry; tab/layout registries | +| 5 | R14–R16 | Dates-as-real-types ADR; one connector abstraction; i18n-scope ADR | +| 6 | R17–R18 | Comment cleanup (why-not-what); god-object file splits | +| — | R19 | Watch-only (no action) | + +### 2.2 Out of scope + +- New product features or screens beyond the approved prototype (except + product-owner-approved extensions already recorded in `CLAUDE.md §2`). +- Redesign or restyling of any existing screen. +- Jira **bidirectional write-back** — captured as a *Proposed* decision + (ADR-0080) awaiting product-owner sign-off; **not** implemented. +- Full screen-body internationalisation (deliberately deferred — see ADR-0084). +- Data migrations for legacy display-string date columns — planned per-module + under ADR-0082 but not executed in this engagement. +- Any change to the client as a security control (authorization stays + server-authoritative). + +--- + +## 3. Deliverables & status + +### 3.1 Security hardening +| Deliverable | Status | +|---|---| +| Authorization gaps closed (H1/H2/M1/M2/M3 + follow-up sweep of ~10 further read/write endpoints) | ✅ Delivered | +| CSP (M4) + all LOW findings + by-id ownership authorization | ✅ Delivered | +| nginx CSP + cipher hardening; Jira attachment SSRF guard; backup-webhook validation | ✅ Delivered | +| GitHub Actions pinned to commit SHAs; Dependabot for actions | ✅ Delivered | + +### 3.2 Engineering quality & CI gates +| Deliverable | Status | +|---|---| +| Backend coverage measurement (coverlet) + CI floor (65% line) | ✅ Delivered | +| Frontend coverage measurement (v8) + CI floor (6% line) | ✅ Delivered | +| ESLint ratchets: `max-lines`, `max-lines-per-function`, literal-hex-colour ban | ✅ Delivered | +| Module-boundary ratchet (ADR-0072, NetArchTest) enforced in CI | ✅ Delivered (pre-existing, respected) | +| **Generated API type contract** (OpenAPI → `src/api/generated.ts`) + CI drift job (R11) | ✅ Delivered — ADR-0081 | + +### 3.3 Structural refactors +| Deliverable | Status | +|---|---| +| Whiteboard shape registry + client/server drift guard (R12) | ✅ Delivered (metadata half; render unification tracked in #98) | +| Server module-folder layout + `Auth:Enabled` single reader (R8/R9) | ✅ Delivered | +| Entity-hue palette unification (R10 stage A) | ✅ Delivered | +| Project/Dashboard tab & layout registries (R13) | ✅ Delivered | +| **One work-item connector abstraction** (Jira + Azure DevOps → `IWorkItemConnector` + generic queue/worker) (R15) | ✅ Delivered — ADR-0083 | +| Comment cleanup — delete restatement, keep rationale (R17) | ✅ Delivered | +| God-object split: `WriteEndpoints.cs` (805 → 83-line composer + 7 files) (R18 pt 1) | ✅ Delivered | + +### 3.4 Architecture Decision Records +| ADR | Subject | Status | +|---|---|---| +| ADR-0080 | Jira bidirectional write-back | **Proposed** (awaiting PO decision) | +| ADR-0081 | Generated API type contract | Accepted | +| ADR-0082 | Persist dates as real `date`/`timestamptz` | Proposed (ADR only; migration staged) | +| ADR-0083 | One work-item connector abstraction | Accepted | +| ADR-0084 | i18n scope: localised chrome, English content | Accepted | +| — | Consolidated `ALL-ADRS.md` (84 ADRs) + generator, CI staleness check | ✅ Delivered | + +### 3.5 Verification assets +- Backend: **507** xUnit tests (incl. fixture-based connector sync tests + a + client/server drift guard). ✅ +- Frontend: **145** Vitest tests. ✅ +- Playwright + axe accessibility sweep; Semgrep (SAST), Trivy (deps/secrets/IaC) + security jobs — all green in CI. ✅ + +--- + +## 4. Remaining scope (tracked, open) + +| Item | Description | Why not in this pass | +|---|---|---| +| #98 | Whiteboard render/glyph/SVG unification | Interaction-coupled; needs in-app visual verification | +| #104 (frontend) | Split `Gantt.tsx`, `Admin.tsx`, `Pip.tsx`, and folder-less screens | Needs in-app visual-regression checking; one PR each | +| #104 (backend) | Split `Dtos.cs` (per-module — surfaces hidden coupling to the boundary ratchet) and `Teams.cs` | Sequenced after the frontend splits | +| #90 (R4 tail) | Adopt shared `QueryState` in ~34 more screens | Incremental, one batch per screen group | +| #96 (R10 tail) | Sweep remaining ~442 literal hex colours; flip lint rule to error | Incremental | +| ADR-0082 migrations | Per-module date-column migrations (`Demand.Date` first) | Deliberately staged; needs a migration window | + +--- + +## 5. Approach & methodology + +1. **Analyse first** — measure the finding against current code (facts, not the + original ticket text, which may predate other merges). +2. **Decide & record** — where architectural, an ADR precedes or accompanies the + code; the developer-facing rule goes into `CLAUDE.md`. +3. **Implement** on the designated feature branch, behaviour-preserving. +4. **Verify** — full backend + frontend suites, build, lint, coverage floors, + contract-drift and boundary ratchets — locally and in CI. +5. **One issue → one PR**, squash-merged after all required CI checks pass. + +--- + +## 6. Acceptance criteria + +- All required CI checks green on each PR: frontend (lint/test/build), backend + (build/test), API-type-contract drift, accessibility (axe), SAST/Trivy, + coverage floors. +- No regression in the 507 backend / 145 frontend tests. +- Each finding's issue closed with a summary comment, or explicitly left open + with the remaining scope documented. +- Architectural changes recorded as an Accepted ADR (or Proposed where PO + sign-off is required). + +> Note: the `github-advanced-security` (Copilot Autofix) check is an external +> service that intermittently errors independently of the code; it is **not** a +> gating check for this engagement, per client direction. + +--- + +## 7. Assumptions & constraints + +- **On-prem, air-gapped deployment**: no internet egress at runtime; all fonts + and assets self-hosted/bundled (ADR-0078). Build-time dev tooling + (e.g. `openapi-typescript`) runs in CI only, never ships. +- **Deployment model**: the client deploys by downloading built files to a + Windows server; there is no git on the target. Changes therefore must be + self-contained and reproducible from the repo. +- The approved prototype (`design/Atlas PPM.dc.html`) is the visual source of + truth and is not edited; product-owner-approved deviations are recorded in + `CLAUDE.md §2` + an ADR. +- Six canonical backend roles enforce authorization; the 9-identity header + switcher is cosmetic. + +--- + +## 8. Roles & responsibilities + +| Party | Responsibility | +|---|---| +| Engineering (delivery) | Analysis, implementation, tests, ADRs, PRs, CI verification | +| Product Owner (Birgma) | Sign-off on *Proposed* ADRs (0080 Jira write-back; 0082 date migrations); prioritisation of remaining #104/#90/#96 work | +| Design team | Regenerate `design/` to reflect approved extensions (tracked, external to this engagement) | +| Platform/Ops | Provide a migration window for the ADR-0082 date-column migrations when scheduled | + +--- + +## 9. Risks & dependencies + +- **Visual-regression risk** on the remaining frontend god-object splits (#104) + — mitigated by requiring in-app verification before those PRs merge. +- **Data-migration risk** (ADR-0082) — `Demand.Date` back-fill must infer a + missing year; requires a migration window and is called out per-PR. +- **Dependency**: R18 backend `Dtos.cs` split may *surface* (not create) latent + cross-module coupling once DTOs move into module namespaces — expected and + desirable, but may require follow-up boundary fixes. +- Jira write-back (ADR-0080) reverses a foundational pull-only decision and must + not be implemented until it graduates to *Accepted*. + +--- + +*This SoW describes the Atlas PPM code-review remediation engagement (Epic +#106). If a Statement of Work for the broader Atlas PPM product build (all +screens, integrations, and governance modules) is what's needed instead, that +can be produced as a separate document.* diff --git a/SoW/flows-gallery.html b/SoW/flows-gallery.html new file mode 100644 index 0000000..1d01206 --- /dev/null +++ b/SoW/flows-gallery.html @@ -0,0 +1,26 @@ + +

Atlas PPM · Statement of Work

Functional Flows

+

Three views of Atlas PPM — how the system moves data, how users (per role) get work done, and how the engineering pieces interact at build, run and deploy.

+

SystemSystem & data flows

00 Application map & navigation
Application map & navigation
01 Authentication & RBAC gate
Authentication & RBAC gate
02 Dashboard — layout switching & data
Dashboard — layout switching & data
03 Demand intake → scoring → approval funnel
Demand intake → scoring → approval funnel
04 Portfolio → Project drill-in
Portfolio → Project drill-in
05 Project stage gates (G0–G5) & reviews
Project stage gates (G0–G5) & reviews
06 Task board move — realtime, cap-schedule
Task board move — realtime, cap-schedule
07 Timeline / Gantt & cross-entity dependencies
Timeline / Gantt & cross-entity dependencies
08 Resource utilisation & capacity
Resource utilisation & capacity
09 Financials roll-up → portfolio ROI
Financials roll-up → portfolio ROI
10 Program detail — stakeholder matrix
Program detail — stakeholder matrix
11 Products → Releases → deployment
Products → Releases → deployment
12 OKRs — objectives, key results, linkage
OKRs — objectives, key results, linkage
13 Delivery status reporting by period
Delivery status reporting by period
14 Weekly news wall (edit / view)
Weekly news wall (edit / view)
15 Connector sync (Jira / Azure DevOps)
Connector sync (Jira / Azure DevOps)
16 Whiteboard live co-editing
Whiteboard live co-editing
17 Reports & export
Reports & export
18 Administration
Administration
19 Governance & compliance
Governance & compliance

UserUser journeys

01 Executive — portfolio review
Executive — portfolio review
02 PMO — triage & approve a demand
PMO — triage & approve a demand
03 PM — create a project (wizard)
PM — create a project (wizard)
04 PM — manage tasks & Jira sync
PM — manage tasks & Jira sync
05 PM — request a stage-gate review
PM — request a stage-gate review
06 Team member — update my work
Team member — update my work
07 Stakeholder — check my status
Stakeholder — check my status
08 Manager — My Team (skills · SWOT · dev plan)
Manager — My Team (skills · SWOT · dev plan)
09 Platform Admin — administration
Platform Admin — administration
10 Chief Architect — governance
Chief Architect — governance

DevSoftware-development interaction

01 Change lifecycle — issue → PR → merge
Change lifecycle — issue → PR → merge
02 CI pipeline — the gating jobs
CI pipeline — the gating jobs
03 API type contract (OpenAPI → TS) + drift guard
API type contract (OpenAPI → TS) + drift guard
04 Module-boundary ratchet (ADR-0072)
Module-boundary ratchet (ADR-0072)
05 Test strategy — unit → integration → e2e → perf
Test strategy — unit → integration → e2e → perf
06 Local dev loop (auth on/off)
Local dev loop (auth on/off)
07 Build & air-gapped deploy
Build & air-gapped deploy
08 Runtime topology (component interaction)
Runtime topology (component interaction)
09 Extending a connector (IWorkItemConnector)
Extending a connector (IWorkItemConnector)
Generated from SoW/flows/*.mmd · Atlas theme. Sources in SoW/flows.md.
\ No newline at end of file diff --git a/SoW/flows.md b/SoW/flows.md new file mode 100644 index 0000000..912715c --- /dev/null +++ b/SoW/flows.md @@ -0,0 +1,787 @@ +# Atlas PPM — Functional Flows + +Flow diagrams in three views: **system & data flows**, **user journeys** (persona → goal), and **software-development interaction**. Each entry shows live Mermaid + a static PNG in `images/`. + + +## System & data flows + +- [Application map & navigation](#00-app-sitemap) +- [Authentication & RBAC gate](#01-auth-rbac) +- [Dashboard — layout switching & data](#02-dashboard) +- [Demand intake → scoring → approval funnel](#03-demands) +- [Portfolio → Project drill-in](#04-portfolio-project) +- [Project stage gates (G0–G5) & reviews](#05-project-gates) +- [Task board move — realtime, cap-schedule](#06-tasks-board) +- [Timeline / Gantt & cross-entity dependencies](#07-gantt) +- [Resource utilisation & capacity](#08-resources) +- [Financials roll-up → portfolio ROI](#09-financials) +- [Program detail — stakeholder matrix](#10-programs) +- [Products → Releases → deployment](#11-products-releases) +- [OKRs — objectives, key results, linkage](#12-okrs) +- [Delivery status reporting by period](#13-delivery) +- [Weekly news wall (edit / view)](#14-news) +- [Connector sync (Jira / Azure DevOps)](#15-integrations-sync) +- [Whiteboard live co-editing](#16-whiteboard) +- [Reports & export](#17-reports) +- [Administration](#18-admin) +- [Governance & compliance](#19-governance-compliance) + + +## User journeys + +- [Executive — portfolio review](#user-01-executive-review) +- [PMO — triage & approve a demand](#user-02-pmo-demand-approval) +- [PM — create a project (wizard)](#user-03-pm-create-project) +- [PM — manage tasks & Jira sync](#user-04-pm-manage-tasks) +- [PM — request a stage-gate review](#user-05-pm-stage-gate) +- [Team member — update my work](#user-06-team-member-update) +- [Stakeholder — check my status](#user-07-stakeholder-status) +- [Manager — My Team (skills · SWOT · dev plan)](#user-08-manager-team) +- [Platform Admin — administration](#user-09-platform-admin) +- [Chief Architect — governance](#user-10-architect-governance) + + +## Software-development interaction + +- [Change lifecycle — issue → PR → merge](#dev-01-change-lifecycle) +- [CI pipeline — the gating jobs](#dev-02-ci-pipeline) +- [API type contract (OpenAPI → TS) + drift guard](#dev-03-api-type-contract) +- [Module-boundary ratchet (ADR-0072)](#dev-04-module-boundary) +- [Test strategy — unit → integration → e2e → perf](#dev-05-test-strategy) +- [Local dev loop (auth on/off)](#dev-06-local-dev) +- [Build & air-gapped deploy](#dev-07-build-deploy) +- [Runtime topology (component interaction)](#dev-08-runtime-topology) +- [Extending a connector (IWorkItemConnector)](#dev-09-connector-extension) + + +--- + +# System & data flows + + + + +## Application map & navigation + +![Application map & navigation](images/00-app-sitemap.png) + +```mermaid +graph LR + ATLAS(["Atlas PPM"]):::start + ATLAS --> WS["Workspace"] + ATLAS --> CFG["Configuration"] + ATLAS --> STK["Stakeholder"] + WS --> W1["Dashboard · Portfolio · Programs
Products · OKRs · Demands · Timeline"] + WS --> W2["Project Detail · Resources · Financials
Delivery · Releases · News"] + CFG --> C1["My Team · Methodologies · Integrations
Reports · Administration · Help"] + STK --> S1["My Projects · My Demands
Delivery · Releases · News · Help"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Authentication & RBAC gate + +![Authentication & RBAC gate](images/01-auth-rbac.png) + +```mermaid +graph TD + U(["User opens Atlas"]):::start --> A{"VITE_AUTH_ENABLED?"} + A -- "No (dev)" --> DEV["Anonymous mode
X-Atlas-Role header"] + A -- "Yes" --> MSAL["MSAL redirect → Entra ID"] + MSAL --> TOK["Bearer token"] + DEV --> API["Call /api/v1/* "] + TOK --> API + API --> RBAC{"Server RBAC
capability check"} + RBAC -- allow --> OK(["200 + data"]):::start + RBAC -- deny --> F["403 Forbidden"]:::deny + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; +``` + + + + +## Dashboard — layout switching & data + +![Dashboard — layout switching & data](images/02-dashboard.png) + +```mermaid +graph LR + N(["Open Dashboard"]):::start --> L{"Layout"} + L --> E["Executive"] + L --> O["Operational"] + L --> C["Compact"] + L --> CU["Custom builder
drag/add/remove widgets"] + E --> Q["useDashboard() query"] + O --> Q + C --> Q + CU --> Q + Q --> D{"Data?"} + D -- yes --> R["KPIs · charts · tables · pipeline"] + D -- empty --> Z["Zeroed KPIs · empty panels"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Demand intake → scoring → approval funnel + +![Demand intake → scoring → approval funnel](images/03-demands.png) + +```mermaid +graph TD + C(["Create demand"]):::start --> SC["Score: value + effort (1–5)"] + SC --> DR["Draft"] + DR --> BK["Backlog"] + BK -->|"drag card (live funnel)"| AP{"Approve?
governance-gated"} + AP -- approved --> PG["In progress"] + AP -- hold --> HD["Hold"] + PG --> CV["Converted to project"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Portfolio → Project drill-in + +![Portfolio → Project drill-in](images/04-portfolio-project.png) + +```mermaid +graph LR + P(["Portfolio"]):::start --> T{"Sub-tab"} + T --> PJ["Projects
filter chips · cards/table"] + T --> BK["Blockers
list + side panel"] + PJ -->|"click project"| PD(["Project Detail"]):::start + PD --> TABS["Overview · Tasks · Epics · RAID
Artifacts · Costs · Gates · Security"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Project stage gates (G0–G5) & reviews + +![Project stage gates (G0–G5) & reviews](images/05-project-gates.png) + +```mermaid +graph LR + G0["G0
Concept"] --> G1["G1
Initiate"] --> G2["G2
Plan"] --> G3["G3
Build"] --> G4["G4
Deploy"] --> G5["G5
Close"] + R{"Gate review
cap-approve"}:::gate + G1 -.-> R + G3 -.-> R + R -- pass --> ADV["Advance to next gate"] + R -- fail --> REM["Remediate / hold"]:::deny + classDef gate fill:#fff6e6,stroke:#a9791a,color:#5a3d00; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; +``` + + + + +## Task board move — realtime, cap-schedule + +![Task board move — realtime, cap-schedule](images/06-tasks-board.png) + +```mermaid +graph TD + U(["Planner drags task card"]):::start --> CAP{"cap-schedule?
Admin · PMO · PM · PM Lead"} + CAP -- no --> DENY["403 — status change denied"]:::deny + CAP -- yes --> MV["PATCH task status"] + MV --> HUB["SignalR room tasks:{projectId}"] + HUB --> PEERS["Card moves live for every viewer"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; +``` + + + + +## Timeline / Gantt & cross-entity dependencies + +![Timeline / Gantt & cross-entity dependencies](images/07-gantt.png) + +```mermaid +graph LR + SC{"Scope"} --> PJ["Project"] + SC --> PG["Program"] + PJ --> T["Timeline: phases · bars · milestones"] + PG --> T + T --> DEP["Finish→Start dependency arrows"] + DEP --> S{"source"} + S --> M["manual (hand-drawn, cap-projects)"] + S --> J["jira (issue-link ingest)"] + S --> PL["project links (auto)"] +``` + + + + +## Resource utilisation & capacity + +![Resource utilisation & capacity](images/08-resources.png) + +```mermaid +graph TD + R(["Resources roster
synced from Entra ID"]):::start --> W{"Period window"} + W --> WIN["day/week/month/quarter/half/year
or custom date range"] + WIN --> ENG["Shared time-phased engine"] + ENG --> UT["Avg utilisation = Ops + Project + Product"] + UT --> OV{"over 100%?"} + OV -- yes --> FLAG["Over-allocation → resource risk"]:::deny + OV -- no --> OK["Within capacity"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; +``` + + + + +## Financials roll-up → portfolio ROI + +![Financials roll-up → portfolio ROI](images/09-financials.png) + +```mermaid +graph LR + SRC{"Source toggle"} --> BUD["Budget vs Actual"] + BUD --> SP["CapEx / OpEx split"] + SP --> FAC["Forecast at completion"] + FAC --> BEN["Savings / benefit"] + BEN --> ROI(["Portfolio ROI"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Program detail — stakeholder matrix + +![Program detail — stakeholder matrix](images/10-programs.png) + +```mermaid +graph TD + PG(["Program detail"]):::start --> MTX["Stakeholder power/interest matrix"] + PG --> LP["Linked projects — roll-up status"] + PG --> SY["Sync from Jira (cap-projects E)"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Products → Releases → deployment + +![Products → Releases → deployment](images/11-products-releases.png) + +```mermaid +graph LR + PRD(["Product"]):::start --> MAP["Jira / ADO tasks mapped"] + MAP --> REL["Releases"] + REL --> CAL["Release calendar"] + CAL --> DEP["Deployment tracking"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## OKRs — objectives, key results, linkage + +![OKRs — objectives, key results, linkage](images/12-okrs.png) + +```mermaid +graph TD + O(["Objective"]):::start --> KR["Key results"] + KR --> L{"Link target"} + L --> P["Project"] + L --> PG["Program"] + L --> PR["Product"] + KR --> PROG["Progress roll-up (0–100%)"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Delivery status reporting by period + +![Delivery status reporting by period](images/13-delivery.png) + +```mermaid +graph LR + PER{"Period
weekly → yearly"} --> AGG["Completed · in-progress · planned"] + AGG --> VEL["Velocity + on-time %"] + AGG --> BLK["Blockers"] + AGG --> BURN["Budget burn"] + VEL --> RPT(["Stakeholder delivery report"]):::start + BLK --> RPT + BURN --> RPT + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Weekly news wall (edit / view) + +![Weekly news wall (edit / view)](images/14-news.png) + +```mermaid +graph TD + ED{"Edit mode?"} -- yes --> BLK["Add blocks: headline · metric · shout-out
image · milestone · doc"] + BLK --> SAVE["Save news wall"] + ED -- no --> VIEW(["Masonry news wall (themed)"]):::start + SAVE --> VIEW + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Connector sync (Jira / Azure DevOps) + +![Connector sync (Jira / Azure DevOps)](images/15-integrations-sync.png) + +```mermaid +sequenceDiagram + autonumber + actor U as PM · cap-projects E + participant API as Atlas API + participant Q as SyncQueue⟨T⟩ + participant W as SyncWorker⟨T⟩ + participant C as IWorkItemConnector + participant EX as Jira / Azure DevOps + U->>API: POST /projects/{id}/{conn}/sync?background=true + API->>API: gate cap-projects E + API->>Q: enqueue job + API-->>U: 202 Accepted + jobId + W->>C: SyncCoreAsync(targets, delta) + C->>EX: pull issues (delta watermark, ISO) + EX-->>C: work items + C->>API: upsert projects / sprints / epics / tasks + W->>API: write audit event + U->>API: GET .../sync/status/{jobId} + API-->>U: status = done (counts) +``` + + + + +## Whiteboard live co-editing + +![Whiteboard live co-editing](images/16-whiteboard.png) + +```mermaid +graph TD + U(["User edits node / edge"]):::start --> OP["Authorized op
scope-gated by entity capability"] + OP --> SAN["Server sanitises + persists typed row"] + SAN --> HUB["Room hub broadcast"] + HUB --> PEERS["Live co-edit: presence · cursors
field-merge · off-screen peers"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Reports & export + +![Reports & export](images/17-reports.png) + +```mermaid +graph LR + SEL(["Select report
portfolio · demand · blocker · audit"]):::start --> BR["Apply branding"] + BR --> F{"Export format"} + F --> PDF["PDF"] + F --> XL["Excel"] + F --> PP["PPTX"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Administration + +![Administration](images/18-admin.png) + +```mermaid +graph TD + A(["Administration"]):::start --> RBAC["Roles & permissions matrix"] + A --> BK["Backups / restore (validated)"] + A --> AUD["Audit log"] + A --> SY["AD directory sync"] + A --> DEL["Deletion requests (GDPR)"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Governance & compliance + +![Governance & compliance](images/19-governance-compliance.png) + +```mermaid +graph TD + GOV(["Governance & compliance"]):::start --> SOA["ISO 27001 SoA — 93 Annex A controls"] + GOV --> ADR["Decision log (ADR)"] + GOV --> TG["TOGAF ADM phases · ARB · waivers"] + GOV --> SEC["GDPR · PCI-DSS · EU AI Act · SOC 2 · NIS2"] + SOA --> COV["Coverage roll-up"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + +--- + +# User journeys + + + + +## Executive — portfolio review + +![Executive — portfolio review](images/user-01-executive-review.png) + +```mermaid +graph LR + U(["Executive"]):::start --> A["Open Dashboard → Executive layout"] + A --> B["Scan portfolio-health donut + KPI cards"] + B --> C{"Anything needs attention?"} + C -- yes --> D["Open a 'needs attention' project"] + D --> E["Read status · budget burn · blockers"] + C -- no --> F["Review demand pipeline + recent activity"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## PMO — triage & approve a demand + +![PMO — triage & approve a demand](images/user-02-pmo-demand-approval.png) + +```mermaid +graph LR + U(["PMO"]):::start --> A["Open Demands funnel"] + A --> B["Review a scored demand (value vs effort)"] + B --> C{"Approve?"} + C -- yes --> D["Drag card to Approved → confirm"] + D --> E["Demand becomes project intake"] + C -- no --> F["Move to Hold · add comment"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## PM — create a project (wizard) + +![PM — create a project (wizard)](images/user-03-pm-create-project.png) + +```mermaid +graph LR + U(["Project Manager"]):::start --> A["Methodologies → Create project"] + A --> B["Step 1 · pick methodology"] + B --> C["Step 2 · name · department · owner"] + C --> D["Step 3 · choose integration (Jira / ADO / none)"] + D --> E(["Project created → opens Project Detail"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## PM — manage tasks & Jira sync + +![PM — manage tasks & Jira sync](images/user-04-pm-manage-tasks.png) + +```mermaid +graph LR + U(["Project Manager"]):::start --> A["Project → Tasks (board)"] + A --> B["Drag a card between columns"] + B --> C["Status updates live for the team"] + A --> D["Sync from Jira (pull latest)"] + D --> E["Board reflects imported issues"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## PM — request a stage-gate review + +![PM — request a stage-gate review](images/user-05-pm-stage-gate.png) + +```mermaid +graph LR + U(["Project Manager"]):::start --> A["Project → Gates (G0–G5)"] + A --> B["Prepare gate evidence / checklist"] + B --> C["Request gate review"] + C --> D{"Reviewer decision"} + D -- pass --> E["Advance to next gate"] + D -- fail --> F["Remediate and resubmit"]:::deny + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; +``` + + + + +## Team member — update my work + +![Team member — update my work](images/user-06-team-member-update.png) + +```mermaid +graph LR + U(["Team member"]):::start --> A["Dashboard → Operational → My tasks"] + A --> B["Open a task"] + B --> C["Update status · progress · notes"] + C --> D["Saved → rolls up to project + delivery"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Stakeholder — check my status + +![Stakeholder — check my status](images/user-07-stakeholder-status.png) + +```mermaid +graph LR + U(["Stakeholder"]):::start --> A["My Projects (reduced nav)"] + A --> B["Open a project → read-only status"] + B --> C["Check Delivery status + Releases"] + C --> D["Read Weekly Updates (News)"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Manager — My Team (skills · SWOT · dev plan) + +![Manager — My Team (skills · SWOT · dev plan)](images/user-08-manager-team.png) + +```mermaid +graph LR + U(["Manager"]):::start --> A["My Team"] + A --> B["Review members + skills matrix"] + B --> C["Update team SWOT"] + B --> D["Record individual development plan (manager-only)"] + C --> E["Saved · governance-gated · audited"] + D --> E + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Platform Admin — administration + +![Platform Admin — administration](images/user-09-platform-admin.png) + +```mermaid +graph LR + U(["Platform Admin"]):::start --> A["Administration"] + A --> B["Roles & permissions matrix"] + A --> C["Backups / restore · audit log"] + A --> D["AD directory sync · connector config"] + A --> E["Review & action deletion requests (GDPR)"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Chief Architect — governance + +![Chief Architect — governance](images/user-10-architect-governance.png) + +```mermaid +graph LR + U(["Chief Architect"]):::start --> A["Governance"] + A --> B["Decision log — record an ADR"] + A --> C["Architecture gate reviews (G1 / G3)"] + A --> D["TOGAF ADM · domains · waivers · ARB"] + A --> E["Project → Security: ISO 27001 SoA"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + +--- + +# Software-development interaction + + + + +## Change lifecycle — issue → PR → merge + +![Change lifecycle — issue → PR → merge](images/dev-01-change-lifecycle.png) + +```mermaid +graph LR + I(["Issue / finding"]):::start --> B["Branch (claude/…)"] + B --> IMP["Implement · ADR if architectural"] + IMP --> PR["Open ONE PR (one issue → one PR)"] + PR --> CI{"CI green?"} + CI -- no --> FIX["Fix → push"] + FIX --> CI + CI -- yes --> RV["Review"] + RV --> M(["Squash-merge to main"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## CI pipeline — the gating jobs + +![CI pipeline — the gating jobs](images/dev-02-ci-pipeline.png) + +```mermaid +graph TD + P(["Push / Pull request"]):::start --> J{"CI jobs — parallel"} + J --> FE["Frontend: lint · test · build · coverage floor"] + J --> BE["API: build · test · coverage floor"] + J --> CT["API type-contract drift"] + J --> AX["Accessibility (Playwright + axe)"] + J --> SEC["SAST (Semgrep) · Trivy (deps/secrets/IaC)"] + FE --> G{"All required green?"} + BE --> G + CT --> G + AX --> G + SEC --> G + G -- yes --> MG(["Mergeable"]):::start + G -- no --> BL["Blocked"]:::deny + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; +``` + + + + +## API type contract (OpenAPI → TS) + drift guard + +![API type contract (OpenAPI → TS) + drift guard](images/dev-03-api-type-contract.png) + +```mermaid +graph LR + DTO["Server DTOs · .Produces<T>"] --> DUMP["Boot API (Atlas:SkipDbInit, no DB)"] + DUMP --> DOC["openapi/atlas-v1.json"] + DOC --> GEN["openapi-typescript"] + GEN --> TS["src/api/generated.ts"] + TS --> DIFF{"CI: git diff --exit-code"} + DIFF -- drift --> FAIL["Fail — run npm run api:types"]:::deny + DIFF -- clean --> OK(["Contract in sync"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; +``` + + + + +## Module-boundary ratchet (ADR-0072) + +![Module-boundary ratchet (ADR-0072)](images/dev-04-module-boundary.png) + +```mermaid +graph LR + BUILD(["Build + test"]):::start --> ARCH["NetArchTest / Mono.Cecil ratchet (ADR-0072)"] + ARCH --> CHK{"Atlas.Api.<Domain> edges legal?"} + CHK -- "Integrations reaches a business module" --> FAIL["Build fails"]:::deny + CHK -- "leaf boundaries respected" --> OK(["Pass"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; +``` + + + + +## Test strategy — unit → integration → e2e → perf + +![Test strategy — unit → integration → e2e → perf](images/dev-05-test-strategy.png) + +```mermaid +graph TD + U["Unit — xUnit (server) · Vitest (frontend)"] --> I["Integration — WebApplicationFactory (in-memory DB)"] + I --> E["E2E — Playwright + axe (empty-state DOM)"] + E --> PF["Performance — k6 budget"] + PF --> COV(["Coverage floors gated in CI"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Local dev loop (auth on/off) + +![Local dev loop (auth on/off)](images/dev-06-local-dev.png) + +```mermaid +graph LR + DEV(["Developer"]):::start --> A["npm install → npm run dev (:5173)"] + A --> B{"VITE_AUTH_ENABLED?"} + B -- false --> C["Browse every screen → empty states (no backend)"] + B -- true --> D["Entra SSO + VITE_API_PROXY → live API"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Build & air-gapped deploy + +![Build & air-gapped deploy](images/dev-07-build-deploy.png) + +```mermaid +graph LR + SRC(["Source"]):::start --> FE["npm run build (tsc + Vite)"] + SRC --> BE["dotnet publish"] + FE --> ART["Self-contained artefacts (assets bundled)"] + BE --> ART + ART --> DL["Download to Windows server (no git on target)"] + DL --> NG(["nginx same-origin: app · /api/v1 · /hubs"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Runtime topology (component interaction) + +![Runtime topology (component interaction)](images/dev-08-runtime-topology.png) + +```mermaid +graph LR + BR(["Browser · React SPA"]):::start --> NG["nginx (same-origin)"] + NG --> API["Atlas .NET API · /api/v1"] + NG --> HUB["SignalR · /hubs (realtime rooms)"] + API --> DB[("PostgreSQL 16")] + API --> EXT["Connectors: Jira · Azure DevOps · …"] + BR -. "MSAL bearer" .-> ENTRA["Entra ID (SSO)"] + API -. "validate token" .-> ENTRA + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` + + + + +## Extending a connector (IWorkItemConnector) + +![Extending a connector (IWorkItemConnector)](images/dev-09-connector-extension.png) + +```mermaid +graph LR + NEW(["New tracker (e.g. ServiceNow)"]):::start --> IMPL["implement IWorkItemConnector"] + IMPL --> REG["register in DI: SyncQueue<T> + SyncWorker<T>"] + REG --> EP["reuse shared enqueue · 202/poll · gate"] + EP --> PARSE["add ONLY connector-specific parsing"] + PARSE --> TST(["fixture tests + boundary stays a leaf"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; +``` diff --git a/SoW/flows/00-app-sitemap.mmd b/SoW/flows/00-app-sitemap.mmd new file mode 100644 index 0000000..6a3f6bf --- /dev/null +++ b/SoW/flows/00-app-sitemap.mmd @@ -0,0 +1,10 @@ +graph LR + ATLAS(["Atlas PPM"]):::start + ATLAS --> WS["Workspace"] + ATLAS --> CFG["Configuration"] + ATLAS --> STK["Stakeholder"] + WS --> W1["Dashboard · Portfolio · Programs
Products · OKRs · Demands · Timeline"] + WS --> W2["Project Detail · Resources · Financials
Delivery · Releases · News"] + CFG --> C1["My Team · Methodologies · Integrations
Reports · Administration · Help"] + STK --> S1["My Projects · My Demands
Delivery · Releases · News · Help"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/01-auth-rbac.mmd b/SoW/flows/01-auth-rbac.mmd new file mode 100644 index 0000000..a21c547 --- /dev/null +++ b/SoW/flows/01-auth-rbac.mmd @@ -0,0 +1,12 @@ +graph TD + U(["User opens Atlas"]):::start --> A{"VITE_AUTH_ENABLED?"} + A -- "No (dev)" --> DEV["Anonymous mode
X-Atlas-Role header"] + A -- "Yes" --> MSAL["MSAL redirect → Entra ID"] + MSAL --> TOK["Bearer token"] + DEV --> API["Call /api/v1/* "] + TOK --> API + API --> RBAC{"Server RBAC
capability check"} + RBAC -- allow --> OK(["200 + data"]):::start + RBAC -- deny --> F["403 Forbidden"]:::deny + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; diff --git a/SoW/flows/02-dashboard.mmd b/SoW/flows/02-dashboard.mmd new file mode 100644 index 0000000..94967a9 --- /dev/null +++ b/SoW/flows/02-dashboard.mmd @@ -0,0 +1,14 @@ +graph LR + N(["Open Dashboard"]):::start --> L{"Layout"} + L --> E["Executive"] + L --> O["Operational"] + L --> C["Compact"] + L --> CU["Custom builder
drag/add/remove widgets"] + E --> Q["useDashboard() query"] + O --> Q + C --> Q + CU --> Q + Q --> D{"Data?"} + D -- yes --> R["KPIs · charts · tables · pipeline"] + D -- empty --> Z["Zeroed KPIs · empty panels"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/03-demands.mmd b/SoW/flows/03-demands.mmd new file mode 100644 index 0000000..f5e1e88 --- /dev/null +++ b/SoW/flows/03-demands.mmd @@ -0,0 +1,9 @@ +graph TD + C(["Create demand"]):::start --> SC["Score: value + effort (1–5)"] + SC --> DR["Draft"] + DR --> BK["Backlog"] + BK -->|"drag card (live funnel)"| AP{"Approve?
governance-gated"} + AP -- approved --> PG["In progress"] + AP -- hold --> HD["Hold"] + PG --> CV["Converted to project"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/04-portfolio-project.mmd b/SoW/flows/04-portfolio-project.mmd new file mode 100644 index 0000000..bfffa2e --- /dev/null +++ b/SoW/flows/04-portfolio-project.mmd @@ -0,0 +1,7 @@ +graph LR + P(["Portfolio"]):::start --> T{"Sub-tab"} + T --> PJ["Projects
filter chips · cards/table"] + T --> BK["Blockers
list + side panel"] + PJ -->|"click project"| PD(["Project Detail"]):::start + PD --> TABS["Overview · Tasks · Epics · RAID
Artifacts · Costs · Gates · Security"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/05-project-gates.mmd b/SoW/flows/05-project-gates.mmd new file mode 100644 index 0000000..623bb05 --- /dev/null +++ b/SoW/flows/05-project-gates.mmd @@ -0,0 +1,9 @@ +graph LR + G0["G0
Concept"] --> G1["G1
Initiate"] --> G2["G2
Plan"] --> G3["G3
Build"] --> G4["G4
Deploy"] --> G5["G5
Close"] + R{"Gate review
cap-approve"}:::gate + G1 -.-> R + G3 -.-> R + R -- pass --> ADV["Advance to next gate"] + R -- fail --> REM["Remediate / hold"]:::deny + classDef gate fill:#fff6e6,stroke:#a9791a,color:#5a3d00; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; diff --git a/SoW/flows/06-tasks-board.mmd b/SoW/flows/06-tasks-board.mmd new file mode 100644 index 0000000..07d16f2 --- /dev/null +++ b/SoW/flows/06-tasks-board.mmd @@ -0,0 +1,8 @@ +graph TD + U(["Planner drags task card"]):::start --> CAP{"cap-schedule?
Admin · PMO · PM · PM Lead"} + CAP -- no --> DENY["403 — status change denied"]:::deny + CAP -- yes --> MV["PATCH task status"] + MV --> HUB["SignalR room tasks:{projectId}"] + HUB --> PEERS["Card moves live for every viewer"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; diff --git a/SoW/flows/07-gantt.mmd b/SoW/flows/07-gantt.mmd new file mode 100644 index 0000000..46fdb3c --- /dev/null +++ b/SoW/flows/07-gantt.mmd @@ -0,0 +1,10 @@ +graph LR + SC{"Scope"} --> PJ["Project"] + SC --> PG["Program"] + PJ --> T["Timeline: phases · bars · milestones"] + PG --> T + T --> DEP["Finish→Start dependency arrows"] + DEP --> S{"source"} + S --> M["manual (hand-drawn, cap-projects)"] + S --> J["jira (issue-link ingest)"] + S --> PL["project links (auto)"] diff --git a/SoW/flows/08-resources.mmd b/SoW/flows/08-resources.mmd new file mode 100644 index 0000000..4edb25c --- /dev/null +++ b/SoW/flows/08-resources.mmd @@ -0,0 +1,10 @@ +graph TD + R(["Resources roster
synced from Entra ID"]):::start --> W{"Period window"} + W --> WIN["day/week/month/quarter/half/year
or custom date range"] + WIN --> ENG["Shared time-phased engine"] + ENG --> UT["Avg utilisation = Ops + Project + Product"] + UT --> OV{"over 100%?"} + OV -- yes --> FLAG["Over-allocation → resource risk"]:::deny + OV -- no --> OK["Within capacity"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; diff --git a/SoW/flows/09-financials.mmd b/SoW/flows/09-financials.mmd new file mode 100644 index 0000000..43de8fd --- /dev/null +++ b/SoW/flows/09-financials.mmd @@ -0,0 +1,7 @@ +graph LR + SRC{"Source toggle"} --> BUD["Budget vs Actual"] + BUD --> SP["CapEx / OpEx split"] + SP --> FAC["Forecast at completion"] + FAC --> BEN["Savings / benefit"] + BEN --> ROI(["Portfolio ROI"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/10-programs.mmd b/SoW/flows/10-programs.mmd new file mode 100644 index 0000000..53db8cc --- /dev/null +++ b/SoW/flows/10-programs.mmd @@ -0,0 +1,5 @@ +graph TD + PG(["Program detail"]):::start --> MTX["Stakeholder power/interest matrix"] + PG --> LP["Linked projects — roll-up status"] + PG --> SY["Sync from Jira (cap-projects E)"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/11-products-releases.mmd b/SoW/flows/11-products-releases.mmd new file mode 100644 index 0000000..01dd6a4 --- /dev/null +++ b/SoW/flows/11-products-releases.mmd @@ -0,0 +1,6 @@ +graph LR + PRD(["Product"]):::start --> MAP["Jira / ADO tasks mapped"] + MAP --> REL["Releases"] + REL --> CAL["Release calendar"] + CAL --> DEP["Deployment tracking"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/12-okrs.mmd b/SoW/flows/12-okrs.mmd new file mode 100644 index 0000000..7fe2f9e --- /dev/null +++ b/SoW/flows/12-okrs.mmd @@ -0,0 +1,8 @@ +graph TD + O(["Objective"]):::start --> KR["Key results"] + KR --> L{"Link target"} + L --> P["Project"] + L --> PG["Program"] + L --> PR["Product"] + KR --> PROG["Progress roll-up (0–100%)"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/13-delivery.mmd b/SoW/flows/13-delivery.mmd new file mode 100644 index 0000000..68fda3e --- /dev/null +++ b/SoW/flows/13-delivery.mmd @@ -0,0 +1,9 @@ +graph LR + PER{"Period
weekly → yearly"} --> AGG["Completed · in-progress · planned"] + AGG --> VEL["Velocity + on-time %"] + AGG --> BLK["Blockers"] + AGG --> BURN["Budget burn"] + VEL --> RPT(["Stakeholder delivery report"]):::start + BLK --> RPT + BURN --> RPT + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/14-news.mmd b/SoW/flows/14-news.mmd new file mode 100644 index 0000000..72920d6 --- /dev/null +++ b/SoW/flows/14-news.mmd @@ -0,0 +1,6 @@ +graph TD + ED{"Edit mode?"} -- yes --> BLK["Add blocks: headline · metric · shout-out
image · milestone · doc"] + BLK --> SAVE["Save news wall"] + ED -- no --> VIEW(["Masonry news wall (themed)"]):::start + SAVE --> VIEW + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/15-integrations-sync.mmd b/SoW/flows/15-integrations-sync.mmd new file mode 100644 index 0000000..36d357b --- /dev/null +++ b/SoW/flows/15-integrations-sync.mmd @@ -0,0 +1,19 @@ +sequenceDiagram + autonumber + actor U as PM · cap-projects E + participant API as Atlas API + participant Q as SyncQueue⟨T⟩ + participant W as SyncWorker⟨T⟩ + participant C as IWorkItemConnector + participant EX as Jira / Azure DevOps + U->>API: POST /projects/{id}/{conn}/sync?background=true + API->>API: gate cap-projects E + API->>Q: enqueue job + API-->>U: 202 Accepted + jobId + W->>C: SyncCoreAsync(targets, delta) + C->>EX: pull issues (delta watermark, ISO) + EX-->>C: work items + C->>API: upsert projects / sprints / epics / tasks + W->>API: write audit event + U->>API: GET .../sync/status/{jobId} + API-->>U: status = done (counts) diff --git a/SoW/flows/16-whiteboard.mmd b/SoW/flows/16-whiteboard.mmd new file mode 100644 index 0000000..1b8ee98 --- /dev/null +++ b/SoW/flows/16-whiteboard.mmd @@ -0,0 +1,6 @@ +graph TD + U(["User edits node / edge"]):::start --> OP["Authorized op
scope-gated by entity capability"] + OP --> SAN["Server sanitises + persists typed row"] + SAN --> HUB["Room hub broadcast"] + HUB --> PEERS["Live co-edit: presence · cursors
field-merge · off-screen peers"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/17-reports.mmd b/SoW/flows/17-reports.mmd new file mode 100644 index 0000000..3c57691 --- /dev/null +++ b/SoW/flows/17-reports.mmd @@ -0,0 +1,7 @@ +graph LR + SEL(["Select report
portfolio · demand · blocker · audit"]):::start --> BR["Apply branding"] + BR --> F{"Export format"} + F --> PDF["PDF"] + F --> XL["Excel"] + F --> PP["PPTX"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/18-admin.mmd b/SoW/flows/18-admin.mmd new file mode 100644 index 0000000..3753b64 --- /dev/null +++ b/SoW/flows/18-admin.mmd @@ -0,0 +1,7 @@ +graph TD + A(["Administration"]):::start --> RBAC["Roles & permissions matrix"] + A --> BK["Backups / restore (validated)"] + A --> AUD["Audit log"] + A --> SY["AD directory sync"] + A --> DEL["Deletion requests (GDPR)"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/19-governance-compliance.mmd b/SoW/flows/19-governance-compliance.mmd new file mode 100644 index 0000000..d91b80d --- /dev/null +++ b/SoW/flows/19-governance-compliance.mmd @@ -0,0 +1,7 @@ +graph TD + GOV(["Governance & compliance"]):::start --> SOA["ISO 27001 SoA — 93 Annex A controls"] + GOV --> ADR["Decision log (ADR)"] + GOV --> TG["TOGAF ADM phases · ARB · waivers"] + GOV --> SEC["GDPR · PCI-DSS · EU AI Act · SOC 2 · NIS2"] + SOA --> COV["Coverage roll-up"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/dev-01-change-lifecycle.mmd b/SoW/flows/dev-01-change-lifecycle.mmd new file mode 100644 index 0000000..b911847 --- /dev/null +++ b/SoW/flows/dev-01-change-lifecycle.mmd @@ -0,0 +1,10 @@ +graph LR + I(["Issue / finding"]):::start --> B["Branch (claude/…)"] + B --> IMP["Implement · ADR if architectural"] + IMP --> PR["Open ONE PR (one issue → one PR)"] + PR --> CI{"CI green?"} + CI -- no --> FIX["Fix → push"] + FIX --> CI + CI -- yes --> RV["Review"] + RV --> M(["Squash-merge to main"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/dev-02-ci-pipeline.mmd b/SoW/flows/dev-02-ci-pipeline.mmd new file mode 100644 index 0000000..6de68c7 --- /dev/null +++ b/SoW/flows/dev-02-ci-pipeline.mmd @@ -0,0 +1,16 @@ +graph TD + P(["Push / Pull request"]):::start --> J{"CI jobs — parallel"} + J --> FE["Frontend: lint · test · build · coverage floor"] + J --> BE["API: build · test · coverage floor"] + J --> CT["API type-contract drift"] + J --> AX["Accessibility (Playwright + axe)"] + J --> SEC["SAST (Semgrep) · Trivy (deps/secrets/IaC)"] + FE --> G{"All required green?"} + BE --> G + CT --> G + AX --> G + SEC --> G + G -- yes --> MG(["Mergeable"]):::start + G -- no --> BL["Blocked"]:::deny + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; diff --git a/SoW/flows/dev-03-api-type-contract.mmd b/SoW/flows/dev-03-api-type-contract.mmd new file mode 100644 index 0000000..980bb13 --- /dev/null +++ b/SoW/flows/dev-03-api-type-contract.mmd @@ -0,0 +1,10 @@ +graph LR + DTO["Server DTOs · .Produces<T>"] --> DUMP["Boot API (Atlas:SkipDbInit, no DB)"] + DUMP --> DOC["openapi/atlas-v1.json"] + DOC --> GEN["openapi-typescript"] + GEN --> TS["src/api/generated.ts"] + TS --> DIFF{"CI: git diff --exit-code"} + DIFF -- drift --> FAIL["Fail — run npm run api:types"]:::deny + DIFF -- clean --> OK(["Contract in sync"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; diff --git a/SoW/flows/dev-04-module-boundary.mmd b/SoW/flows/dev-04-module-boundary.mmd new file mode 100644 index 0000000..d94d419 --- /dev/null +++ b/SoW/flows/dev-04-module-boundary.mmd @@ -0,0 +1,7 @@ +graph LR + BUILD(["Build + test"]):::start --> ARCH["NetArchTest / Mono.Cecil ratchet (ADR-0072)"] + ARCH --> CHK{"Atlas.Api.<Domain> edges legal?"} + CHK -- "Integrations reaches a business module" --> FAIL["Build fails"]:::deny + CHK -- "leaf boundaries respected" --> OK(["Pass"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; diff --git a/SoW/flows/dev-05-test-strategy.mmd b/SoW/flows/dev-05-test-strategy.mmd new file mode 100644 index 0000000..9f41070 --- /dev/null +++ b/SoW/flows/dev-05-test-strategy.mmd @@ -0,0 +1,6 @@ +graph TD + U["Unit — xUnit (server) · Vitest (frontend)"] --> I["Integration — WebApplicationFactory (in-memory DB)"] + I --> E["E2E — Playwright + axe (empty-state DOM)"] + E --> PF["Performance — k6 budget"] + PF --> COV(["Coverage floors gated in CI"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/dev-06-local-dev.mmd b/SoW/flows/dev-06-local-dev.mmd new file mode 100644 index 0000000..95bc56c --- /dev/null +++ b/SoW/flows/dev-06-local-dev.mmd @@ -0,0 +1,6 @@ +graph LR + DEV(["Developer"]):::start --> A["npm install → npm run dev (:5173)"] + A --> B{"VITE_AUTH_ENABLED?"} + B -- false --> C["Browse every screen → empty states (no backend)"] + B -- true --> D["Entra SSO + VITE_API_PROXY → live API"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/dev-07-build-deploy.mmd b/SoW/flows/dev-07-build-deploy.mmd new file mode 100644 index 0000000..5032b11 --- /dev/null +++ b/SoW/flows/dev-07-build-deploy.mmd @@ -0,0 +1,8 @@ +graph LR + SRC(["Source"]):::start --> FE["npm run build (tsc + Vite)"] + SRC --> BE["dotnet publish"] + FE --> ART["Self-contained artefacts (assets bundled)"] + BE --> ART + ART --> DL["Download to Windows server (no git on target)"] + DL --> NG(["nginx same-origin: app · /api/v1 · /hubs"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/dev-08-runtime-topology.mmd b/SoW/flows/dev-08-runtime-topology.mmd new file mode 100644 index 0000000..28bbeab --- /dev/null +++ b/SoW/flows/dev-08-runtime-topology.mmd @@ -0,0 +1,9 @@ +graph LR + BR(["Browser · React SPA"]):::start --> NG["nginx (same-origin)"] + NG --> API["Atlas .NET API · /api/v1"] + NG --> HUB["SignalR · /hubs (realtime rooms)"] + API --> DB[("PostgreSQL 16")] + API --> EXT["Connectors: Jira · Azure DevOps · …"] + BR -. "MSAL bearer" .-> ENTRA["Entra ID (SSO)"] + API -. "validate token" .-> ENTRA + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/dev-09-connector-extension.mmd b/SoW/flows/dev-09-connector-extension.mmd new file mode 100644 index 0000000..d4dd025 --- /dev/null +++ b/SoW/flows/dev-09-connector-extension.mmd @@ -0,0 +1,7 @@ +graph LR + NEW(["New tracker (e.g. ServiceNow)"]):::start --> IMPL["implement IWorkItemConnector"] + IMPL --> REG["register in DI: SyncQueue<T> + SyncWorker<T>"] + REG --> EP["reuse shared enqueue · 202/poll · gate"] + EP --> PARSE["add ONLY connector-specific parsing"] + PARSE --> TST(["fixture tests + boundary stays a leaf"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/user-01-executive-review.mmd b/SoW/flows/user-01-executive-review.mmd new file mode 100644 index 0000000..2ac09b2 --- /dev/null +++ b/SoW/flows/user-01-executive-review.mmd @@ -0,0 +1,8 @@ +graph LR + U(["Executive"]):::start --> A["Open Dashboard → Executive layout"] + A --> B["Scan portfolio-health donut + KPI cards"] + B --> C{"Anything needs attention?"} + C -- yes --> D["Open a 'needs attention' project"] + D --> E["Read status · budget burn · blockers"] + C -- no --> F["Review demand pipeline + recent activity"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/user-02-pmo-demand-approval.mmd b/SoW/flows/user-02-pmo-demand-approval.mmd new file mode 100644 index 0000000..aec3581 --- /dev/null +++ b/SoW/flows/user-02-pmo-demand-approval.mmd @@ -0,0 +1,8 @@ +graph LR + U(["PMO"]):::start --> A["Open Demands funnel"] + A --> B["Review a scored demand (value vs effort)"] + B --> C{"Approve?"} + C -- yes --> D["Drag card to Approved → confirm"] + D --> E["Demand becomes project intake"] + C -- no --> F["Move to Hold · add comment"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/user-03-pm-create-project.mmd b/SoW/flows/user-03-pm-create-project.mmd new file mode 100644 index 0000000..5b99564 --- /dev/null +++ b/SoW/flows/user-03-pm-create-project.mmd @@ -0,0 +1,7 @@ +graph LR + U(["Project Manager"]):::start --> A["Methodologies → Create project"] + A --> B["Step 1 · pick methodology"] + B --> C["Step 2 · name · department · owner"] + C --> D["Step 3 · choose integration (Jira / ADO / none)"] + D --> E(["Project created → opens Project Detail"]):::start + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/user-04-pm-manage-tasks.mmd b/SoW/flows/user-04-pm-manage-tasks.mmd new file mode 100644 index 0000000..2544e84 --- /dev/null +++ b/SoW/flows/user-04-pm-manage-tasks.mmd @@ -0,0 +1,7 @@ +graph LR + U(["Project Manager"]):::start --> A["Project → Tasks (board)"] + A --> B["Drag a card between columns"] + B --> C["Status updates live for the team"] + A --> D["Sync from Jira (pull latest)"] + D --> E["Board reflects imported issues"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/user-05-pm-stage-gate.mmd b/SoW/flows/user-05-pm-stage-gate.mmd new file mode 100644 index 0000000..a83fea8 --- /dev/null +++ b/SoW/flows/user-05-pm-stage-gate.mmd @@ -0,0 +1,9 @@ +graph LR + U(["Project Manager"]):::start --> A["Project → Gates (G0–G5)"] + A --> B["Prepare gate evidence / checklist"] + B --> C["Request gate review"] + C --> D{"Reviewer decision"} + D -- pass --> E["Advance to next gate"] + D -- fail --> F["Remediate and resubmit"]:::deny + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; + classDef deny fill:#f7dede,stroke:#b23a3a,color:#7a1f1f; diff --git a/SoW/flows/user-06-team-member-update.mmd b/SoW/flows/user-06-team-member-update.mmd new file mode 100644 index 0000000..63fa629 --- /dev/null +++ b/SoW/flows/user-06-team-member-update.mmd @@ -0,0 +1,6 @@ +graph LR + U(["Team member"]):::start --> A["Dashboard → Operational → My tasks"] + A --> B["Open a task"] + B --> C["Update status · progress · notes"] + C --> D["Saved → rolls up to project + delivery"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/user-07-stakeholder-status.mmd b/SoW/flows/user-07-stakeholder-status.mmd new file mode 100644 index 0000000..1c872dc --- /dev/null +++ b/SoW/flows/user-07-stakeholder-status.mmd @@ -0,0 +1,6 @@ +graph LR + U(["Stakeholder"]):::start --> A["My Projects (reduced nav)"] + A --> B["Open a project → read-only status"] + B --> C["Check Delivery status + Releases"] + C --> D["Read Weekly Updates (News)"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/user-08-manager-team.mmd b/SoW/flows/user-08-manager-team.mmd new file mode 100644 index 0000000..5194154 --- /dev/null +++ b/SoW/flows/user-08-manager-team.mmd @@ -0,0 +1,8 @@ +graph LR + U(["Manager"]):::start --> A["My Team"] + A --> B["Review members + skills matrix"] + B --> C["Update team SWOT"] + B --> D["Record individual development plan (manager-only)"] + C --> E["Saved · governance-gated · audited"] + D --> E + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/user-09-platform-admin.mmd b/SoW/flows/user-09-platform-admin.mmd new file mode 100644 index 0000000..b68e74e --- /dev/null +++ b/SoW/flows/user-09-platform-admin.mmd @@ -0,0 +1,7 @@ +graph LR + U(["Platform Admin"]):::start --> A["Administration"] + A --> B["Roles & permissions matrix"] + A --> C["Backups / restore · audit log"] + A --> D["AD directory sync · connector config"] + A --> E["Review & action deletion requests (GDPR)"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/flows/user-10-architect-governance.mmd b/SoW/flows/user-10-architect-governance.mmd new file mode 100644 index 0000000..2f8cba4 --- /dev/null +++ b/SoW/flows/user-10-architect-governance.mmd @@ -0,0 +1,7 @@ +graph LR + U(["Chief Architect"]):::start --> A["Governance"] + A --> B["Decision log — record an ADR"] + A --> C["Architecture gate reviews (G1 / G3)"] + A --> D["TOGAF ADM · domains · waivers · ARB"] + A --> E["Project → Security: ISO 27001 SoA"] + classDef start fill:#2a4c8f,stroke:#22407a,color:#ffffff,font-weight:600; diff --git a/SoW/images/00-app-sitemap.png b/SoW/images/00-app-sitemap.png new file mode 100644 index 0000000..f17e8ca Binary files /dev/null and b/SoW/images/00-app-sitemap.png differ diff --git a/SoW/images/01-auth-rbac.png b/SoW/images/01-auth-rbac.png new file mode 100644 index 0000000..8046c6d Binary files /dev/null and b/SoW/images/01-auth-rbac.png differ diff --git a/SoW/images/02-dashboard.png b/SoW/images/02-dashboard.png new file mode 100644 index 0000000..608e5a0 Binary files /dev/null and b/SoW/images/02-dashboard.png differ diff --git a/SoW/images/03-demands.png b/SoW/images/03-demands.png new file mode 100644 index 0000000..69e7879 Binary files /dev/null and b/SoW/images/03-demands.png differ diff --git a/SoW/images/04-portfolio-project.png b/SoW/images/04-portfolio-project.png new file mode 100644 index 0000000..85ade0a Binary files /dev/null and b/SoW/images/04-portfolio-project.png differ diff --git a/SoW/images/05-project-gates.png b/SoW/images/05-project-gates.png new file mode 100644 index 0000000..b68433c Binary files /dev/null and b/SoW/images/05-project-gates.png differ diff --git a/SoW/images/06-tasks-board.png b/SoW/images/06-tasks-board.png new file mode 100644 index 0000000..0fa81bd Binary files /dev/null and b/SoW/images/06-tasks-board.png differ diff --git a/SoW/images/07-gantt.png b/SoW/images/07-gantt.png new file mode 100644 index 0000000..2d9994f Binary files /dev/null and b/SoW/images/07-gantt.png differ diff --git a/SoW/images/08-resources.png b/SoW/images/08-resources.png new file mode 100644 index 0000000..ce028ea Binary files /dev/null and b/SoW/images/08-resources.png differ diff --git a/SoW/images/09-financials.png b/SoW/images/09-financials.png new file mode 100644 index 0000000..38c1ad0 Binary files /dev/null and b/SoW/images/09-financials.png differ diff --git a/SoW/images/10-programs.png b/SoW/images/10-programs.png new file mode 100644 index 0000000..04d1d6f Binary files /dev/null and b/SoW/images/10-programs.png differ diff --git a/SoW/images/11-products-releases.png b/SoW/images/11-products-releases.png new file mode 100644 index 0000000..00a647d Binary files /dev/null and b/SoW/images/11-products-releases.png differ diff --git a/SoW/images/12-okrs.png b/SoW/images/12-okrs.png new file mode 100644 index 0000000..6ff347c Binary files /dev/null and b/SoW/images/12-okrs.png differ diff --git a/SoW/images/13-delivery.png b/SoW/images/13-delivery.png new file mode 100644 index 0000000..e2e0642 Binary files /dev/null and b/SoW/images/13-delivery.png differ diff --git a/SoW/images/14-news.png b/SoW/images/14-news.png new file mode 100644 index 0000000..6e02a41 Binary files /dev/null and b/SoW/images/14-news.png differ diff --git a/SoW/images/15-integrations-sync.png b/SoW/images/15-integrations-sync.png new file mode 100644 index 0000000..bb3777f Binary files /dev/null and b/SoW/images/15-integrations-sync.png differ diff --git a/SoW/images/16-whiteboard.png b/SoW/images/16-whiteboard.png new file mode 100644 index 0000000..4ca05cc Binary files /dev/null and b/SoW/images/16-whiteboard.png differ diff --git a/SoW/images/17-reports.png b/SoW/images/17-reports.png new file mode 100644 index 0000000..0bd7385 Binary files /dev/null and b/SoW/images/17-reports.png differ diff --git a/SoW/images/18-admin.png b/SoW/images/18-admin.png new file mode 100644 index 0000000..243ebcf Binary files /dev/null and b/SoW/images/18-admin.png differ diff --git a/SoW/images/19-governance-compliance.png b/SoW/images/19-governance-compliance.png new file mode 100644 index 0000000..857fc46 Binary files /dev/null and b/SoW/images/19-governance-compliance.png differ diff --git a/SoW/images/dev-01-change-lifecycle.png b/SoW/images/dev-01-change-lifecycle.png new file mode 100644 index 0000000..c83e904 Binary files /dev/null and b/SoW/images/dev-01-change-lifecycle.png differ diff --git a/SoW/images/dev-02-ci-pipeline.png b/SoW/images/dev-02-ci-pipeline.png new file mode 100644 index 0000000..3312564 Binary files /dev/null and b/SoW/images/dev-02-ci-pipeline.png differ diff --git a/SoW/images/dev-03-api-type-contract.png b/SoW/images/dev-03-api-type-contract.png new file mode 100644 index 0000000..0889b90 Binary files /dev/null and b/SoW/images/dev-03-api-type-contract.png differ diff --git a/SoW/images/dev-04-module-boundary.png b/SoW/images/dev-04-module-boundary.png new file mode 100644 index 0000000..449fff0 Binary files /dev/null and b/SoW/images/dev-04-module-boundary.png differ diff --git a/SoW/images/dev-05-test-strategy.png b/SoW/images/dev-05-test-strategy.png new file mode 100644 index 0000000..b528d98 Binary files /dev/null and b/SoW/images/dev-05-test-strategy.png differ diff --git a/SoW/images/dev-06-local-dev.png b/SoW/images/dev-06-local-dev.png new file mode 100644 index 0000000..11afdfa Binary files /dev/null and b/SoW/images/dev-06-local-dev.png differ diff --git a/SoW/images/dev-07-build-deploy.png b/SoW/images/dev-07-build-deploy.png new file mode 100644 index 0000000..0726ccf Binary files /dev/null and b/SoW/images/dev-07-build-deploy.png differ diff --git a/SoW/images/dev-08-runtime-topology.png b/SoW/images/dev-08-runtime-topology.png new file mode 100644 index 0000000..6f6247a Binary files /dev/null and b/SoW/images/dev-08-runtime-topology.png differ diff --git a/SoW/images/dev-09-connector-extension.png b/SoW/images/dev-09-connector-extension.png new file mode 100644 index 0000000..a800ea9 Binary files /dev/null and b/SoW/images/dev-09-connector-extension.png differ diff --git a/SoW/images/user-01-executive-review.png b/SoW/images/user-01-executive-review.png new file mode 100644 index 0000000..4f24cbd Binary files /dev/null and b/SoW/images/user-01-executive-review.png differ diff --git a/SoW/images/user-02-pmo-demand-approval.png b/SoW/images/user-02-pmo-demand-approval.png new file mode 100644 index 0000000..efadcf9 Binary files /dev/null and b/SoW/images/user-02-pmo-demand-approval.png differ diff --git a/SoW/images/user-03-pm-create-project.png b/SoW/images/user-03-pm-create-project.png new file mode 100644 index 0000000..d00d7f0 Binary files /dev/null and b/SoW/images/user-03-pm-create-project.png differ diff --git a/SoW/images/user-04-pm-manage-tasks.png b/SoW/images/user-04-pm-manage-tasks.png new file mode 100644 index 0000000..40bb3cc Binary files /dev/null and b/SoW/images/user-04-pm-manage-tasks.png differ diff --git a/SoW/images/user-05-pm-stage-gate.png b/SoW/images/user-05-pm-stage-gate.png new file mode 100644 index 0000000..43998df Binary files /dev/null and b/SoW/images/user-05-pm-stage-gate.png differ diff --git a/SoW/images/user-06-team-member-update.png b/SoW/images/user-06-team-member-update.png new file mode 100644 index 0000000..02255ba Binary files /dev/null and b/SoW/images/user-06-team-member-update.png differ diff --git a/SoW/images/user-07-stakeholder-status.png b/SoW/images/user-07-stakeholder-status.png new file mode 100644 index 0000000..83030ce Binary files /dev/null and b/SoW/images/user-07-stakeholder-status.png differ diff --git a/SoW/images/user-08-manager-team.png b/SoW/images/user-08-manager-team.png new file mode 100644 index 0000000..700d44a Binary files /dev/null and b/SoW/images/user-08-manager-team.png differ diff --git a/SoW/images/user-09-platform-admin.png b/SoW/images/user-09-platform-admin.png new file mode 100644 index 0000000..2896257 Binary files /dev/null and b/SoW/images/user-09-platform-admin.png differ diff --git a/SoW/images/user-10-architect-governance.png b/SoW/images/user-10-architect-governance.png new file mode 100644 index 0000000..dd64056 Binary files /dev/null and b/SoW/images/user-10-architect-governance.png differ diff --git a/SoW/sow-atlas-ppm-product-build.html b/SoW/sow-atlas-ppm-product-build.html new file mode 100644 index 0000000..d14bf4f --- /dev/null +++ b/SoW/sow-atlas-ppm-product-build.html @@ -0,0 +1,414 @@ + + +
+
+

Statement of Work

+

Atlas PPM — Product Build

+

Portfolio & Project Management platform for Birgma / Biltema Group

+
+
Project
Atlas PPM platform
+
Client
Birgma / Biltema Group
+
Repository
nicpozent/ATLASPPM_AdditionalFeatures
+
Prepared for
nicolas.pozza@birgma.com
+
Date
2026-08-07
+
Document type
For signature — v1.0 (draft)
+
+
+ +
+

1 Background & objectives

+

Atlas is a Portfolio & Project Management web application for Birgma / Biltema Group. This engagement delivers the full application — every screen and all functionality — pixel-faithful to the approved prototype (design/Atlas PPM.dc.html), wired to the .NET 10 minimal API backend, and hardened for an on-premise, air-gapped deployment.

+
    +
  • Reproduce every prototype screen 1:1 — layout, typography, colour, components, states, copy — with no redesign or additions beyond approved extensions.
  • +
  • Data-drive every screen from the /api/v1/* API via TanStack Query, with first-class loading / empty / error states (empty by default — no fabricated seed data).
  • +
  • Enforce server-authoritative role-based access control; the client is never a security boundary.
  • +
  • Meet the non-functional bar: accessibility (WCAG AA), localised chrome, security/compliance modules, and a continuously green automated build.
  • +
+
+ +
+

2 Scope of work

+ +

2.1 Workspace screens

+
    +
  • Dashboard — four layouts via a segmented control: Executive (portfolio-health donut, budget-burn, KPI cards w/ sparklines, active-projects table, needs-attention, demand pipeline, recent activity), Operational, Compact, and a drag-and-drop Custom builder.
  • +
  • Portfolio — Projects (filter chips + cards/table) and Blockers (list + side panel); drill-through to Project Detail.
  • +
  • Programs — list + detail (stakeholder power/interest matrix, linked projects, status); create-program modal.
  • +
  • Products — product portfolio; Jira/ADO tasks mapped to releases.
  • +
  • OKRs — objectives with key results linked to projects/programs/products.
  • +
  • Demands — value-vs-effort scored intake funnel; drag across stages; create/approve modals.
  • +
  • Timeline / Gantt — Project / Program scope; phases, bars, milestones, dependency arrows, month grid, export.
  • +
  • Project Detail — tabs: Overview, Tasks (board + list, drag), Epics, RAID, Artifacts (+ versions), Costs (labor/license/PaaS/IaaS/SaaS), Gates (G0–G5), Security (ISO 27001 SoA), plus people, linked products, change requests.
  • +
  • Resources — people synced from Entra ID; allocation vs availability; period-windowed utilisation with a date-range filter.
  • +
  • Financials — budget vs actual, CapEx/OpEx, forecast-at-completion, savings/benefit, portfolio ROI, source toggle.
  • +
  • Delivery Status — stakeholder report by period; velocity, on-time %, blockers, budget burn.
  • +
  • Releases — release calendar & deployment tracking.
  • +
  • Weekly Updates (News) — editable news wall (masonry, themes, edit mode).
  • +
+ +

2.2 Configuration screens

+
    +
  • My Team — members & skills, per-team SWOT, individual development plans (manager-scoped; governance-gated).
  • +
  • Methodologies — methodology library + create-project wizard.
  • +
  • Integrations — connectors (Jira, Azure DevOps, ServiceNow, ManageEngine SDP, GitHub, Confluence, Teams, Slack, Power BI), SSO, email, directory sync.
  • +
  • Reports — branded portfolio/demand/blocker/audit reports; export formats.
  • +
  • Administration — roles & permissions matrix, backups/restore, audit log, AD sync, install/integration guides, deletion requests.
  • +
  • Help — role-based guides, articles, contact.
  • +
+ +

2.3 Stakeholder experience

+
  • Reduced navigation: My Projects, My Demands + Delivery, Releases, News, Help.
+ +

2.4 Governance modules

+

Stage gates G0–G5, gate reviews (architecture/security), decision log (ADR), TOGAF ADM phases, architecture domains/waivers/ARB, and a security/compliance module (GDPR, PCI-DSS, ISO 27001, EU AI Act, SOC 2, NIS2) with control mappings — reproduced where the prototype places them.

+ +

2.5 Approved extensions (beyond the frozen prototype)

+

Built in the existing design language and recorded per CLAUDE.md §2 + an ADR: Microsoft Teams notifications; real-time collaboration (SignalR rooms — PI Program Board, demand funnel, task board, live presence/cursors/off-screen peers); Freeform Whiteboard (co-editing, templates, export); Team SWOT and individual development plans; ISO 27001 Statement of Applicability; cross-entity timeline dependencies; period-windowed resource utilisation; quality test tasks + Jira board ingest; project delivery roles (Tech Lead / Scrum Master); and the three Atlas brand themes (Command / Daylight / Carbon).

+ +

2.6 Platform & cross-cutting

+
    +
  • Entra ID (MSAL) SSO with route guards; server-authoritative RBAC (6 canonical roles; 9 cosmetic header identities).
  • +
  • Generated API type contract (OpenAPI → TypeScript) with CI drift protection.
  • +
  • Self-hosted fonts/assets for air-gapped operation; nginx same-origin serving.
  • +
  • Observability (OpenTelemetry), backups/restore, audit trail, secret rotation.
  • +
+ +

2.7 Out of scope

+
    +
  • Any redesign, restyling, or screens/sections not in the prototype (except the §2.5 approved extensions).
  • +
  • New CSS frameworks or global stylesheets (inline theme tokens only).
  • +
  • Client-side authorization as a security control.
  • +
  • Full screen-body internationalisation (chrome-only per ADR-0084 until a product decision widens it).
  • +
  • Jira bidirectional write-back (Proposed, ADR-0080 — pending sign-off).
  • +
  • Editing the design reference (design/) — regenerated by the design team.
  • +
+ +

2.8 User roles & journeys

+

Authorization is enforced server-side on 6 canonical roles; the header's 9 identities are cosmetic (they change the visible nav, not access). Each role's primary journey is a flow diagram in the flow package (SoW/flows/user-*).

+
+ + + + + + + + + + +
Role (enforced)Header identity(ies)Primary journeysFlow
Platform AdminPlatform AdminAdministration — RBAC matrix, backups/restore, audit log, AD sync, deletion requestsuser-09
PMOPMOTriage & approve demands; portfolio oversightuser-02, user-01
Project ManagerPM · PM Lead / delivery leadsCreate project (wizard); manage tasks & Jira sync; request a stage-gate reviewuser-03/04/05
Team MemberEngineering / Service / Dev / Infra Manager & membersUpdate my work; My Team — skills, SWOT, development plansuser-06, user-08
Executive(leadership)Portfolio reviewuser-01
StakeholderStakeholderCheck my projects / demands / delivery (reduced nav)user-07
ArchitectureChief ArchitectGovernance — ADR log, architecture gate reviews, TOGAF ADM, ISO 27001 SoAuser-10
+

The four Manager identities (Engineering / Service / Dev / Infra) differ only cosmetically and share the Team Member / My Team journeys. Beyond these role journeys the flow package also documents system & data flows (20) and software-development interaction flows (9) — see SoW/flows.md and the gallery.

+

The ten per-role journeys:

+
Executive — portfolio review
Executive — portfolio review
PMO — triage & approve a demand
PMO — triage & approve a demand
PM — create a project (wizard)
PM — create a project (wizard)
PM — manage tasks & Jira sync
PM — manage tasks & Jira sync
PM — request a stage-gate review
PM — request a stage-gate review
Team member — update my work
Team member — update my work
Stakeholder — check my status
Stakeholder — check my status
Manager — My Team
Manager — My Team
Platform Admin — administration
Platform Admin — administration
Chief Architect — governance
Chief Architect — governance
+
+ +
+

3 Deliverables

+
    +
  • The complete, prototype-faithful Atlas PPM frontend (React 18 + TS + Vite), one screen component per route, split into local sub-components.
  • +
  • The supporting .NET 10 minimal API endpoints each screen consumes (extended where needed), EF Core 10 / PostgreSQL 16.
  • +
  • Entra SSO wiring (login/redirect, route guards) and the RBAC capability matrix.
  • +
  • Generated API types + api.ts client; TanStack Query hooks with loading/empty/error states.
  • +
  • Automated test suites — backend (xUnit, incl. fixtures + architecture boundary tests), frontend (Vitest), accessibility (Playwright + axe), performance (k6) — gated in CI with coverage floors.
  • +
  • Flow diagrams (SoW/flows) — 39 diagrams in three views: system & data flows (20), per-role user journeys (10), software-development interaction flows (9), with rendered images and an index/gallery.
  • +
  • Architecture Decision Records for every architectural choice, plus a consolidated ALL-ADRS.md.
  • +
  • Deployment artefacts for the air-gapped Windows on-prem target (self-contained build output, nginx config, setup/integration guides).
  • +
+
+ +
+

4 Approach & methodology

+
    +
  • Prototype is the source of truth. Inline styles lifted from the prototype; theme.ts tokens and the three fonts only; computed visuals (charts, donuts, sparklines, gantt geometry) ported faithfully.
  • +
  • Empty by default. Real layout with tasteful empty states until the API returns data; never fabricated seed data.
  • +
  • Server-authoritative security. The API is the authority for authorization; UI role checks are cosmetic affordances only.
  • +
  • Typed, tested, accessible. TypeScript strict; generated API types; ≥44px hit targets, real controls, focus styles, aria-*; every data view has loading/empty/error.
  • +
  • Build one screen fully (visually faithful + data-wired + empty state) before the next; compare side-by-side with the prototype.
  • +
  • ADR-driven + one-change-one-PR, each verified green in CI before merge.
  • +
+
+ +
+

5 Technical architecture

+
+ + + + + + + + + + +
LayerTechnology
FrontendReact 18, TypeScript (strict), Vite, react-router v6, TanStack Query, @azure/msal-browser, SignalR client
StylingInline styles + theme.ts tokens (CSS-variable themes; 5 palettes); self-hosted fonts
Backend.NET 10 minimal API, modular monolith (per-domain Atlas.Api.<Domain>), EF Core 10
DataPostgreSQL 16 (date/timestamptz typed dates per ADR-0082)
RealtimeSignalR "room" hub (presence, cursors, live sync)
Servingnginx, same-origin, /api/v1/*; on-prem air-gapped
Quality gatesModule-boundary ratchet (NetArchTest), coverage floors, OpenAPI type-contract drift, axe a11y, Semgrep/Trivy
+
+ +
+

6 Milestones (build order)

+
+ + + + + + + + + + + + +
#PhaseContents
M1DashboardExecutive layout first (tokens, cards, charts, tables), then Operational/Compact/Custom
M2Core objectPortfolio (+ Blockers) and Project Detail drill-in
M3Flow & timeDemands funnel, Gantt timeline
M4Portfolio breadthPrograms, Products, OKRs, Resources, Financials
M5ReportingDelivery Status, Releases, News
M6ConfigurationMethodologies (+ wizard), Integrations, Reports, Admin, Help
M7StakeholderMy Projects / My Demands + role-based nav & affordances
M8GovernanceGates, decisions, TOGAF ADM, security/compliance
M9Platform hardeningEntra SSO, real API wiring, loading/empty/error finalisation, air-gapped packaging
+

Milestones are delivery groupings, not a fixed calendar; sequencing may be reprioritised with the product owner.

+
+ +
+

7 Acceptance criteria

+
    +
  • Visual fidelity — each screen matches the prototype 1:1 on side-by-side review (layout, spacing, type, colour, components, states, copy).
  • +
  • Data-wired — every view reads real data via TanStack Query with loading/empty/error states; empty by default.
  • +
  • Security — authorization enforced server-side; verified by backend tests.
  • +
  • Accessibility — axe sweep passes (structural); WCAG AA colour contrast on all themes.
  • +
  • Quality gates green — frontend + backend suites, coverage floors, OpenAPI contract-drift, module-boundary ratchet, SAST/Trivy.
  • +
  • Deployable — a clean build runs on the air-gapped Windows target from the provided artefacts.
  • +
+
+ +
+

8 Assumptions & constraints

+
    +
  • On-prem, air-gapped — no runtime internet egress; all fonts/assets self-hosted (ADR-0078); dev-only tooling runs in CI, never ships.
  • +
  • Deployment — client downloads built files to a Windows server; no git on target — artefacts must be self-contained.
  • +
  • Identity — Entra ID (Azure AD) tenant available for SSO; directory sync for Resources.
  • +
  • Prototype freezedesign/Atlas PPM.dc.html is authoritative and not edited; approved deviations recorded in CLAUDE.md §2 + an ADR, and flagged for the design team to regenerate design/.
  • +
  • Roles — six canonical backend roles enforce access; the nine-identity header switcher is cosmetic.
  • +
+
+ +
+

9 Roles & responsibilities

+
+ + + + + + + + +
PartyResponsibility
Engineering (delivery)Frontend + API implementation, tests, ADRs, CI, deployment artefacts
Product Owner (Birgma)Prototype sign-off, approval of extensions & Proposed ADRs, milestone prioritisation
Design teamOwn design/; regenerate to reflect approved extensions
Platform / IT (Birgma)Entra tenant, on-prem/nginx environment, DB provisioning, deploy windows
Security / ComplianceDPIA / MBL §11 sign-off for personnel-data features; governance module review
+
+ +
+

10 Non-functional requirements

+
    +
  • Accessibility — WCAG AA; keyboard + AT support; axe-gated in CI.
  • +
  • Internationalisation — six-locale chrome catalogue (en/sv/fi/da/no/fr) + completeness test; English screen content (ADR-0084).
  • +
  • Security & compliance — RBAC capability matrix; GDPR/ISO 27001/PCI-DSS/EU AI Act/SOC 2/NIS2 modules; audit trail; secret rotation; CSP + TLS hardening.
  • +
  • Performance — k6 performance budget; time-phased resource engine shared across roster/report/export to prevent drift.
  • +
  • Observability — OpenTelemetry traces/metrics/logs (OTLP, opt-in).
  • +
  • Data integrity — typed dates (date/timestamptz); no display-string date columns (ADR-0082).
  • +
+
+ +
+

11 Risks & dependencies

+
+ + + + + + + + + +
Risk / dependencyMitigation
Prototype fidelity disputesSide-by-side review as an explicit acceptance gate
Air-gapped runtime (no CDNs)Self-host all assets; verify offline build
Entra tenant / directory accessConfirm tenant + app registration early (M9 depends on it)
Personnel-data features (SWOT / dev plans)Gated off until DPIA + MBL §11 sign-off (ADR-0063)
External connector availability (Jira/ADO/etc.)Empty/degraded states; connectors dormant until configured
Compliance-module accuracyReview with Security/Compliance before acceptance
+
+ +
+

12 Commercials & timeline

+

To be completed by the parties. The figures below are placeholders — Atlas engineering scope, milestones and acceptance are fixed by this document; pricing, rates and calendar dates are commercial terms to be agreed and filled in before signature.

+
+ + + + + + + + + + + + + +
TermValue
Pricing model‹fixed-price / capped T&M / T&M — to be agreed›
Total price / not-to-exceed‹to be agreed›
Rate card (if T&M)‹to be agreed›
Estimated effort‹to be agreed›
Payment scheduleOn acceptance of each milestone (M1–M9, §6) ‹split % to be agreed›
Expenses & travel‹to be agreed›
Start date‹TBD›
Target completion‹TBD› (milestone dates per §6)
Warranty / support‹to be agreed›
Governing agreementThis SoW is issued under ‹MSA / framework agreement ref — TBD›
+

Change control: any change to the fixed scope (§2) is handled by a written change request priced against the agreed model before work proceeds.

+
+ +
+

13 Acceptance & sign-off

+

Work is accepted milestone-by-milestone against the criteria in §7. This Statement of Work is agreed and authorised by the undersigned.

+
+
+

For Birgma / Biltema Group

+

Client

+
Name
+
Title
+
Signature
+
Date
+
+
+

For the Supplier

+

‹supplier legal name — TBD›

+
Name
+
Title
+
Signature
+
Date
+
+
+

Effective date: ‹on last signature› · SoW version: v1.0 (draft) · Supersedes: ‹none / prior version›

+
+ +
+

A Appendix — System & data flows

+
Application map & navigation
Application map & navigation
Authentication & RBAC gate
Authentication & RBAC gate
Dashboard layouts & data
Dashboard layouts & data
Demand funnel
Demand funnel
Portfolio → Project
Portfolio → Project
Stage gates G0–G5
Stage gates G0–G5
Task board (realtime)
Task board (realtime)
Gantt & dependencies
Gantt & dependencies
Resource utilisation
Resource utilisation
Financials roll-up
Financials roll-up
Program detail
Program detail
Products → Releases
Products → Releases
OKRs linkage
OKRs linkage
Delivery status
Delivery status
News wall
News wall
Connector sync (Jira/ADO)
Connector sync (Jira/ADO)
Whiteboard co-editing
Whiteboard co-editing
Reports & export
Reports & export
Administration
Administration
Governance & compliance
Governance & compliance
+
+ +
+

B Appendix — Software-development interaction flows

+
Change lifecycle
Change lifecycle
CI pipeline
CI pipeline
API type contract + drift
API type contract + drift
Module-boundary ratchet
Module-boundary ratchet
Test strategy
Test strategy
Local dev loop
Local dev loop
Build & air-gapped deploy
Build & air-gapped deploy
Runtime topology
Runtime topology
Extending a connector
Extending a connector
+
+ + +