Repository navigation
Expand file tree
/
Copy pathdocs.html
More file actions
179 lines (175 loc) · 19.3 KB
/
Copy pathdocs.html
File metadata and controls
179 lines (175 loc) · 19.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<!doctype html>
<html lang="en" class="preload">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DotNetSolutionKit - documentation</title>
<meta name="description" content="The documents of DotNetSolutionKit, a dotnet new template for .NET 8 microservices on PostgreSQL: generating a solution, the architecture, every feature switch, operations and the decisions behind them.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="site/site.css?v=140">
<link rel="stylesheet" href="site/docs.css?v=103">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.11/katex.min.css">
<script src="site/config.js?v=103"></script>
<script src="site/boot.js?v=103"></script>
</head>
<body>
<div id="main">
<div id="cols">
<aside id="sidebar" aria-label="Documents">
<div class="side-head">
<span class="side-title">Documents</span>
<button id="side-lang" type="button" title="Читать по-русски" aria-label="Читать по-русски">RU</button>
<button id="side-theme" type="button" title="Theme: follows the device" aria-label="Theme">◐</button>
<button id="side-swap" type="button" title="Move the panel to the other side" aria-label="Move the panel to the other side">⇄</button>
<button id="side-close" type="button" title="Close" aria-label="Close the panel">✕</button>
</div>
<div class="side-body"><div id="menu">
<!-- Rendered here as well as by the script: without it a crawler, a link preview or a
reader with no JavaScript gets an empty page. The script replaces this on load.
Generated from the shelf in site/config.js. -->
<h2>Getting started</h2>
<ul>
<li><a href="#generating" data-id="generating">Generating a solution</a></li>
<li><a href="#upgrading" data-id="upgrading">Versions of the template</a></li>
<li><a href="#overview" data-id="overview">The documentation at a glance</a></li>
<li><a href="#roadmap" data-id="roadmap">Roadmap</a></li>
</ul>
<h2>Architecture</h2>
<ul>
<li><a href="#layers" data-id="layers">Projects and layers</a></li>
<li><a href="#web-layer" data-id="web-layer">Web layer</a></li>
<li><a href="#errors" data-id="errors">Errors</a></li>
<li><a href="#validation" data-id="validation">Validation and pagination</a></li>
<li><a href="#auth" data-id="auth">Authentication and permissions</a></li>
<li><a href="#persistence" data-id="persistence">Persistence</a></li>
<li><a href="#domain-events" data-id="domain-events">Domain events</a></li>
<li><a href="#testing" data-id="testing">Testing</a></li>
</ul>
<h2>Features</h2>
<ul>
<li><a href="#jobs" data-id="jobs">Background jobs</a></li>
<li><a href="#messaging" data-id="messaging">Message bus</a></li>
<li><a href="#secrets" data-id="secrets">Secrets from Infisical</a></li>
<li><a href="#feature-flags" data-id="feature-flags">Feature flags</a></li>
<li><a href="#api-diff" data-id="api-diff">API diff</a></li>
<li><a href="#ci" data-id="ci">CI on GitHub Actions</a></li>
<li><a href="#hierarchy-rules" data-id="hierarchy-rules">Access rules over a tenant tree</a></li>
<li><a href="#storage" data-id="storage">Object storage</a></li>
<li><a href="#clickhouse" data-id="clickhouse">ClickHouse</a></li>
<li><a href="#audit" data-id="audit">Audit journal</a></li>
<li><a href="#gateway" data-id="gateway">API gateway</a></li>
</ul>
<h2>Operations</h2>
<ul>
<li><a href="#docker" data-id="docker">Docker</a></li>
<li><a href="#deployment" data-id="deployment">Deployment</a></li>
<li><a href="#health" data-id="health">Health</a></li>
<li><a href="#startup-checks" data-id="startup-checks">Startup checks</a></li>
<li><a href="#switching-off" data-id="switching-off">Switching dependencies off</a></li>
</ul>
<h2>Decisions</h2>
<ul>
<li><a href="#adr-001" data-id="adr-001">ADR-001: Domain events in three phases</a></li>
<li><a href="#adr-002" data-id="adr-002">ADR-002: Repositories on specifications</a></li>
<li><a href="#adr-003" data-id="adr-003">ADR-003: The API document from the built application</a></li>
<li><a href="#adr-004" data-id="adr-004">ADR-004: The product version by hand</a></li>
<li><a href="#adr-005" data-id="adr-005">ADR-005: How a service is tested</a></li>
</ul>
</div></div>
</aside>
<div id="below">
<div class="bar">
<div class="wrap bar-inner">
<button id="burger" type="button" aria-expanded="false" aria-controls="sidebar" title="Sections of this page">≡</button>
<a class="bar__mark" href="./">
<!-- the SawKing Tech mark, inline as FoQLens has its magnifier, so .bar__mark svg sizes it; ids prefixed bm- -->
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="236 34 328 328"> <defs> <radialGradient id="bm-disc-b" gradientUnits="userSpaceOnUse" cx="503.9" cy="138" r="180"><stop offset="0" stop-color="#9b4f96" stop-opacity="0.75"/><stop offset="1" stop-color="#9b4f96" stop-opacity="0"/></radialGradient><radialGradient id="bm-disc-c" gradientUnits="userSpaceOnUse" cx="400" cy="268" r="180"><stop offset="0" stop-color="#8cd600" stop-opacity="0.9"/><stop stop-color="#2fa6c4" offset="0.45" stop-opacity="0.45"/><stop stop-color="#2fa6c4" offset="1" stop-opacity="0"/></radialGradient> <mask id="bm-under-green" maskUnits="userSpaceOnUse" x="310" y="192" width="188" height="74"><rect x="310" y="192" width="188" height="74" fill="#fff"/><path d="M409.2 214.4C416.2 209.2 431.6 197 439.7 195.2C444.9 194 449.5 198.2 450 203.3C450.5 209.7 442.5 213.7 437.9 216.7Z"/></mask> </defs> <mask id="bm-cut" maskUnits="userSpaceOnUse" x="236" y="34" width="328" height="328"> <rect x="236" y="34" width="328" height="328" fill="#fff"/> <g fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <g><g opacity="0.35"><path stroke-dasharray="3 2.2" d="M411.8 124.5Q456.7 144.7 498.1 168.4"/><path stroke-linejoin="miter" stroke-linecap="butt" d="M493.5 168.4L499.4 169.1L495.8 164.4"/></g><path stroke-dasharray="3 2.2" d="M369.5 161.6Q379.7 144.5 396.1 128.6"/><path stroke-linejoin="miter" stroke-linecap="butt" d="M394.8 133L397.1 127.6L391.6 129.7"/><path stroke-dasharray="3 2.2" d="M372 168.7Q389.9 174.6 403.3 175.7"/><path stroke-linejoin="miter" stroke-linecap="butt" d="M399.2 177.7L404.8 175.8L399.5 173.1"/><path stroke-dasharray="3 2.2" d="M414.5 165.8Q409.3 147.8 405.8 130.9"/><path stroke-linejoin="miter" stroke-linecap="butt" d="M408.9 134.4L405.5 129.4L404.4 135.3"/><path stroke-dasharray="3 2.2" d="M412.5 117.9Q434.4 109.3 450 108.8"/><path stroke-linejoin="miter" stroke-linecap="butt" d="M446.1 111.2L451.5 108.7L445.9 106.6"/><path stroke-dasharray="3 2.2" d="M424.7 167.4Q439.9 146.9 455.9 117.1"/><path stroke-linejoin="miter" stroke-linecap="butt" d="M456 121.7L456.6 115.8L452 119.6"/><path stroke-dasharray="3 2.2" d="M471.7 113A111.2 111.2 0 0 1 505.4 162.5"/><path stroke-linejoin="miter" stroke-linecap="butt" d="M502 159.4L505.8 163.9L506.3 158"/><path stroke-dasharray="3 2.2" d="M430.9 177.9Q464.7 177.3 496.8 174.4"/><path stroke-linejoin="miter" stroke-linecap="butt" d="M493.1 177.1L498.3 174.3L492.6 172.5"/><circle fill="#fff" cx="364.9" cy="167.2" r="7.2"/><circle fill="#fff" cx="417.7" cy="178.6" r="13.2"/><circle fill="#fff" cx="403.2" cy="120.1" r="9.6"/><circle fill="#fff" cx="462.6" cy="106.1" r="11.4"/><circle fill="#fff" cx="508.5" cy="173.8" r="10.2"/></g> <g><path d="M447.8 209.3C454.4 204.4 468.7 192.4 475.9 201.7C479.1 205.9 476.9 209.6 474.8 213.4" stroke-linecap="butt" mask="url(#bm-under-green)"/> <path d="M333.8 241.9C351.3 262.3 407.7 267.1 432.5 259.9C450 254.9 466.4 244.6 480.9 233.8C485.7 230.1 495.3 226.3 494.7 219C494.3 214 490 210.5 485.1 210.6C473 211.1 453.2 226 440.4 230.6" stroke-linecap="butt"/> <path d="M409.2 214.4C416 209.4 432.1 196.6 440 195.1C444.9 194.2 449.3 198.1 449.9 202.8C450.9 210.2 440.5 215 435.4 218.4" stroke-linecap="butt"/> <path d="M338 207.3C349.6 203.8 362.2 198 374.5 198.6C385.6 199.2 393.3 207.4 402.5 212.3C405.3 213.8 408.8 214.5 411.9 215.4C418.3 217.4 431.2 214.3 436.5 219.2C437.8 220.4 438.5 222.3 439.1 224L439.1 224C439.5 225.6 441 228.2 440.7 229.9C438.4 245.6 392.1 237 382.2 233.5"/> <path d="M321.9 198.1L335.9 199.7A3 3 0 0 1 338.5 203L333.1 247.1A3 3 0 0 1 329.8 249.7L315.8 248A3 3 0 0 1 313.1 244.7L318.6 200.7A3 3 0 0 1 321.9 198.1Z"/></g> </g> </mask> <g mask="url(#bm-cut)"><circle fill="#512bd4" cx="400" cy="198" r="155"/><circle cx="400" cy="198" r="155" fill="url(#bm-disc-b)"/><circle cx="400" cy="198" r="155" fill="url(#bm-disc-c)"/></g> </svg>
DotNetSolutionKit
</a>
<span class="spacer"></span>
<a href="./"><span lang="en">About</span><span lang="ru">О шаблоне</span></a>
<a href="docs.html" aria-current="page"><span lang="en">Docs</span><span lang="ru">Документы</span></a>
<a href="samples.html"><span lang="en">Samples</span><span lang="ru">Примеры</span></a>
<a href="https://github.com/sawking-tech/DotNetSolutionKit" target="_blank" rel="noopener">GitHub</a>
</div>
</div>
<main class="doc wrap" id="doc">
<h1>The documents of the template</h1>
<p>DotNetSolutionKit is a <code>dotnet new</code> template for .NET 8 microservices on PostgreSQL. These are its documents: how to generate a solution, how a service is built, what each switch adds, how it runs in production and why it is made the way it is.</p>
<p>Every document below is a markdown file in the repository, and each link goes to its source.</p>
<h3>Getting started</h3>
<ul>
<li><a href="#generating">Generating a solution</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/getting-started/generating-a-solution.md">docs/getting-started/generating-a-solution.md</a></span></li>
<li><a href="#upgrading">Versions of the template</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/getting-started/upgrading.md">docs/getting-started/upgrading.md</a></span></li>
<li><a href="#overview">The documentation at a glance</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/README.md">docs/README.md</a></span></li>
<li><a href="#roadmap">Roadmap</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/roadmap.md">docs/roadmap.md</a></span></li>
</ul>
<h3>Architecture</h3>
<ul>
<li><a href="#layers">Projects and layers</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/architecture/projects-and-layers.md">docs/architecture/projects-and-layers.md</a></span></li>
<li><a href="#web-layer">Web layer</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/architecture/web-layer.md">docs/architecture/web-layer.md</a></span></li>
<li><a href="#errors">Errors</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/architecture/errors.md">docs/architecture/errors.md</a></span></li>
<li><a href="#validation">Validation and pagination</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/architecture/validation-and-pagination.md">docs/architecture/validation-and-pagination.md</a></span></li>
<li><a href="#auth">Authentication and permissions</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/architecture/authentication-and-permissions.md">docs/architecture/authentication-and-permissions.md</a></span></li>
<li><a href="#persistence">Persistence</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/architecture/persistence.md">docs/architecture/persistence.md</a></span></li>
<li><a href="#domain-events">Domain events</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/architecture/domain-events.md">docs/architecture/domain-events.md</a></span></li>
<li><a href="#testing">Testing</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/architecture/testing.md">docs/architecture/testing.md</a></span></li>
</ul>
<h3>Features</h3>
<ul>
<li><a href="#jobs">Background jobs</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/background-jobs.md">docs/features/background-jobs.md</a></span></li>
<li><a href="#messaging">Message bus</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/messaging.md">docs/features/messaging.md</a></span></li>
<li><a href="#secrets">Secrets from Infisical</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/secrets.md">docs/features/secrets.md</a></span></li>
<li><a href="#feature-flags">Feature flags</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/feature-flags.md">docs/features/feature-flags.md</a></span></li>
<li><a href="#api-diff">API diff</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/api-diff.md">docs/features/api-diff.md</a></span></li>
<li><a href="#ci">CI on GitHub Actions</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/ci.md">docs/features/ci.md</a></span></li>
<li><a href="#hierarchy-rules">Access rules over a tenant tree</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/hierarchy-rules.md">docs/features/hierarchy-rules.md</a></span></li>
<li><a href="#storage">Object storage</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/object-storage.md">docs/features/object-storage.md</a></span></li>
<li><a href="#clickhouse">ClickHouse</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/clickhouse.md">docs/features/clickhouse.md</a></span></li>
<li><a href="#audit">Audit journal</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/audit.md">docs/features/audit.md</a></span></li>
<li><a href="#gateway">API gateway</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/features/api-gateway.md">docs/features/api-gateway.md</a></span></li>
</ul>
<h3>Operations</h3>
<ul>
<li><a href="#docker">Docker</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/operations/docker.md">docs/operations/docker.md</a></span></li>
<li><a href="#deployment">Deployment</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/operations/deployment.md">docs/operations/deployment.md</a></span></li>
<li><a href="#health">Health</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/operations/health.md">docs/operations/health.md</a></span></li>
<li><a href="#startup-checks">Startup checks</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/operations/startup-checks.md">docs/operations/startup-checks.md</a></span></li>
<li><a href="#switching-off">Switching dependencies off</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/operations/switching-dependencies-off.md">docs/operations/switching-dependencies-off.md</a></span></li>
</ul>
<h3>Decisions</h3>
<ul>
<li><a href="#adr-001">ADR-001: Domain events in three phases</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/adr/001-three-phase-domain-events.md">docs/adr/001-three-phase-domain-events.md</a></span></li>
<li><a href="#adr-002">ADR-002: Repositories on specifications</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/adr/002-repositories-on-specifications.md">docs/adr/002-repositories-on-specifications.md</a></span></li>
<li><a href="#adr-003">ADR-003: The API document from the built application</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/adr/003-api-schema-generation.md">docs/adr/003-api-schema-generation.md</a></span></li>
<li><a href="#adr-004">ADR-004: The product version by hand</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/adr/004-product-version-by-hand.md">docs/adr/004-product-version-by-hand.md</a></span></li>
<li><a href="#adr-005">ADR-005: How a service is tested</a> <span class="src">· <a href="https://github.com/sawking-tech/DotNetSolutionKit/blob/master/docs/adr/005-testing-a-service.md">docs/adr/005-testing-a-service.md</a></span></li>
</ul>
</main>
<footer>
<div class="wrap">
<p lang="en">Made by <a href="https://sawking.tech/cv">Vladimir Savkin</a>, systems architect, at <a href="https://sawking.tech">sawking.tech</a>.</p>
<p lang="ru">Сделал <a href="https://sawking.tech/cv">Владимир Савкин</a>, системный архитектор, <a href="https://sawking.tech">sawking.tech</a>.</p>
<p><span lang="en">Source on</span><span lang="ru">Исходники на</span> <a href="https://github.com/sawking-tech/DotNetSolutionKit">GitHub</a>
· <span lang="en">package on</span><span lang="ru">пакет на</span> <a href="https://www.nuget.org/packages/SawKing.DotNetSolutionKit">nuget.org</a>
· <a href="samples.html"><span lang="en">generated samples</span><span lang="ru">сгенерированные примеры</span></a></p>
</div>
</footer>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/15.0.7/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.11/katex.min.js"></script>
<script src="site/panel.js?v=103"></script>
<script src="site/docs.js?v=103"></script>
<script>
/* Transitions come back only once the panel and the sheet stand where storage says - two frames
later, so the browser has laid the page out and painted it at rest. This lives in the page, next
to the class it removes: from a cached script it might never run, and the page would keep every
animation switched off. */
requestAnimationFrame(() => requestAnimationFrame(() => document.documentElement.classList.remove("preload")));
</script>
</body>
</html>