feat: Persons section redesign — Concept A (Enriched Directory) #159
Reference in New Issue
Block a user
Delete Branch "feat/persons-redesign-concept-a"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #157
Summary
Implements the full Persons section redesign per Concept A (Enriched Directory), covering 10 of 11 planned phases (Phase 11 — visual regression — requires designer review gate).
Backend
@RequirePermission(WRITE_ALL)on all write endpoints (POST,PUT,DELETE /api/persons/*); unauthenticated/read-only users receive 403@Sizeconstraints on allPersonUpdateDTOfields;@Validon controller; year bounds validated (must be > 0, birth ≤ death)GET /api/persons, includesdocumentCount(sender + receiver combined via native SQL)firstName,lastName,alias,birthYear,deathYear,notes) viaPersonUpdateDTOResponseStatusExceptionusages inPersonServicewithDomainException.notFound(PERSON_NOT_FOUND, ...){ totalPersons, totalDocuments }for the stats bar widgetPersonController100%,StatsController100%,PersonService93.6%Frontend
/persons): Stats bar ("N Personen · M Dokumente"), person cards enriched with alias (italic), life date range (* YYYY – † YYYY), and document count chip;PersonsStatsBarandPersonsEmptyStateextracted as components/persons/new): Form extended withbirthYear,deathYear, andnotesfields/persons/[id]): 2-column layout (35% / 65%); edit mode removed (Edit button navigates to/persons/[id]/edit); inline merge panel removed/persons/[id]/edit): New route withPersonEditForm(6 fields), sticky save bar, and collapsible Danger Zone accordion containing the merge panel; guarded byWRITE_ALLin the load functionformatLifeDateRange()andformatDocumentStatus()extracted tosrc/lib/utils/de.json,en.json,es.jsonfor all new UI strings and error codesTest plan
./mvnw test— all 575 backend tests passnpx vitest run— all 285 frontend tests pass, coverage ≥ 90%npm run lint— prettier + eslint clean (0 errors)npm run check— svelte-check: 95 errors (93 were pre-existing on main; 2 new are unavoidableServerLoadEventtype noise in test files matching the existing pattern)/personslist shows stats bar, alias, life dates, doc count chip/persons/newform has all 6 fields/persons/[id]detail shows 2-column layout, Edit button navigates to edit route/persons/[id]/editloads form pre-filled, Save updates and redirects, Discard returns to detail/persons/[id]/edit(gets 403)🤖 Generated with Claude Code
POST /api/persons, PUT /api/persons/{id}, POST /api/persons/{id}/merge now return 403 for READ_ALL-only users. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>firstName/lastName max 100, alias max 200, notes max 5000 chars. PUT /api/persons/{id} returns 400 for oversized fields. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>