|
All checks were successful
CD / Build and push images (push) Successful in 3m17s
CI / Lint, typecheck, test (push) Successful in 2m34s
CI / Auth e2e pack (push) Successful in 3m27s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 8s
CD / Smoke tests against Test (push) Successful in 1m14s
CD / Promote to Int (push) Successful in 11s
Site Admins tune quotas per user and per pond on the three-level ladder (pond override → user override → instance default, data-model.md §Quotas). - api `admin/`: a `QuotaAdminService` + Site-Admin-gated endpoints under `/admin/quotas` — look up a user (username/e-mail) or pond (slug), list every quota's override / instance default / effective value (resolved through the existing QuotaService, the single consumption path, so a change takes effect immediately) plus current usage, and set/clear a per-subject override. Every change is audit-logged. A pond's effective values resolve on its own override then its owner's, matching the consumption checks. - web: the Admin area gains a 'Quotas' surface — the instance defaults move into a proper number-input form (was raw settings, #19), and a per-subject panel looks a user/pond up, shows the ladder with usage, flags subjects over their effective limit, and sets/clears overrides. New `quotas` i18n namespace (de+en). - tests: `quota-admin.e2e.db.test.ts` (override → effective changes at once and QuotaService sees it; clear → falls back to the default; lookup; Site-Admin gating); a browser `admin-quotas` pack proving an override raised in the UI immediately lets a user create another shared pond (issue #22 consumption). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1 |
||
|---|---|---|
| .. | ||
| access-rules.spec.ts | ||
| admin-quotas.spec.ts | ||
| auth.spec.ts | ||
| backlinks.spec.ts | ||
| collab-permissions.spec.ts | ||
| collab.spec.ts | ||
| content.spec.ts | ||
| editor.spec.ts | ||
| helpers.ts | ||
| image.spec.ts | ||
| labels.spec.ts | ||
| link.spec.ts | ||
| markdown.spec.ts | ||
| members.spec.ts | ||
| offline.spec.ts | ||
| public.spec.ts | ||
| README.md | ||
| reorder.spec.ts | ||
| search.spec.ts | ||
| sidebar.spec.ts | ||
| smoke.spec.ts | ||
| trash.spec.ts | ||
| wikilink.spec.ts | ||
End-to-end tests
Playwright suites, most local-only — three run in CI/CD:
| Suite | Target | Where it runs |
|---|---|---|
smoke.spec.ts |
any deployed stage | CD pipeline against https://test.dorfteich.cloud after every deploy |
auth.spec.ts |
full local stack with Mailpit | CI job auth-e2e on every PR/push; locally against the dev stack |
content.spec.ts |
full local stack | same CI job auth-e2e (a second step), right after the auth pack |
| everything else | full local stack | locally only — editor/sidebar/image/link/markdown/trash.spec.ts |
content.spec.ts is the M2 content regression pack (issue #32): page
lifecycle, editor basics, image paste, Markdown round-trip, and trash —
enough to catch a regression across the whole content model without
re-running every edge case the feature-specific packs above already cover.
Its Markdown round-trip test is a real regression pin, not just a smoke
check: it compares the seeded "Every Element" fixture page's exported
Markdown byte-for-byte against the checked-in content-page.md (see
"Content fixtures" below) — any schema/serializer change that alters how a
node round-trips fails it, once the seed has re-run against the changed
code (build → migrate → seed → test, exactly CI's order).
Running locally
# 1. Stack: database + Mailpit, api (3001), web dev server (5173)
docker compose -f deploy/compose/docker-compose.yml -f deploy/compose/compose.dev.yml up -d db mailpit
DATABASE_URL=postgresql://dorfteich:dorfteich@localhost:5434/dorfteich pnpm --filter @dorfteich/api db:seed
DATABASE_URL=postgresql://dorfteich:dorfteich@localhost:5434/dorfteich PORT=3001 pnpm --filter @dorfteich/api start:dev &
pnpm --filter @dorfteich/web dev &
# 2. Tests
E2E_BASE_URL=http://localhost:5173 E2E_MAILPIT_URL=http://localhost:8025 pnpm --filter @dorfteich/web e2e
auth.spec.ts skips itself when E2E_MAILPIT_URL is unset, so the CD
smoke run never trips over it.
Fixture matrix
Seeded by pnpm --filter @dorfteich/api db:seed (idempotent — re-running
never duplicates). Shared password: fixture passwort 123. Fixtures exist
only on dev machines and disposable CI/Test databases.
| Username | State | Purpose |
|---|---|---|
fixture-admin |
active, Site Admin | admin UI/permissions cases |
fixture-user |
active | regular journeys, settings, sessions |
fixture-editor |
active | second regular account for the collab-permissions pack (reader/editor of another's pond) |
fixture-viewer |
active | signed-in non-member for authenticated/public access-rule cases (issue #55) |
fixture-pending |
e-mail not verified | unverified-login cases |
Content fixtures
db:seed also creates a shared pond content-fixtures (owned by
fixture-user) with two pages, for the content regression pack and manual
QA:
- Every Element (
every-element) — every editor schema node and mark (issue #24: headings 1–4, all list types, table, blockquote, code block, horizontal rule, hard break, and all five marks). Loaded from the checked-inapps/api/prisma/fixtures/content-page.yjs, a Yjs snapshot generated from the human-readablecontent-page.mdnext to it —content-page.mdis the thing to read or edit; the.yjsfile is a build artifact of it, not source. - Fixture Image (
fixture-image) — one real, servable uploaded image (the placeholderfileIdinside the Markdown fixture above is not a real attachment; this page's image is).
Regenerating after editing content-page.md:
pnpm --filter @dorfteich/api fixtures:regenerate
This is deterministic — re-running without editing the Markdown produces a
byte-identical .yjs file (the script pins the Yjs document's clientID,
which is otherwise randomized per Y.Doc instance) — and it refuses to
write a snapshot that isn't a fixed point of the Markdown round-trip
(docToMarkdown(markdownToDoc(x)) === x), so a stale fixture can't get
checked in silently.
Conventions
- New feature packs get their own
<feature>.spec.tsnext to these and extend the fixture matrix here (permission matrix arrives with M5, issue #60). - Use
contextForUser()fromhelpers.tsfor signed-in tests — it logs in through the api and hands you a browser context with the session cookie, no UI login repetition. - Flaky tests are defects (ADR 0014): fix or quarantine immediately.