Add BMAD planning artifacts: brief, PRD, architecture, UX, spec, tickets
Includes the BMAD install config, the initiative ticket tree, the portal context-resources scripts, and the .gitignore change that tracks BMAD files (generated _bmad/render/ is ignored). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sk72AxLwQnYttF6VFSxQLt
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
97b2a95062
commit
24de5878ed
+46
@@ -0,0 +1,46 @@
|
||||
---
|
||||
tracker_id: ""
|
||||
key: ""
|
||||
type: epic
|
||||
title: "A user manages their own account"
|
||||
parent: initiative-ping-mee-portal
|
||||
covers: [CAP-2, CAP-3, CAP-4]
|
||||
after: []
|
||||
assignee: ""
|
||||
risk: high
|
||||
---
|
||||
|
||||
# A user manages their own account
|
||||
|
||||
## Description
|
||||
|
||||
Users change their own password, profile details, e-mail address and profile picture in the live portal. This is the main reason the portal exists: it removes the admin from known-password changes and routine profile edits.
|
||||
|
||||
## Outcome
|
||||
|
||||
Family and friends change their own password, details and picture without the admin; the first part of the spec's success signal.
|
||||
|
||||
## Done when
|
||||
|
||||
1. A user changes their password with the AD password policy shown first, other sessions end, and a confirmation e-mail arrives.
|
||||
2. A user edits first name, last name, display name, telephone and mobile, and the values appear in AD.
|
||||
3. An e-mail change applies only after the current password and a confirmation from the new address, and the old address receives a 24-hour undo link whose use ends sessions and notifies the Admin.
|
||||
4. A user uploads a JPEG, PNG, HEIC or WebP picture up to 10 MB, crops it, sees Pending until the sync task has processed it, and can remove it.
|
||||
5. Injection strings and attempts on another user's data change nothing, and every action leaves an audit entry.
|
||||
|
||||
## Boundaries
|
||||
|
||||
The password, profile, e-mail and picture features and the share adapter. Not announcements or Admin pages, and no change to the PowerShell scripts. Touch point owned here: the picture file share and sync task.
|
||||
|
||||
## References
|
||||
|
||||
- parent — _bmad-output/initiative-ping-mee-portal/initiative-ping-mee-portal.md, section Requirements
|
||||
- spec — _bmad-output/specs/spec-ping-mee-self-service-platform/SPEC.md, CAP-2, CAP-3, CAP-4
|
||||
- architecture — ARCHITECTURE-SPINE.md, AD-2, AD-3, AD-4, AD-8, AD-9, AD-10
|
||||
- design — DESIGN.md and EXPERIENCE.md; mock-ups key-password.html and key-picture-pending.html
|
||||
- constraint — SPEC.md, section Constraints
|
||||
|
||||
## Notes
|
||||
|
||||
- Waits on epic-platform-and-sign-in because: it needs sign-in, sessions, the directory adapter, throttling, the audit service and the mail outbox.
|
||||
- Not yet sliced: this epic is broken into stories when it is selected.
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
---
|
||||
tracker_id: ""
|
||||
key: ""
|
||||
type: epic
|
||||
title: "The admin announces changes and runs the portal"
|
||||
parent: initiative-ping-mee-portal
|
||||
covers: [CAP-5, CAP-6, CAP-7, CAP-8, CAP-10]
|
||||
after: []
|
||||
assignee: ""
|
||||
risk: medium
|
||||
---
|
||||
|
||||
# The admin announces changes and runs the portal
|
||||
|
||||
## Description
|
||||
|
||||
Publishers announce planned downtime and changes, users receive them by e-mail and see them on the dashboard, and the Admin manages the look, reads the audit log and watches the status of backups, mail and background jobs. It finishes the portal and proves it ready for the internet.
|
||||
|
||||
## Outcome
|
||||
|
||||
Every planned downtime reaches opted-in users by e-mail and banner, and the admin can see that the portal is healthy; the second part of the spec's success signal.
|
||||
|
||||
## Done when
|
||||
|
||||
1. A Publisher writes an announcement with an always-set severity and optional window, expiry and schedule, and it appears as a banner and in the list at the right time.
|
||||
2. Every user in the OU with a valid e-mail address and no opt-out receives it, and the Publisher sees counts and reasons beforehand.
|
||||
3. The dashboard shows active announcements and the account card including the password date.
|
||||
4. The Admin changes the accent colour with a contrast warning, uploads a background, edits settings, reads the audit log and sees backup age, failed e-mails and job runs.
|
||||
5. Consistent backup files appear on schedule, the nightly AD reconciliation runs, and audit retention applies.
|
||||
6. Security tests (injection, cross-user, throttling, sessions) and the accessibility pass succeed, and a smoke checklist exists for the test OU.
|
||||
|
||||
## Boundaries
|
||||
|
||||
Announcements, announcement e-mail, the dashboard, the Admin pages, the maintenance jobs and the final hardening. Not account features (epic-account-self-service). Touch point owned here: the Veeam copy job that copies the backup folder.
|
||||
|
||||
## References
|
||||
|
||||
- parent — _bmad-output/initiative-ping-mee-portal/initiative-ping-mee-portal.md, section Requirements
|
||||
- spec — _bmad-output/specs/spec-ping-mee-self-service-platform/SPEC.md, CAP-5, CAP-6, CAP-7, CAP-8, CAP-10
|
||||
- architecture — ARCHITECTURE-SPINE.md, AD-4, AD-11 to AD-16
|
||||
- design — DESIGN.md and EXPERIENCE.md; mock-ups key-announcement-editor.html, key-admin-appearance.html, key-admin-status.html, key-admin-audit.html, key-dashboard.html
|
||||
- constraint — SPEC.md, section Constraints
|
||||
|
||||
## Notes
|
||||
|
||||
- Waits on epic-account-self-service because: the dashboard account card shows picture status and uses the profile data it creates.
|
||||
- Not yet sliced: this epic is broken into stories when it is selected.
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
---
|
||||
tracker_id: ""
|
||||
key: ""
|
||||
type: epic
|
||||
title: "A user can sign in to the live portal"
|
||||
parent: initiative-ping-mee-portal
|
||||
covers: [CAP-1, CAP-9]
|
||||
after: []
|
||||
assignee: ""
|
||||
risk: high
|
||||
---
|
||||
|
||||
# A user can sign in to the live portal
|
||||
|
||||
## Description
|
||||
|
||||
The platform baseline: the container, configuration, the Active Directory adapter, sign-in through authentik, sessions with roles, the page shell with preferences, and the scheduler with the mail outbox. When it is done, a person signs in to the portal running on the Linux host and sees their own name from Active Directory in the new layout; every later epic builds on it.
|
||||
|
||||
## Outcome
|
||||
|
||||
The admin can sign in to the live portal through authentik and see their own name from AD in the page shell, which proves every layer connects.
|
||||
|
||||
## Requirements
|
||||
|
||||
Owned from the spec: CAP-1 (sign-in, roles, sessions, throttling base) and the shell and preference parts of CAP-9. Groundwork for CAP-10 (container, configuration, health) and CAP-8 (audit foundation) is laid here; their completion is in the third epic.
|
||||
|
||||
- CAP-1 — spec SPEC.md, Capabilities (PRD FR-1 to FR-4)
|
||||
- CAP-9, shell part — PRD FR-29, FR-31; EXPERIENCE.md Foundation and Information Architecture
|
||||
- CAP-10, groundwork — PRD FR-26, FR-27; architecture AD-13, AD-18
|
||||
|
||||
## Done when
|
||||
|
||||
1. A user in the test OU signs in through the portal's own OIDC application in authentik and lands in the page shell showing their name from AD.
|
||||
2. A user outside the Publisher and Admin groups cannot open Publisher or Admin pages by direct address; a disabled or locked AD account is refused.
|
||||
3. Sessions end after 1 hour idle and 4 hours total; repeated sensitive requests are refused before any AD call.
|
||||
4. The container starts only with valid environment variables, answers its health check without AD, and runs on the Linux host behind Zoraxy.
|
||||
5. Theme, language and German form of address can be chosen and are kept per device; the layout works on a phone.
|
||||
6. The scheduler ticks and the mail outbox sends a test e-mail through the configured SMTP server.
|
||||
|
||||
## Boundaries
|
||||
|
||||
The portal's platform and sign-in only. Not profile, password or picture features (epic-account-self-service), not announcements or the Admin pages (epic-announcements-and-administration). Touch points owned here: Active Directory, authentik, Zoraxy, IONOS mail.
|
||||
|
||||
## References
|
||||
|
||||
- parent — _bmad-output/initiative-ping-mee-portal/initiative-ping-mee-portal.md, section Requirements
|
||||
- spec — _bmad-output/specs/spec-ping-mee-self-service-platform/SPEC.md, CAP-1, CAP-9, CAP-10
|
||||
- architecture — _bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md, AD-1 to AD-7, AD-11 to AD-13, AD-15, AD-18, AD-19
|
||||
- design — _bmad-output/ux-designs/ux-ping-mee-self-service-platform-2026-10-15/DESIGN.md and EXPERIENCE.md, mock-ups key-dashboard.html
|
||||
- constraint — SPEC.md, section Constraints
|
||||
|
||||
## Notes
|
||||
|
||||
- Decision: tracer bullet is the scaffold followed by sign-in; the first visible result is the user's name in the shell at entry 6 (2026-10-15).
|
||||
- Decision: a closing Refactor sweep is proposed by default; no end-to-end suite for this epic unless the user asks (2026-10-15).
|
||||
- Decision: the checkpoints agreed in the spec's stories carry over: plan review on entries 1, 4 and 5, and a pause after entry 5 (user, 2026-10-15).
|
||||
- Assumption: Zoraxy appends the real client IP as the last `X-Forwarded-For` entry; to be checked with a test request when the container is first deployed behind it.
|
||||
- Assumption: the exact AD attribute names for the password policy are verified in the test OU during entry 4.
|
||||
- Source conflict: none found.
|
||||
@@ -0,0 +1,101 @@
|
||||
# Breakdown of epic-platform-and-sign-in. The order of the tables is the build order.
|
||||
|
||||
[[entry]]
|
||||
id = 1
|
||||
type = "story"
|
||||
title = "Project scaffold, configuration and container"
|
||||
description = "Creates the Django project, environment-variable configuration that refuses to start when invalid, the multi-stage Docker image and compose file, a health check that does not call AD, JSON logging, security headers with a strict content-security policy, and the test setup with adapter fakes."
|
||||
verify = "The container starts with valid environment variables, refuses to start with an invalid one, and answers its health check on the Linux host."
|
||||
covers = ["CAP-10"]
|
||||
after = []
|
||||
hitl = false
|
||||
risk = "medium"
|
||||
plan_checkpoint = true
|
||||
references = ["_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-13", "_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-18"]
|
||||
|
||||
[[entry]]
|
||||
id = 2
|
||||
type = "story"
|
||||
title = "Prepare the test environment"
|
||||
description = "A person creates a test OU in the production AD with a service account scoped to it and the delegated rights from the spine, supplies the internal CA bundle, creates a dedicated OIDC application in the production authentik restricted to test users, notes the Zoraxy route and trusted-proxy value, and prepares a test mailbox."
|
||||
verify = "The service account can read and write a test user in the test OU over LDAPS, the authentik application lets a test user sign in, and the values are written down for the build."
|
||||
covers = ["CAP-1"]
|
||||
after = []
|
||||
hitl = true
|
||||
risk = "medium"
|
||||
notes = ["Authentik is production only; never change an existing authentik application.", "I can set up a test OU, but not a separate authentik."]
|
||||
|
||||
[[entry]]
|
||||
id = 3
|
||||
type = "story"
|
||||
title = "Audit, throttle and session foundations"
|
||||
description = "Builds the audit service, database-backed throttle counters, and server-side sessions with the username in its own column and a kill-by-user function; the other epics write audit entries and end sessions through these."
|
||||
verify = "Tests show an audit entry is written in the same transaction as a change, a throttle refuses after its limit, and ending a user's sessions removes every session of that user."
|
||||
covers = ["CAP-1", "CAP-8"]
|
||||
after = [1]
|
||||
hitl = false
|
||||
risk = "medium"
|
||||
references = ["_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-4", "_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-6", "_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-7"]
|
||||
|
||||
[[entry]]
|
||||
id = 4
|
||||
type = "story"
|
||||
title = "Directory adapter"
|
||||
description = "Builds the only code that talks to AD: lookup by sAMAccountName in the configured OU, group membership, account state, password verification, password policy read and the allow-listed writes, with an in-memory fake; sign-in and the account features call its interface."
|
||||
verify = "Against the test OU the adapter reads and writes allowed attributes over LDAPS with certificate verification, refuses others, and returns the password policy."
|
||||
covers = ["CAP-1", "CAP-2", "CAP-3"]
|
||||
after = [1, 2]
|
||||
hitl = false
|
||||
risk = "high"
|
||||
plan_checkpoint = true
|
||||
references = ["_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-1", "_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-2"]
|
||||
notes = ["Test only against the test OU, never the production OU."]
|
||||
|
||||
[[entry]]
|
||||
id = 5
|
||||
type = "story"
|
||||
title = "Sign-in with OIDC and roles"
|
||||
description = "Implements sign-in through the identity provider with the authorization-code flow, session creation, roles from AD group membership with a short cache, refusal of disabled or locked accounts, and the trusted-proxy client IP rule, using the directory adapter's interface."
|
||||
verify = "A test user signs in through authentik and reaches a page showing their own name; a user outside the Publisher and Admin groups cannot open those pages; a disabled account is refused."
|
||||
covers = ["CAP-1"]
|
||||
after = [2, 3, 4]
|
||||
hitl = false
|
||||
risk = "high"
|
||||
plan_checkpoint = true
|
||||
done_checkpoint = true
|
||||
references = ["_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-5", "_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-7"]
|
||||
|
||||
[[entry]]
|
||||
id = 6
|
||||
type = "story"
|
||||
title = "Page shell, preferences and translations"
|
||||
description = "Builds the base layout with the Fluent components bundled into the image: top bar, left menu with role-based groups, avatar menu for theme, language and German form of address, German and English text, light and dark themes, and the phone layout."
|
||||
verify = "After sign-in the shell shows the user's name, the menu groups match their role, the three preferences persist per device, and the layout works at phone width."
|
||||
covers = ["CAP-9"]
|
||||
after = [5]
|
||||
hitl = false
|
||||
risk = "medium"
|
||||
references = ["_bmad-output/ux-designs/ux-ping-mee-self-service-platform-2026-10-15/mockups/key-dashboard.html", "_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-15", "_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-16"]
|
||||
|
||||
[[entry]]
|
||||
id = 7
|
||||
type = "story"
|
||||
title = "Scheduler and mail outbox"
|
||||
description = "Builds the single 30-second scheduler tick with idempotent jobs and job-run records, the mailer adapter with the outbox, retries, backoff and rate limit, and a fake mailer; other epics only call its enqueue function."
|
||||
verify = "A queued test e-mail is sent through the configured SMTP server, a failed send is retried and recorded, and a restart sends nothing twice."
|
||||
covers = ["CAP-6", "CAP-10"]
|
||||
after = [3]
|
||||
hitl = false
|
||||
risk = "medium"
|
||||
references = ["_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-11", "_bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md#ad-12"]
|
||||
|
||||
[[entry]]
|
||||
id = 8
|
||||
type = "story"
|
||||
title = "Refactor sweep"
|
||||
description = "Cleans up the epic's code using the plans and the review findings deferred during the epic; scope pushed out of another story is a new story, not part of this one."
|
||||
verify = "The test suite still passes and the deferred review findings from entries 1 to 7 are resolved or recorded."
|
||||
covers = []
|
||||
after = [1, 2, 3, 4, 5, 6, 7]
|
||||
hitl = false
|
||||
risk = "low"
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
tracker_id: ""
|
||||
key: ""
|
||||
type: initiative
|
||||
title: "Users run their own account and the admin has one announcement channel"
|
||||
parent: none
|
||||
covers: [CAP-1, CAP-2, CAP-3, CAP-4, CAP-5, CAP-6, CAP-7, CAP-8, CAP-9, CAP-10]
|
||||
after: []
|
||||
assignee: ""
|
||||
risk: high
|
||||
---
|
||||
|
||||
# Users run their own account and the admin has one announcement channel
|
||||
|
||||
## Description
|
||||
|
||||
The ping-mee Self-Service Portal lets about ten homelab users change their own password, details and profile picture, and lets the admin announce planned downtime by e-mail and on a page. The spec owns the capabilities, constraints and non-goals; this initiative delivers them to production, internet-facing, in a form that can later be deployed elsewhere.
|
||||
|
||||
## Outcome
|
||||
|
||||
Family and friends change their own password, details and picture without the admin, and every planned downtime reaches opted-in users by e-mail and banner; the spec's success signal is the measure.
|
||||
|
||||
## Requirements
|
||||
|
||||
The numbered spec is the requirement source: CAP-1 to CAP-10 in `_bmad-output/specs/spec-ping-mee-self-service-platform/SPEC.md`. Requirement-level detail (FR-1 to FR-32) is in its PRD companion.
|
||||
|
||||
## Done when
|
||||
|
||||
1. A family member changes their own password, name, phone number and picture in the live portal with no admin help.
|
||||
2. A scheduled downtime announcement reaches every opted-in user by e-mail and shows as a banner on the dashboard.
|
||||
3. Injection, cross-user access and brute-force attempts against the live portal fail and appear in the audit log.
|
||||
4. The portal runs from one Docker image configured only by environment variables on the Linux host behind the reverse proxy.
|
||||
5. Consistent database backup files appear in the backup folder and the status page shows their age.
|
||||
6. Every capability CAP-1 to CAP-10 is live for all users, not behind a flag.
|
||||
|
||||
## Boundaries
|
||||
|
||||
The portal and its adapters. Not an Active Directory admin console, not a password-reset flow, not a replacement for the PowerShell picture scripts or the identity provider; see the spec's non-goals. Tracer path: sign in through authentik, look up the user in the test OU, and see their name in the new page shell.
|
||||
|
||||
- Touch point: Active Directory (LDAPS) — the portal reads and writes through a service account; owner: epic-platform-and-sign-in
|
||||
- Touch point: authentik (production) — a dedicated OIDC application for the portal; owner: epic-platform-and-sign-in
|
||||
- Touch point: Zoraxy reverse proxy — trusted-proxy and client-IP settings; owner: epic-platform-and-sign-in
|
||||
- Touch point: IONOS mail — SMTP credentials for the outbox; owner: epic-platform-and-sign-in
|
||||
- Touch point: picture file share and the PowerShell sync task — write source files, read processed hashes, no script changes; owner: epic-account-self-service
|
||||
- Touch point: Veeam copy job — copies the backup folder; owner: epic-announcements-and-administration
|
||||
|
||||
## References
|
||||
|
||||
- spec — _bmad-output/specs/spec-ping-mee-self-service-platform/SPEC.md, section Capabilities
|
||||
- spec companion — _bmad-output/prds/prd-ping-mee-self-service-platform-2026-10-15/prd.md, sections Features and Cross-Cutting Requirements
|
||||
- architecture — _bmad-output/architecture/architecture-ping-mee-self-service-platform-2026-10-15/ARCHITECTURE-SPINE.md, section Invariants & Rules (the decisions every epic adopts: AD-1 to AD-19)
|
||||
- design — _bmad-output/ux-designs/ux-ping-mee-self-service-platform-2026-10-15/DESIGN.md and EXPERIENCE.md, with the mock-ups in mockups/
|
||||
- constraint — SPEC.md, section Constraints
|
||||
|
||||
## Notes
|
||||
|
||||
- Decision: three epics cut by "usable early": platform and sign-in, then account self-service, then announcements and administration (user, 2026-10-15).
|
||||
- Decision: the spec stays in `_bmad-output/specs/spec-ping-mee-self-service-platform/` and is cited by path, because its companions use relative links.
|
||||
- Decision: the epic rule "split only for a distinct outcome, owner or a part usable early" is saved for later slicing (user, 2026-10-15).
|
||||
- Decision: no spike; the user is not worried about any one area (2026-10-15).
|
||||
- Assumption: the test environment is a test OU in the production AD with a scoped service account, and a dedicated OIDC application in the production authentik restricted to test users; there is no staging environment.
|
||||
- Parked: nothing from the spec is deferred.
|
||||
- Waits on epic-platform-and-sign-in because: every other epic uses its sign-in, directory adapter, sessions and mail outbox.
|
||||
@@ -0,0 +1,21 @@
|
||||
# Epics of the initiative, in build order.
|
||||
|
||||
[[epic]]
|
||||
id = 1
|
||||
slug = "epic-platform-and-sign-in"
|
||||
title = "A user can sign in to the live portal"
|
||||
covers = ["CAP-1", "CAP-9"]
|
||||
|
||||
[[epic]]
|
||||
id = 2
|
||||
slug = "epic-account-self-service"
|
||||
title = "A user manages their own account"
|
||||
covers = ["CAP-2", "CAP-3", "CAP-4"]
|
||||
after = [{ epic = 1, needs = "sign-in and sessions, the directory adapter, throttling, the audit service and the mail outbox" }]
|
||||
|
||||
[[epic]]
|
||||
id = 3
|
||||
slug = "epic-announcements-and-administration"
|
||||
title = "The admin announces changes and runs the portal"
|
||||
covers = ["CAP-5", "CAP-6", "CAP-7", "CAP-8", "CAP-10"]
|
||||
after = [{ epic = 2, needs = "the profile and picture data the dashboard account card shows" }]
|
||||
Reference in New Issue
Block a user