Initial project setup: Add contracts, API definitions, tests, and documentation
- Add Foundry project configuration (foundry.toml, foundry.lock) - Add Solidity contracts (TokenFactory138, BridgeVault138, ComplianceRegistry, etc.) - Add API definitions (OpenAPI, GraphQL, gRPC, AsyncAPI) - Add comprehensive test suite (unit, integration, fuzz, invariants) - Add API services (REST, GraphQL, orchestrator, packet service) - Add documentation (ISO20022 mapping, runbooks, adapter guides) - Add development tools (RBC tool, Swagger UI, mock server) - Update OpenZeppelin submodules to v5.0.0
This commit is contained in:
61
docs/api/error-catalog.md
Normal file
61
docs/api/error-catalog.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Error Catalog
|
||||
|
||||
This document maps Solidity reason codes to HTTP status codes and provides error handling guidance.
|
||||
|
||||
## Reason Code to HTTP Status Mapping
|
||||
|
||||
| Reason Code | HTTP Status | Description |
|
||||
|------------|-------------|-------------|
|
||||
| `OK` | 200 | Operation successful |
|
||||
| `PAUSED` | 503 | Token is paused |
|
||||
| `FROM_FROZEN` | 403 | Source account is frozen |
|
||||
| `TO_FROZEN` | 403 | Destination account is frozen |
|
||||
| `FROM_NOT_COMPLIANT` | 403 | Source account not compliant |
|
||||
| `TO_NOT_COMPLIANT` | 403 | Destination account not compliant |
|
||||
| `LIEN_BLOCK` | 403 | Transfer blocked by active lien (hard freeze mode) |
|
||||
| `INSUFF_FREE_BAL` | 403 | Insufficient free balance (encumbered mode) |
|
||||
| `BRIDGE_ONLY` | 403 | Token in bridge-only mode |
|
||||
| `NOT_ALLOWED_ROUTE` | 403 | Payment rail not allowed |
|
||||
| `UNAUTHORIZED` | 401 | Unauthorized operation |
|
||||
| `CONFIG_ERROR` | 500 | Configuration error |
|
||||
|
||||
## Standard Error Response Format
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "ERROR_CODE",
|
||||
"message": "Human-readable error message",
|
||||
"reasonCode": "PAUSED",
|
||||
"details": {
|
||||
"token": "0x1234...",
|
||||
"account": "0xabcd..."
|
||||
},
|
||||
"requestId": "uuid-here"
|
||||
}
|
||||
```
|
||||
|
||||
## Retry Rules
|
||||
|
||||
### Retryable Errors (5xx)
|
||||
- `500` Internal Server Error - Retry with exponential backoff
|
||||
- `503` Service Unavailable - Retry with exponential backoff
|
||||
- `502` Bad Gateway - Retry with exponential backoff
|
||||
|
||||
### Non-Retryable Errors (4xx)
|
||||
- `400` Bad Request - Do not retry, fix request
|
||||
- `401` Unauthorized - Do not retry, refresh token
|
||||
- `403` Forbidden - Do not retry, check permissions
|
||||
- `404` Not Found - Do not retry, check resource ID
|
||||
- `409` Conflict - Do not retry, check idempotency key
|
||||
|
||||
## Idempotency
|
||||
|
||||
Endpoints marked with `x-idempotency: true` accept an `Idempotency-Key` header. Requests with the same key within 24 hours return the same response without re-executing.
|
||||
|
||||
## Error Handling Best Practices
|
||||
|
||||
1. Always include `reasonCode` in error responses for transfer operations
|
||||
2. Use `requestId` for correlation in logs
|
||||
3. Provide actionable error messages
|
||||
4. Include relevant context in `details` field
|
||||
|
||||
246
docs/api/integration-cookbook.md
Normal file
246
docs/api/integration-cookbook.md
Normal file
@@ -0,0 +1,246 @@
|
||||
# Integration Cookbook
|
||||
|
||||
This document provides step-by-step guides for common integration flows.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Deploy a Token](#deploy-a-token)
|
||||
2. [Place a Lien](#place-a-lien)
|
||||
3. [Submit ISO-20022 Message](#submit-iso-20022-message)
|
||||
4. [Generate and Dispatch Packet](#generate-and-dispatch-packet)
|
||||
5. [Bridge Lock/Unlock](#bridge-lockunlock)
|
||||
|
||||
## Deploy a Token
|
||||
|
||||
### REST API
|
||||
|
||||
```bash
|
||||
POST /v1/tokens
|
||||
Authorization: Bearer <token>
|
||||
Idempotency-Key: <uuid>
|
||||
|
||||
{
|
||||
"name": "USD Wrapped",
|
||||
"symbol": "USDW",
|
||||
"decimals": 18,
|
||||
"issuer": "0x1234...",
|
||||
"defaultLienMode": "ENCUMBERED",
|
||||
"bridgeOnly": false
|
||||
}
|
||||
```
|
||||
|
||||
### GraphQL
|
||||
|
||||
```graphql
|
||||
mutation {
|
||||
deployToken(input: {
|
||||
name: "USD Wrapped"
|
||||
symbol: "USDW"
|
||||
decimals: 18
|
||||
issuer: "0x1234..."
|
||||
defaultLienMode: ENCUMBERED
|
||||
}) {
|
||||
code
|
||||
address
|
||||
policy {
|
||||
lienMode
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Place a Lien
|
||||
|
||||
### REST API
|
||||
|
||||
```bash
|
||||
POST /v1/liens
|
||||
Authorization: Bearer <token>
|
||||
|
||||
{
|
||||
"debtor": "0xabcd...",
|
||||
"amount": "1000000000000000000",
|
||||
"priority": 1,
|
||||
"reasonCode": "DEBT_ENFORCEMENT"
|
||||
}
|
||||
```
|
||||
|
||||
### GraphQL
|
||||
|
||||
```graphql
|
||||
mutation {
|
||||
placeLien(input: {
|
||||
debtor: "0xabcd..."
|
||||
amount: "1000000000000000000"
|
||||
priority: 1
|
||||
reasonCode: DEBT_ENFORCEMENT
|
||||
}) {
|
||||
lienId
|
||||
amount
|
||||
active
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Submit ISO-20022 Message
|
||||
|
||||
### Inbound (from rail adapter)
|
||||
|
||||
```bash
|
||||
POST /v1/iso/inbound
|
||||
Authorization: Bearer <token> (or mTLS)
|
||||
Idempotency-Key: <uuid>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"msgType": "pacs.008",
|
||||
"instructionId": "0x1234...",
|
||||
"payloadHash": "0xabcd...",
|
||||
"payload": "<Document>...</Document>",
|
||||
"rail": "FEDWIRE"
|
||||
}
|
||||
```
|
||||
|
||||
### Outbound (from client)
|
||||
|
||||
```bash
|
||||
POST /v1/iso/outbound
|
||||
Authorization: Bearer <token>
|
||||
Idempotency-Key: <uuid>
|
||||
|
||||
{
|
||||
"msgType": "pain.001",
|
||||
"instructionId": "0x1234...",
|
||||
"payloadHash": "0xabcd...",
|
||||
"payload": "<Document>...</Document>",
|
||||
"rail": "SEPA",
|
||||
"token": "0x5678...",
|
||||
"amount": "1000000000000000000",
|
||||
"accountRefId": "0xdef0...",
|
||||
"counterpartyRefId": "0x9876..."
|
||||
}
|
||||
```
|
||||
|
||||
## Generate and Dispatch Packet
|
||||
|
||||
### Step 1: Generate Packet
|
||||
|
||||
```bash
|
||||
POST /v1/packets
|
||||
Authorization: Bearer <token>
|
||||
Idempotency-Key: <uuid>
|
||||
|
||||
{
|
||||
"triggerId": "abc123...",
|
||||
"channel": "PDF"
|
||||
}
|
||||
```
|
||||
|
||||
### Step 2: Dispatch Packet
|
||||
|
||||
```bash
|
||||
POST /v1/packets/{packetId}/dispatch
|
||||
Authorization: Bearer <token>
|
||||
Idempotency-Key: <uuid>
|
||||
|
||||
{
|
||||
"channel": "EMAIL",
|
||||
"recipient": "recipient@example.com"
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Record Acknowledgement
|
||||
|
||||
```bash
|
||||
POST /v1/packets/{packetId}/ack
|
||||
Authorization: Bearer <token>
|
||||
Idempotency-Key: <uuid>
|
||||
|
||||
{
|
||||
"status": "ACCEPTED",
|
||||
"ackId": "ack-123"
|
||||
}
|
||||
```
|
||||
|
||||
## Bridge Lock/Unlock
|
||||
|
||||
### Lock Tokens
|
||||
|
||||
```bash
|
||||
POST /v1/bridge/lock
|
||||
Authorization: Bearer <token>
|
||||
|
||||
{
|
||||
"token": "0x1234...",
|
||||
"amount": "1000000000000000000",
|
||||
"targetChain": "0x0000...0001",
|
||||
"targetRecipient": "0xabcd..."
|
||||
}
|
||||
```
|
||||
|
||||
### Unlock Tokens
|
||||
|
||||
```bash
|
||||
POST /v1/bridge/unlock
|
||||
Authorization: Bearer <token>
|
||||
Idempotency-Key: <uuid>
|
||||
|
||||
{
|
||||
"lockId": "lock-123",
|
||||
"token": "0x1234...",
|
||||
"to": "0xabcd...",
|
||||
"amount": "1000000000000000000",
|
||||
"sourceChain": "0x0000...0001",
|
||||
"sourceTx": "0x5678...",
|
||||
"proof": "0xdef0..."
|
||||
}
|
||||
```
|
||||
|
||||
## Webhook Integration
|
||||
|
||||
### Register Webhook
|
||||
|
||||
```bash
|
||||
POST /v1/webhooks
|
||||
Authorization: Bearer <token>
|
||||
|
||||
{
|
||||
"url": "https://example.com/webhooks",
|
||||
"events": ["triggers.created", "liens.placed"],
|
||||
"secret": "webhook-secret"
|
||||
}
|
||||
```
|
||||
|
||||
### Webhook Payload
|
||||
|
||||
```json
|
||||
{
|
||||
"eventId": "uuid",
|
||||
"eventType": "triggers.created",
|
||||
"occurredAt": "2024-01-01T00:00:00Z",
|
||||
"payload": {
|
||||
"triggerId": "abc123...",
|
||||
"rail": "FEDWIRE"
|
||||
},
|
||||
"signatures": [{
|
||||
"signer": "system",
|
||||
"signature": "hmac-sha256-signature"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
### Verify Webhook Signature
|
||||
|
||||
```javascript
|
||||
const crypto = require('crypto');
|
||||
|
||||
function verifyWebhook(payload, signature, secret) {
|
||||
const hmac = crypto.createHmac('sha256', secret);
|
||||
const expectedSignature = hmac.update(JSON.stringify(payload)).digest('hex');
|
||||
return crypto.timingSafeEqual(
|
||||
Buffer.from(signature),
|
||||
Buffer.from(expectedSignature)
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
95
docs/api/iso20022-handbook.md
Normal file
95
docs/api/iso20022-handbook.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# ISO-20022 Mapping Handbook
|
||||
|
||||
This document provides detailed guidance on ISO-20022 message processing and mapping to canonical formats.
|
||||
|
||||
## Message Type Overview
|
||||
|
||||
| Message Type | Direction | Purpose | Trigger Action |
|
||||
|-------------|-----------|---------|----------------|
|
||||
| `pain.001` | Outbound | Customer Credit Transfer Initiation | `validateAndLock()` → `markSubmitted()` |
|
||||
| `pacs.008` | Outbound | FIToFICustomerCreditTransfer | `validateAndLock()` → `markSubmitted()` |
|
||||
| `pacs.009` | Outbound | FinancialInstitutionCreditTransfer | `validateAndLock()` → `markSubmitted()` |
|
||||
| `camt.054` | Inbound | BankToCustomerDebitCreditNotification | `confirmSettled()` (mint tokens) |
|
||||
| `pacs.002` | Inbound | Payment Status Report | `confirmSettled()` or `confirmRejected()` |
|
||||
| `pacs.004` | Return | Payment Return | `confirmRejected()` (release escrow) |
|
||||
| `camt.056` | Cancellation | FIToFIPaymentCancellationRequest | `confirmCancelled()` (release escrow) |
|
||||
|
||||
## Field Mapping
|
||||
|
||||
### pain.001 Mapping
|
||||
|
||||
```yaml
|
||||
instructionId: Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/PmtId/InstrId
|
||||
endToEndId: Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/PmtId/EndToEndId
|
||||
amount: Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/Amt/InstdAmt
|
||||
currency: Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/Amt/InstdAmt/@Ccy
|
||||
debtorAccount: Document/CstmrCdtTrfInitn/PmtInf/DbtrAcct/Id/Othr/Id
|
||||
creditorAccount: Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/CdtrAcct/Id/Othr/Id
|
||||
```
|
||||
|
||||
### pacs.008 Mapping
|
||||
|
||||
```yaml
|
||||
instructionId: Document/FIToFICstmrCdtTrf/GrpHdr/MsgId
|
||||
endToEndId: Document/FIToFICstmrCdtTrf/CdtTrfTxInf/PmtId/EndToEndId
|
||||
amount: Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt
|
||||
currency: Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/@Ccy
|
||||
```
|
||||
|
||||
### pacs.002 Status Mapping
|
||||
|
||||
| Status Code | Meaning | Action |
|
||||
|------------|---------|--------|
|
||||
| `ACSC` | AcceptedSettlementCompleted | `confirmSettled()` |
|
||||
| `RJCT` | Rejected | `confirmRejected()` |
|
||||
| `PNDG` | Pending | Wait for final status |
|
||||
| `CANC` | Cancelled | `confirmCancelled()` |
|
||||
|
||||
## Processing Flow
|
||||
|
||||
### Outbound Flow
|
||||
|
||||
1. Client submits `pain.001` or `pacs.008` via `/v1/iso/outbound`
|
||||
2. ISO Router normalizes message to canonical format
|
||||
3. Orchestrator creates trigger in `CREATED` state
|
||||
4. Orchestrator validates and locks funds (`VALIDATED` state)
|
||||
5. Adapter submits to rail (`SUBMITTED_TO_RAIL` state)
|
||||
6. Trigger moves to `PENDING` state
|
||||
7. Rail adapter receives `pacs.002` or `camt.054`
|
||||
8. Orchestrator confirms settled/rejected (`SETTLED`/`REJECTED` state)
|
||||
|
||||
### Inbound Flow
|
||||
|
||||
1. Rail adapter receives `camt.054` or `pacs.002`
|
||||
2. Adapter submits via `/v1/iso/inbound` (mTLS)
|
||||
3. ISO Router normalizes message
|
||||
4. Orchestrator creates trigger
|
||||
5. For `camt.054` with credit: mint tokens and `confirmSettled()`
|
||||
6. For `pacs.002` with `RJCT`: `confirmRejected()`
|
||||
|
||||
## Idempotency
|
||||
|
||||
All ISO-20022 message submissions are idempotent by `instructionId`. Duplicate submissions with the same `instructionId` are rejected.
|
||||
|
||||
## Payload Storage
|
||||
|
||||
- Full ISO-20022 XML payloads stored off-chain
|
||||
- Only `payloadHash` stored on-chain in trigger
|
||||
- Payloads can be retrieved via API for reconciliation
|
||||
|
||||
## Reconciliation
|
||||
|
||||
Use `instructionId` and `endToEndId` for end-to-end reconciliation:
|
||||
|
||||
```bash
|
||||
GET /v1/triggers?instructionId=0x1234...
|
||||
GET /v1/triggers?endToEndId=0xabcd...
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
Invalid ISO-20022 messages trigger `confirmRejected()` with appropriate reason codes:
|
||||
- Schema validation errors → `CONFIG_ERROR`
|
||||
- Missing required fields → `CONFIG_ERROR`
|
||||
- Invalid amounts → `CONFIG_ERROR`
|
||||
|
||||
248
docs/api/swagger-ui-guide.md
Normal file
248
docs/api/swagger-ui-guide.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# Swagger UI Documentation Guide
|
||||
|
||||
## Overview
|
||||
|
||||
The Swagger UI provides interactive, browser-based documentation for the eMoney Token Factory API. It automatically generates documentation from the OpenAPI 3.1 specification.
|
||||
|
||||
## Accessing the Documentation
|
||||
|
||||
### Local Development
|
||||
|
||||
```bash
|
||||
cd api/tools/swagger-ui
|
||||
pnpm install
|
||||
pnpm run dev
|
||||
```
|
||||
|
||||
Visit: **http://localhost:8080/api-docs**
|
||||
|
||||
### Production
|
||||
|
||||
The Swagger UI can be:
|
||||
- Deployed as a standalone service
|
||||
- Embedded in the main API server
|
||||
- Served via CDN
|
||||
- Generated as static HTML
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Interactive API Explorer
|
||||
|
||||
- **Browse Endpoints**: Navigate through all API endpoints organized by tags
|
||||
- **View Schemas**: Explore request/response data models
|
||||
- **See Examples**: View example payloads for each endpoint
|
||||
- **Filter**: Search and filter endpoints by tag or keyword
|
||||
|
||||
### 2. Try It Out
|
||||
|
||||
- **Test API Calls**: Execute API requests directly from the browser
|
||||
- **Set Parameters**: Fill in path, query, and body parameters
|
||||
- **View Responses**: See real API responses with status codes
|
||||
- **Debug**: Inspect request/response headers and bodies
|
||||
|
||||
### 3. Authentication
|
||||
|
||||
- **OAuth2**: Test OAuth2 client credentials flow
|
||||
- **mTLS**: Configure mutual TLS for adapter endpoints
|
||||
- **API Key**: Set API keys for internal services
|
||||
- **Token Persistence**: Authorization tokens persist across page reloads
|
||||
|
||||
### 4. Schema Documentation
|
||||
|
||||
- **Data Models**: View all data structures with field descriptions
|
||||
- **Enums**: See all possible enum values
|
||||
- **Relationships**: Understand how models relate to each other
|
||||
- **Examples**: View example JSON for each model
|
||||
|
||||
## Using the Documentation
|
||||
|
||||
### Finding an Endpoint
|
||||
|
||||
1. Use the search box to filter endpoints
|
||||
2. Expand tags to see related endpoints
|
||||
3. Click on an endpoint to see details
|
||||
|
||||
### Testing an Endpoint
|
||||
|
||||
1. Click "Try it out" button
|
||||
2. Fill in required parameters
|
||||
3. Click "Execute"
|
||||
4. View the response below
|
||||
|
||||
### Setting Authentication
|
||||
|
||||
1. Click "Authorize" button at the top
|
||||
2. Enter your OAuth2 token or API key
|
||||
3. Click "Authorize"
|
||||
4. Token will be used for all requests
|
||||
|
||||
### Exporting the Spec
|
||||
|
||||
- **JSON**: Visit `/openapi.json`
|
||||
- **YAML**: Visit `/openapi.yaml`
|
||||
- **Download**: Use the download button in Swagger UI
|
||||
|
||||
## Endpoint Categories
|
||||
|
||||
### Tokens
|
||||
- Deploy new tokens
|
||||
- Manage token policies
|
||||
- Mint/burn operations
|
||||
- Clawback and force transfer
|
||||
|
||||
### Liens
|
||||
- Place liens on accounts
|
||||
- Reduce or release liens
|
||||
- Query lien information
|
||||
- Check encumbrance
|
||||
|
||||
### Compliance
|
||||
- Set compliance profiles
|
||||
- Freeze/unfreeze accounts
|
||||
- Manage risk tiers
|
||||
- Set jurisdiction information
|
||||
|
||||
### Mappings
|
||||
- Link accounts to wallets
|
||||
- Query bidirectional mappings
|
||||
- Manage provider connections
|
||||
|
||||
### Triggers
|
||||
- Submit ISO-20022 messages
|
||||
- Query trigger status
|
||||
- Manage trigger lifecycle
|
||||
- View trigger history
|
||||
|
||||
### ISO-20022
|
||||
- Submit inbound messages
|
||||
- Submit outbound messages
|
||||
- Normalize messages
|
||||
- Track message processing
|
||||
|
||||
### Packets
|
||||
- Generate packets
|
||||
- Dispatch packets
|
||||
- Track acknowledgements
|
||||
- Download packet files
|
||||
|
||||
### Bridge
|
||||
- Lock tokens for cross-chain
|
||||
- Unlock tokens with proofs
|
||||
- Query lock status
|
||||
- View supported corridors
|
||||
|
||||
## Best Practices
|
||||
|
||||
### For Developers
|
||||
|
||||
1. **Start with Examples**: Use the example payloads as starting points
|
||||
2. **Test Locally**: Use Swagger UI to test before writing code
|
||||
3. **Check Schemas**: Understand data models before integration
|
||||
4. **Use Try It Out**: Validate your understanding of endpoints
|
||||
|
||||
### For Integration Teams
|
||||
|
||||
1. **Share Links**: Share specific endpoint URLs with team members
|
||||
2. **Export Specs**: Download OpenAPI spec for code generation
|
||||
3. **Document Issues**: Use Swagger UI to demonstrate API issues
|
||||
4. **Validate Requests**: Use Try It Out to validate request formats
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Endpoint Not Showing
|
||||
|
||||
- Check if endpoint is in OpenAPI spec
|
||||
- Verify tag is correct
|
||||
- Check for syntax errors in spec
|
||||
|
||||
### Try It Out Not Working
|
||||
|
||||
- Verify server is running
|
||||
- Check CORS settings
|
||||
- Ensure authentication is set
|
||||
- Check network tab for errors
|
||||
|
||||
### Authentication Failing
|
||||
|
||||
- Verify token format
|
||||
- Check token expiration
|
||||
- Ensure correct OAuth2 flow
|
||||
- Check server logs
|
||||
|
||||
## Integration
|
||||
|
||||
### Embed in Main API
|
||||
|
||||
Add to `api/services/rest-api/src/index.ts`:
|
||||
|
||||
```typescript
|
||||
import swaggerUi from 'swagger-ui-express';
|
||||
import YAML from 'yamljs';
|
||||
import { join } from 'path';
|
||||
|
||||
const openapiSpec = YAML.load(join(__dirname, '../../packages/openapi/v1/openapi.yaml'));
|
||||
|
||||
app.use('/docs', swaggerUi.serve, swaggerUi.setup(openapiSpec));
|
||||
```
|
||||
|
||||
### Standalone Deployment
|
||||
|
||||
Deploy as separate service:
|
||||
- Lightweight and fast
|
||||
- Can be behind CDN
|
||||
- No API dependencies
|
||||
- Easy to update
|
||||
|
||||
### Static HTML Generation
|
||||
|
||||
Generate standalone HTML file:
|
||||
|
||||
```bash
|
||||
cd api/tools/swagger-ui
|
||||
pnpm run generate:standalone
|
||||
```
|
||||
|
||||
Output: `static/standalone.html` (can be opened directly in browser)
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Custom Theme
|
||||
|
||||
Edit `src/index.ts`:
|
||||
|
||||
```typescript
|
||||
const swaggerOptions = {
|
||||
customCss: `
|
||||
.swagger-ui .info .title { color: #your-color; }
|
||||
`,
|
||||
};
|
||||
```
|
||||
|
||||
### Default Values
|
||||
|
||||
Set default server URL:
|
||||
|
||||
```typescript
|
||||
swaggerOptions: {
|
||||
url: 'https://api.emoney.example.com/v1',
|
||||
}
|
||||
```
|
||||
|
||||
### OAuth2 Configuration
|
||||
|
||||
Configure OAuth2 redirect:
|
||||
|
||||
```typescript
|
||||
swaggerOptions: {
|
||||
oauth2RedirectUrl: 'https://your-domain.com/oauth2-redirect.html',
|
||||
}
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions:
|
||||
- Check OpenAPI spec syntax
|
||||
- Verify server configuration
|
||||
- Review Swagger UI logs
|
||||
- Consult Swagger UI documentation
|
||||
|
||||
153
docs/api/versioning-policy.md
Normal file
153
docs/api/versioning-policy.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# API Versioning Policy
|
||||
|
||||
This document defines the versioning strategy for all API types in the eMoney Token Factory system.
|
||||
|
||||
## Versioning Schemes
|
||||
|
||||
### REST API
|
||||
|
||||
- **URL-based versioning**: `/v1/`, `/v2/`, etc.
|
||||
- **Additive changes only**: New fields, endpoints, or query parameters are allowed
|
||||
- **Breaking changes**: Require new version (e.g., `/v2/`)
|
||||
- **Deprecation window**: Minimum 6 months before removal
|
||||
|
||||
### GraphQL API
|
||||
|
||||
- **Schema versioning**: Single schema with deprecation warnings
|
||||
- **Field deprecation**: Use `@deprecated` directive
|
||||
- **Breaking changes**: Add new fields, deprecate old ones
|
||||
- **Removal**: After deprecation period (minimum 6 months)
|
||||
|
||||
### AsyncAPI
|
||||
|
||||
- **Event type versioning**: `triggers.state.updated.v1`, `triggers.state.updated.v2`
|
||||
- **Event envelope**: Versioned separately
|
||||
- **Backward compatibility**: Old event types supported for 6 months
|
||||
|
||||
### gRPC/Protobuf
|
||||
|
||||
- **Package versioning**: `emoney.orchestrator.v1`, `emoney.orchestrator.v2`
|
||||
- **Service versioning**: New service versions for breaking changes
|
||||
- **Message compatibility**: Follow Protobuf compatibility rules
|
||||
|
||||
## Breaking Change Definition
|
||||
|
||||
A change is considered breaking if it:
|
||||
|
||||
1. Removes an endpoint, field, or parameter
|
||||
2. Changes the type of a field or parameter
|
||||
3. Changes the semantics of an endpoint
|
||||
4. Removes an enum value
|
||||
5. Changes authentication requirements
|
||||
6. Changes error response format
|
||||
|
||||
## Non-Breaking Changes
|
||||
|
||||
These changes are allowed without version bump:
|
||||
|
||||
1. Adding new endpoints
|
||||
2. Adding optional fields to requests/responses
|
||||
3. Adding new enum values
|
||||
4. Adding new query parameters
|
||||
5. Improving error messages
|
||||
6. Adding new response fields
|
||||
|
||||
## Deprecation Process
|
||||
|
||||
1. **Announcement**: Mark as deprecated in API documentation
|
||||
2. **Warning Period**: 6 months minimum
|
||||
3. **Removal**: Remove in next major version
|
||||
|
||||
### GraphQL Deprecation Example
|
||||
|
||||
```graphql
|
||||
type Token {
|
||||
code: String!
|
||||
address: String!
|
||||
oldField: String @deprecated(reason: "Use newField instead")
|
||||
newField: String!
|
||||
}
|
||||
```
|
||||
|
||||
### REST Deprecation Example
|
||||
|
||||
```http
|
||||
GET /v1/tokens
|
||||
Deprecation: true
|
||||
Sunset: 2024-07-01
|
||||
Link: <https://api.emoney.example.com/docs/v2>; rel="successor-version"
|
||||
```
|
||||
|
||||
## Version Lifecycle
|
||||
|
||||
1. **Alpha**: Internal testing only
|
||||
2. **Beta**: Public beta, may have breaking changes
|
||||
3. **Stable**: Production-ready, follows versioning policy
|
||||
4. **Deprecated**: Scheduled for removal
|
||||
5. **Sunset**: No longer supported
|
||||
|
||||
## Migration Guide
|
||||
|
||||
When a new version is released:
|
||||
|
||||
1. Provide migration guide in documentation
|
||||
2. Offer SDK updates
|
||||
3. Provide compatibility layer if possible
|
||||
4. Support both versions during transition period
|
||||
|
||||
## Examples
|
||||
|
||||
### REST API Versioning
|
||||
|
||||
```
|
||||
/v1/tokens # Version 1
|
||||
/v2/tokens # Version 2 (breaking changes)
|
||||
/v1/tokens # Still supported during transition
|
||||
```
|
||||
|
||||
### GraphQL Deprecation
|
||||
|
||||
```graphql
|
||||
# v1
|
||||
type Token {
|
||||
oldName: String!
|
||||
}
|
||||
|
||||
# v2 (additive)
|
||||
type Token {
|
||||
oldName: String! @deprecated(reason: "Use name instead")
|
||||
name: String!
|
||||
}
|
||||
|
||||
# v3 (removal)
|
||||
type Token {
|
||||
name: String!
|
||||
}
|
||||
```
|
||||
|
||||
### AsyncAPI Versioning
|
||||
|
||||
```yaml
|
||||
# v1
|
||||
channels:
|
||||
triggers.created.v1:
|
||||
# ...
|
||||
|
||||
# v2
|
||||
channels:
|
||||
triggers.created.v2:
|
||||
# ...
|
||||
triggers.created.v1: # Still supported
|
||||
# ...
|
||||
```
|
||||
|
||||
## Compliance
|
||||
|
||||
All API changes must:
|
||||
|
||||
1. Follow semantic versioning principles
|
||||
2. Maintain backward compatibility within major version
|
||||
3. Provide deprecation warnings before removal
|
||||
4. Document migration path
|
||||
5. Support transition period (minimum 6 months)
|
||||
|
||||
Reference in New Issue
Block a user