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 \ E2E_BASE_URL=http://localhost:5173 \
pnpm --filter @dorfteich/web exec playwright test e2e/graph.spec.ts 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 - name: Reset login rate limit before search pack
run: | run: |
echo "DELETE FROM rate_limits WHERE key LIKE 'login%';" | \ 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', { const pond = await json<{ id: string; slug: string }>(context, '/api/v1/ponds', {
name: `Vault Pond ${ts}`, name: `Vault Pond ${ts}`,
}); });
const mount = await json<{ id: string; slug: string; title: string }>( await json<{ id: string; slug: string; title: string }>(
context, context,
`/api/v1/ponds/${pond.id}/pages`, `/api/v1/ponds/${pond.id}/pages`,
{ title: `Vault Mount ${ts}` }, { title: `Vault Mount ${ts}` },

View File

@ -49,6 +49,13 @@ Familien oder Projekte.
Slugs und Links bleiben flach, Verschieben bricht also nie etwas; der Slugs und Links bleiben flach, Verschieben bricht also nie etwas; der
ZIP-Export bleibt ebenfalls flach (die Hierarchie ist rein ZIP-Export bleibt ebenfalls flach (die Hierarchie ist rein
organisatorisch). 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 - **Wissensgraph**: eine interaktive Karte jedes Teichs — Seiten als
Knoten, Wikilinks als Kanten, fehlende Ziele als gestrichelte Knoten, Wikilinks als Kanten, fehlende Ziele als gestrichelte
Phantome, die ein Klick anlegt; jede Seite hat zusätzlich einen 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 — Ein Teich ohne Freigabe ist über diese Schnittstellen unsichtbar —
selbst für die Tokens der eigenen Mitglieder. 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 ## Dateien
Die **Dateiverwaltung** listet die Uploads des Teichs mit ihrer 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 - **Wikilinks:** Tippe `[[seiten-slug]]` oder
`[[seiten-slug|angezeigter Text]]`. Links auf Seiten, die es noch `[[seiten-slug|angezeigter Text]]`. Links auf Seiten, die es noch
nicht gibt, listet die Teich-Startseite unter „Fehlende Seiten" — ein nicht gibt, listet die Teich-Startseite unter „Fehlende Seiten" — ein
Klick legt das Ziel an. Das Panel **„Verlinkt von"** einer Seite zeigt Klick legt das Ziel an. Genauso kannst du einem solchen Link einfach
jede Seite, die auf sie verweist. 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 - **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 den Text ein. Andere Dateitypen (PDFs usw., soweit die Instanz sie
erlaubt) hängst du über das **Büroklammer-Symbol** an die Seite. 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 - **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 stay flat, so moving a page never breaks anything; the ZIP export also
stays flat (the hierarchy is organizational only) 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, - **Knowledge graph**: an interactive map of every pond — pages as nodes,
wikilinks as edges, missing targets as dashed phantoms you can create wikilinks as edges, missing targets as dashed phantoms you can create
with a click; each page also gets a local neighborhood graph 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 A pond that has not opted in is invisible through those interfaces, even
to its own members' tokens. 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 ## Files
The **file manager** lists the pond's uploads with their usage (which 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). overflow menu → Copy/Download Markdown).
- **Wikilinks:** type `[[page-slug]]` or `[[page-slug|shown text]]`. - **Wikilinks:** type `[[page-slug]]` or `[[page-slug|shown text]]`.
Links to pages that do not exist yet are listed on the pond home page Links to pages that do not exist yet are listed on the pond home page
("phantom pages") — one click creates the target. The **backlinks** ("phantom pages") — one click creates the target. Following such a link
panel of a page shows every page that links to it. 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 - **Images and attachments:** paste or drag images straight into the
text. Other file types (PDFs etc., as allowed by the instance) attach text. Other file types (PDFs etc., as allowed by the instance) attach
to the page via the **paperclip icon**. to the page via the **paperclip icon**.