sovrium 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ <p align="center">
2
+ <h1 align="center">Sovrium</h1>
3
+ </p>
4
+
1
5
  <h3 align="center">Build business apps with config. Own your data forever.</h3>
2
6
 
3
7
  <p align="center">
@@ -7,7 +11,6 @@
7
11
 
8
12
  <p align="center">
9
13
  <a href="https://github.com/sovrium/sovrium/blob/main/LICENSE.md"><img src="https://img.shields.io/badge/license-BSL--1.1-blue" alt="License" /></a>
10
- <a href="SPEC-PROGRESS.md"><img src="https://img.shields.io/badge/specs-99%25_passing-brightgreen" alt="Specs" /></a>
11
14
  <a href="https://bun.sh"><img src="https://img.shields.io/badge/runtime-Bun_1.3-f472b6" alt="Bun" /></a>
12
15
  <a href="https://www.typescriptlang.org"><img src="https://img.shields.io/badge/TypeScript-5.9-3178c6" alt="TypeScript" /></a>
13
16
  <a href="https://www.npmjs.com/package/sovrium"><img src="https://img.shields.io/npm/v/sovrium" alt="npm" /></a>
@@ -15,21 +18,22 @@
15
18
  </p>
16
19
 
17
20
  <p align="center">
21
+ <a href="https://sovrium.com">Website</a> &middot;
18
22
  <a href="VISION.md">Vision</a> &middot;
19
23
  <a href="SPEC-PROGRESS.md">Roadmap</a> &middot;
20
24
  <a href="CLAUDE.md">Docs</a> &middot;
21
25
  <a href="https://github.com/sovrium/sovrium/issues">Issues</a>
22
26
  </p>
23
27
 
28
+ <!-- TODO: Add a product screenshot or demo GIF here (recommended: 1200x800px). -->
29
+
24
30
  ---
25
31
 
26
32
  ## What is Sovrium?
27
33
 
28
- Sovrium turns **configuration files** into full-featured web applications -- database, auth, API, and UI included.
29
-
30
- No code generation. No external services. Just config and `sovrium start`.
34
+ Sovrium turns a **configuration file** into a complete web application database, authentication, API, and pages included.
31
35
 
32
- **Choose your format** -- YAML for readability, TypeScript for type safety:
36
+ No code generation. No external services. Write a config file, run one command, and your app is live.
33
37
 
34
38
  ```yaml
35
39
  # sovrium.yaml
@@ -60,11 +64,15 @@ pages:
60
64
  content: Welcome to My CRM
61
65
  ```
62
66
 
67
+ ```bash
68
+ sovrium start sovrium.yaml
69
+ # -> http://localhost:3000
70
+ ```
71
+
63
72
  <details>
64
- <summary>Or use TypeScript for IDE completion</summary>
73
+ <summary>Prefer TypeScript? Use it for autocompletion and type checking.</summary>
65
74
 
66
75
  ```typescript
67
- // app.ts
68
76
  import { start } from 'sovrium'
69
77
 
70
78
  await start({
@@ -93,229 +101,101 @@ await start({
93
101
 
94
102
  </details>
95
103
 
96
- ```bash
97
- sovrium start sovrium.yaml # Run with YAML
98
- bun run app.ts # Or run with TypeScript
99
- # -> http://localhost:3000
100
- ```
101
-
102
- ---
103
-
104
- ## Why Sovrium?
105
-
106
- **The problem**: Organizations pay $10k+/month for 20+ SaaS tools, with data scattered everywhere and zero control.
107
-
108
- **The solution**: One self-hosted platform that does what you need, configured in files you own.
109
-
110
- | | Sovrium | SaaS Tools |
111
- | ------------------- | :-------------: | :----------: |
112
- | **Data ownership** | Your servers | Vendor cloud |
113
- | **Monthly cost** | $0 (infra only) | $20-50/user |
114
- | **Vendor lock-in** | None | Complete |
115
- | **Customization** | Unlimited | Limited |
116
- | **Version control** | Git-native | None |
117
-
118
104
  ---
119
105
 
120
- ## Quick Start
106
+ ## 🚀 Quick Start
121
107
 
122
- **Requirements**: [Bun](https://bun.sh) 1.3+ and [PostgreSQL](https://www.postgresql.org/) 15+
108
+ **You need**: [Bun](https://bun.sh) 1.3+ and [PostgreSQL](https://www.postgresql.org/) 15+
123
109
 
124
110
  ```bash
125
- # Install
126
111
  bun add sovrium
127
-
128
- # Create config
129
- cat > sovrium.yaml << EOF
130
- name: my-app
131
- pages:
132
- - name: home
133
- path: /
134
- sections:
135
- - type: h1
136
- content: Hello World
137
- EOF
138
-
139
- # Run
140
112
  sovrium start sovrium.yaml
141
-
142
- # Or use environment variable (JSON, YAML, or URL)
143
- APP_SCHEMA='{"name":"my-app"}' sovrium start
144
- APP_SCHEMA='name: my-app' sovrium start
145
- APP_SCHEMA='https://example.com/app.yaml' sovrium start
146
113
  ```
147
114
 
148
- ---
149
-
150
- ## Features
151
-
152
- ### Database & Tables
153
-
154
- Define your data model in config. Sovrium creates PostgreSQL tables, handles migrations, and exposes a full REST API automatically.
155
-
156
- - **40 field types** -- text, numeric, date/time, selection, media, relational, user tracking, and advanced types (formula, JSON, geolocation, barcode, autonumber, and more)
157
- - **Relationships** -- one-to-many and many-to-many with lookup and rollup fields
158
- - **Views** -- filtered, sorted, and grouped views with field-level visibility
159
- - **Indexes and constraints** -- primary keys, unique constraints, check constraints
160
- - **Soft delete** -- built-in trash with restore capability
161
- - **Permissions** -- role-based table and field-level access control
162
- - **Schema evolution** -- migration system for safe schema changes
115
+ Your app is running at `http://localhost:3000`.
163
116
 
164
- ### REST API
165
-
166
- Every table gets a full CRUD API with no additional code.
167
-
168
- - **Records** -- create, read, update, delete with field validation
169
- - **Batch operations** -- bulk create, update, and upsert
170
- - **Filtering and sorting** -- query records with field-based filters
171
- - **Pagination** -- cursor and offset-based pagination
172
- - **Activity logs** -- audit trail for all record changes
173
- - **Rate limiting** -- configurable per-endpoint rate limits
174
-
175
- ### Authentication
176
-
177
- Production-ready auth out of the box.
178
-
179
- - **Email/password** -- sign up, sign in, email verification, password reset
180
- - **Magic link** -- passwordless email authentication
181
- - **Two-factor** -- TOTP-based 2FA
182
- - **OAuth** -- social login providers
183
- - **Roles** -- admin, member, viewer with custom roles
184
- - **Admin plugin** -- user management, banning, impersonation
185
- - **Session management** -- list, revoke, and manage active sessions
186
-
187
- ### Pages & UI
188
-
189
- Server-rendered pages with a component-based system.
190
-
191
- - **Dynamic routing** -- path-based page routing
192
- - **Sections** -- composable content sections with theming support
193
- - **Reusable components** -- define once with `$ref`, customize with `$vars`
194
- - **SEO metadata** -- title, description, Open Graph, structured data
195
- - **Scripts** -- custom head and body scripts per page
196
-
197
- ### Theming
117
+ ---
198
118
 
199
- Design system configuration for consistent styling.
119
+ ## Features
200
120
 
201
- - **Colors** -- primary, secondary, accent, and semantic color tokens
202
- - **Fonts** -- custom font families with Google Fonts support
203
- - **Spacing, shadows, border-radius** -- design tokens applied globally
204
- - **Animations** -- configurable keyframe animations
205
- - **Breakpoints** -- responsive design breakpoints
121
+ | | Feature | What you get |
122
+ | :-- | :----------------- | :-------------------------------------------------------------------------------------------------------------------------------------- |
123
+ | 🗄️ | **Tables** | 40 field types including formulas, lookups, and rollups. Views with filtering and sorting. Trash with restore. Granular access control. |
124
+ | 🔌 | **Automatic API** | Every table gets its own API. Filter, sort, paginate, and track changes — no code needed. |
125
+ | 🔐 | **Authentication** | Email/password, magic link, two-factor, social login. Built-in roles (admin, member, viewer) and user management. |
126
+ | 🖥️ | **Pages** | Build pages from reusable sections. Define once, customize with variables. SEO-ready out of the box. |
127
+ | 🎨 | **Theming** | Colors, fonts, spacing, shadows, animations, and responsive breakpoints — all defined in your config file. |
128
+ | 🌐 | **Multi-language** | Built-in translation system with browser language detection and user preference memory. |
129
+ | ⌨️ | **CLI** | `sovrium start` to run your app. `sovrium build` to export a static site. Supports YAML, JSON, and TypeScript. |
206
130
 
207
- ### Internationalization
131
+ ---
208
132
 
209
- Multi-language support built in.
133
+ ## 💡 Why Sovrium?
210
134
 
211
- - **Language configuration** -- define supported languages and default
212
- - **Translation tokens** -- `$t:` syntax for referencing translations in pages
213
- - **Browser detection** -- automatic language detection
214
- - **Persistence** -- remember user language preference
135
+ Organizations pay **$10k+/month** for 20+ SaaS tools, with data scattered everywhere and zero control.
215
136
 
216
- ### CLI
137
+ Sovrium is **one self-hosted platform** that does what you need, configured in files you own.
217
138
 
218
- - `sovrium start` -- run the application from a config file
219
- - `sovrium build` -- generate a static site from config
220
- - Supports YAML, JSON, and TypeScript config files
139
+ | | Sovrium | SaaS Tools |
140
+ | ------------------- | :-------------: | :----------: |
141
+ | **Data ownership** | Your servers | Vendor cloud |
142
+ | **Monthly cost** | $0 (infra only) | $20-50/user |
143
+ | **Vendor lock-in** | None | Complete |
144
+ | **Customization** | Unlimited | Limited |
145
+ | **Version control** | Git-native | None |
221
146
 
222
147
  ---
223
148
 
224
- ## Architecture
149
+ ## 📊 Status
225
150
 
226
- ```
227
- Config File (YAML/JSON/TS)
228
- |
229
- v
230
- Effect Schema (validation)
231
- |
232
- v
233
- Sovrium Runtime
234
- |
235
- +---> PostgreSQL (tables, records, migrations)
236
- +---> Hono (REST API + SSR)
237
- +---> Better Auth (sessions, OAuth, 2FA)
238
- +---> React + Tailwind (server-rendered UI)
239
- ```
151
+ Sovrium is under **active development**. The core feature set — tables, API, authentication, pages, theming, and i18n — is defined and tested across 272 user stories. Implementation is ongoing with automated pipelines.
240
152
 
241
- ### Stack
242
-
243
- | | |
244
- | :---------------------------------------- | :------------- |
245
- | [Bun](https://bun.sh) | Runtime |
246
- | [Hono](https://hono.dev) | Web framework |
247
- | [Drizzle](https://orm.drizzle.team) | Database ORM |
248
- | [Effect](https://effect.website) | Type-safe FP |
249
- | [React 19](https://react.dev) | UI (SSR) |
250
- | [Tailwind CSS 4](https://tailwindcss.com) | Styling |
251
- | [Better Auth](https://better-auth.com) | Authentication |
252
-
253
- ### Project Structure
254
-
255
- ```
256
- src/
257
- domain/ # Business logic, Effect Schema models
258
- models/app/ # App configuration schema (tables, auth, pages, theme, ...)
259
- models/api/ # API contracts (Zod schemas for OpenAPI)
260
- application/ # Use cases, Effect programs
261
- infrastructure/ # Database, auth, CSS compiler, email, logging
262
- presentation/ # API routes, CLI, React components, styling
263
- specs/ # 2,200+ E2E tests (Playwright)
264
- docs/ # Architecture and infrastructure documentation
265
- ```
153
+ 📋 [See the full roadmap →](SPEC-PROGRESS.md)
266
154
 
267
155
  ---
268
156
 
269
- ## Status
157
+ ## 🤝 Contributing
270
158
 
271
- **Sovrium is under active development.**
159
+ We welcome contributions of all kinds!
272
160
 
273
- The specification and testing phase is nearly complete: **2,270 out of 2,283 E2E tests are passing** across 225 spec files, covering 272 user stories with 2,394 acceptance criteria. A TDD automation pipeline handles test implementation, averaging 15+ specs fixed per day.
274
-
275
- | Domain | Spec Files | Tests | Status |
276
- | ---------- | ---------: | ----: | ------ |
277
- | API | 67 | 627 | 100% |
278
- | App Schema | 131 | 1,398 | 99% |
279
- | CLI | 9 | 108 | 100% |
280
- | Migrations | 17 | 139 | 100% |
281
- | Templates | 1 | 11 | 100% |
161
+ ```bash
162
+ git clone https://github.com/sovrium/sovrium
163
+ cd sovrium && bun install
164
+ bun run start
165
+ ```
282
166
 
283
- Track progress in detail: [SPEC-PROGRESS.md](SPEC-PROGRESS.md)
167
+ 📖 See [CLAUDE.md](CLAUDE.md) for coding standards and architecture details.
284
168
 
285
169
  ---
286
170
 
287
- ## Development
171
+ ## 💬 Community & Support
288
172
 
289
- ```bash
290
- bun install # Install dependencies
291
- bun run start # Run application
292
- bun run quality --skip-e2e # Lint, format, typecheck, unit tests
293
- bun test:unit # Unit tests only
294
- bun test:e2e:regression # E2E regression tests
295
- bun run progress # Spec analysis and progress report
296
- ```
173
+ - [GitHub Issues](https://github.com/sovrium/sovrium/issues) — Bug reports and feature requests
174
+ - [GitHub Discussions](https://github.com/sovrium/sovrium/discussions) — Questions, ideas, and general chat
175
+ - [Vision](VISION.md) Where Sovrium is headed
297
176
 
298
177
  ---
299
178
 
300
- ## Contributing
179
+ <details>
180
+ <summary>🛠️ Built with</summary>
181
+ <br />
301
182
 
302
- We welcome contributions! See [CLAUDE.md](CLAUDE.md) for coding standards and architecture details.
183
+ [Bun](https://bun.sh) · [Hono](https://hono.dev) · [Drizzle ORM](https://orm.drizzle.team) · [Effect](https://effect.website) · [React 19](https://react.dev) · [Tailwind CSS 4](https://tailwindcss.com) · [Better Auth](https://better-auth.com)
303
184
 
304
- ```bash
305
- git clone https://github.com/sovrium/sovrium
306
- cd sovrium && bun install
307
- ```
185
+ See [CLAUDE.md](CLAUDE.md) for the full architecture and project structure.
186
+
187
+ </details>
308
188
 
309
189
  ---
310
190
 
311
- ## License
191
+ ## 📄 License
312
192
 
313
- [BSL-1.1](LICENSE.md) -- Free for internal and non-commercial use. Becomes Apache 2.0 on January 1, 2029.
193
+ [BSL-1.1](LICENSE.md) Free for internal and non-commercial use. Automatically converts to **Apache 2.0** on January 1, 2029.
314
194
 
315
195
  ---
316
196
 
317
197
  <p align="center">
318
- <sub><strong>Own your data. Own your tools. Own your future.</strong></sub>
198
+ <strong>Own your data. Own your tools. Own your future.</strong>
319
199
  </p>
320
200
 
321
201
  <p align="center">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sovrium",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "packageManager": "bun@1.3.10",
5
5
  "description": "Configuration-driven web application platform built with Bun, Effect, React, and Tailwind CSS",
6
6
  "module": "src/index.ts",
@@ -48,8 +48,6 @@
48
48
  ],
49
49
  "files": [
50
50
  "drizzle/**",
51
- "schemas/**",
52
- "!schemas/development/**",
53
51
  "src/**/*.ts",
54
52
  "src/**/*.tsx",
55
53
  "src/**/*.css",
@@ -137,6 +135,7 @@
137
135
  "globals": "^17.4.0",
138
136
  "knip": "^5.85.0",
139
137
  "otplib": "^13.3.0",
138
+ "pagefind": "^1.4.0",
140
139
  "pg": "^8.19.0",
141
140
  "playwright": "^1.58.2",
142
141
  "prettier-plugin-tailwindcss": "^0.7.2",
@@ -147,19 +146,20 @@
147
146
  "typescript": "^5.9.3"
148
147
  },
149
148
  "dependencies": {
149
+ "@better-auth/drizzle-adapter": "^1.5.3",
150
150
  "@effect/experimental": "^0.58.0",
151
151
  "@hono/zod-openapi": "^1.2.2",
152
152
  "@hono/zod-validator": "^0.7.6",
153
153
  "@hookform/resolvers": "^5.2.2",
154
- "@scalar/hono-api-reference": "^0.9.47",
154
+ "@scalar/hono-api-reference": "^0.9.48",
155
155
  "@tailwindcss/postcss": "^4.2.1",
156
156
  "@tanstack/react-query": "^5.90.21",
157
157
  "@tanstack/react-table": "^8.21.3",
158
- "better-auth": "^1.5.2",
158
+ "better-auth": "^1.5.3",
159
159
  "dompurify": "^3.3.1",
160
160
  "drizzle-orm": "^0.45.1",
161
161
  "effect": "^3.19.19",
162
- "hono": "^4.12.3",
162
+ "hono": "^4.12.4",
163
163
  "js-yaml": "^4.1.1",
164
164
  "lucide-react": "^0.575.0",
165
165
  "nanoid": "^5.1.6",
@@ -17,18 +17,34 @@ export interface HreflangConfig {
17
17
  readonly defaultLanguage: string
18
18
  }
19
19
 
20
+ /**
21
+ * Repair whitespace inside <pre> tags that Prettier's HTML formatter damages.
22
+ *
23
+ * Prettier adds a newline + indentation after the opening `>` of `<pre>` tags.
24
+ * Because `<pre>` renders whitespace literally (CSS `white-space: pre`), this
25
+ * introduces a visible blank first line in code blocks.
26
+ *
27
+ * This function strips the newline and any spaces immediately after `<pre ...>`.
28
+ */
29
+ const repairPreWhitespace = (html: string): string => html.replace(/(<pre[^>]*>)\n[ ]*/g, '$1')
30
+
20
31
  /**
21
32
  * Format HTML with Prettier for professional formatting
22
- * Loads Prettier config and formats HTML using the HTML parser
33
+ * Loads Prettier config and formats HTML using the HTML parser.
34
+ *
35
+ * After formatting, repairs `<pre>` whitespace that Prettier damages
36
+ * (leading newline + indentation, trailing whitespace).
23
37
  */
24
38
  export const formatHtmlWithPrettier = async (html: string): Promise<string> => {
25
39
  const prettier = await import('prettier')
26
40
  const config = await prettier.resolveConfig(process.cwd())
27
41
 
28
- return await prettier.format(html, {
42
+ const formatted = await prettier.format(html, {
29
43
  ...config,
30
44
  parser: 'html',
31
45
  })
46
+
47
+ return repairPreWhitespace(formatted)
32
48
  }
33
49
 
34
50
  /**
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Copyright (c) 2025 ESSENTIAL SERVICES
3
+ *
4
+ * This source code is licensed under the Business Source License 1.1
5
+ * found in the LICENSE.md file in the root directory of this source tree.
6
+ */
7
+
8
+ import { z } from 'zod'
9
+
10
+ // ============================================================================
11
+ // Activity Log Schemas
12
+ // ============================================================================
13
+
14
+ /**
15
+ * Activity log user reference schema
16
+ */
17
+ export const activityLogUserSchema = z.object({
18
+ id: z.string().describe('User identifier'),
19
+ name: z.string().describe('User display name'),
20
+ email: z.string().describe('User email address'),
21
+ })
22
+
23
+ /**
24
+ * Activity log entry schema (list view)
25
+ */
26
+ export const activityLogSchema = z.object({
27
+ id: z.string().describe('Activity log identifier'),
28
+ createdAt: z.string().describe('ISO 8601 timestamp of the activity'),
29
+ userId: z.string().optional().describe('User who performed the action'),
30
+ action: z.enum(['create', 'update', 'delete', 'restore']).describe('Action type'),
31
+ tableName: z.string().describe('Name of the affected table'),
32
+ recordId: z.union([z.string(), z.number()]).describe('ID of the affected record'),
33
+ user: activityLogUserSchema.nullable().describe('User details (null for system activities)'),
34
+ })
35
+
36
+ /**
37
+ * Activity log detail schema (single view, includes changes)
38
+ */
39
+ export const activityLogDetailSchema = activityLogSchema.extend({
40
+ changes: z
41
+ .record(z.string(), z.unknown())
42
+ .nullable()
43
+ .describe('Field changes (null for delete actions)'),
44
+ })
45
+
46
+ /**
47
+ * Activity log pagination schema
48
+ */
49
+ export const activityPaginationSchema = z.object({
50
+ total: z.number().int().describe('Total count of activities'),
51
+ page: z.number().int().describe('Current page number'),
52
+ pageSize: z.number().int().describe('Items per page'),
53
+ totalPages: z.number().int().describe('Total number of pages'),
54
+ })
55
+
56
+ // ============================================================================
57
+ // Activity Log Response Schemas
58
+ // ============================================================================
59
+
60
+ /**
61
+ * List activity logs response schema
62
+ *
63
+ * GET /api/activity
64
+ */
65
+ export const listActivityLogsResponseSchema = z.object({
66
+ activities: z.array(activityLogSchema).describe('List of activity log entries'),
67
+ pagination: activityPaginationSchema.describe('Pagination metadata'),
68
+ })
69
+
70
+ /**
71
+ * Get activity log detail response schema
72
+ *
73
+ * GET /api/activity/:activityId
74
+ */
75
+ export const getActivityLogResponseSchema = activityLogDetailSchema.describe(
76
+ 'Single activity log entry with change details'
77
+ )
78
+
79
+ // ============================================================================
80
+ // TypeScript Types
81
+ // ============================================================================
82
+
83
+ export type ActivityLogUser = z.infer<typeof activityLogUserSchema>
84
+ export type ActivityLog = z.infer<typeof activityLogSchema>
85
+ export type ActivityLogDetail = z.infer<typeof activityLogDetailSchema>
86
+ export type ListActivityLogsResponse = z.infer<typeof listActivityLogsResponseSchema>
87
+ export type GetActivityLogResponse = z.infer<typeof getActivityLogResponseSchema>
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Copyright (c) 2025 ESSENTIAL SERVICES
3
+ *
4
+ * This source code is licensed under the Business Source License 1.1
5
+ * found in the LICENSE.md file in the root directory of this source tree.
6
+ */
7
+
8
+ import { z } from 'zod'
9
+
10
+ // ============================================================================
11
+ // Comment Schemas
12
+ // ============================================================================
13
+
14
+ /**
15
+ * Comment user metadata schema
16
+ */
17
+ export const commentUserSchema = z.object({
18
+ id: z.string().describe('User identifier'),
19
+ name: z.string().describe('User display name'),
20
+ email: z.string().describe('User email address'),
21
+ image: z.string().nullable().optional().describe('User avatar URL'),
22
+ })
23
+
24
+ /**
25
+ * Comment response schema
26
+ */
27
+ export const commentSchema = z.object({
28
+ id: z.string().describe('Comment identifier'),
29
+ content: z.string().describe('Comment content'),
30
+ userId: z.string().describe('Author user ID'),
31
+ recordId: z.union([z.string(), z.number()]).describe('Parent record ID'),
32
+ tableId: z.union([z.string(), z.number()]).describe('Parent table ID'),
33
+ createdAt: z.string().describe('ISO 8601 creation timestamp'),
34
+ updatedAt: z.string().describe('ISO 8601 last update timestamp'),
35
+ user: commentUserSchema.describe('Comment author details'),
36
+ })
37
+
38
+ /**
39
+ * Comment pagination schema
40
+ */
41
+ export const commentPaginationSchema = z.object({
42
+ total: z.number().int().describe('Total count of comments'),
43
+ limit: z.number().int().describe('Items returned'),
44
+ offset: z.number().int().describe('Items skipped'),
45
+ hasMore: z.boolean().describe('Whether more results exist'),
46
+ })
47
+
48
+ /**
49
+ * List comments response schema
50
+ *
51
+ * GET /api/tables/:tableId/records/:recordId/comments
52
+ */
53
+ export const listCommentsResponseSchema = z.object({
54
+ comments: z.array(commentSchema).describe('List of comments'),
55
+ pagination: commentPaginationSchema.describe('Pagination metadata'),
56
+ })
57
+
58
+ /**
59
+ * Get single comment response schema
60
+ *
61
+ * GET /api/tables/:tableId/records/:recordId/comments/:commentId
62
+ */
63
+ export const getCommentResponseSchema = commentSchema.describe('Single comment details')
64
+
65
+ /**
66
+ * Create comment response schema
67
+ *
68
+ * POST /api/tables/:tableId/records/:recordId/comments
69
+ */
70
+ export const createCommentResponseSchema = z.object({
71
+ comment: commentSchema.describe('Created comment'),
72
+ })
73
+
74
+ /**
75
+ * Update comment response schema
76
+ *
77
+ * PATCH /api/tables/:tableId/records/:recordId/comments/:commentId
78
+ */
79
+ export const updateCommentResponseSchema = commentSchema.describe('Updated comment details')
80
+
81
+ // ============================================================================
82
+ // Record History Schemas
83
+ // ============================================================================
84
+
85
+ /**
86
+ * Record history entry schema
87
+ */
88
+ export const recordHistoryEntrySchema = z.object({
89
+ id: z.string().describe('Activity log identifier'),
90
+ userId: z.string().optional().describe('User who performed the action'),
91
+ action: z.enum(['create', 'update', 'delete', 'restore']).describe('Action type'),
92
+ tableName: z.string().describe('Name of the affected table'),
93
+ recordId: z.union([z.string(), z.number()]).describe('ID of the affected record'),
94
+ changes: z
95
+ .record(z.string(), z.unknown())
96
+ .nullable()
97
+ .describe('Field changes (null for delete/restore)'),
98
+ createdAt: z.string().describe('ISO 8601 timestamp'),
99
+ user: z
100
+ .object({
101
+ id: z.string().describe('User identifier'),
102
+ name: z.string().describe('User display name'),
103
+ email: z.string().describe('User email address'),
104
+ })
105
+ .nullable()
106
+ .describe('User details (null for system activities)'),
107
+ })
108
+
109
+ /**
110
+ * Get record history response schema
111
+ *
112
+ * GET /api/tables/:tableId/records/:recordId/history
113
+ */
114
+ export const getRecordHistoryResponseSchema = z.object({
115
+ history: z.array(recordHistoryEntrySchema).describe('List of history entries'),
116
+ pagination: z
117
+ .object({
118
+ total: z.number().int().describe('Total activity count'),
119
+ limit: z.number().int().describe('Items returned'),
120
+ offset: z.number().int().describe('Items skipped'),
121
+ })
122
+ .optional()
123
+ .describe('Pagination metadata'),
124
+ })
125
+
126
+ // ============================================================================
127
+ // TypeScript Types
128
+ // ============================================================================
129
+
130
+ export type Comment = z.infer<typeof commentSchema>
131
+ export type RecordHistoryEntry = z.infer<typeof recordHistoryEntrySchema>
@@ -20,6 +20,9 @@
20
20
  * - request: Request input validation
21
21
  */
22
22
 
23
+ // Activity log schemas
24
+ export * from './activity'
25
+
23
26
  // Analytics schemas
24
27
  export * from './analytics'
25
28
 
@@ -35,8 +38,14 @@ export * from './health'
35
38
  // Authentication schemas
36
39
  export * from './auth'
37
40
 
41
+ // Comment and history schemas
42
+ export * from './comments'
43
+
38
44
  // Table and record schemas
39
45
  export * from './tables'
40
46
 
47
+ // OpenAPI parameter schemas
48
+ export * from './params'
49
+
41
50
  // Request schemas (input validation)
42
51
  export * from './request'