|
@@ -7,7 +7,7 @@ normalizes them, resolves recipients via `companies` → `groups` →
|
|
|
Telegram, SMS, email, voice, Slack, MS Teams, and arbitrary outbound
|
|
Telegram, SMS, email, voice, Slack, MS Teams, and arbitrary outbound
|
|
|
webhooks.
|
|
webhooks.
|
|
|
|
|
|
|
|
-> **Status**: M0 + M1 + M2 + M3 + M4 + M5 **shipped** 2026-06-14. M0 is the
|
|
|
|
|
|
|
+> **Status**: M0 + M1 + M2 + M3 + M4 + M5 + M6 **shipped** 2026-06-14. M0 is the
|
|
|
> single-host docker-compose stack + 4 Go services + loadgen-http
|
|
> single-host docker-compose stack + 4 Go services + loadgen-http
|
|
|
> + alert schema. M1 is the end-to-end: signed webhook → broker →
|
|
> + alert schema. M1 is the end-to-end: signed webhook → broker →
|
|
|
> router → deliverd-fcm → fakefcmd (live-verified, 1530 deliveries
|
|
> router → deliverd-fcm → fakefcmd (live-verified, 1530 deliveries
|
|
@@ -25,11 +25,17 @@ webhooks.
|
|
|
> 12 deliveries in 5-step smoke with 0 failures). M5 is
|
|
> 12 deliveries in 5-step smoke with 0 failures). M5 is
|
|
|
> WebSocket ingest (`GET /v1/ingest/ws` with `{api_key}` auth
|
|
> WebSocket ingest (`GET /v1/ingest/ws` with `{api_key}` auth
|
|
|
> frame, 35-conn load test, per-IP cap 32) + live tail
|
|
> frame, 35-conn load test, per-IP cap 32) + live tail
|
|
|
-> (`GET /v1/tail/ws?token=...&company_id=...` for operators,
|
|
|
|
|
|
|
+> (`GET /v1/tail/ws?token=***&company_id=...` for operators,
|
|
|
> in-process pub/sub fan-out, 13/13 checks green across 3
|
|
> in-process pub/sub fan-out, 13/13 checks green across 3
|
|
|
-> consecutive smoke runs).
|
|
|
|
|
-> See `M0_VERIFICATION.md` … `M5_VERIFICATION.md` and
|
|
|
|
|
-> `M1_SMOKE_LOG.md` … `M5_SMOKE_LOG.md` for the smoke tests.
|
|
|
|
|
|
|
+> consecutive smoke runs). M6 is dedupe + ×N display
|
|
|
|
|
+> (sliding-window TTL via single Lua script, default 300s;
|
|
|
|
|
+> dedupe runs before rate limit so duplicates are "free";
|
|
|
|
|
+> recipient sees `(×N)` inline suffix on the title;
|
|
|
|
|
+> per-source `dedupe_collapsed_total` and
|
|
|
|
|
+> `dedupe_count_max_observed` metrics, 11/11 checks green
|
|
|
|
|
+> across 3 consecutive smoke runs).
|
|
|
|
|
+> See `M0_VERIFICATION.md` … `M6_VERIFICATION.md` and
|
|
|
|
|
+> `M1_SMOKE_LOG.md` … `M6_SMOKE_LOG.md` for the smoke tests.
|
|
|
> Spec is in `SPEC.md`, diagrams in `ARCHITECTURE.md`, build log
|
|
> Spec is in `SPEC.md`, diagrams in `ARCHITECTURE.md`, build log
|
|
|
> in `PROMPT.md`.
|
|
> in `PROMPT.md`.
|
|
|
|
|
|
|
@@ -45,8 +51,8 @@ Compose, 50k/sec design ceiling for v2 K8s.
|
|
|
## Repo layout
|
|
## Repo layout
|
|
|
|
|
|
|
|
```
|
|
```
|
|
|
-SPEC.md — requirements, entities, severity, retention
|
|
|
|
|
-ARCHITECTURE.md — diagrams, sequences, SLOs, capacity model
|
|
|
|
|
|
|
+SPEC.md - requirements, entities, severity, retention
|
|
|
|
|
+ARCHITECTURE.md - diagrams, sequences, SLOs, capacity model
|
|
|
PROMPT.md — build log, decisions, open questions
|
|
PROMPT.md — build log, decisions, open questions
|
|
|
M0_VERIFICATION.md — M0 smoke test (signed webhook → 202)
|
|
M0_VERIFICATION.md — M0 smoke test (signed webhook → 202)
|
|
|
M1_VERIFICATION.md — M1 smoke test (end-to-end → fakefcmd)
|
|
M1_VERIFICATION.md — M1 smoke test (end-to-end → fakefcmd)
|
|
@@ -54,37 +60,39 @@ M2_VERIFICATION.md — M2 smoke test (recipient resolution)
|
|
|
M3_VERIFICATION.md — M3 smoke test (Telegram delivery + bot)
|
|
M3_VERIFICATION.md — M3 smoke test (Telegram delivery + bot)
|
|
|
M4_VERIFICATION.md — M4 smoke test (MQTT ingest + EMQX ACL)
|
|
M4_VERIFICATION.md — M4 smoke test (MQTT ingest + EMQX ACL)
|
|
|
M5_VERIFICATION.md — M5 smoke test (WS ingest + live tail + per-IP cap)
|
|
M5_VERIFICATION.md — M5 smoke test (WS ingest + live tail + per-IP cap)
|
|
|
|
|
+M6_VERIFICATION.md — M6 smoke test (dedupe + ×N + sliding TTL + free-for-dupes)
|
|
|
M1_SMOKE_LOG.md — M1 live run results
|
|
M1_SMOKE_LOG.md — M1 live run results
|
|
|
M2_SMOKE_LOG.md — M2 live run results
|
|
M2_SMOKE_LOG.md — M2 live run results
|
|
|
M3_SMOKE_LOG.md — M3 live run results
|
|
M3_SMOKE_LOG.md — M3 live run results
|
|
|
M4_SMOKE_LOG.md — M4 live run results
|
|
M4_SMOKE_LOG.md — M4 live run results
|
|
|
M5_SMOKE_LOG.md — M5 live run results (3 consecutive green)
|
|
M5_SMOKE_LOG.md — M5 live run results (3 consecutive green)
|
|
|
-docker-compose.yml — single-host M0–M5 stack
|
|
|
|
|
|
|
+M6_SMOKE_LOG.md — M6 live run results (3 consecutive green)
|
|
|
|
|
+docker-compose.yml — single-host M0–M6 stack
|
|
|
Dockerfile — multi-stage build for all 7 binaries
|
|
Dockerfile — multi-stage build for all 7 binaries
|
|
|
.env.example — every BA_* knob documented
|
|
.env.example — every BA_* knob documented
|
|
|
-cmd/ingestd/ — HTTP POST handler (M0) + MQTT subscriber (M4) + WS ingest (M5); M11 = TLS
|
|
|
|
|
-cmd/routerd/ — M2 rules engine + M3 channel union
|
|
|
|
|
-cmd/deliverd-fcm/ — M1 FCM HTTP v1 delivery (renamed from deliverd M3)
|
|
|
|
|
-cmd/deliverd-telegram/ — M3 Telegram Bot API delivery
|
|
|
|
|
-cmd/telegramd/ — M3 long-polling bot loop + command handler
|
|
|
|
|
-cmd/admind/ — scaffold + /v1/ping (M8)
|
|
|
|
|
-loadgen/cmd/http/ — HTTP traffic generator (M0)
|
|
|
|
|
-loadgen/cmd/mqtt/ — MQTT traffic generator (M4)
|
|
|
|
|
-loadgen/cmd/ws/ — WebSocket traffic generator (M5)
|
|
|
|
|
-internal/alert/ — Alert v1 type + Validate() + Severity.Rank
|
|
|
|
|
-internal/broker/ — NATS JetStream wrapper
|
|
|
|
|
-internal/config/ — env-driven config
|
|
|
|
|
-internal/dedupe/ — 60s SET NX EX + INCR
|
|
|
|
|
-internal/ratelimit/ — per-second INCR bucket
|
|
|
|
|
-internal/httpserver/ — /health + /metrics scaffold
|
|
|
|
|
-internal/observability/ — slog + Prometheus
|
|
|
|
|
-internal/postgres/ — pgxpool wrapper
|
|
|
|
|
-internal/routing/ — Resolver (M2 rules engine, M3 channel union)
|
|
|
|
|
-internal/telegram/ — BotClient + command parser + handler
|
|
|
|
|
-internal/store/ — Redis + (later) Postgres
|
|
|
|
|
-deploy/prometheus/ — prometheus.yml
|
|
|
|
|
-migrations/ — 001–004 + seed/seed_m2/seed_m3.sql
|
|
|
|
|
-testfakes/ — fakefcmd (M1), faketgmd (M3)
|
|
|
|
|
|
|
+cmd/ingestd/ — HTTP POST handler (M0) + MQTT subscriber (M4) + WS ingest (M5) + dedupe before rate limit (M6); M11 = TLS
|
|
|
|
|
+cmd/routerd/ - M2 rules engine + M3 channel union
|
|
|
|
|
+cmd/deliverd-fcm/ - M1 FCM HTTP v1 delivery (renamed from deliverd M3)
|
|
|
|
|
+cmd/deliverd-telegram/ - M3 Telegram Bot API delivery
|
|
|
|
|
+cmd/telegramd/ - M3 long-polling bot loop + command handler
|
|
|
|
|
+cmd/admind/ - scaffold + /v1/ping (M8)
|
|
|
|
|
+loadgen/cmd/http/ - HTTP traffic generator (M0)
|
|
|
|
|
+loadgen/cmd/mqtt/ - MQTT traffic generator (M4)
|
|
|
|
|
+loadgen/cmd/ws/ - WebSocket traffic generator (M5)
|
|
|
|
|
+internal/alert/ - Alert v1 type + Validate() + Severity.Rank
|
|
|
|
|
+internal/broker/ - NATS JetStream wrapper
|
|
|
|
|
+internal/config/ - env-driven config
|
|
|
|
|
+internal/dedupe/ - 60s SET NX EX + INCR
|
|
|
|
|
+internal/ratelimit/ - per-second INCR bucket
|
|
|
|
|
+internal/httpserver/ - /health + /metrics scaffold
|
|
|
|
|
+internal/observability/ - slog + Prometheus
|
|
|
|
|
+internal/postgres/ - pgxpool wrapper
|
|
|
|
|
+internal/routing/ - Resolver (M2 rules engine, M3 channel union)
|
|
|
|
|
+internal/telegram/ - BotClient + command parser + handler
|
|
|
|
|
+internal/store/ - Redis + (later) Postgres
|
|
|
|
|
+deploy/prometheus/ - prometheus.yml
|
|
|
|
|
+migrations/ - 001-004 + seed/seed_m2/seed_m3.sql
|
|
|
|
|
+testfakes/ - fakefcmd (M1), faketgmd (M3)
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
## License
|
|
## License
|