#302: configurable pond start page, created with every new pond #310
No reviewers
Labels
No Label
area:auth
area:docs
area:export
area:ops
area:storage
area:supply-chain
auth
backend
blocked
collab
deployment
docs
effort:L
effort:M
effort:S
frontend
plugins
qa
vs-nfd
vs-nfd:blocker
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: stwaidele/dorfteich#310
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "issue-302-pond-start-page"
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 #302.
/p/:pondSlugredirected topages.data[0]— the first page in the sidebar's sort order. Deterministic, but a rule no user could see, and one whose target moves as soon as someone adds a page that sorts ahead of it. New ponds had no page at all and landed on the empty-pond hint.No migration needed
Pond.settingsis alreadyJson, sostartPageIdis a schema addition inpackages/shared/src/ponds.tsand nothing else. The issue assumed a migration; there isn't one.It stores an id, not a slug — renaming or moving the page keeps the setting working.
Resolution
PondHomePageprefers the configured page, but only when it appears in this user's page list. That list already contains just what they may see, so:Checking against the loaded list rather than fetching the page costs no extra request.
Creation
Both paths (
createShared,ensurePersonalPond) create a start page, titled from the creator's storeduser.locale— the mechanism already used for mails. A new api-sidepondsi18n namespace holds the two strings.It runs after the creating transaction commits. The owner's
POND_ADMINgrant is written inside that transaction and the permission layer caches per pond, so creating the page any earlier would ask about rights the grant has not published yet. It goes throughPagesService.create()so the page carries every invariant — unique slug, sort key, content cache, search indexing, a Yjs state the collab server can bind to.Failure is logged, not fatal: a pond without a start page falls back and still works. Losing the pond over its first page would be the worse trade.
Module direction, not forwardRef
PagesModuleimportedPondsModulewithout using anything from it —PagesServicenever injectedPondsService, and both controllers only takePagesService. Removing that vestigial edge letPondsModuledepend onPagesModulein the honest direction. The alternative,forwardRefin both, would have written a cycle into the module graph to work around an import that was already dead.Fallout the full suite caught
Every pond created through the api now owns a page.
Page.ponddeliberately has noonDelete: Cascade— a real purge removes a pond's contents explicitly and audits it, and a silent database cascade would hide that. So eight suites whose teardown went straight forpond.deleteManyhit the foreign key.A shared
deletePondsWhere(prisma, where)helper intesting/test-db.tsdeletes pages first; the affected teardowns use it.Two tests counted pages and now account for the start page instead of pretending the pond began empty:
plugin-api: "a full reader sees all pages" reads the id from the pond's settings and includes it, keeping the assertion exact.pond-purge: the audited page count is 3, with a comment saying why.Fixing those surfaced a real bug:
createSharedreturned the pond row captured inside the transaction, so callers gotstartPageId: nullfor a pond that had one. It now re-reads before building the view.Verification
attachment-integrityfail; it passes in isolation and passed on the repeat run — the load flakiness documented for parallel local runs, not this change.deandenhalves, so the test cannot pass on a hardcoded string), changing the start page without losing neighbouring settings, and clearing it back to the default.pnpm typecheck, fullpnpm lint,pnpm i18n:checkgreen; shared rebuilt.Not verified here: the picker in a running browser. The a11y pack covers
/settings, not pond settings.