-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontracts.d.ts
More file actions
63 lines (56 loc) · 1.85 KB
/
Copy pathcontracts.d.ts
File metadata and controls
63 lines (56 loc) · 1.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/**
* TaskFlow API contract — the single source of truth for the shapes that cross
* the network between the NestJS backend and the Next.js frontend.
*
* This is a TYPE-ONLY declaration file on purpose:
* - `import type` from it erases at compile time, so neither app gains a
* runtime dependency, a build step, or a bundled module — each still runs
* with a plain `npm install && npm run dev`.
* - Both apps validate against it at COMPILE time: the frontend derives its
* types from here, and the backend asserts its enums/event names match
* (see `backend/src/contracts.parity.ts`). Drift becomes a build error.
*
* Note: this describes the WIRE shape (JSON). Dates are ISO strings here —
* the backend's domain entity uses `Date` and serialises to this on the way out.
*/
export type TaskStatus = 'todo' | 'in_progress' | 'done' | 'archived';
export type TaskPriority = 1 | 2 | 3;
export interface TaskDto {
id: string;
title: string;
description?: string;
status: TaskStatus;
priority: TaskPriority;
tags: string[];
createdAt: string;
updatedAt: string;
}
export interface TaskPageDto {
items: TaskDto[];
nextCursor: string | null;
total: number;
}
export interface TaskStatsDto {
total: number;
byStatus: Record<TaskStatus, number>;
byPriority: Record<TaskPriority, number>;
}
/** Server → client WebSocket event names. */
export type TaskEventName = 'task:created' | 'task:updated' | 'task:deleted';
/** Stable, machine-readable error codes in the error envelope. */
export type ErrorCode =
| 'VALIDATION_ERROR'
| 'INVALID_API_KEY'
| 'TASK_NOT_FOUND'
| 'ILLEGAL_STATUS_TRANSITION'
| 'EMPTY_UPDATE'
| 'TASK_ARCHIVED_READONLY'
| 'INVALID_CURSOR'
| 'INTERNAL_ERROR';
export interface ApiErrorBody {
statusCode: number;
code: ErrorCode;
message: string | string[];
path: string;
timestamp: string;
}