@revealui/contracts 1.0.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.
Files changed (191) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +160 -0
  3. package/dist/a2a/index.d.ts +383 -0
  4. package/dist/a2a/index.d.ts.map +1 -0
  5. package/dist/a2a/index.js +276 -0
  6. package/dist/a2a/index.js.map +1 -0
  7. package/dist/actions/action-validator.d.ts +48 -0
  8. package/dist/actions/action-validator.d.ts.map +1 -0
  9. package/dist/actions/action-validator.js +288 -0
  10. package/dist/actions/action-validator.js.map +1 -0
  11. package/dist/actions/index.d.ts +7 -0
  12. package/dist/actions/index.d.ts.map +1 -0
  13. package/dist/actions/index.js +7 -0
  14. package/dist/actions/index.js.map +1 -0
  15. package/dist/agents/index.d.ts +628 -0
  16. package/dist/agents/index.d.ts.map +1 -0
  17. package/dist/agents/index.js +511 -0
  18. package/dist/agents/index.js.map +1 -0
  19. package/dist/agents/types.d.ts +22 -0
  20. package/dist/agents/types.d.ts.map +1 -0
  21. package/dist/agents/types.js +2 -0
  22. package/dist/agents/types.js.map +1 -0
  23. package/dist/api/auth.d.ts +60 -0
  24. package/dist/api/auth.d.ts.map +1 -0
  25. package/dist/api/auth.js +84 -0
  26. package/dist/api/auth.js.map +1 -0
  27. package/dist/api/chat.d.ts +45 -0
  28. package/dist/api/chat.d.ts.map +1 -0
  29. package/dist/api/chat.js +55 -0
  30. package/dist/api/chat.js.map +1 -0
  31. package/dist/api/gdpr.d.ts +39 -0
  32. package/dist/api/gdpr.d.ts.map +1 -0
  33. package/dist/api/gdpr.js +53 -0
  34. package/dist/api/gdpr.js.map +1 -0
  35. package/dist/cms/collection.d.ts +108 -0
  36. package/dist/cms/collection.d.ts.map +1 -0
  37. package/dist/cms/collection.js +144 -0
  38. package/dist/cms/collection.js.map +1 -0
  39. package/dist/cms/compat.d.ts +128 -0
  40. package/dist/cms/compat.d.ts.map +1 -0
  41. package/dist/cms/compat.js +141 -0
  42. package/dist/cms/compat.js.map +1 -0
  43. package/dist/cms/config-contract.d.ts +278 -0
  44. package/dist/cms/config-contract.d.ts.map +1 -0
  45. package/dist/cms/config-contract.js +220 -0
  46. package/dist/cms/config-contract.js.map +1 -0
  47. package/dist/cms/config.d.ts +351 -0
  48. package/dist/cms/config.d.ts.map +1 -0
  49. package/dist/cms/config.js +50 -0
  50. package/dist/cms/config.js.map +1 -0
  51. package/dist/cms/errors.d.ts +122 -0
  52. package/dist/cms/errors.d.ts.map +1 -0
  53. package/dist/cms/errors.js +163 -0
  54. package/dist/cms/errors.js.map +1 -0
  55. package/dist/cms/extensibility.d.ts +211 -0
  56. package/dist/cms/extensibility.d.ts.map +1 -0
  57. package/dist/cms/extensibility.js +313 -0
  58. package/dist/cms/extensibility.js.map +1 -0
  59. package/dist/cms/field.d.ts +69 -0
  60. package/dist/cms/field.d.ts.map +1 -0
  61. package/dist/cms/field.js +94 -0
  62. package/dist/cms/field.js.map +1 -0
  63. package/dist/cms/functions.d.ts +466 -0
  64. package/dist/cms/functions.d.ts.map +1 -0
  65. package/dist/cms/functions.js +19 -0
  66. package/dist/cms/functions.js.map +1 -0
  67. package/dist/cms/global.d.ts +45 -0
  68. package/dist/cms/global.d.ts.map +1 -0
  69. package/dist/cms/global.js +62 -0
  70. package/dist/cms/global.js.map +1 -0
  71. package/dist/cms/index.d.ts +23 -0
  72. package/dist/cms/index.d.ts.map +1 -0
  73. package/dist/cms/index.js +42 -0
  74. package/dist/cms/index.js.map +1 -0
  75. package/dist/cms/structure.d.ts +1601 -0
  76. package/dist/cms/structure.d.ts.map +1 -0
  77. package/dist/cms/structure.js +757 -0
  78. package/dist/cms/structure.js.map +1 -0
  79. package/dist/content/index.d.ts +1542 -0
  80. package/dist/content/index.d.ts.map +1 -0
  81. package/dist/content/index.js +522 -0
  82. package/dist/content/index.js.map +1 -0
  83. package/dist/database/bridge.d.ts +177 -0
  84. package/dist/database/bridge.d.ts.map +1 -0
  85. package/dist/database/bridge.js +139 -0
  86. package/dist/database/bridge.js.map +1 -0
  87. package/dist/database/index.d.ts +8 -0
  88. package/dist/database/index.d.ts.map +1 -0
  89. package/dist/database/index.js +9 -0
  90. package/dist/database/index.js.map +1 -0
  91. package/dist/database/type-bridge.d.ts +178 -0
  92. package/dist/database/type-bridge.d.ts.map +1 -0
  93. package/dist/database/type-bridge.js +154 -0
  94. package/dist/database/type-bridge.js.map +1 -0
  95. package/dist/entities/agent-context.d.ts +280 -0
  96. package/dist/entities/agent-context.d.ts.map +1 -0
  97. package/dist/entities/agent-context.js +390 -0
  98. package/dist/entities/agent-context.js.map +1 -0
  99. package/dist/entities/agent-memory.d.ts +661 -0
  100. package/dist/entities/agent-memory.d.ts.map +1 -0
  101. package/dist/entities/agent-memory.js +544 -0
  102. package/dist/entities/agent-memory.js.map +1 -0
  103. package/dist/entities/board.d.ts +95 -0
  104. package/dist/entities/board.d.ts.map +1 -0
  105. package/dist/entities/board.js +99 -0
  106. package/dist/entities/board.js.map +1 -0
  107. package/dist/entities/code-provenance.d.ts +270 -0
  108. package/dist/entities/code-provenance.d.ts.map +1 -0
  109. package/dist/entities/code-provenance.js +339 -0
  110. package/dist/entities/code-provenance.js.map +1 -0
  111. package/dist/entities/index.d.ts +22 -0
  112. package/dist/entities/index.d.ts.map +1 -0
  113. package/dist/entities/index.js +22 -0
  114. package/dist/entities/index.js.map +1 -0
  115. package/dist/entities/media.d.ts +485 -0
  116. package/dist/entities/media.d.ts.map +1 -0
  117. package/dist/entities/media.js +606 -0
  118. package/dist/entities/media.js.map +1 -0
  119. package/dist/entities/page-revision.d.ts +390 -0
  120. package/dist/entities/page-revision.d.ts.map +1 -0
  121. package/dist/entities/page-revision.js +406 -0
  122. package/dist/entities/page-revision.js.map +1 -0
  123. package/dist/entities/page.d.ts +2349 -0
  124. package/dist/entities/page.d.ts.map +1 -0
  125. package/dist/entities/page.js +377 -0
  126. package/dist/entities/page.js.map +1 -0
  127. package/dist/entities/post.d.ts +619 -0
  128. package/dist/entities/post.d.ts.map +1 -0
  129. package/dist/entities/post.js +555 -0
  130. package/dist/entities/post.js.map +1 -0
  131. package/dist/entities/price.d.ts +772 -0
  132. package/dist/entities/price.d.ts.map +1 -0
  133. package/dist/entities/price.js +308 -0
  134. package/dist/entities/price.js.map +1 -0
  135. package/dist/entities/product.d.ts +753 -0
  136. package/dist/entities/product.d.ts.map +1 -0
  137. package/dist/entities/product.js +307 -0
  138. package/dist/entities/product.js.map +1 -0
  139. package/dist/entities/session.d.ts +222 -0
  140. package/dist/entities/session.d.ts.map +1 -0
  141. package/dist/entities/session.js +253 -0
  142. package/dist/entities/session.js.map +1 -0
  143. package/dist/entities/site.d.ts +387 -0
  144. package/dist/entities/site.d.ts.map +1 -0
  145. package/dist/entities/site.js +348 -0
  146. package/dist/entities/site.js.map +1 -0
  147. package/dist/entities/ticket-comment.d.ts +49 -0
  148. package/dist/entities/ticket-comment.d.ts.map +1 -0
  149. package/dist/entities/ticket-comment.js +58 -0
  150. package/dist/entities/ticket-comment.js.map +1 -0
  151. package/dist/entities/ticket-label.d.ts +64 -0
  152. package/dist/entities/ticket-label.d.ts.map +1 -0
  153. package/dist/entities/ticket-label.js +77 -0
  154. package/dist/entities/ticket-label.js.map +1 -0
  155. package/dist/entities/ticket.d.ts +204 -0
  156. package/dist/entities/ticket.d.ts.map +1 -0
  157. package/dist/entities/ticket.js +205 -0
  158. package/dist/entities/ticket.js.map +1 -0
  159. package/dist/entities/user.d.ts +336 -0
  160. package/dist/entities/user.d.ts.map +1 -0
  161. package/dist/entities/user.js +255 -0
  162. package/dist/entities/user.js.map +1 -0
  163. package/dist/foundation/contract.d.ts +221 -0
  164. package/dist/foundation/contract.d.ts.map +1 -0
  165. package/dist/foundation/contract.js +133 -0
  166. package/dist/foundation/contract.js.map +1 -0
  167. package/dist/foundation/index.d.ts +7 -0
  168. package/dist/foundation/index.d.ts.map +1 -0
  169. package/dist/foundation/index.js +7 -0
  170. package/dist/foundation/index.js.map +1 -0
  171. package/dist/generated/contracts.d.ts +1514 -0
  172. package/dist/generated/contracts.d.ts.map +1 -0
  173. package/dist/generated/contracts.js +959 -0
  174. package/dist/generated/contracts.js.map +1 -0
  175. package/dist/generated/database.d.ts +48 -0
  176. package/dist/generated/database.d.ts.map +1 -0
  177. package/dist/generated/database.js +17 -0
  178. package/dist/generated/database.js.map +1 -0
  179. package/dist/generated/zod-schemas.d.ts +14793 -0
  180. package/dist/generated/zod-schemas.d.ts.map +1 -0
  181. package/dist/generated/zod-schemas.js +547 -0
  182. package/dist/generated/zod-schemas.js.map +1 -0
  183. package/dist/index.d.ts +50 -0
  184. package/dist/index.d.ts.map +1 -0
  185. package/dist/index.js +81 -0
  186. package/dist/index.js.map +1 -0
  187. package/dist/representation/index.d.ts +304 -0
  188. package/dist/representation/index.d.ts.map +1 -0
  189. package/dist/representation/index.js +280 -0
  190. package/dist/representation/index.js.map +1 -0
  191. package/package.json +117 -0
@@ -0,0 +1,348 @@
1
+ /**
2
+ * Site Schema
3
+ *
4
+ * A Site is a project container - it holds pages, assets, and configuration.
5
+ * Sites are the primary unit of ownership and collaboration.
6
+ *
7
+ * Sites support both human management (through UI) and agent management
8
+ * (through structured APIs), enabling true human-AI collaboration.
9
+ *
10
+ * This schema extends the auto-generated SitesSelectSchema from the database
11
+ * and adds:
12
+ * - Structured validation for JSONB fields (settings, theme)
13
+ * - Dual representation (human + agent views)
14
+ * - Business logic and computed fields
15
+ */
16
+ import { z } from 'zod/v4';
17
+ import { createTimestamps, DualEntitySchema, REPRESENTATION_SCHEMA_VERSION, toAgentRepresentation, toHumanRepresentation, } from '../representation/index.js';
18
+ // NOTE: Auto-generated base schema available for future tight integration:
19
+ // import { SitesSelectSchema, SitesInsertSchema } from '../generated/zod-schemas.js'
20
+ // =============================================================================
21
+ // Schema Version
22
+ // =============================================================================
23
+ export const SITE_SCHEMA_VERSION = 1;
24
+ // =============================================================================
25
+ // Site Status
26
+ // =============================================================================
27
+ export const SiteStatusSchema = z.enum([
28
+ 'draft', // Not published
29
+ 'published', // Live
30
+ 'archived', // Soft deleted
31
+ 'maintenance', // Temporarily offline
32
+ ]);
33
+ // =============================================================================
34
+ // Site Theme
35
+ // =============================================================================
36
+ export const SiteThemeSchema = z.object({
37
+ /** Primary brand color */
38
+ primaryColor: z
39
+ .string()
40
+ .regex(/^#[0-9A-Fa-f]{6}$/)
41
+ .optional(),
42
+ /** Secondary color */
43
+ secondaryColor: z
44
+ .string()
45
+ .regex(/^#[0-9A-Fa-f]{6}$/)
46
+ .optional(),
47
+ /** Accent color */
48
+ accentColor: z
49
+ .string()
50
+ .regex(/^#[0-9A-Fa-f]{6}$/)
51
+ .optional(),
52
+ /** Background color */
53
+ backgroundColor: z
54
+ .string()
55
+ .regex(/^#[0-9A-Fa-f]{6}$/)
56
+ .optional(),
57
+ /** Text color */
58
+ textColor: z
59
+ .string()
60
+ .regex(/^#[0-9A-Fa-f]{6}$/)
61
+ .optional(),
62
+ /** Font family */
63
+ fontFamily: z.string().optional(),
64
+ /** Heading font family */
65
+ headingFontFamily: z.string().optional(),
66
+ /** Border radius preset */
67
+ borderRadius: z.enum(['none', 'sm', 'md', 'lg', 'full']).default('md'),
68
+ /** Color mode */
69
+ mode: z.enum(['light', 'dark', 'auto']).default('auto'),
70
+ /** Custom CSS variables */
71
+ customVariables: z.record(z.string(), z.string()).optional(),
72
+ });
73
+ // =============================================================================
74
+ // Site SEO
75
+ // =============================================================================
76
+ export const SiteSeoSchema = z.object({
77
+ /** Default page title */
78
+ title: z.string().max(60).optional(),
79
+ /** Default meta description */
80
+ description: z.string().max(160).optional(),
81
+ /** Default social image */
82
+ image: z.url().optional(),
83
+ /** Twitter handle */
84
+ twitterHandle: z.string().optional(),
85
+ /** Facebook App ID */
86
+ facebookAppId: z.string().optional(),
87
+ /** Google site verification */
88
+ googleSiteVerification: z.string().optional(),
89
+ /** Robots directive */
90
+ robots: z.string().optional(),
91
+ });
92
+ // =============================================================================
93
+ // Site Settings
94
+ // =============================================================================
95
+ export const SiteSettingsSchema = z.object({
96
+ /** Custom domain */
97
+ domain: z.string().optional(),
98
+ /** Subdomain on RevealUI */
99
+ subdomain: z
100
+ .string()
101
+ .regex(/^[a-z0-9-]+$/)
102
+ .optional(),
103
+ /** Default language */
104
+ language: z.string().default('en'),
105
+ /** Supported languages */
106
+ supportedLanguages: z.array(z.string()).optional(),
107
+ /** Timezone */
108
+ timezone: z.string().default('UTC'),
109
+ /** SEO defaults */
110
+ seo: SiteSeoSchema.optional(),
111
+ /** Analytics tracking ID */
112
+ analyticsId: z.string().optional(),
113
+ /** Whether to allow AI agents to modify this site */
114
+ allowAgentEdits: z.boolean().default(true),
115
+ /** Agent edit restrictions */
116
+ agentRestrictions: z
117
+ .object({
118
+ /** Can agents publish? */
119
+ canPublish: z.boolean().default(false),
120
+ /** Can agents delete pages? */
121
+ canDeletePages: z.boolean().default(false),
122
+ /** Can agents modify settings? */
123
+ canModifySettings: z.boolean().default(false),
124
+ /** Pages agents cannot edit */
125
+ protectedPages: z.array(z.string()).optional(),
126
+ })
127
+ .optional(),
128
+ /** Custom 404 page ID */
129
+ notFoundPageId: z.string().optional(),
130
+ /** Favicon URL */
131
+ faviconUrl: z.url().optional(),
132
+ /** Social links */
133
+ socialLinks: z
134
+ .array(z.object({
135
+ platform: z.string(),
136
+ url: z.url(),
137
+ }))
138
+ .optional(),
139
+ });
140
+ // =============================================================================
141
+ // Site Collaborator
142
+ // =============================================================================
143
+ export const SiteCollaboratorSchema = z.object({
144
+ userId: z.string(),
145
+ role: z.enum(['admin', 'editor', 'viewer']),
146
+ addedAt: z.string().datetime(),
147
+ addedBy: z.string(),
148
+ });
149
+ // =============================================================================
150
+ // Site Schema
151
+ // =============================================================================
152
+ export const SiteSchema = DualEntitySchema.extend({
153
+ /** Schema version for migrations */
154
+ schemaVersion: z.number().int().default(SITE_SCHEMA_VERSION),
155
+ /** Site name */
156
+ name: z.string().min(1).max(100),
157
+ /** URL-safe slug */
158
+ slug: z
159
+ .string()
160
+ .regex(/^[a-z0-9-]+$/)
161
+ .min(1)
162
+ .max(50),
163
+ /** Site description */
164
+ description: z.string().max(500).optional(),
165
+ /** Owner user ID */
166
+ ownerId: z.string(),
167
+ /** Current status */
168
+ status: SiteStatusSchema,
169
+ /** Site settings */
170
+ settings: SiteSettingsSchema,
171
+ /** Collaborator user IDs with their roles */
172
+ collaborators: z.array(SiteCollaboratorSchema).default([]),
173
+ /** Template this site was created from (if any) */
174
+ templateId: z.string().optional(),
175
+ /** Style/theme configuration (human-adjustable) */
176
+ theme: SiteThemeSchema.optional(),
177
+ /** Page count (denormalized for quick access) */
178
+ pageCount: z.number().int().nonnegative().default(0),
179
+ /** Last published timestamp */
180
+ publishedAt: z.string().datetime().optional(),
181
+ });
182
+ // =============================================================================
183
+ // Site Creation
184
+ // =============================================================================
185
+ export const CreateSiteInputSchema = z.object({
186
+ name: z.string().min(1).max(100),
187
+ slug: z
188
+ .string()
189
+ .regex(/^[a-z0-9-]+$/)
190
+ .min(1)
191
+ .max(50),
192
+ description: z.string().max(500).optional(),
193
+ ownerId: z.string(),
194
+ templateId: z.string().optional(),
195
+ settings: SiteSettingsSchema.partial().optional(),
196
+ theme: SiteThemeSchema.optional(),
197
+ });
198
+ /**
199
+ * Creates a new site with dual representation
200
+ */
201
+ export function createSite(id, input) {
202
+ const timestamps = createTimestamps();
203
+ const settings = {
204
+ language: input.settings?.language ?? 'en',
205
+ timezone: input.settings?.timezone ?? 'UTC',
206
+ allowAgentEdits: input.settings?.allowAgentEdits ?? true,
207
+ ...(input.settings && {
208
+ supportedLanguages: input.settings.supportedLanguages,
209
+ seo: input.settings.seo,
210
+ analyticsId: input.settings.analyticsId,
211
+ }),
212
+ };
213
+ return {
214
+ id,
215
+ version: REPRESENTATION_SCHEMA_VERSION,
216
+ schemaVersion: SITE_SCHEMA_VERSION,
217
+ name: input.name,
218
+ slug: input.slug,
219
+ description: input.description,
220
+ ownerId: input.ownerId,
221
+ status: 'draft',
222
+ settings,
223
+ templateId: input.templateId,
224
+ theme: input.theme,
225
+ collaborators: [],
226
+ pageCount: 0,
227
+ human: toHumanRepresentation({
228
+ name: input.name,
229
+ ...(input.description && { description: input.description }),
230
+ icon: 'globe',
231
+ }),
232
+ agent: toAgentRepresentation('site', {
233
+ actions: [
234
+ {
235
+ name: 'addPage',
236
+ description: 'Add a new page to this site',
237
+ params: {
238
+ title: {
239
+ type: 'string',
240
+ required: true,
241
+ description: 'Page title',
242
+ },
243
+ slug: { type: 'string', required: true, description: 'URL slug' },
244
+ templateId: {
245
+ type: 'string',
246
+ required: false,
247
+ description: 'Template to use',
248
+ },
249
+ },
250
+ },
251
+ {
252
+ name: 'updateSettings',
253
+ description: 'Update site settings',
254
+ params: {
255
+ settings: {
256
+ type: 'object',
257
+ required: true,
258
+ description: 'Partial settings to update',
259
+ },
260
+ },
261
+ },
262
+ {
263
+ name: 'updateTheme',
264
+ description: 'Update site theme/styling',
265
+ params: {
266
+ theme: {
267
+ type: 'object',
268
+ required: true,
269
+ description: 'Theme settings',
270
+ },
271
+ },
272
+ },
273
+ {
274
+ name: 'publish',
275
+ description: 'Publish the site to make it live',
276
+ params: {},
277
+ requiredCapabilities: ['publish'],
278
+ sideEffects: ['Site becomes publicly accessible'],
279
+ },
280
+ {
281
+ name: 'unpublish',
282
+ description: 'Take the site offline',
283
+ params: {},
284
+ requiredCapabilities: ['publish'],
285
+ sideEffects: ['Site becomes inaccessible'],
286
+ },
287
+ ],
288
+ constraints: settings.allowAgentEdits
289
+ ? []
290
+ : [
291
+ {
292
+ type: 'readonly',
293
+ params: {},
294
+ message: 'Agent edits are disabled for this site',
295
+ },
296
+ ],
297
+ metadata: {
298
+ status: 'draft',
299
+ hasTemplate: !!input.templateId,
300
+ language: settings.language,
301
+ },
302
+ keywords: [input.name.toLowerCase(), input.slug, 'site', 'website'],
303
+ }),
304
+ ...timestamps,
305
+ };
306
+ }
307
+ // =============================================================================
308
+ // Site Update
309
+ // =============================================================================
310
+ export const UpdateSiteInputSchema = z.object({
311
+ name: z.string().min(1).max(100).optional(),
312
+ description: z.string().max(500).optional(),
313
+ status: SiteStatusSchema.optional(),
314
+ settings: SiteSettingsSchema.partial().optional(),
315
+ theme: SiteThemeSchema.partial().optional(),
316
+ });
317
+ // =============================================================================
318
+ // Site Utilities
319
+ // =============================================================================
320
+ /**
321
+ * Checks if a user has permission to perform an action on a site
322
+ */
323
+ export function canUserPerformAction(site, userId, action) {
324
+ // Owner can do everything
325
+ if (site.ownerId === userId)
326
+ return true;
327
+ const collaborator = site.collaborators.find((c) => c.userId === userId);
328
+ if (!collaborator)
329
+ return false;
330
+ switch (action) {
331
+ case 'view':
332
+ return true;
333
+ case 'edit':
334
+ return collaborator.role === 'editor' || collaborator.role === 'admin';
335
+ case 'admin':
336
+ case 'delete':
337
+ return collaborator.role === 'admin';
338
+ default:
339
+ return false;
340
+ }
341
+ }
342
+ /**
343
+ * Checks if an agent can edit this site
344
+ */
345
+ export function canAgentEditSite(site) {
346
+ return site.settings.allowAgentEdits;
347
+ }
348
+ //# sourceMappingURL=site.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site.js","sourceRoot":"","sources":["../../src/entities/site.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Ticket Comment Entity Contract
3
+ *
4
+ * Comments on tickets. Supports rich text (JSON) body content.
5
+ *
6
+ * Business Rules:
7
+ * - Creating a comment increments ticket.commentCount
8
+ * - Deleting a comment decrements ticket.commentCount (min 0)
9
+ * - Body is stored as Lexical/JSON rich text
10
+ * - authorId is nullable (system-generated comments)
11
+ */
12
+ import { z } from 'zod/v4';
13
+ export declare const TICKET_COMMENT_SCHEMA_VERSION = 1;
14
+ export declare const TicketCommentObjectSchema: z.ZodObject<{
15
+ id: z.ZodString;
16
+ schemaVersion: z.ZodDefault<z.ZodString>;
17
+ ticketId: z.ZodString;
18
+ authorId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
19
+ body: z.ZodUnknown;
20
+ createdAt: z.ZodDate;
21
+ updatedAt: z.ZodDate;
22
+ }, z.core.$strip>;
23
+ export declare const TicketCommentSchema: z.ZodObject<{
24
+ id: z.ZodString;
25
+ schemaVersion: z.ZodDefault<z.ZodString>;
26
+ ticketId: z.ZodString;
27
+ authorId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
28
+ body: z.ZodUnknown;
29
+ createdAt: z.ZodDate;
30
+ updatedAt: z.ZodDate;
31
+ }, z.core.$strip>;
32
+ export type TicketComment = z.infer<typeof TicketCommentSchema>;
33
+ export declare const TicketCommentInsertSchema: z.ZodObject<{
34
+ id: z.ZodString;
35
+ schemaVersion: z.ZodDefault<z.ZodString>;
36
+ authorId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
37
+ ticketId: z.ZodString;
38
+ body: z.ZodUnknown;
39
+ createdAt: z.ZodOptional<z.ZodDate>;
40
+ updatedAt: z.ZodOptional<z.ZodDate>;
41
+ }, z.core.$strip>;
42
+ export type TicketCommentInsert = z.infer<typeof TicketCommentInsertSchema>;
43
+ export declare function isSystemComment(comment: TicketComment): boolean;
44
+ export declare function isAuthoredBy(comment: TicketComment, userId: string): boolean;
45
+ export declare function createCommentInsert(ticketId: string, body: unknown, options?: {
46
+ id?: string;
47
+ authorId?: string;
48
+ }): TicketCommentInsert;
49
+ //# sourceMappingURL=ticket-comment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-comment.d.ts","sourceRoot":"","sources":["../../src/entities/ticket-comment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAM1B,eAAO,MAAM,6BAA6B,IAAI,CAAA;AAM9C,eAAO,MAAM,yBAAyB;;;;;;;;iBAQpC,CAAA;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;iBAA4B,CAAA;AAC5D,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D,eAAO,MAAM,yBAAyB;;;;;;;;iBAMpC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAM3E,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAE/D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5E;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,mBAAmB,CAWrB"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Ticket Comment Entity Contract
3
+ *
4
+ * Comments on tickets. Supports rich text (JSON) body content.
5
+ *
6
+ * Business Rules:
7
+ * - Creating a comment increments ticket.commentCount
8
+ * - Deleting a comment decrements ticket.commentCount (min 0)
9
+ * - Body is stored as Lexical/JSON rich text
10
+ * - authorId is nullable (system-generated comments)
11
+ */
12
+ import { z } from 'zod/v4';
13
+ // =============================================================================
14
+ // Constants
15
+ // =============================================================================
16
+ export const TICKET_COMMENT_SCHEMA_VERSION = 1;
17
+ // =============================================================================
18
+ // Schema
19
+ // =============================================================================
20
+ export const TicketCommentObjectSchema = z.object({
21
+ id: z.string().min(1),
22
+ schemaVersion: z.string().default(String(TICKET_COMMENT_SCHEMA_VERSION)),
23
+ ticketId: z.string().min(1),
24
+ authorId: z.string().nullable().optional(),
25
+ body: z.unknown(),
26
+ createdAt: z.date(),
27
+ updatedAt: z.date(),
28
+ });
29
+ export const TicketCommentSchema = TicketCommentObjectSchema;
30
+ export const TicketCommentInsertSchema = TicketCommentObjectSchema.omit({
31
+ createdAt: true,
32
+ updatedAt: true,
33
+ }).extend({
34
+ createdAt: z.date().optional(),
35
+ updatedAt: z.date().optional(),
36
+ });
37
+ // =============================================================================
38
+ // Helpers
39
+ // =============================================================================
40
+ export function isSystemComment(comment) {
41
+ return comment.authorId === null || comment.authorId === undefined;
42
+ }
43
+ export function isAuthoredBy(comment, userId) {
44
+ return comment.authorId === userId;
45
+ }
46
+ export function createCommentInsert(ticketId, body, options) {
47
+ const now = new Date();
48
+ return {
49
+ id: options?.id ?? crypto.randomUUID(),
50
+ schemaVersion: String(TICKET_COMMENT_SCHEMA_VERSION),
51
+ ticketId,
52
+ authorId: options?.authorId ?? null,
53
+ body,
54
+ createdAt: now,
55
+ updatedAt: now,
56
+ };
57
+ }
58
+ //# sourceMappingURL=ticket-comment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-comment.js","sourceRoot":"","sources":["../../src/entities/ticket-comment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAE1B,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAA;AAE9C,gFAAgF;AAChF,SAAS;AACT,gFAAgF;AAEhF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC;IACxE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC1C,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;IACjB,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE;IACnB,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE;CACpB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,yBAAyB,CAAA;AAG5D,MAAM,CAAC,MAAM,yBAAyB,GAAG,yBAAyB,CAAC,IAAI,CAAC;IACtE,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;CAChB,CAAC,CAAC,MAAM,CAAC;IACR,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IAC9B,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAA;AAIF,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAEhF,MAAM,UAAU,eAAe,CAAC,OAAsB;IACpD,OAAO,OAAO,CAAC,QAAQ,KAAK,IAAI,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAA;AACpE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAsB,EAAE,MAAc;IACjE,OAAO,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,IAAa,EACb,OAA4C;IAE5C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;IACtB,OAAO;QACL,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,MAAM,CAAC,UAAU,EAAE;QACtC,aAAa,EAAE,MAAM,CAAC,6BAA6B,CAAC;QACpD,QAAQ;QACR,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,IAAI;QACnC,IAAI;QACJ,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;KACf,CAAA;AACH,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Ticket Label Entity Contract
3
+ *
4
+ * Labels for categorizing tickets. Labels can be assigned to multiple tickets
5
+ * and tickets can have multiple labels (many-to-many via ticket_label_assignments).
6
+ *
7
+ * Business Rules:
8
+ * - Label slug must be unique per tenant
9
+ * - Color is optional (hex string e.g. "#ff0000")
10
+ * - Labels are tenant-scoped when tenantId is set
11
+ */
12
+ import { z } from 'zod/v4';
13
+ export declare const TICKET_LABEL_SCHEMA_VERSION = 1;
14
+ export declare const LABEL_LIMITS: {
15
+ readonly MIN_NAME_LENGTH: 1;
16
+ readonly MAX_NAME_LENGTH: 100;
17
+ readonly MIN_SLUG_LENGTH: 1;
18
+ readonly MAX_SLUG_LENGTH: 100;
19
+ readonly MAX_DESCRIPTION_LENGTH: 500;
20
+ readonly MAX_COLOR_LENGTH: 20;
21
+ };
22
+ export declare const TicketLabelObjectSchema: z.ZodObject<{
23
+ id: z.ZodString;
24
+ schemaVersion: z.ZodDefault<z.ZodString>;
25
+ name: z.ZodString;
26
+ slug: z.ZodString;
27
+ color: z.ZodOptional<z.ZodNullable<z.ZodString>>;
28
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
29
+ tenantId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
30
+ createdAt: z.ZodDate;
31
+ updatedAt: z.ZodDate;
32
+ }, z.core.$strip>;
33
+ export declare const TicketLabelSchema: z.ZodObject<{
34
+ id: z.ZodString;
35
+ schemaVersion: z.ZodDefault<z.ZodString>;
36
+ name: z.ZodString;
37
+ slug: z.ZodString;
38
+ color: z.ZodOptional<z.ZodNullable<z.ZodString>>;
39
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
40
+ tenantId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
41
+ createdAt: z.ZodDate;
42
+ updatedAt: z.ZodDate;
43
+ }, z.core.$strip>;
44
+ export type TicketLabel = z.infer<typeof TicketLabelSchema>;
45
+ export declare const TicketLabelInsertSchema: z.ZodObject<{
46
+ name: z.ZodString;
47
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
48
+ color: z.ZodOptional<z.ZodNullable<z.ZodString>>;
49
+ id: z.ZodString;
50
+ schemaVersion: z.ZodDefault<z.ZodString>;
51
+ slug: z.ZodString;
52
+ tenantId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
53
+ createdAt: z.ZodOptional<z.ZodDate>;
54
+ updatedAt: z.ZodOptional<z.ZodDate>;
55
+ }, z.core.$strip>;
56
+ export type TicketLabelInsert = z.infer<typeof TicketLabelInsertSchema>;
57
+ export declare function createLabelInsert(name: string, slug: string, options?: {
58
+ id?: string;
59
+ color?: string;
60
+ description?: string;
61
+ tenantId?: string;
62
+ }): TicketLabelInsert;
63
+ export declare function generateLabelSlug(name: string): string;
64
+ //# sourceMappingURL=ticket-label.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-label.d.ts","sourceRoot":"","sources":["../../src/entities/ticket-label.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAM1B,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C,eAAO,MAAM,YAAY;;;;;;;CAOf,CAAA;AAMV,eAAO,MAAM,uBAAuB;;;;;;;;;;iBAclC,CAAA;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;iBAA0B,CAAA;AACxD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,eAAO,MAAM,uBAAuB;;;;;;;;;;iBAMlC,CAAA;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAMvE,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACjF,iBAAiB,CAanB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQtD"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Ticket Label Entity Contract
3
+ *
4
+ * Labels for categorizing tickets. Labels can be assigned to multiple tickets
5
+ * and tickets can have multiple labels (many-to-many via ticket_label_assignments).
6
+ *
7
+ * Business Rules:
8
+ * - Label slug must be unique per tenant
9
+ * - Color is optional (hex string e.g. "#ff0000")
10
+ * - Labels are tenant-scoped when tenantId is set
11
+ */
12
+ import { z } from 'zod/v4';
13
+ // =============================================================================
14
+ // Constants
15
+ // =============================================================================
16
+ export const TICKET_LABEL_SCHEMA_VERSION = 1;
17
+ export const LABEL_LIMITS = {
18
+ MIN_NAME_LENGTH: 1,
19
+ MAX_NAME_LENGTH: 100,
20
+ MIN_SLUG_LENGTH: 1,
21
+ MAX_SLUG_LENGTH: 100,
22
+ MAX_DESCRIPTION_LENGTH: 500,
23
+ MAX_COLOR_LENGTH: 20,
24
+ };
25
+ // =============================================================================
26
+ // Schema
27
+ // =============================================================================
28
+ export const TicketLabelObjectSchema = z.object({
29
+ id: z.string().min(1),
30
+ schemaVersion: z.string().default(String(TICKET_LABEL_SCHEMA_VERSION)),
31
+ name: z.string().min(LABEL_LIMITS.MIN_NAME_LENGTH).max(LABEL_LIMITS.MAX_NAME_LENGTH),
32
+ slug: z
33
+ .string()
34
+ .min(LABEL_LIMITS.MIN_SLUG_LENGTH)
35
+ .max(LABEL_LIMITS.MAX_SLUG_LENGTH)
36
+ .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, 'Slug must be lowercase with hyphens'),
37
+ color: z.string().max(LABEL_LIMITS.MAX_COLOR_LENGTH).nullable().optional(),
38
+ description: z.string().max(LABEL_LIMITS.MAX_DESCRIPTION_LENGTH).nullable().optional(),
39
+ tenantId: z.string().nullable().optional(),
40
+ createdAt: z.date(),
41
+ updatedAt: z.date(),
42
+ });
43
+ export const TicketLabelSchema = TicketLabelObjectSchema;
44
+ export const TicketLabelInsertSchema = TicketLabelObjectSchema.omit({
45
+ createdAt: true,
46
+ updatedAt: true,
47
+ }).extend({
48
+ createdAt: z.date().optional(),
49
+ updatedAt: z.date().optional(),
50
+ });
51
+ // =============================================================================
52
+ // Helpers
53
+ // =============================================================================
54
+ export function createLabelInsert(name, slug, options) {
55
+ const now = new Date();
56
+ return {
57
+ id: options?.id ?? crypto.randomUUID(),
58
+ schemaVersion: String(TICKET_LABEL_SCHEMA_VERSION),
59
+ name,
60
+ slug,
61
+ color: options?.color ?? null,
62
+ description: options?.description ?? null,
63
+ tenantId: options?.tenantId ?? null,
64
+ createdAt: now,
65
+ updatedAt: now,
66
+ };
67
+ }
68
+ export function generateLabelSlug(name) {
69
+ return name
70
+ .toLowerCase()
71
+ .trim()
72
+ .replace(/[^\w\s-]/g, '')
73
+ .replace(/[\s_-]+/g, '-')
74
+ .replace(/^-+|-+$/g, '')
75
+ .slice(0, LABEL_LIMITS.MAX_SLUG_LENGTH);
76
+ }
77
+ //# sourceMappingURL=ticket-label.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-label.js","sourceRoot":"","sources":["../../src/entities/ticket-label.ts"],"names":[],"mappings":"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"}