First-attempt commit3a5c6e184only captured the .gitignore change; the pre-commit hook silently dropped the 343 staged moves/deletes during lint-staged's "no matching task" path. This commit re-applies the intended J1 content on top ofbec75f143(which was pushed in parallel). Uses --no-verify because: - J1 only touches .md/.json/.log/.png/binaries — zero code that would benefit from lint-staged, typecheck, or vitest - The hook demonstrated it corrupts pure-rename commits in this repo - Explicitly authorized by user for this one commit Changes (343 total: 169 deletions + 174 renames): Binaries purged (~167 MB): - veza-backend-api/{server,modern-server,encrypt_oauth_tokens,seed,seed-v2} Generated reports purged: - 9 apps/web/lint_report*.json (~32 MB) - 8 apps/web/tsc_*.{log,txt} + ts_*.log (TS error snapshots) - 3 apps/web/storybook_*.json (1375+ stored errors) - apps/web/{build_errors*,build_output,final_errors}.txt - 70 veza-backend-api/coverage*.out + coverage_groups/ (~4 MB) - 3 veza-backend-api/internal/handlers/*.bak Root cleanup: - 54 audit-*.png (visual regression baselines, ~11 MB) - 9 stale MVP-era scripts (Jan 27, hardcoded v0.101): start_{iteration,mvp,recovery}.sh, test_{mvp_endpoints,protected_endpoints,user_journey}.sh, validate_v0101.sh, verify_logs_setup.sh, gen_hash.py Session docs archived (not deleted — preserved under docs/archive/): - 78 apps/web/*.md → docs/archive/frontend-sessions-2026/ - 43 veza-backend-api/*.md → docs/archive/backend-sessions-2026/ - 53 docs/{RETROSPECTIVE_V,SMOKE_TEST_V,PLAN_V0_,V0_*_RELEASE_SCOPE, AUDIT_,PLAN_ACTION_AUDIT,REMEDIATION_PROGRESS}*.md → docs/archive/v0-history/ README.md and CONTRIBUTING.md preserved in apps/web/ and veza-backend-api/. Note: The .gitignore rules preventing recurrence were already pushed in3a5c6e184and remain in place — this commit does not modify .gitignore. Refs: AUDIT_REPORT.md §11
94 lines
2.3 KiB
Markdown
94 lines
2.3 KiB
Markdown
# Veza API Frontend Integration Guide
|
|
|
|
## 1. Introduction
|
|
This guide provides instructions for consuming the Veza Backend API in frontend applications (React, Vue, etc.).
|
|
|
|
## 2. API Client Setup
|
|
We recommend creating a typed API client.
|
|
|
|
### 2.1. TypeScript Interfaces
|
|
|
|
```typescript
|
|
// Base Response Envelope
|
|
export interface APIResponse<T> {
|
|
success: boolean;
|
|
data: T | null;
|
|
error: APIError | null;
|
|
}
|
|
|
|
// Error Structure
|
|
export interface APIError {
|
|
code: number;
|
|
message: string;
|
|
details?: ValidationErrorDetail[] | null;
|
|
request_id?: string;
|
|
timestamp?: string;
|
|
}
|
|
|
|
export interface ValidationErrorDetail {
|
|
field: string;
|
|
message: string;
|
|
value?: string;
|
|
tag?: string;
|
|
}
|
|
|
|
// Pagination
|
|
export interface PaginatedList<T> {
|
|
list: T[];
|
|
pagination: {
|
|
page: number;
|
|
limit: number;
|
|
total: number;
|
|
has_next: boolean;
|
|
};
|
|
}
|
|
```
|
|
|
|
## 3. Making Requests
|
|
|
|
### 3.1. Fetch Wrapper Example
|
|
|
|
```typescript
|
|
async function apiRequest<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
|
const token = localStorage.getItem('access_token');
|
|
const headers = {
|
|
'Content-Type': 'application/json',
|
|
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
|
|
...options.headers,
|
|
};
|
|
|
|
const response = await fetch(\`/api/v1${endpoint}\`, { ...options, headers });
|
|
const result: APIResponse<T> = await response.json();
|
|
|
|
if (!result.success) {
|
|
// Handle API Error
|
|
console.error('API Error:', result.error);
|
|
throw new Error(result.error?.message || 'Unknown API Error');
|
|
}
|
|
|
|
// Return the data payload directly
|
|
return result.data as T;
|
|
}
|
|
```
|
|
|
|
## 4. Handling Validation Errors
|
|
When a `400 Bad Request` or `422 Unprocessable Entity` occurs:
|
|
|
|
```typescript
|
|
try {
|
|
await apiRequest('/auth/login', { method: 'POST', body: JSON.stringify(creds) });
|
|
} catch (error) {
|
|
// If error has details, map them to form fields
|
|
const apiError = error as APIError; // You might need to adjust error throwing logic
|
|
if (apiError.details) {
|
|
apiError.details.forEach(detail => {
|
|
setFieldError(detail.field, detail.message);
|
|
});
|
|
}
|
|
}
|
|
```
|
|
|
|
## 5. Resources & Endpoints (Swagger)
|
|
For a full list of endpoints, request/response bodies, please refer to the OpenAPI Specification:
|
|
- Local URL: `http://localhost:8080/swagger/index.html`
|
|
- File: `docs/swagger.json`
|