Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 41 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# Fluxora Backend

Express + TypeScript API for the Fluxora treasury streaming protocol. Today this repository exposes a minimal HTTP surface for stream CRUD and health checks. For Issue 54, the service now defines a concrete indexer-stall health classification plus an inline incident runbook so operators can reason about stale chain-derived state without relying on tribal knowledge.
Express + TypeScript API for the Fluxora treasury streaming protocol. This service implements **API Versioning (/v1)** and a formal **Deprecation Policy** to ensure operator-grade reliability and predictable client transitions.

## Decimal String Serialization Policy

Expand Down Expand Up @@ -57,10 +55,38 @@ Decimal validation failed {"field":"depositAmount","errorCode":"DECIMAL_INVALID_

#### Health Observability

- `GET /health` - Returns service health status
- Request IDs enable correlation across logs
- `GET /v1/health` - Basic health check
- `GET /v1/health/ready` - Readiness probe (for Kubernetes/Load Balancers)
- `GET /v1/health/live` - Liveness probe
- Request IDs (`x-correlation-id`) enable correlation across logs
- Structured JSON logs for log aggregation systems

## API Versioning & Deprecation Policy

### Versioning Scheme
The API follows a URL-based versioning scheme: `/v[N]`.
- Existing production version: `/v1`
- All new features and breaking changes are introduced in a new version increment.

### Deprecation Policy
- **Support Window**: `vN` is supported until `vN+2` is released or for 12 months, whichever is later.
- **Headers**: Deprecated endpoints return a `Deprecation: true` header and a `Link` header pointing to the successor.
- **Transitions**: The `/api` legacy namespace is aliased to `/v1` but marked as deprecated.

### Error Envelope Standards
All errors (4xx/5xx) return a consistent JSON payload:
```json
{
"error": {
"code": "API_ERROR_CODE",
"message": "Human readable message",
"status": 400,
"requestId": "uuid-v4",
"details": { "..." }
}
}
```

#### Verification Commands

```bash
Expand Down Expand Up @@ -131,13 +157,16 @@ API runs at [http://localhost:3000](http://localhost:3000).

## API overview

| Method | Path | Description |
| ------ | ------------------ | -------------------------------------------------------------------------------- |
| GET | `/` | API info |
| GET | `/health` | Health check |
| GET | `/api/streams` | List streams |
| GET | `/api/streams/:id` | Get one stream |
| POST | `/api/streams` | Create stream (body: sender, recipient, depositAmount, ratePerSecond, startTime) |
| Method | Path | Description |
| ------ | ---------------- | ------------------------------------------------------------------------------ |
| GET | `/` | API Discovery & Discovery |
| GET | `/v1/health` | Health check |
| GET | `/v1/streams` | List streams |
| GET | `/v1/streams/:id`| Get one stream |
| POST | `/v1/streams` | Create stream (body: sender, recipient, depositAmount, ratePerSecond, startTime) |

> [!NOTE]
> Legacy paths like `/api/streams` are deprecated and will be removed in a future release. Please migrate to `/v1/streams`.

Contract guarantees for this area:

Expand Down
22 changes: 10 additions & 12 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@ export default {
testEnvironment: 'node',
roots: ['<rootDir>/src'],
testMatch: ['**/*.test.ts'],
moduleFileExtensions: ['ts', 'js'],
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.test.ts',
'!src/index.ts',
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
},
extensionsToTreatAsEsm: ['.ts'],
transform: {
'^.+\\.tsx?$': [
'ts-jest',
{
useESM: true,
},
],
},
};
3 changes: 3 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,20 @@
"type": "module",
"scripts": {
"build": "tsc",
"test": "node --import tsx --test src/**/*.test.ts",
"start": "node dist/index.js",
"dev": "tsx watch src/index.ts",
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
"test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch"
"test": "tsx --test src/**/*.test.ts src/v1.test.ts",
"test:watch": "tsx --test --watch src/**/*.test.ts src/v1.test.ts",
"test:v1": "tsx --test src/v1.test.ts"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@types/express": "^4.17.21",
"@types/express-serve-static-core": "^4.19.8",
"@types/jest": "^29.5.12",
"@types/node": "^20.11.16",
"@types/serve-static": "^1.15.10",
"@types/supertest": "^6.0.2",
"jest": "^29.7.0",
"supertest": "^6.3.4",
Expand All @@ -29,7 +28,9 @@
},
"jest": {
"preset": "ts-jest/presets/default-esm",
"extensionsToTreatAsEsm": [".ts"],
"extensionsToTreatAsEsm": [
".ts"
],
"moduleNameMapper": {
"^(\\.{1,2}/.*)\\.js$": "$1"
},
Expand Down
Loading