feat(031): Maintenance Banner for Dashboards — full spec→plan→tasks package
Spec: 5 user stories (P1-P3), 17 FRs, 7 SCs, 12 edge cases, RBAC matrix Plan: 7 research decisions, 15 semantic contracts (C1-C4) Data: 4 SQLAlchemy models (Banner entity enforces one-chart-per-dashboard) UX: async-only API, banner template with optional variables, admin settings UI Tasks: 64 tasks across 8 phases, 12 reused frontend components Workflow: component reuse scan mandated in speckit.plan/tasks + semantics-svelte Constitution: filled with 7 architecture principles from ADRs
This commit is contained in:
@@ -71,6 +71,35 @@ Use `[NEED_CONTEXT: target]` instead of inventing relation targets, DTO names, o
|
||||
|
||||
## Phase 1: Design, ADR Continuity, and Contracts
|
||||
|
||||
### Frontend Component Reuse Scan (MANDATORY — before contract generation)
|
||||
|
||||
Before designing any new Svelte component, execute a **component inventory scan** of the existing codebase to maximise reuse and prevent duplicate primitives. Use a subagent with `subagent_type: "explore"` to scan:
|
||||
|
||||
**Scan targets** (priority order):
|
||||
1. `frontend/src/lib/ui/` — design-system atoms: `Button.svelte`, `Select.svelte`, `Input.svelte`, `Card.svelte`
|
||||
2. `frontend/src/lib/components/ui/` — composite UI widgets: `SearchableMultiSelect.svelte`, `MultiSelect.svelte`
|
||||
3. `frontend/src/lib/components/` — feature components that may be adaptable
|
||||
4. Inline patterns in existing pages (`frontend/src/routes/`) — badges, skeletons, empty states, collapsibles
|
||||
|
||||
**For each found component, the scan MUST return:**
|
||||
- Exact file path
|
||||
- Props interface (what it accepts)
|
||||
- Whether it's a direct fit, adaptable, or pattern-only
|
||||
|
||||
**Reuse decision tree:**
|
||||
| Situation | Action |
|
||||
|-----------|--------|
|
||||
| Component exists and fits | `@RELATION DEPENDS_ON -> [ExistingComponent]` — zero new code |
|
||||
| Pattern exists (badge, skeleton, tooltip) | Document the Tailwind classes to replicate; no component extraction |
|
||||
| No reusable asset exists | Create new component only then |
|
||||
|
||||
**Output:** The `contracts/modules.md` for every frontend contract MUST include `@RELATION` edges to reused components and a `@RATIONALE` noting WHY the component is reused rather than rebuilt. For pattern-only reuse, the contract MUST reference the source page/file where the pattern was observed.
|
||||
|
||||
**Forbidden patterns:**
|
||||
- Creating a new `<Modal>` when `confirm()` suffices
|
||||
- Building a custom `<Select>` when `$lib/ui/Select.svelte` exists
|
||||
- Inventing a `<Toast>` system when `addToast()` from `$lib/toasts.js` is already wired
|
||||
|
||||
### UX / Interaction Validation
|
||||
|
||||
Validate the proposed design against `ux_reference.md` as an **interaction reference** for operators, API callers, CLI/operator flows, result envelopes, warnings, recovery guidance, and (when applicable) browser-based UI flows.
|
||||
|
||||
@@ -117,6 +117,18 @@ Examples:
|
||||
|
||||
If no safe executable task wording exists because the accepted path is still unclear, stop and emit `[NEED_CONTEXT: target]`.
|
||||
|
||||
### Component Reuse Mandate
|
||||
|
||||
Every frontend task MUST reference existing components from the design system before creating new ones. The component inventory from `contracts/modules.md` (populated during `/speckit.plan`) drives task generation:
|
||||
|
||||
| Reuse Level | Task Wording Rule |
|
||||
|-------------|-------------------|
|
||||
| **Existing component** (e.g. `<Button>`) | Task says: "...using `<Button>` from `$lib/ui/Button.svelte` (existing)" |
|
||||
| **Existing pattern** (e.g. badge, skeleton) | Task says: "...inline Tailwind: `rounded-full px-2.5 py-0.5 text-xs font-medium bg-{color}-100` (matches DashboardHub badge convention)" |
|
||||
| **New component required** | Task says: "Implement new `ComponentName.svelte`" — only when inventory confirms no reusable asset |
|
||||
|
||||
**Before writing any frontend task, verify:** does an existing component or page already do this? If `contracts/modules.md` maps a `@RELATION DEPENDS_ON -> [ExistingComponent]`, the task MUST use it. Never schedule "build a custom dropdown" when `<Select>` exists; never schedule "create a toast system" when `addToast()` is wired.
|
||||
|
||||
### Test Tasks
|
||||
|
||||
Tests are optional only when the feature truly has no new verification surface. Test tasks are usually expected for:
|
||||
|
||||
Reference in New Issue
Block a user