feat: notification service

This commit is contained in:
Ilia Denisov
2026-04-22 08:49:45 +02:00
committed by GitHub
parent 5b7593e6f6
commit 32dc29359a
135 changed files with 21828 additions and 130 deletions
@@ -0,0 +1,71 @@
package notification
import (
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
)
var expectedNotificationPushPublicationDocumentationSnippets = []string{
"one long-lived `push` route publisher",
"the `push` publisher claims only routes whose `route_id` starts with `push:`",
"`Gateway` publication uses `XADD MAXLEN ~` with `NOTIFICATION_GATEWAY_CLIENT_EVENTS_STREAM_MAX_LEN`",
"`event_id` equals `<notification_id>/<route_id>`",
"`device_session_id` is intentionally omitted so `Gateway` fans the event out to every active stream of that user",
}
var expectedNotificationMailPublicationDocumentationSnippets = []string{
"one long-lived `email` route publisher",
"template-mode `email` publication toward `Mail Service`",
"`Mail Service` publication uses plain `XADD` with no stream trimming",
"`delivery_id` equals `<notification_id>/<route_id>`",
"`idempotency_key` equals `notification:<notification_id>/<route_id>`",
"`requested_at_ms` equals `accepted_at_ms`",
"`payload_json.to` contains exactly one resolved recipient email",
"`payload_json.cc`, `payload_json.bcc`, `payload_json.reply_to`, and `payload_json.attachments` are empty arrays in v1",
"`email` publication failures are classified minimally as `payload_encoding_failed` and `mail_stream_publish_failed`",
}
func TestNotificationRoutePublicationDocsStayInSync(t *testing.T) {
t.Parallel()
readme := loadTextFile(t, "README.md")
flowsDoc := loadTextFile(t, filepath.Join("docs", "flows.md"))
runtimeDoc := loadTextFile(t, filepath.Join("docs", "runtime.md"))
docsIndex := loadTextFile(t, filepath.Join("docs", "README.md"))
mailReadme := loadTextFile(t, filepath.Join("..", "mail", "README.md"))
mailAsyncAPI := loadTextFile(t, filepath.Join("..", "mail", "api", "delivery-commands-asyncapi.yaml"))
normalizedReadme := normalizeWhitespace(readme)
normalizedFlowsDoc := normalizeWhitespace(flowsDoc)
normalizedRuntimeDoc := normalizeWhitespace(runtimeDoc)
normalizedMailReadme := normalizeWhitespace(mailReadme)
require.Contains(t, docsIndex, "- [Main flows](flows.md)")
require.Contains(t, docsIndex, "- [Runtime and components](runtime.md)")
for _, snippet := range expectedNotificationPushPublicationDocumentationSnippets {
normalizedSnippet := normalizeWhitespace(snippet)
require.Contains(t, normalizedReadme, normalizedSnippet)
}
for _, snippet := range expectedNotificationMailPublicationDocumentationSnippets {
normalizedSnippet := normalizeWhitespace(snippet)
require.Contains(t, normalizedReadme, normalizedSnippet)
}
require.Contains(t, normalizedRuntimeDoc, normalizeWhitespace("processes only scheduled route IDs beginning with `push:`"))
require.Contains(t, normalizedRuntimeDoc, normalizeWhitespace("processes only scheduled route IDs beginning with `email:`"))
require.Contains(t, normalizedFlowsDoc, normalizeWhitespace("XADD MAXLEN ~ gateway client-event stream"))
require.Contains(t, normalizedFlowsDoc, normalizeWhitespace("XADD mail:delivery_commands"))
require.Contains(t, normalizedFlowsDoc, normalizeWhitespace("`payload_mode=template`"))
require.Contains(t, normalizedReadme, normalizeWhitespace("`notification:route_leases:<notification_id>:<route_id>`"))
require.Contains(t, normalizedReadme, normalizeWhitespace("`payload_encoding_failed`"))
require.Contains(t, normalizedReadme, normalizeWhitespace("`gateway_stream_publish_failed`"))
require.Contains(t, normalizedReadme, normalizeWhitespace("`mail_stream_publish_failed`"))
require.Contains(t, normalizedMailReadme, normalizeWhitespace("- `requested_at_ms`"))
require.Contains(t, normalizedMailReadme, normalizeWhitespace("`requested_at_ms` stores the publisher-side original request timestamp"))
require.Contains(t, mailAsyncAPI, "requested_at_ms:")
require.Contains(t, mailAsyncAPI, "payload_mode:")
}