Pond data model and CRUD API with personal pond at signup #21

Closed
opened 2026-07-04 14:52:07 +02:00 by fable-5 · 1 comment
Collaborator

Context

Ponds are the top-level container of the product. Every self-registered person gets a personal pond where they are Pond Admin (vision).

Scope

Prisma models ponds (+ pond-level trash columns) per data-model.md; endpoints POST/GET/PATCH /ponds, GET /ponds/:slug, DELETE /ponds/:id (soft delete). On e-mail verification (#13) auto-create the personal pond (type=personal, name from display name, unique slug). Until M5, access control is interim: only the owner (and Site Admins) can see/modify a pond — implement this in one clearly marked InterimAccessService that M5 will replace.

Acceptance criteria

  • signup+verify yields a personal pond visible via GET /ponds
  • slug collisions resolve deterministically (suffix), slugs are URL-safe
  • soft-deleted ponds disappear from lists; restore is possible via API (Site Admin)
  • unit tests for slug generation; e2e for create/rename/delete of a shared pond
  • InterimAccessService is the only place answering access questions (grep-provable)

Technical notes

  • data-model.md §ponds, ADR 0013 (pond trash), permissions.md (the real model lands in M5 — do not anticipate it beyond the interim service).
  • Pond settings jsonb: store sidebarSort and font slots with defaults now; editing UIs come later.

Dependencies

Depends on #13, #20.

Size: ~1.5 days


Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add de and en), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.

## Context Ponds are the top-level container of the product. Every self-registered person gets a personal pond where they are Pond Admin (vision). ## Scope Prisma models `ponds` (+ pond-level trash columns) per data-model.md; endpoints `POST/GET/PATCH /ponds`, `GET /ponds/:slug`, `DELETE /ponds/:id` (soft delete). On e-mail verification (#13) auto-create the personal pond (`type=personal`, name from display name, unique slug). Until M5, access control is interim: only the owner (and Site Admins) can see/modify a pond — implement this in one clearly marked `InterimAccessService` that M5 will replace. ## Acceptance criteria - [ ] signup+verify yields a personal pond visible via `GET /ponds` - [ ] slug collisions resolve deterministically (suffix), slugs are URL-safe - [ ] soft-deleted ponds disappear from lists; restore is possible via API (Site Admin) - [ ] unit tests for slug generation; e2e for create/rename/delete of a shared pond - [ ] `InterimAccessService` is the only place answering access questions (grep-provable) ## Technical notes - data-model.md §ponds, ADR 0013 (pond trash), permissions.md (the real model lands in M5 — do not anticipate it beyond the interim service). - Pond settings jsonb: store `sidebarSort` and font slots with defaults now; editing UIs come later. ## Dependencies Depends on #13, #20. **Size**: ~1.5 days --- *Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add `de` **and** `en`), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.*
fable-5 added this to the M2 — Ponds & pages, single-user editing milestone 2026-07-04 14:52:07 +02:00
fable-5 added the
backend
label 2026-07-04 14:52:07 +02:00
Author
Collaborator

Implemented in f0850ee, pipeline fully green (CI incl. db-backed e2e, CD deploy test → smoke → int).

Verification against acceptance criteria:

  • signup+verify creates the personal pond — covered by e2e (real verify flow) and live-checked on test.dorfteich.cloud (fixture accounts now own their personal ponds after re-seed)
  • slug collisions resolve deterministically (-2, -3, …), slugify is URL-safe with German transliteration — unit + e2e tests
  • soft-deleted ponds vanish from list and slug lookup; Site Admin restores via POST /ponds/:id/restore — e2e
  • InterimAccessService is the only place answering pond access questions (grep -rn "isSiteAdmin\|ownerId ===" apps/api/src/ponds → only interim-access.service.ts); trash/restore additionally use the existing SiteAdminGuard
  • Extra: personal ponds cannot be trashed (personal_pond_undeletable, localized de/en); seed creates personal ponds for active fixtures
Implemented in f0850ee, pipeline fully green (CI incl. db-backed e2e, CD deploy test → smoke → int). Verification against acceptance criteria: - signup+verify creates the personal pond — covered by e2e (real verify flow) and live-checked on test.dorfteich.cloud (fixture accounts now own their personal ponds after re-seed) - slug collisions resolve deterministically (`-2`, `-3`, …), slugify is URL-safe with German transliteration — unit + e2e tests - soft-deleted ponds vanish from list and slug lookup; Site Admin restores via POST /ponds/:id/restore — e2e - `InterimAccessService` is the only place answering pond access questions (`grep -rn "isSiteAdmin\|ownerId ===" apps/api/src/ponds` → only interim-access.service.ts); trash/restore additionally use the existing SiteAdminGuard - Extra: personal ponds cannot be trashed (`personal_pond_undeletable`, localized de/en); seed creates personal ponds for active fixtures
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#21
No description provided.