The canonical structure for every docs/<Area>/<Package>.md page. Copy the skeleton, keep the
section order and emoji headers exactly — readers navigate the whole doc set by them — and follow
the per-section rules. Every page is written from the source, not from memory: read the
package’s public surface first and document only what the code actually does.
nameof-safe examples. Code samples must compile as written: declare every member an
example references, include the using lines, and prefer nameof(...) over string literals.### block. A feature section explains one thing, shows one runnable
example, then states its edge cases — not a tour../Other-Package.md, ../Services/...) so links work on
GitHub and GitHub Pages alike.# DKNet.<Area>.<PackageName>
One or two sentences: what the package does and the mechanism it uses — concrete, not marketing.
("A pluggable before/after-SaveChanges interceptor pipeline for EF Core — one shared interceptor
per DbContext type plus a small pair of interfaces you implement.")
> [!IMPORTANT]
> Optional. Only for something that changes whether/how the reader should use the package at all
> (retirement, hard prerequisite, security caveat). At most one.
## ✨ Why use it?
- **Bold claim, then justification** — 4–6 bullets. Each names the problem you'd otherwise solve
by hand and how this package removes it. First bullet = the strongest reason.
- **State what it is NOT** as the final line when the name invites misuse
("It is not a test-data generator: no seeding, no repeatable sequence.").
## 🚀 Quick Start
```bash
dotnet add package DKNet.<Area>.<PackageName>
// The smallest end-to-end working snippet: DI registration + one real use.
// A reader should be able to paste this and see the package do its job.
IBeforeSaveHookAsync — mutate before the write”>What it does, when it runs, what guarantees it gives. Then one focused example:
// runnable, minimal, compiles as written
If the feature has a shape — a lifecycle, a pipeline, a branch — add its diagram right after the example (see Diagrams below). End with the edge cases of THIS feature (what happens on failure, what the default is, what it deliberately does not do).
Repeat. Order sections by the reader’s journey: the type they write first, then the supporting pieces, then “how it runs” internals (only as far as they explain behaviour).
When one feature has multiple declaration forms or modes, open with a form-picker table
(Form | Looks like | Use when) before diving into each form as a #### subsection.
Every knob in one place, as a table. If there is no options object, say so explicitly and table the DI registrations instead:
| Option / Registration | Type / Lifetime | Default | Effect |
|---|---|---|---|
| … | … | … | … |
Where the package sits in the DDD/Onion layering, which packages sit above/below it, and the one diagram if the flow deserves it. Name its dependencies (or state “zero dependencies”).
Add a diagram whenever a feature has a drawable shape — don’t reserve them for the architecture overview. Pick the type from what the feature is:
| Feature shape | Diagram type | Example |
|---|---|---|
| Multi-step processing, “what happens on X” | workflow / flow | what one SaveChangesAsync runs, in order |
| Two+ components exchanging calls over time | sequence | interceptor → hook → publisher during a save |
| A value or entity moving through transforms | dataflow | token text → extractor → resolver → formatted output |
| Distinct states + transitions | lifecycle / state | entity Added → Modified → Deleted; disabled/enabled hook scopes |
| Static structure, layers, wiring | architecture | which package owns which interface; DI graph |
| Branching decision (“which form/overload do I use?”) | flow (decision) | type-naming vs labelled vs label-less [RaisesEvent] |
Tool: archify — the required diagram tool for this repo
(full conventions in docs/diagrams/README.md). Diagrams are authored as archify’s typed JSON
intermediate representation, not drawn by hand. That IR is what makes every diagram
enhanceable later: to add a node, rename an edge, or restyle the whole set, edit the JSON
and re-render — no diagram ever has to be redrawn from scratch, and a reviewer can diff the
change like code.
docs/diagrams/<name>.<type>.json
(<type> ∈ architecture | workflow | sequence | dataflow | lifecycle — the type selects
the schema and renderer). The JSON is the source of truth — edit it, never the SVG.Validate, then render (both must pass at showcase quality):
archify validate <type> docs/diagrams/<name>.<type>.json --quality showcase
archify render <type> docs/diagrams/<name>.<type>.json /tmp/<name>.html --quality showcase
The committed .svg is the <svg> element extracted from that HTML with the theme
<style> inlined — standalone, renders on GitHub and GitHub Pages without external CSS.
<name>.<type>.json (source) and <name>.svg (rendered) — and set
meta.quality_profile: "showcase" plus a populated meta.legend.entries (generic swatch
labels are a review reject).ASCII fallback — for a trivial linear flow (≤ 5 nodes, no branching), an ASCII diagram in a
fenced code block is acceptable inline and needs no docs/diagrams/ asset:
request ──▶ [key extracted] ──▶ store.TryAdd ──▶ hit? ──▶ cached response
└─ miss ──▶ endpoint runs ──▶ response cached
Rules either way:
| Section | Must contain | Must NOT contain |
|---|---|---|
| Title + lede | Mechanism in one breath | Feature list, superlatives |
| ✨ Why use it? | Problems removed, strongest first; a “not for” line when needed | API details, code |
| 🚀 Quick Start | Install + smallest working end-to-end snippet | Every option, edge cases |
| 🧩 Features | One ### per concern; runnable example each; a diagram when the feature has a shape; diagnostics codes (DK*) inline where the mistake happens |
Marketing prose, untested snippets, mermaid fences |
| ⚙️ Configuration | Exhaustive table of every knob with defaults | Behaviour explanations (link back to the feature section) |
| 🧱 Where it fits | Layer, dependencies, composition with sibling packages, optional diagram | Restating features |
| ⚠️ Gotchas & limits | Source-verified footguns with workarounds | Generic advice (“remember to test”) |
| 🔗 Related packages | Every sibling it composes with + routing rule | Bare links without the “reach for it when” |
using lines present, current API names.Type.FullName”).archify validate passes at
showcase; alt text narrates the diagram; no mermaid fences; no hand-edited SVGs.README.md index.