CI proved cross-file sharing of a virtual-module mock body cannot work in
@vitest/browser-playwright 4.1.6: the static-import spread fails the hoist
("no top level variables"), and the await-vi.hoisted-import form fails to
parse ("Unexpected identifier 'vi'"). vi.hoisted has the same hoist
constraint as vi.mock, so there is no way to thread an external module's
body into the factory here.
Reverts Phase 1: restores the 4 $app/forms/$app/navigation specs to their
inline factories, inlines NotificationBell.spec's forms stub, deletes the
src/__mocks__/$app/* modules and the $mocks alias (vite, vitest-coverage,
kit). The no-factory-ban meta-test stays (no-factory vi.mock is still
banned). ADR-012 amended to record the infeasibility. Everything else
($app/state migration, confirm context-inject, notification refactor, the
pin, the meta-test) is unaffected. Part of #560.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
shared (frontend)
Cross-domain utilities and UI primitives. Any file here is consumed by two or more domain folders and has no domain identity of its own.
Admission criteria (what belongs here)
A file belongs in shared/ if it meets all three conditions:
- No domain identity — it does not represent a
Document,Person,Tag, etc. - Consumed by ≥ 2 domain folders — or is framework infrastructure that every domain depends on.
- Generic — could work in a different SvelteKit project with zero business-logic changes.
If any condition fails, the file belongs in the domain folder of its primary consumer.
What this folder owns
| Sub-folder / file | Purpose |
|---|---|
api.server.ts |
Typed openapi-fetch client factory — the standard entry point for all backend API calls in server-side load functions and actions |
errors.ts |
Mirror of the backend ErrorCode enum + getErrorMessage() → Paraglide i18n key mapping |
types.ts |
Cross-domain TypeScript interfaces |
utils.ts |
Pure utility functions (date formatting, sorting, debounce) |
relativeTime.ts |
Human-relative time formatting ("2 days ago") |
primitives/ |
Generic UI components: BackButton.svelte, form inputs, pagination, layout shells |
discussion/ |
Comment/mention editor shared by document/ and geschichte/ |
dashboard/ |
Family Pulse widget and recent-activity components assembled in the / route |
hooks/ |
Svelte 5 reactive hooks: useTypeahead, useUnsavedWarning |
services/ |
Generic client-side service helpers |
actions/ |
Shared SvelteKit form action utilities |
server/ |
Server-only shared utilities (load function helpers) |
help/ |
Coach marks and empty-state components used across multiple domains |
What does NOT belong here
- Components owned by one domain — move to that domain's folder.
- Domain-specific business logic — even if shared, it belongs in the owning domain's public surface.
Adding to shared/
If you need to add a file here, confirm it meets all three admission criteria. If it's domain-adjacent, check whether the owning domain should export it as part of its public surface instead.