refinement phase 9
This commit is contained in:
@@ -15,6 +15,15 @@ is invented; "not needed" claims are backed by the absence of the package/code.
|
||||
> and flipping the selector turns each on, no code change. What is still genuinely absent (no adapter): **Redis**
|
||||
> (5), **Elasticsearch** (17), and the LLM **review-moderation classifier** (15, optional). MoH/INO/eNamad (16)
|
||||
> stay **manual by design**. See the mocks-registry refinement-phase-8 banner for the provider tokens per rail.
|
||||
>
|
||||
> **Refinement-phase-9 update (2026-07-13) — observability (service 4):** the two overlapping metric stacks were
|
||||
> consolidated onto **one OpenTelemetry stack** — prometheus-net was removed; metrics are scraped at `/metrics` via
|
||||
> the OTel Prometheus exporter, and **distributed tracing** (ASP.NET Core + EF Core) was added, exporting **OTLP
|
||||
> only when `OpenTelemetry:Otlp:Endpoint` is configured** (an MVP with Prometheus alone is unchanged). A request's
|
||||
> `ApiResult.requestId` is its W3C trace id (support ↔ trace 1:1). Health checks split into `/healthz/live`
|
||||
> (process) vs `/healthz/ready` (app DB + log DB [deployed] + an object-storage write probe); `/HealthCheck` stays
|
||||
> as the aggregate. An **OTLP collector** (Grafana Tempo / Jaeger / OTEL Collector) becomes the optional new
|
||||
> observability service when trace export is turned on. Elasticsearch (17) is still deferred.
|
||||
|
||||
## Service inventory
|
||||
|
||||
@@ -23,7 +32,7 @@ is invented; "not needed" claims are backed by the absence of the package/code.
|
||||
| 1 | **SQL Server** (app DB `Baya`) | System of record — 12 schemas (`usr ops geo catalog verif search booking payments payouts reviews messaging partner`) | EF Core; `ConnectionStrings:SqlServer` | **Required now** | — |
|
||||
| 2 | **SQL Server** (log DB `Baya_Logs`) | Serilog sink in deployed envs (Warning+, auto-created `log.LogEvents`) | `ConnectionStrings:logDb` | **Required now** (deployed) | — |
|
||||
| 3 | **Reverse proxy / TLS** (nginx·caddy·traefik) | TLS termination, HTTP/1.1+2, forwarded headers | Kestrel config; JWE bearer | **Required now** | — |
|
||||
| 4 | **Prometheus** (+ Grafana) | Scrapes `/metrics`; health forwarded to gauges | `UseMetricServer` + OTel exporter | **Recommended now** | — |
|
||||
| 4 | **Prometheus** (+ Grafana) · optional **OTLP collector** | Scrapes `/metrics` (one OTel stack, refinement-phase-9); traces export OTLP when configured | OTel metrics + tracing; `OpenTelemetry:Otlp:Endpoint` | **Recommended now** (collector optional) | — |
|
||||
| 5 | **Redis** | `ICacheService` + `IDistributedLock` (money-path mutex) | `Seams:*` (keys TBD; none today) | Before >1 API instance | rows 14, 42 |
|
||||
| 6 | **MinIO / S3 / ArvanCloud** | `IObjectStorage` — verification docs, avatars (REQ-006), invoice PDFs | `Seams:ObjectStorage:*` | Before real verification | row 13 |
|
||||
| 7 | **Job scheduler** — in-process, SQL only (refinement-phase-7 **done**) | The recurring crons: booking-expiry, notification-retention, credential-expiry scan, no-show sweep, weekly payout-batch generation (Moadian/refund-settlement poll = Phase 8) | `RecurringJobSchedulerHostedService` + `IRecurringJob`s | **Done for single instance** (no new infra) | row 26 |
|
||||
@@ -133,8 +142,9 @@ flowchart LR
|
||||
Both DBs fit one instance; `Baya_Logs` can move later.
|
||||
- **Config:** `ConnectionStrings:SqlServer`, `ConnectionStrings:logDb` — **rotate + externalize first**
|
||||
(plan §1.1; live `sa` credentials are committed today).
|
||||
- **Health/readiness:** the app's only health check (`/HealthCheck`,
|
||||
`Monitoring/Configurations/HealthCheckConfigurations.cs:17`); `logDb` has none (plan §7.2). Boot runs
|
||||
- **Health/readiness (refinement-phase-9 — §7.2 landed):** split `/healthz/live` (process) vs `/healthz/ready`
|
||||
(app DB + `logDb` [deployed] + object-storage write probe); `/HealthCheck` stays as the aggregate
|
||||
(`Monitoring/Configurations/HealthCheckConfigurations.cs`). Boot runs
|
||||
`MigrateAsync` + 3 seeders (`Program.cs:99-104`) → the login needs DDL rights and concurrent multi-node
|
||||
boot races (plan §4.3).
|
||||
|
||||
@@ -149,13 +159,16 @@ flowchart LR
|
||||
- **Default:** caddy 2 / nginx 1.27; terminate TLS, h2 to clients, HTTP/1.1 (or h2c) upstream once §1.5
|
||||
lands.
|
||||
|
||||
### 4 · Prometheus (+ Grafana)
|
||||
### 4 · Prometheus (+ Grafana) · optional OTLP collector
|
||||
|
||||
- **Evidence:** `/metrics` via prometheus-net `UseMetricServer` + OTel `AddPrometheusExporter` (two stacks —
|
||||
consolidate, plan §7.1) at `Monitoring/Configurations/PrometheusMetricsConfigurations.cs:11` and
|
||||
`OpenTelemetryConfigurations.cs:21`; health forwarded (`HealthCheckConfigurations.cs:18`).
|
||||
- **Default:** `prom/prometheus:v2.53` + `grafana/grafana:11`. No tracing backend exists yet (metrics-only);
|
||||
an OTLP collector becomes relevant with plan §7.1.
|
||||
- **Evidence (refinement-phase-9 — §7.1 landed):** **one** OpenTelemetry stack — metrics scraped at `/metrics` via
|
||||
`UseOpenTelemetryPrometheusScrapingEndpoint()` (`Monitoring/Configurations/PrometheusMetricsConfigurations.cs`),
|
||||
plus `WithTracing` (ASP.NET Core + EF Core) exporting **OTLP only when `OpenTelemetry:Otlp:Endpoint` is set**
|
||||
(`OpenTelemetryConfigurations.cs`). The duplicate prometheus-net stack (`UseMetricServer`/`UseHttpMetrics`/
|
||||
`ForwardToPrometheus` + packages) was removed. A request's `ApiResult.requestId` is its W3C trace id.
|
||||
- **Default:** `prom/prometheus:v2.53` + `grafana/grafana:11`. A **tracing backend / OTLP collector** (Grafana
|
||||
Tempo · Jaeger · OpenTelemetry Collector) is the optional new service — set `OpenTelemetry:Otlp:Endpoint` at it to
|
||||
turn trace + metric export on; Prometheus-scrape-only is an acceptable MVP.
|
||||
|
||||
### 5 · Redis
|
||||
|
||||
@@ -278,14 +291,16 @@ flowchart LR
|
||||
2. **Environment files:** `appsettings.json` ≡ `appsettings.Development.json` (byte-identical); **no
|
||||
Production/Staging file exists.** All non-secret env differences ride on ~14 `Seams:*` groups whose
|
||||
defaults live in code (`SeamOptions.cs`), not in config files.
|
||||
3. **HTTP posture:** HTTP/2-only Kestrel default (plan §1.5), gRPC plugin + reflection always on
|
||||
(plan §7.5), TLS required for JWE sanity.
|
||||
3. **HTTP posture:** mixed `Http1AndHttp2` Kestrel (refinement-phase-5), so gRPC shares the listener via ALPN;
|
||||
gRPC **reflection is Development-only** (refinement-phase-9 §7.5); TLS required for JWE sanity.
|
||||
4. **Single-instance constraints today:** in-memory cache, in-proc money lock, the in-proc recurring-job
|
||||
scheduler (refinement-phase-7 — its per-tick lock is that same in-proc seam), per-instance rate-limit buckets.
|
||||
§4.3 (migrations split from boot) **landed**; scaling past one instance still requires §4.2 (Redis for the
|
||||
shared cache + the cross-instance lock the scheduler/money path use) first — the DB uniques keep money
|
||||
*correct* either way, but locks/cache/limits/scheduler-de-dup silently degrade.
|
||||
5. **Logs:** deployed envs write Warning+ to `Baya_Logs` only (Information dropped — plan §7.3); dev writes
|
||||
console + `logs/log.json`.
|
||||
5. **Logs (refinement-phase-9 — §7.3 landed):** deployed envs write **Information+** to `Baya_Logs` (framework
|
||||
categories held at Warning); **no PII/secrets** (the OTP code is no longer logged in any env). The dead
|
||||
Elasticsearch sink + package were removed; log-table retention is an ops/DBA task (or ship logs to the OTLP
|
||||
collector). Dev writes console + `logs/log.json`.
|
||||
6. **Client:** the Next.js app needs `NEXT_PUBLIC_API_URL` pointing at the proxy; wire casing camelCase;
|
||||
snake_case routes.
|
||||
|
||||
Reference in New Issue
Block a user