QA: wire the M13 packs into CI, document the vault import (#119)
All checks were successful
CD / Build and push images (push) Successful in 2m40s
CD / Deploy to Test (push) Successful in 10s
CD / Smoke tests against Test (push) Successful in 1m9s
CI / Lint, typecheck, test (push) Successful in 4m23s
CI / Build container images (push) Has been skipped
CD / Promote to Int (push) Successful in 12s
CI / Auth e2e pack (push) Successful in 6m15s
CI / Import/export fidelity gate (push) Successful in 47s
Release / Build release images and notes (push) Successful in 1m7s
Release / Release-candidate operations QA (push) Successful in 41s
Prod deploy / Deploy the released images to Prod (push) Successful in 16s

CI runs the two new packs after the graph pack (chained, each preceded
by the login rate-limit reset): create-missing-page.spec.ts (#115) and
import-vault.spec.ts (#117/#118).

Docs: the pond-admin guide gains a full 'Import an Obsidian vault'
chapter — the three dialog choices, and what happens to folders, links
(including the duplicate-name rule: the alphabetically first vault path
wins), tags, images, and embeds, plus the limits and the all-or-nothing
semantics. The user guide explains following a link to a page that does
not exist yet. features.md gets both bullets. German mirrors updated
throughout (English stays authoritative).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Claude Fable 5 2026-07-14 18:28:45 +02:00
parent 704ebe48a6
commit 2d51a55119
8 changed files with 124 additions and 5 deletions

View File

@ -386,6 +386,26 @@ jobs:
E2E_BASE_URL=http://localhost:5173 \
pnpm --filter @dorfteich/web exec playwright test e2e/graph.spec.ts
- name: Reset login rate limit before create-missing-page pack
run: |
echo "DELETE FROM rate_limits WHERE key LIKE 'login%';" | \
pnpm --filter @dorfteich/api exec prisma db execute --stdin --url "$DATABASE_URL"
- name: Run create-missing-page pack
run: |
E2E_BASE_URL=http://localhost:5173 \
pnpm --filter @dorfteich/web exec playwright test e2e/create-missing-page.spec.ts
- name: Reset login rate limit before vault-import pack
run: |
echo "DELETE FROM rate_limits WHERE key LIKE 'login%';" | \
pnpm --filter @dorfteich/api exec prisma db execute --stdin --url "$DATABASE_URL"
- name: Run vault-import pack
run: |
E2E_BASE_URL=http://localhost:5173 \
pnpm --filter @dorfteich/web exec playwright test e2e/import-vault.spec.ts
- name: Reset login rate limit before search pack
run: |
echo "DELETE FROM rate_limits WHERE key LIKE 'login%';" | \

View File

@ -45,7 +45,7 @@ test('a pond admin imports an Obsidian vault through the settings dialog', async
const pond = await json<{ id: string; slug: string }>(context, '/api/v1/ponds', {
name: `Vault Pond ${ts}`,
});
const mount = await json<{ id: string; slug: string; title: string }>(
await json<{ id: string; slug: string; title: string }>(
context,
`/api/v1/ponds/${pond.id}/pages`,
{ title: `Vault Mount ${ts}` },

View File

@ -49,6 +49,13 @@ Familien oder Projekte.
Slugs und Links bleiben flach, Verschieben bricht also nie etwas; der
ZIP-Export bleibt ebenfalls flach (die Hierarchie ist rein
organisatorisch).
- **Obsidian-Vault-Import**: Eine Teich-Administration lädt einen ganzen
Vault als ZIP hoch — Ordner werden zum Seitenbaum, Tags zu Labels,
`[[Wikilinks]]` werden so umgeschrieben, dass sie weiter funktionieren,
und Bilder kommen als Teich-Dateien mit
- **Tote Links sind einen Klick von einer Seite entfernt**: Wer einen Link
auf eine noch nicht existierende Seite öffnet, bekommt sie direkt zum
Anlegen angeboten
- **Wissensgraph**: eine interaktive Karte jedes Teichs — Seiten als
Knoten, Wikilinks als Kanten, fehlende Ziele als gestrichelte
Phantome, die ein Klick anlegt; jede Seite hat zusätzlich einen

View File

@ -107,6 +107,49 @@ den passenden Instanz-Schalter aktiviert hat:
Ein Teich ohne Freigabe ist über diese Schnittstellen unsichtbar —
selbst für die Tokens der eigenen Mitglieder.
## Obsidian-Vault importieren
Teich-Einstellungen → **Obsidian-Vault importieren** nimmt ein ZIP eines
ganzen Vaults und macht Seiten daraus. Du wählst drei Dinge:
- **Einhängen unter** — die Seite, unter der der Vault landet (oder die
oberste Ebene).
- **Zusätzliche Labels** — bekommt jede importierte Seite, zusätzlich zu
den Labels aus den Tags des Vaults.
- **YAML-Frontmatter** — entfernen oder als Code-Block am Seitenanfang
behalten.
Was mit dem Vault passiert:
- **Ordner werden Seiten.** Jeder Ordner wird eine Container-Seite, die
Notizen hängen darunter — die Vault-Struktur bleibt erhalten. Seiten
verschachteln höchstens sechs Ebenen tief; ist der Vault (samt
Einhänge-Tiefe) tiefer, werden die untersten Ordner-Ebenen zu einer
Seite mit Titel `so/zusammengelegt`.
- **`[[Wikilinks]]` funktionieren weiter.** Obsidian-Links zeigen auf
Notiz-_Namen_, Dorfteich-Links auf Seiten-_Adressen_ — jeder Link wird
deshalb auf die Adresse umgeschrieben, die die Notiz tatsächlich
bekommen hat: `[[Notiz|Anzeigetext]]`, `[[Notiz#Überschrift]]` (der
Überschriften-Teil entfällt) und `[[Ordner/Notiz]]` inklusive. Links
auf Notizen, die es im Vault nicht gibt, werden zu Links auf fehlende
Seiten — genau wie selbst getippt. Tragen zwei Notizen in verschiedenen
Ordnern denselben Namen, zeigt ein einfaches `[[Name]]` auf die, deren
Vault-Pfad alphabetisch zuerst kommt.
- **Tags werden Labels.** Sowohl `tags:` im Frontmatter als auch `#Tags`
im Text (die dabei aus dem Text verschwinden). Verschachtelte Tags wie
`#status/aktiv` werden zu einer Label-Hierarchie.
- **Bilder und Dateien kommen mit.** Bilder, auf die eine Notiz verweist
(`![[bild.png]]` oder `![](media/bild.png)`), werden zu Teich-Dateien
und erscheinen in der Seite; andere erlaubte Dateitypen werden Anhänge.
Sie zählen gegen das Speicher-Kontingent des Teichs.
`![[Andere Notiz]]`-Einbettungen werden zu normalen Links (Dorfteich
bettet keine Seiten ineinander ein).
Grenzen: Das ZIP darf bis zu 64 MiB groß sein, entpackt bis 256 MiB.
**Ein Import ist Alles-oder-nichts** — schlägt etwas fehl (voller Teich,
kaputtes Archiv), bleibt nichts zurück und du kannst es einfach erneut
versuchen.
## Dateien
Die **Dateiverwaltung** listet die Uploads des Teichs mit ihrer

View File

@ -81,8 +81,11 @@ Die Werkzeugleiste bleibt beim Scrollen sichtbar.
- **Wikilinks:** Tippe `[[seiten-slug]]` oder
`[[seiten-slug|angezeigter Text]]`. Links auf Seiten, die es noch
nicht gibt, listet die Teich-Startseite unter „Fehlende Seiten" — ein
Klick legt das Ziel an. Das Panel **„Verlinkt von"** einer Seite zeigt
jede Seite, die auf sie verweist.
Klick legt das Ziel an. Genauso kannst du einem solchen Link einfach
folgen: Die Seite öffnet sich mit dem Hinweis, dass es sie noch nicht
gibt, und einem Knopf, der sie **direkt dort anlegt** — danach
funktionieren alle Links auf diese Adresse. Das Panel
**„Verlinkt von"** einer Seite zeigt jede Seite, die auf sie verweist.
- **Bilder und Anhänge:** Füge Bilder direkt per Einfügen oder Ziehen in
den Text ein. Andere Dateitypen (PDFs usw., soweit die Instanz sie
erlaubt) hängst du über das **Büroklammer-Symbol** an die Seite.

View File

@ -42,6 +42,11 @@ projects.
- **Page tree**: nest pages under pages (up to 6 levels) — slugs and links
stay flat, so moving a page never breaks anything; the ZIP export also
stays flat (the hierarchy is organizational only)
- **Obsidian vault import**: a pond admin uploads a whole vault as a ZIP —
folders become the page tree, tags become labels, `[[wikilinks]]` are
rewritten so they keep working, and images come along as pond files
- **Dead links are one click from a page**: opening a link to a page that
does not exist yet offers to create it right there
- **Knowledge graph**: an interactive map of every pond — pages as nodes,
wikilinks as edges, missing targets as dashed phantoms you can create
with a click; each page also gets a local neighborhood graph

View File

@ -95,6 +95,44 @@ the matching instance switch:
A pond that has not opted in is invisible through those interfaces, even
to its own members' tokens.
## Import an Obsidian vault
Pond settings → **Import an Obsidian vault** takes a ZIP of a whole vault
and turns it into pages. You choose three things:
- **Mount under** — the page the vault hangs below (or the top level).
- **Additional labels** — assigned to every imported page, on top of the
labels made from the vault's tags.
- **YAML frontmatter** — removed, or kept as a code block at the top of
the page.
What happens to the vault:
- **Folders become pages.** Each folder turns into a container page and
the notes hang below it, mirroring the vault. Pages nest six levels
deep at most; if the vault (plus the mount depth) is deeper, the
deepest folder levels are merged into one page titled `like/this`.
- **`[[Wikilinks]]` keep working.** Obsidian links point at note _names_,
Dorfteich links at page _addresses_, so every link is rewritten to the
address the note actually got — including `[[Note|shown text]]`,
`[[Note#Heading]]` (the heading part is dropped), and
`[[folder/Note]]`. Links to notes that are not in the vault become
missing-page links, exactly as if you had typed them. When two notes in
different folders share a name, a plain `[[Name]]` resolves to the one
whose vault path comes first alphabetically.
- **Tags become labels.** Both `tags:` in the frontmatter and `#tags` in
the text (which are removed from the text). Nested tags like
`#status/active` become a label hierarchy.
- **Images and files come along.** Images referenced by a note
(`![[image.png]]` or `![](media/image.png)`) become pond files shown in
the page; other allowed file types become attachments. They count
against the pond's storage quota. `![[Another note]]` embeds become
plain links (Dorfteich does not transclude pages).
Limits: the ZIP may be up to 64 MiB, and 256 MiB unpacked. **An import is
all-or-nothing** — if anything fails (a full pond, a broken archive),
nothing is left behind and you can simply try again.
## Files
The **file manager** lists the pond's uploads with their usage (which

View File

@ -69,8 +69,11 @@ toolbar stays visible while you scroll.
overflow menu → Copy/Download Markdown).
- **Wikilinks:** type `[[page-slug]]` or `[[page-slug|shown text]]`.
Links to pages that do not exist yet are listed on the pond home page
("phantom pages") — one click creates the target. The **backlinks**
panel of a page shows every page that links to it.
("phantom pages") — one click creates the target. Following such a link
works too: the page opens with a "this page does not exist yet" notice
and a button that **creates it right there**, and every link pointing at
the address starts working. The **backlinks** panel of a page shows
every page that links to it.
- **Images and attachments:** paste or drag images straight into the
text. Other file types (PDFs etc., as allowed by the instance) attach
to the page via the **paperclip icon**.