1
0

ACCEPTANCE.md 5.3 KB

Acceptance checklist (spec §10) — walkthrough

This is the checklist from the spec. Run it against a fresh container after Phase 7 lands. Expected outcome is noted next to each step; edit this file (and open a bug) if any step deviates.

Setup

docker compose down && rm -rf data/app.sqlite
docker compose up --build

.env should have EITHER valid ENTRA_* values OR LOCAL_ADMIN_EMAIL + LOCAL_ADMIN_PASSWORD set. Below, "sign in" means whichever flow you configured.

Steps

  1. Fresh container, empty DB → sign in → you're the admin.

    • Open http://localhost:8080.
    • If OIDC configured, click Sign in with Microsoft → complete Entra round-trip. If local admin configured, click Sign in as local admin and enter the env credentials.
    • Expected: header shows your display name + admin badge. SELECT is_admin FROM users LIMIT 1 in data/app.sqlite returns 1. audit_log has rows: CREATE user / BOOTSTRAP_ADMIN user / LOGIN user.
  2. Create a sprint with 4 weeks.

    • Header → New sprint → name "Sprint 1", reasonable dates, reserve 20%, weeks = 4 → Create sprint.
    • Expected: redirect to /sprints/1; empty-state banner says "No workers". Clicking Settings opens the settings page. The weeks table shows 4 rows with max_working_days 5.0 each and ISO week numbers computed from the start date.
  3. Add 6 workers, reorder by dragging — reload persists order.

    • Header → Workers → add Alice, Bob, Carol, Dan, Eve, Frank.
    • Back to /sprints/1/settings → add all 6 to the sprint via Add → buttons.
    • Drag the "≡" handles to reorder (e.g. reverse order).
    • Reload the page.
    • Expected: the reordered sequence persists. audit_log shows UPDATE sprint_worker rows for every moved row (unchanged rows emit nothing thanks to the no-op rule).
  4. Fill Arbeitstage; Ressourcen / Reserven / Available update live.

    • Open /sprints/1 → edit a day cell (0.5-step input).
    • Blur the input.
    • Expected: Σ column updates immediately, the capacity strip updates (Ressourcen, − Reserven, Available). Status pill flashes "Saved N cell(s)". audit_log has one CREATE sprint_worker_days row per edited cell.
  5. Add tasks, assign days — Tot updates; over-commit turns Available red but still saves.

    • In Section B: click + Add task → focus jumps to the title input → type "Report for Q1", set priority 1, assign 10 days to one worker whose capacity is 8.
    • Expected: Tot cell shows 10; that worker's Available in the capacity strip goes negative and turns red. The assignment is persisted (reload still shows 10); audit_log has CREATE task + CREATE task_assignment.
  6. Sort task table by Owner, then by a worker column; clear → original drag order returns.

    • Click the Owner header — rows sort asc, header shows "↑".
    • Click again — desc, "↓".
    • Click any worker column header — sorts by that cell's days.
    • Click the same header a third time (or any other until cleared) — the rows return to data-sort-order (the drag-persisted order).
    • Expected: no 500s, no layout shift, drag is disabled while a sort is active.
  7. Filter tasks: Prio=1, Owner=X, free-text "report".

    • Set prio filter to "Prio 1 only", owner to a specific worker, type "report" into the search box.
    • Expected: only matching rows stay visible. The "No tasks match the current filters" banner appears when every row is hidden.
  8. Rename a worker in /workers — reflected everywhere.

    • Header → Workers → change "Alice" to "Alice Cooper" → Save.
    • Open /sprints/1 in another tab.
    • Expected: Arbeitstage row label, task list column header, and the Owner dropdowns all show the new name. audit_log has an UPDATE worker row.
  9. /audit shows one row per change with diffs visible.

    • Header → Audit log.
    • Expected: reverse-chronological table with 50/page pagination. Every change you made is there. Each row's "before / after" <details> opens to show pretty-printed JSON snapshots.
    • Filter by user / action / entity type / date range / entity_id substring — narrow the list.
  10. Sign out; unauthenticated → redirect to /auth/login.

    • Click Sign out.
    • Expected: session cleared, audit_log has a LOGOUT user row.
    • Try visiting /workers or /sprints/1/settings while anonymous → redirected to /auth/login (and then Entra, or the local form).

Spot-check (spec §12)

If you have Tool_Sprint_PlanningSample.xlsx handy:

  • Pick a worker with known weekly availability (e.g. 4-4-5-5-2). Ressourcen should match Excel: sum across weeks.
  • − Reserven should match: round_to_0.5(Ressourcen * 0.8) with reserve = 20 %.
  • For a prio-1 task totalling N days on that worker, Available should be (Ressourcen − Reserven) − N, and turn red when negative.

Security headers (spec §9)

With the app running, curl -I http://localhost:8080/ should report:

X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'; script-src 'self' …; …

Strict-Transport-Security appears only when APP_BASE_URL uses https://.