Files
familienarchiv/.specify/features/_example/tasks.md
Marcel 01f51854f6 feat(sdd): add .specify scaffold — constitution, AGENTS, personas, templates, example, RTM
Introduces the SDD root: a v1.0.0 constitution and machine-readable AGENTS.md
grounded in the project's real conventions; six EARS-aware persona spec-review
checklists that cross-reference .claude/personas/; feature-spec/ADR/threat-model/
api-contract templates; a fully worked _example feature; a living RTM; and an
adrs/ pointer that reuses the existing docs/adr/ archive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 11:56:31 +02:00

3.1 KiB

Tasks — Profile picture upload

Red/Green TDD order: each implementation task is preceded by the failing test that requires it. Task IDs are referenced from spec.md → Traceability and from .specify/rtm.md. Check off as work lands; reference the issue in each commit (Refs #<n>).

Backend

  • T-1 Add ErrorCode.AVATAR_TOO_LARGE in all four sites at once: ErrorCode.java, frontend/src/lib/shared/errors.ts, getErrorMessage(), messages/{de,en,es}.json. (No new behavior yet — enables REQ-008's error.) → covers REQ-008 (error plumbing)
  • T-2 @WebMvcTest UserAvatarControllerTest: write failing slice tests — unauthenticatedReturns401, rejectsNonImage (400 UNSUPPORTED_FILE_TYPE), rejectsOversize (400 AVATAR_TOO_LARGE). Then implement UserAvatarController + @RequirePermission to green. → REQ-006, REQ-007, REQ-008
  • T-3 Unit UserServiceAvatarTest: failing tests storesUnderUserKey, replaceLeavesNoOrphan, validation maps to DomainException. Then implement UserService.setAvatar/removeAvatar (mock FileService) to green. → REQ-001, REQ-002, REQ-003
  • T-4 Flyway V78__add_app_user_avatar_object_key.sql (verify next free number on disk) adding nullable avatar_object_key VARCHAR(512); add the column + @Schema to AppUser / UserProfileView (avatarUrl derived). Test: repository round-trip. → REQ-002
  • T-5 deleteMyAvatar controller test + impl (clears key, deletes object, returns avatarUrl: null). → REQ-003
  • T-6 Admin path: failing tests adminDeletesOthersAvatar (200), nonAdminForbiddenOnOthers (403). Implement ownership/ADMIN_USER check to green. → REQ-005, REQ-009
  • T-7 Authenticated proxy getUserAvatar streaming endpoint + Content-Type + X-Content-Type-Options: nosniff; test 200 bytes / 404 when no avatar. → REQ-004 (view side)
  • T-A Run npm run generate:api after T-4/T-7 so avatarUrl lands in api.ts.

Frontend

  • T-8 i18n keys for the new strings in messages/{de,en,es}.json (button labels, validation errors mapped via getErrorMessage). → REQ-007, REQ-008 (UX)
  • T-9 Component test avatar-placeholder.svelte.spec.ts: failing test asserting initials render when avatarUrl is null; implement the placeholder. → REQ-004
  • T-10 /profile upload control: file picker, client-side type/size pre-check, instant preview, confirm/remove. States: idle/preview/uploading/error/done. → REQ-002, REQ-003
  • T-11 Render avatar where names appear (comments, activity feed, /users/[id]), falling back to the placeholder. → REQ-004
  • T-12 E2E avatar.spec.ts: upload → preview → confirm → avatar visible; remove → initials return. → REQ-002, REQ-003, REQ-004

Cross-cutting

  • T-13 Set spring.servlet.multipart.max-file-size to a 2 MB-matching ceiling so an oversized body is rejected at the container edge (defense in depth for REQ-008).
  • T-14 Update .specify/rtm.md Status column to Done per REQ as each test goes green.