Skip to content

Commit 440ee95

Browse files
committed
docs: update documentation, add Admin API auth details, and refresh project status badges
1 parent 517f06f commit 440ee95

3 files changed

Lines changed: 60 additions & 24 deletions

File tree

.scannerwork/report-task.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ projectKey=dispatch
22
serverUrl=http://10.27.27.202:9000
33
serverVersion=26.4.0.121862
44
dashboardUrl=http://10.27.27.202:9000/dashboard?id=dispatch
5-
ceTaskId=f6d4b0a5-29bb-480d-8727-32f681318ba9
6-
ceTaskUrl=http://10.27.27.202:9000/api/ce/task?id=f6d4b0a5-29bb-480d-8727-32f681318ba9
5+
ceTaskId=68fb8656-1ed5-4f18-83e6-c1bb725748fe
6+
ceTaskUrl=http://10.27.27.202:9000/api/ce/task?id=68fb8656-1ed5-4f18-83e6-c1bb725748fe

ARCHITECTURE.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ NATS Consumer (pull, explicit ACK, 30s ack-wait)
139139

140140
## MS Graph Integration
141141

142+
### E-Mail-Versand (`msgraph.Service`)
143+
142144
```
143145
SendEmail(req)
144146
@@ -160,6 +162,27 @@ Gesamtgröße Attachments?
160162
POST .../messages/{id}/send
161163
```
162164

165+
### NDR-Crawling (`msgraph.BounceService`)
166+
167+
```
168+
BounceService.GetUnreadMessages(mailbox)
169+
170+
171+
GET /users/{mailbox}/messages?$filter=isRead+eq+false&$select=id,subject,body
172+
173+
174+
Parse → []NDRMessage{ID, Subject, Body}
175+
176+
177+
Crawler.process → Trace-ID extrahieren → DISPATCH_BOUNCES
178+
179+
180+
BounceService.MarkAsRead(mailbox, messageID)
181+
182+
183+
PATCH /users/{mailbox}/messages/{id} {"isRead": true}
184+
```
185+
163186
**Fehler-Handling im HTTP-Client:**
164187

165188
| HTTP-Status | Fehlertyp | Verhalten |
@@ -176,6 +199,7 @@ Gesamtgröße Attachments?
176199

177200
| Fehler | HTTP | Auslöser |
178201
|---|---|---|
202+
| Request-Body überschreitet Limit | 413 | `http.MaxBytesReader` vor JSON-Decode |
179203
| Validierungsfehler (Format, MIME, Größe) | 400 | Stage 1 |
180204
| Unbekannter `appTag` | 400 | Stage 2 |
181205
| Domain nicht erlaubt | 400 | Stage 3 |
@@ -195,7 +219,9 @@ Gesamtgröße Attachments?
195219

196220
**Attachments:** NATS Object Store entkoppelt Payload-Größe vom JetStream-Limit. Bucket-TTL (72 h) bereinigt Waisen-Objekte nach Worker-Crash ohne Cleanup.
197221

198-
**Bounce-Matching:** Dreistufig — Trace-ID im NDR-Body → Anhänge → Empfänger-Lookup im Audit-Stream (implementiert im Crawler, Stufen 2/3 deferiert).
222+
**Bounce-Matching:** `BounceService` (MS Graph) ruft alle 15 Minuten ungelesene Nachrichten aus der Bounce-Mailbox ab, extrahiert die Trace-ID via `X-Dispatch-TraceId`-Header im NDR-Body und schreibt einen `BounceRecord` nach `DISPATCH_BOUNCES`. Verarbeitete Nachrichten werden via `PATCH .../messages/{id}` als gelesen markiert.
223+
224+
**Attachment-Streaming:** Base64-Inhalt von Anhängen wird im Gateway nie vollständig als `[]byte` dekodiert. Validierung (Größe, Formatprüfung) und Upload in den NATS Object Store erfolgen durch Streaming via `base64.NewDecoder` — O(1) Speicher unabhängig von der Anhangsgröße.
199225

200226
---
201227

@@ -206,10 +232,11 @@ Alle Werte kommen aus Umgebungsvariablen. Keine Config-Dateien.
206232
**Pflichtfelder** (ohne die kein Start):
207233
```
208234
NATS_URL
209-
MS_GRAPH_TENANT_ID \
210-
MS_GRAPH_CLIENT_ID } entfallen wenn MS_GRAPH_MOCK_TOKEN gesetzt
211-
MS_GRAPH_CLIENT_SECRET /
235+
MS_GRAPH_TENANT_ID \
236+
MS_GRAPH_CLIENT_ID } entfallen wenn MS_GRAPH_MOCK_TOKEN gesetzt
237+
MS_GRAPH_CLIENT_SECRET /
212238
MS_GRAPH_SENDER_EMAIL
239+
DISPATCH_ADMIN_AUTH_SECRET # HMAC-Schlüssel für Admin-API JWT-Auth
213240
```
214241

215242
**Optionale Felder (Auswahl):**

README.md

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# dispatch
22

33
![Build Status](https://img.shields.io/github/actions/workflow/status/maatini/dispatch/build.yml?branch=main)
4-
![Go Version](https://img.shields.io/github/go-mod/go-version/maatini/dispatch)
5-
![License](https://img.shields.io/github/license/maatini/dispatch)
4+
![Go Version](https://img.shields.io/badge/Go-1.25-00ADD8?logo=go)
5+
![Tests](https://img.shields.io/badge/tests-112-brightgreen)
6+
![Quality Gate](https://img.shields.io/badge/quality_gate-PASSED-brightgreen?logo=sonarqube)
67

78
<div align="center">
89
<img src="assets/banner.png" alt="Dispatch Service Banner" width="100%" />
@@ -81,6 +82,7 @@ MS_GRAPH_TENANT_ID \
8182
MS_GRAPH_CLIENT_ID } entfallen wenn MS_GRAPH_MOCK_TOKEN gesetzt ist
8283
MS_GRAPH_CLIENT_SECRET /
8384
MS_GRAPH_SENDER_EMAIL
85+
DISPATCH_ADMIN_AUTH_SECRET # HMAC-Schlüssel für Admin-API JWT-Auth
8486
```
8587

8688
### Optional
@@ -161,26 +163,26 @@ devbox run sonar # Coverage erzeugen + SonarQube-Scan
161163

162164
| Metrik | Wert |
163165
|--------|------|
164-
| Unit-Tests | 97 |
165-
| Statement Coverage (getestete Packages) | 84 – 100 % |
166+
| Unit-Tests | 112 |
166167
| Mutation Score (alle Core-Packages) | 100 % Efficacy |
167168
| Mutation Score Threshold | ≥ 70 % (efficacy + mutation-coverage) |
168169
| SonarQube Quality Gate | PASSED |
169170

170-
**Coverage pro Package:**
171-
172-
| Package | Coverage |
173-
|---------|---------|
174-
| `internal/config` | 96 % |
175-
| `internal/domain` | 100 % |
176-
| `internal/gateway` | 95 % |
177-
| `internal/hash` | 100 % |
178-
| `internal/msgraph` | 88 % |
179-
| `internal/pii` | 100 % |
180-
| `internal/quota` | 92 % |
181-
| `internal/sender` | 95 % |
182-
| `internal/spam` | 88 % |
183-
| `internal/worker` | 84 % |
171+
**Coverage pro Package** (Unit-Tests, kein NATS/Docker):
172+
173+
| Package | Coverage | Anmerkung |
174+
|---------|---------|-----------|
175+
| `internal/admin` | 13 % | Resolver erfordert NATS; `auth.go` 93 % |
176+
| `internal/config` | 98 % | |
177+
| `internal/domain` | 100 % | |
178+
| `internal/gateway` | 75 % | `AttachmentStore.Upload` nur via Integration |
179+
| `internal/hash` | 100 % | |
180+
| `internal/msgraph` | 46 % | `Service.SendEmail` nur via Integration |
181+
| `internal/pii` | 100 % | |
182+
| `internal/quota` | 89 % | |
183+
| `internal/sender` | 92 % | |
184+
| `internal/spam` | 78 % | |
185+
| `internal/worker` | 55 % | Consumer/AttachStore nur via Integration |
184186

185187
Mutation-Tests laufen mit [gremlins](https://github.com/go-gremlins/gremlins) (`go tool gremlins unleash`) auf den Packages `internal/gateway`, `internal/quota`, `internal/spam`, `internal/worker`, `internal/pii`, `internal/hash` und `internal/msgraph`. Die Schwellwerte sind in [`.gremlins.yaml`](.gremlins.yaml) hinterlegt.
186188

@@ -219,6 +221,7 @@ Content-Type: application/json
219221
|--------|-----------|
220222
| `202` | Nachricht an NATS übergeben |
221223
| `400` | Validierungsfehler (Pflichtfelder, Domain, Spam, MIME) |
224+
| `413` | Request-Body überschreitet Größenlimit (`DISPATCH_VALIDATION_MAX_BODY_SIZE`) |
222225
| `429` | Tages-Quota überschritten (`X-RateLimit-Limit`, `X-RateLimit-Remaining`) |
223226
| `503` | NATS nicht erreichbar, Quota-State-Fehler oder Attachment-Upload fehlgeschlagen |
224227

@@ -232,6 +235,12 @@ GET /health/ready → 200
232235

233236
### Admin GraphQL
234237

238+
Alle Requests an `/graphql` erfordern einen gültigen JWT im Header:
239+
```
240+
Authorization: Bearer <token>
241+
```
242+
Token: HMAC-SHA256, signiert mit `DISPATCH_ADMIN_AUTH_SECRET`, `exp`-Claim erforderlich.
243+
235244
```
236245
POST /graphql
237246

0 commit comments

Comments
 (0)