Vercel detecteert @prisma/client en runt automatisch `prisma generate` zonder --generator filter. Daardoor probeerde de erd-generator op Vercel te draaien en faalde op libnss3.so (puppeteer/Chrome niet beschikbaar in de build container). Cascading: de Prisma-client werd niet ge-update, runtime kreeg oude enum-waarden (ACTIVE i.p.v. OPEN). ERD is dev-only documentatie en niet meer in productie nodig. Generator + dependency + npm scripts + de gegenereerde svg verwijderd. README, prisma-client pattern en architecture docs bijgewerkt. Build script blijft `prisma generate && next build` zodat de client ook bij Vercel build-cache-hits opnieuw wordt gegenereerd.
201 lines
8 KiB
Markdown
201 lines
8 KiB
Markdown
---
|
|
title: Obsidian as Personal Authoring Layer
|
|
status: active
|
|
audience: maintainer, contributor
|
|
language: en
|
|
last_updated: 2026-05-02
|
|
related:
|
|
- docs/adr/README.md
|
|
- scripts/generate-docs-index.mjs
|
|
- .gitignore
|
|
---
|
|
|
|
# Obsidian as Personal Authoring Layer
|
|
|
|
Scrum4Me's documentation lives as plain Markdown under `docs/`. The canonical
|
|
source of truth is the committed `.md` file — rendered on GitHub, read by
|
|
agents (Claude Code, Codex) directly from the file system, and indexed by
|
|
`scripts/generate-docs-index.mjs`.
|
|
|
|
Note: the `mcp` server does **not** expose `docs/` content. Its
|
|
20 tools serve database state (products, sprints, stories, tasks, jobs,
|
|
questions) via Prisma. Documentation reaches the agent only through the
|
|
file-system tools, so the canonical Markdown is the one and only channel.
|
|
|
|
Obsidian is **not** a second source of truth. It is a personal authoring
|
|
layer that you can opt into without changing what the repo or the agent
|
|
sees. This document records the conventions that keep both views consistent.
|
|
|
|
## Why an authoring layer at all
|
|
|
|
A canonical `0003-job-claim-strategy.md` is short, declarative, and final.
|
|
The thinking that produced it — alternatives weighed, links followed, half-
|
|
ideas — is messy and personal. Forcing that into the committed file inflates
|
|
ADRs and dilutes the signal future readers (human or agent) need.
|
|
|
|
Obsidian gives you a place to keep the thinking next to the artefact without
|
|
polluting it: graph view, backlinks, properties, scratch notes. The
|
|
`.gitignore` rules below ensure none of that crosses the repo boundary.
|
|
|
|
## Vault setup
|
|
|
|
Open the repo root as the vault, not just `docs/`.
|
|
|
|
Reasons:
|
|
|
|
- ADRs and patterns frequently reference code (`prisma/schema.prisma`,
|
|
`lib/task-status.ts`). Markdown links from a `docs/`-only vault cannot
|
|
resolve those targets; from a root vault they can.
|
|
- The same vault then surfaces `README.md`, `CLAUDE.md`, and `AGENTS.md`
|
|
as nodes in the graph — useful when reasoning about agent instructions.
|
|
- Per-developer Obsidian config lives in `.obsidian/` at the vault root,
|
|
which is already gitignored.
|
|
|
|
### Two repos, two vaults
|
|
|
|
The MCP server lives in a separate repo (`mcp`) with its own
|
|
`CLAUDE.md`, tools, and tests. Open it as a **separate** Obsidian vault
|
|
when you work there. Each `.obsidian/` directory is per-folder and stays
|
|
gitignored on both sides; cross-repo notes belong in whichever vault you
|
|
opened first, not in some shared third location.
|
|
|
|
Schema-related ADRs are an exception: the MCP server consumes the
|
|
Scrum4Me Prisma schema via the `vendor/scrum4me/` git submodule, so the
|
|
*decision* about the schema belongs in this repo's `docs/adr/`. The
|
|
mirror in `mcp` only needs an `npm run sync-schema` after the
|
|
ADR lands here, not its own ADR.
|
|
|
|
## Link style
|
|
|
|
In Settings → Files & Links:
|
|
|
|
- **Use [[Wikilinks]]** → off
|
|
- **New link format** → Relative path to file
|
|
- **Default location for new notes** → "Same folder as current file"
|
|
|
|
Wikilinks would render as plain text on GitHub and are not parsed by the
|
|
docs index generator. Stick to standard Markdown links (`./adr/0001-foo.md`)
|
|
so the same file works in Obsidian, GitHub, and any agent reader.
|
|
|
|
Obsidian still resolves Markdown links for backlinks and graph view, so you
|
|
do not lose Obsidian's navigation features.
|
|
|
|
## Front-matter is Obsidian Properties
|
|
|
|
`scripts/generate-docs-index.mjs` reads a small set of YAML front-matter
|
|
keys: `title`, `status`, `date` (or `last_updated`). Obsidian renders the
|
|
exact same YAML block as its Properties panel.
|
|
|
|
Practical consequence: flipping a plan from `proposal` to `accepted` in
|
|
the Obsidian Properties UI and then running `npm run docs:index` is a
|
|
complete workflow — no separate metadata store, no plugin needed.
|
|
|
|
The repo's front-matter is intentionally flat (no nested objects, no lists
|
|
beyond simple arrays) to stay parseable by the dependency-free generator.
|
|
When adding fields, keep them flat.
|
|
|
|
## Templates
|
|
|
|
Two ADR templates ship in `docs/adr/templates/`:
|
|
|
|
- `nygard.md` — default, for one-way-door decisions
|
|
- `madr.md` — for decisions where rejected alternatives must be recorded
|
|
|
|
Both use `{{curly braces}}` placeholders so they read naturally in any
|
|
editor and so Codex and Claude Code can fill them mechanically.
|
|
|
|
Two ways to use them from Obsidian:
|
|
|
|
1. **Core Templates plugin** (recommended starting point). Settings →
|
|
Templates → Template folder location: `docs/adr/templates`. Then
|
|
`Cmd-P → Insert template → nygard` inserts the body verbatim. Fill
|
|
placeholders by hand.
|
|
2. **Templater** (community plugin). If filling the next ADR number and
|
|
today's date by hand becomes a bottleneck, write a Templater wrapper
|
|
in a vault-only `_templates/` folder that reads `nygard.md` and
|
|
substitutes `<% tp.date.now("YYYY-MM-DD") %>` plus a computed next
|
|
number. Keep this wrapper out of git — it is personal tooling, not
|
|
part of the canonical convention.
|
|
|
|
Do not modify the canonical templates to use Templater syntax. The
|
|
placeholders must remain agent-readable.
|
|
|
|
## Sidecar files for personal notes
|
|
|
|
`.gitignore` already excludes `_*.md` and the docs index generator
|
|
mirrors that exclusion (`/\/_[^/]+\.md$/`). Use this for any file that
|
|
should stay personal:
|
|
|
|
- `docs/adr/_draft-0003-job-claim-strategy.md` — alternatives, doubts,
|
|
links you considered before settling on the canonical ADR
|
|
- `docs/plans/_questions-for-jp.md` — open questions you want to think
|
|
about but not raise yet
|
|
- `_scratch.md` anywhere in the tree
|
|
|
|
Workflow for an ADR:
|
|
|
|
1. Brainstorm in `docs/adr/_draft-NNNN-…md` — free-form, link-heavy.
|
|
2. When the decision is clear, copy the relevant prose into the canonical
|
|
`docs/adr/NNNN-…md`, applying the Nygard or MADR template.
|
|
3. Run `npm run docs:index`.
|
|
4. Commit only the canonical ADR (the sidecar is invisible to git).
|
|
|
|
The sidecar can stay as a personal trail or be deleted — both are local-
|
|
only choices.
|
|
|
|
## Plugin recommendations
|
|
|
|
Useful and low-risk:
|
|
|
|
- **Outline** (core) — table of contents per file
|
|
- **Backlinks**, **Outgoing Links** (core) — see what links to and from
|
|
the current document
|
|
- **Linter** (community) — can enforce that ADRs have a `status` field
|
|
in front-matter
|
|
|
|
Use with care:
|
|
|
|
- **Dataview** — tempting to replace `INDEX.md` with a Dataview query.
|
|
Don't. The query renders blank on GitHub and is invisible to Claude
|
|
Code. Use Dataview only in a sidecar (`_dashboard.md`) for personal
|
|
views.
|
|
|
|
Avoid as canonical source:
|
|
|
|
- **Canvas**, **Excalidraw** — not diff-able, not agent-readable. Keep
|
|
diagrams as committed SVG or as Mermaid blocks inside Markdown.
|
|
|
|
## Index generator interaction
|
|
|
|
`generate-docs-index.mjs` is the system of record for `docs/INDEX.md`.
|
|
Two reliability concerns when authoring through Obsidian:
|
|
|
|
- **Forgetting to regenerate the index.** If you create or rename a doc
|
|
in Obsidian and commit without running the generator, INDEX.md goes
|
|
stale. Mitigations: a `pre-commit` hook that runs `npm run docs:index`
|
|
whenever staged changes touch `docs/**/*.md`, or a habit of running
|
|
`npm run docs:index` before every `git add docs/`.
|
|
- **Renaming and "update links" prompts.** Obsidian's "automatically
|
|
update internal links" applies to wikilinks. Since this vault uses
|
|
Markdown links, Obsidian will still try to update them — verify the
|
|
diff before committing, especially for cross-folder renames.
|
|
|
|
## What Obsidian must not do
|
|
|
|
- Introduce wikilinks into committed files
|
|
- Add Obsidian-only blocks (callouts, embeds with `![[...]]`) into
|
|
canonical docs
|
|
- Replace `INDEX.md` with a Dataview view in the committed tree
|
|
- Modify front-matter keys outside the documented set without also
|
|
updating `generate-docs-index.mjs`
|
|
|
|
If a workflow benefits the personal vault but breaks one of those rules,
|
|
keep it in a `_*.md` sidecar.
|
|
|
|
## Summary
|
|
|
|
Treat Obsidian like a notebook bound to the same desk as the repo:
|
|
useful for thinking, never confused with what's published. The
|
|
gitignore rules and the index generator already enforce most of this
|
|
mechanically — these conventions cover the parts that still depend on
|
|
the author's judgement.
|