docs: update README files for core packages with architecture diagrams and usage examples

This commit is contained in:
Firman Ramdhani
2026-05-28 12:20:53 +07:00
parent df229c9984
commit c510feadbb
4 changed files with 255 additions and 87 deletions
+69 -55
View File
@@ -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` |