first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
# timestamps
## Purpose
Defines Zod schemas for the audit timestamp fields (`createdAt`, `updatedAt`, and optionally `deletedAt`) that appear on virtually every Suaveplan resource response. Centralising these schemas ensures that every endpoint returns timestamps in the same ISO 8601 wire format and that the TypeScript types derived from the schemas are consistent across server handlers, React data hooks, and OpenAPI generators.
## Features
- `TimestampsOutput` schema — `{createdAt, updatedAt}` as ISO 8601 strings with timezone offset (`z.string().datetime({ offset: true })`)
- `SoftDeleteTimestampsOutput` schema — extends `TimestampsOutput` with a nullable `deletedAt` field for soft-delete patterns
- Strict ISO 8601 validation with timezone offset requirement — prevents bare local-time strings
- Composable via `z.extend()` so resource schemas can merge timestamps in without boilerplate
- Full TypeScript inference via `z.infer<>` — no manual interface duplication
- Zod v4 compatible
## Usage: Basic Example
```ts
import { TimestampsOutput } from "@suaveplan/api-schemas/common";
const ts = TimestampsOutput.parse({
createdAt: "2024-01-15T12:00:00Z",
updatedAt: "2024-06-01T09:30:00+02:00",
});
// → { createdAt: "2024-01-15T12:00:00Z", updatedAt: "2024-06-01T09:30:00+02:00" }
```
## Usage: Advanced Example
```ts
import z from "zod";
import { TimestampsOutput, SoftDeleteTimestampsOutput } from "@suaveplan/api-schemas/common";
// Merge timestamps into a resource schema
const UserResponse = z.object({
id: z.string(),
email: z.string().email(),
}).merge(SoftDeleteTimestampsOutput);
type UserResponse = z.infer<typeof UserResponse>;
// → { id: string; email: string; createdAt: string; updatedAt: string; deletedAt: string | null }
```
## API Reference
### `TimestampsOutput`
Zod object schema.
| Field | Type | Description |
|-------------|-------------------|-----------------------------------------------------|
| `createdAt` | `string` (ISO 8601 with offset) | Resource creation timestamp |
| `updatedAt` | `string` (ISO 8601 with offset) | Most recent modification timestamp |
**Type export:** `type TimestampsOutput = z.infer<typeof TimestampsOutput>`
### `SoftDeleteTimestampsOutput`
Extends `TimestampsOutput`.
| Field | Type | Description |
|-------------|----------------------------------|----------------------------------------------|
| `createdAt` | `string` (ISO 8601 with offset) | Inherited from `TimestampsOutput` |
| `updatedAt` | `string` (ISO 8601 with offset) | Inherited from `TimestampsOutput` |
| `deletedAt` | `string \| null` (ISO 8601 with offset) | Soft-delete timestamp, null if not deleted |
**Type export:** `type SoftDeleteTimestampsOutput = z.infer<typeof SoftDeleteTimestampsOutput>`
## Implementation Notes
The `{ offset: true }` option on `z.string().datetime()` requires that the timestamp include a UTC offset (e.g. `Z` or `+HH:MM`). This prevents bare local-time strings like `"2024-01-15T12:00:00"` from passing validation, which is important because ambiguous timestamps cause subtle bugs when crossing timezone boundaries. All Suaveplan services store and transmit timestamps in UTC or with explicit offset.