docs: update README files for core packages with architecture diagrams and usage examples
This commit is contained in:
+69
-55
@@ -1,65 +1,79 @@
|
||||
# @repo/core-api
|
||||
# Enterprise API Engine (`@repo/core-api`)
|
||||
|
||||
The platform-agnostic API engine for the monorepo. Provides an isolated HTTP client factory, a unified observability pipeline (Grafana Faro + OpenTelemetry), and a generic data services engine — consumed by `apps/web`, `apps/landing`, and any future workspace.
|
||||
[← Back to Root](../../README.md)
|
||||
|
||||
---
|
||||
The platform-agnostic API engine for the monorepo. Provides an isolated HTTP client factory, a unified observability pipeline (Grafana Faro + OpenTelemetry), and a generic data services engine.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Architecture Overview](#architecture-overview)
|
||||
- [HTTP Client](#http-client)
|
||||
- [Observability](#observability)
|
||||
- [Data Services](#data-services)
|
||||
- [Application Setup Guide](#application-setup-guide)
|
||||
- [Per-Request Telemetry (Escape Hatch)](#per-request-telemetry-escape-hatch)
|
||||
- [Error Handling](#error-handling)
|
||||
- [Package Exports](#package-exports)
|
||||
**This package enforces App Autonomy (IoC).** The core provides the engine and interceptor pipelines, but the consuming applications (`apps/web`, `apps/landing`) inject their own specific configurations, authentication tokens, and error handling behaviors.
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────────┐
|
||||
│ @repo/core-api │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌───────────────────┐ ┌───────────────────┐ │
|
||||
│ │ http-client │ │ observability │ │ data-services │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ createHttp │◄──│ faroAdapter │ │ BaseRemoteData │ │
|
||||
│ │ Client() │ │ initTelemetry() │ │ Services │ │
|
||||
│ │ │ │ getFaro() │ │ CommonRemoteData │ │
|
||||
│ │ ApiResponse │ │ noopAdapter │ │ Services │ │
|
||||
│ └──────┬───────┘ └───────────────────┘ └────────┬──────────┘ │
|
||||
│ │ │ │
|
||||
│ └────────────────────┬───────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌────────┴────────┐ │
|
||||
│ │ errors │ │
|
||||
│ │ ApiError │ │
|
||||
│ │ ErrorCodes │ │
|
||||
│ └─────────────────┘ │
|
||||
└────────────────────────────────────────────────────────────────────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
apps/web apps/landing apps/desktop
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph Apps ["apps/* (App Autonomy)"]
|
||||
WEB[apps/web]
|
||||
LAND[apps/landing]
|
||||
DESK[apps/desktop]
|
||||
end
|
||||
|
||||
subgraph Core ["@repo/core-api (Engine)"]
|
||||
subgraph HTTP ["http-client"]
|
||||
FACTORY[createHttpClient]
|
||||
end
|
||||
subgraph OBS ["observability"]
|
||||
FARO[faroAdapter]
|
||||
end
|
||||
subgraph DATA ["data-services"]
|
||||
BASE[BaseRemoteDataServices]
|
||||
COMMON[CommonRemoteDataServices]
|
||||
end
|
||||
subgraph ERRORS ["errors"]
|
||||
API_ERR[ApiError]
|
||||
end
|
||||
end
|
||||
|
||||
WEB & LAND & DESK -->|instantiates| FACTORY
|
||||
WEB & LAND & DESK -->|extends| COMMON
|
||||
COMMON -->|executes via| FACTORY
|
||||
FACTORY -.->|reports via| FARO
|
||||
FACTORY -.->|throws| API_ERR
|
||||
|
||||
style Core fill:#f8f9fa,stroke:#ced4da
|
||||
style Apps fill:#e9ecef,stroke:#adb5bd
|
||||
```
|
||||
|
||||
### Data Flow
|
||||
### Data Flow Lifecycle
|
||||
|
||||
Every HTTP request flows through this pipeline:
|
||||
Every HTTP request flows through this precise interceptor pipeline:
|
||||
|
||||
```
|
||||
Component → DataService.getMany() → execute()
|
||||
→ httpClient.request()
|
||||
→ Request Interceptor:
|
||||
1. faroAdapter.onRequestStart() ← Faro log + optional custom span
|
||||
2. hooks.onRequest() ← App-specific (e.g., Bearer token)
|
||||
→ Network (fetch/XHR)
|
||||
→ Response Interceptor:
|
||||
SUCCESS: faroAdapter.onRequestEnd() → hooks.onResponse()
|
||||
ERROR: faroAdapter.onRequestError() → hooks.onResponseError()
|
||||
→ ApiError.fromAxiosError()
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as UI Component
|
||||
participant S as Data Service
|
||||
participant H as HTTP Client
|
||||
participant F as Faro Adapter
|
||||
participant A as App Hooks (IoC)
|
||||
participant N as Network
|
||||
|
||||
C->>S: getMany()
|
||||
S->>H: request()
|
||||
H->>F: onRequestStart() (Log + Span)
|
||||
H->>A: hooks.onRequest() (Inject Token)
|
||||
A->>N: fetch/XHR
|
||||
|
||||
alt Success
|
||||
N-->>A: 200 OK
|
||||
A->>F: onRequestEnd() (Close Span)
|
||||
F->>A: hooks.onResponse()
|
||||
A-->>S: return data
|
||||
else Error
|
||||
N-->>A: 401 / 500
|
||||
A->>F: onRequestError() (Log Error)
|
||||
F->>A: hooks.onResponseError() (Redirect/Refresh)
|
||||
A-->>S: throw ApiError
|
||||
end
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
@@ -143,10 +157,10 @@ import { initTelemetry } from '@repo/core-api/observability/setup';
|
||||
initTelemetry({
|
||||
appName: 'fe-monorepo-web',
|
||||
appVersion: '1.0.0',
|
||||
telemetryUrl: 'https://telemetry.eigen.co.id/collect',
|
||||
telemetryUrl: '[https://telemetry.eigen.co.id/collect](https://telemetry.eigen.co.id/collect)',
|
||||
environment: 'production',
|
||||
// Optional: direct OTLP export to Grafana Tempo
|
||||
otlpTraceUrl: 'https://telemetry.eigen.co.id/v1/traces',
|
||||
otlpTraceUrl: '[https://telemetry.eigen.co.id/v1/traces](https://telemetry.eigen.co.id/v1/traces)',
|
||||
});
|
||||
```
|
||||
|
||||
@@ -254,8 +268,8 @@ import { initTelemetry } from '@repo/core-api/observability/setup';
|
||||
initTelemetry({
|
||||
appName: import.meta.env.VITE_APP_NAME || 'fe-monorepo-web',
|
||||
appVersion: import.meta.env.VITE_APP_VERSION || '0.0.0',
|
||||
telemetryUrl: import.meta.env.VITE_FARO_URL || 'https://telemetry.eigen.co.id/collect',
|
||||
otlpTraceUrl: import.meta.env.VITE_OTLP_TRACE_URL || 'https://telemetry.eigen.co.id/v1/traces',
|
||||
telemetryUrl: import.meta.env.VITE_FARO_URL || '[https://telemetry.eigen.co.id/collect](https://telemetry.eigen.co.id/collect)',
|
||||
otlpTraceUrl: import.meta.env.VITE_OTLP_TRACE_URL || '[https://telemetry.eigen.co.id/v1/traces](https://telemetry.eigen.co.id/v1/traces)',
|
||||
environment: import.meta.env.VITE_ENV || 'development',
|
||||
});
|
||||
|
||||
@@ -422,4 +436,4 @@ try {
|
||||
| `@repo/core-api/observability` | `faroAdapter`, `noopObservabilityAdapter`, `IObservabilityAdapter`, `initTelemetry`, `getFaro`, `TelemetryConfig` |
|
||||
| `@repo/core-api/observability/setup` | `initTelemetry`, `getFaro`, `TelemetryConfig` |
|
||||
| `@repo/core-api/data-services` | `BaseRemoteDataServices`, `CommonRemoteDataServices`, types, constants |
|
||||
| `@repo/core-api/errors` | `ApiError`, `ApiErrorCode` |
|
||||
| `@repo/core-api/errors` | `ApiError`, `ApiErrorCode` |
|
||||
Reference in New Issue
Block a user