You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,6 +22,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
22
22
- Docker healthcheck now honors the runtime `PORT` environment variable.
23
23
- Versioned `/api/v1/*` endpoints with `{ data, meta }` response envelopes, cache metadata, and structured error bodies.
24
24
25
+
### Changed
26
+
27
+
- Split GNews-specific provider mapping and payload validation into a provider adapter, leaving the news service focused on cache/search orchestration.
28
+
25
29
### Security
26
30
27
31
- Refreshed the dependency lockfile and upgraded OpenTelemetry packages; `npm audit --omit=dev` reports zero vulnerabilities.
1.**Process** — `dotenv` loads first; **`otel-bootstrap`** starts OpenTelemetry when an OTLP endpoint (or `OTEL_TRACING_ENABLED=1`) is configured, before Express loads so HTTP is instrumented.
16
17
2.**Express** (`src/app.ts`) applies middleware in order: trust-proxy (optional), **Pino** request logging, **metrics** observer, **Helmet**, JSON body parser, **rate limiting** (skips `/health`, `/ready`, `/openapi.yaml`, `/metrics`), then mounts `/api` routes.
17
18
3.**Controllers** validate query parameters and map domain results to HTTP status codes.
18
-
4.**News service** builds cache keys from normalized search parameters (`query`, `count`, `lang`, `country`, `from`, `to`, `sortBy`), reads through `getCacheStore()` (in-memory or **Redis** when `REDIS_URL` is set), coalesces identical in-flight misses per process, and otherwise calls GNews `/api/v4/search` via `axios`. Cache backend errors are logged and metriced without failing the article request.
19
+
4.**News service** builds cache keys from normalized search parameters (`query`, `count`, `lang`, `country`, `from`, `to`, `sortBy`), reads through `getCacheStore()` (in-memory or **Redis** when `REDIS_URL` is set), coalesces identical in-flight misses per process, and delegates upstream fetches to the GNews provider adapter. Cache backend errors are logged and metriced without failing the article request.
19
20
5.**Response mapping** keeps legacy `/api/articles*` endpoints backward compatible with raw arrays, while `/api/v1/*` returns `{ data, meta }` envelopes with `requestId`, normalized filters, and cache status.
20
21
6.**Title** and **source** endpoints reuse the search call, then narrow results in memory (exact title match; case-insensitive source name match).
21
22
@@ -41,8 +42,8 @@ sequenceDiagram
41
42
Cache-->>Svc: articles
42
43
else miss (read fail falls through here too)
43
44
Svc->>Svc: coalesce identical in-flight misses
44
-
Svc->>GNews: GET /api/v4/search (timeout)
45
-
GNews-->>Svc: articles (502 on provider/transport error)
45
+
Svc->>GNews: provider adapter: GET /api/v4/search (timeout)
46
+
GNews-->>Svc: normalized articles (502 on provider/transport error)
0 commit comments