@zyacreatives/shared 1.5.6 → 1.5.7
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/dist/schemas/project.d.ts +118 -133
- package/dist/schemas/project.js +132 -357
- package/dist/schemas/user.d.ts +8 -8
- package/dist/types/project.d.ts +12 -12
- package/package.json +1 -1
- package/src/schemas/project.ts +138 -371
- package/src/types/project.ts +40 -25
package/src/schemas/project.ts
CHANGED
|
@@ -2,16 +2,29 @@ import { z } from "@hono/zod-openapi";
|
|
|
2
2
|
import { CLIENT_TYPES, ROLES } from "../constants";
|
|
3
3
|
import { CreateFileInputSchema, FileEntitySchema } from "./file";
|
|
4
4
|
|
|
5
|
+
/* ------------------------------ Core Entities ------------------------------ */
|
|
5
6
|
export const ProjectEntitySchema = z
|
|
6
7
|
.object({
|
|
8
|
+
id: z.string().openapi({
|
|
9
|
+
description: "CUID2 of the project.",
|
|
10
|
+
example: "ckl1y9xyz0000qv7a0h1efgh4",
|
|
11
|
+
}),
|
|
12
|
+
userId: z.string().openapi({
|
|
13
|
+
description: "CUID2 of the user who created the project.",
|
|
14
|
+
example: "ckl1y9xyz0000qv7a0h1efgh4",
|
|
15
|
+
}),
|
|
16
|
+
title: z.string().openapi({
|
|
17
|
+
description: "Title of the project.",
|
|
18
|
+
example: "E-commerce Mobile App",
|
|
19
|
+
}),
|
|
7
20
|
description: z.string().optional().openapi({
|
|
8
21
|
description: "Detailed description of the project, max 1000 characters.",
|
|
9
22
|
example:
|
|
10
23
|
"A modern e-commerce mobile application built with React Native.",
|
|
11
24
|
}),
|
|
12
|
-
|
|
13
|
-
description: "
|
|
14
|
-
example: "
|
|
25
|
+
overview: z.string().optional().openapi({
|
|
26
|
+
description: "Brief overview of the project.",
|
|
27
|
+
example: "A comprehensive e-commerce solution for mobile devices.",
|
|
15
28
|
}),
|
|
16
29
|
url: z.string().optional().openapi({
|
|
17
30
|
description: "URL to the project or live demo.",
|
|
@@ -28,24 +41,6 @@ export const ProjectEntitySchema = z
|
|
|
28
41
|
description: "Array of tags associated with the project.",
|
|
29
42
|
example: ["react-native", "e-commerce", "mobile"],
|
|
30
43
|
}),
|
|
31
|
-
startDate: z.coerce
|
|
32
|
-
.date()
|
|
33
|
-
.optional()
|
|
34
|
-
.openapi({
|
|
35
|
-
description: "Start date of the project.",
|
|
36
|
-
example: new Date("2024-01-01"),
|
|
37
|
-
}),
|
|
38
|
-
endDate: z.coerce
|
|
39
|
-
.date()
|
|
40
|
-
.optional()
|
|
41
|
-
.openapi({
|
|
42
|
-
description: "End date of the project.",
|
|
43
|
-
example: new Date("2024-06-30"),
|
|
44
|
-
}),
|
|
45
|
-
overview: z.string().optional().openapi({
|
|
46
|
-
description: "Brief overview of the project.",
|
|
47
|
-
example: "A comprehensive e-commerce solution for mobile devices.",
|
|
48
|
-
}),
|
|
49
44
|
projectCreatorType: z.enum(ROLES).openapi({
|
|
50
45
|
description: "Type of creator who made this project.",
|
|
51
46
|
example: "CREATIVE",
|
|
@@ -62,14 +57,28 @@ export const ProjectEntitySchema = z
|
|
|
62
57
|
description: "Name of the client.",
|
|
63
58
|
example: "Acme Corp",
|
|
64
59
|
}),
|
|
65
|
-
id: z.string().openapi({
|
|
66
|
-
description: "CUID2 of the project.",
|
|
67
|
-
example: "ckl1y9xyz0000qv7a0h1efgh4",
|
|
68
|
-
}),
|
|
69
60
|
isFeatured: z.boolean().optional().openapi({
|
|
70
61
|
description: "Whether the project is featured.",
|
|
71
62
|
example: true,
|
|
72
63
|
}),
|
|
64
|
+
startDate: z.coerce
|
|
65
|
+
.date()
|
|
66
|
+
.optional()
|
|
67
|
+
.openapi({
|
|
68
|
+
description: "Start date of the project.",
|
|
69
|
+
example: new Date("2024-01-01"),
|
|
70
|
+
}),
|
|
71
|
+
endDate: z.coerce
|
|
72
|
+
.date()
|
|
73
|
+
.optional()
|
|
74
|
+
.openapi({
|
|
75
|
+
description: "End date of the project.",
|
|
76
|
+
example: new Date("2024-06-30"),
|
|
77
|
+
}),
|
|
78
|
+
searchVector: z.string().openapi({
|
|
79
|
+
description: "Search vector for full-text search indexing.",
|
|
80
|
+
example: "ecommerce mobile app react native",
|
|
81
|
+
}),
|
|
73
82
|
createdAt: z.coerce.date().openapi({
|
|
74
83
|
description: "Timestamp when the project was created.",
|
|
75
84
|
example: new Date("2024-01-01T00:00:00.000Z"),
|
|
@@ -78,14 +87,6 @@ export const ProjectEntitySchema = z
|
|
|
78
87
|
description: "Timestamp when the project was last updated.",
|
|
79
88
|
example: new Date("2024-06-30T00:00:00.000Z"),
|
|
80
89
|
}),
|
|
81
|
-
userId: z.string().openapi({
|
|
82
|
-
description: "CUID2 of the user who created the project.",
|
|
83
|
-
example: "ckl1y9xyz0000qv7a0h1efgh4",
|
|
84
|
-
}),
|
|
85
|
-
searchVector: z.string().openapi({
|
|
86
|
-
description: "Search vector for full-text search indexing.",
|
|
87
|
-
example: "ecommerce mobile app react native",
|
|
88
|
-
}),
|
|
89
90
|
})
|
|
90
91
|
.openapi({
|
|
91
92
|
title: "Project DB Entity",
|
|
@@ -94,6 +95,13 @@ export const ProjectEntitySchema = z
|
|
|
94
95
|
|
|
95
96
|
export const ProjectFileEntitySchema = z
|
|
96
97
|
.object({
|
|
98
|
+
id: z
|
|
99
|
+
.string()
|
|
100
|
+
.openapi({ description: "CUID2 of the project file record." }),
|
|
101
|
+
projectId: z.string().openapi({
|
|
102
|
+
description: "CUID2 of the project this file belongs to.",
|
|
103
|
+
}),
|
|
104
|
+
fileId: z.string().openapi({ description: "CUID2 of the linked file." }),
|
|
97
105
|
isPlaceholder: z.boolean().openapi({
|
|
98
106
|
description: "Indicates whether the file is a placeholder.",
|
|
99
107
|
example: false,
|
|
@@ -102,18 +110,6 @@ export const ProjectFileEntitySchema = z
|
|
|
102
110
|
description: "Order index of the file in the project.",
|
|
103
111
|
example: 1,
|
|
104
112
|
}),
|
|
105
|
-
projectId: z.string().openapi({
|
|
106
|
-
description: "CUID2 of the project this file belongs to.",
|
|
107
|
-
example: "ckl1y9xyz0000qv7a0h1efgh4",
|
|
108
|
-
}),
|
|
109
|
-
id: z.string().openapi({
|
|
110
|
-
description: "CUID2 of the project file record.",
|
|
111
|
-
example: "ckl1y9xyz0000qv7a0h1efgh4",
|
|
112
|
-
}),
|
|
113
|
-
fileId: z.string().openapi({
|
|
114
|
-
description: "CUID2 of the linked file.",
|
|
115
|
-
example: "ckl1y9xyz0000qv7a0h1efgh4",
|
|
116
|
-
}),
|
|
117
113
|
})
|
|
118
114
|
.openapi({
|
|
119
115
|
title: "Project File Entity",
|
|
@@ -129,6 +125,7 @@ export const ProjectSocialGraphEntitySchema = z
|
|
|
129
125
|
})
|
|
130
126
|
.openapi("ProjectSocialGraphEntity");
|
|
131
127
|
|
|
128
|
+
/* ------------------------------ Derived Entities ------------------------------ */
|
|
132
129
|
export const ProjectWithFilesEntitySchema = ProjectEntitySchema.extend({
|
|
133
130
|
projectFiles: z
|
|
134
131
|
.array(
|
|
@@ -138,353 +135,157 @@ export const ProjectWithFilesEntitySchema = ProjectEntitySchema.extend({
|
|
|
138
135
|
)
|
|
139
136
|
.optional()
|
|
140
137
|
.openapi({ description: "Files associated with the project." }),
|
|
141
|
-
}).openapi({
|
|
142
|
-
title: "ProjectWithFilesEntity",
|
|
143
|
-
});
|
|
138
|
+
}).openapi({ title: "ProjectWithFilesEntity" });
|
|
144
139
|
|
|
145
140
|
export const ProjectViewEntitySchema = z
|
|
146
141
|
.object({
|
|
147
|
-
id: z.cuid2()
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
sessionId: z.string().optional().openapi({ example: "sess_xyz789" }),
|
|
156
|
-
viewedAt: z.coerce.date().openapi({ example: "2025-10-14T10:30:00.000Z" }),
|
|
157
|
-
viewDate: z.coerce.date().openapi({ example: "2025-10-14T00:00:00.000Z" }),
|
|
142
|
+
id: z.cuid2(),
|
|
143
|
+
projectId: z.cuid2(),
|
|
144
|
+
userId: z.cuid2().optional(),
|
|
145
|
+
ipAddress: z.ipv4().optional(),
|
|
146
|
+
userAgent: z.string().optional(),
|
|
147
|
+
sessionId: z.string().optional(),
|
|
148
|
+
viewedAt: z.coerce.date(),
|
|
149
|
+
viewDate: z.coerce.date(),
|
|
158
150
|
})
|
|
159
151
|
.openapi("ProjectViewEntity");
|
|
160
152
|
|
|
161
153
|
export const ProjectLikeEntitySchema = z
|
|
162
154
|
.object({
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
.openapi({ example: "2025-10-13T11:00:00.000Z" }),
|
|
167
|
-
userId: z.cuid2().openapi({ example: "user_liker_123" }),
|
|
168
|
-
projectId: z.cuid2().openapi({ example: "proj_abc456" }),
|
|
155
|
+
projectId: z.cuid2(),
|
|
156
|
+
userId: z.cuid2(),
|
|
157
|
+
createdAt: z.coerce.date().optional(),
|
|
169
158
|
})
|
|
170
159
|
.openapi("ProjectLikeEntity");
|
|
171
160
|
|
|
172
161
|
export const ProjectCommentEntitySchema = z
|
|
173
162
|
.object({
|
|
174
|
-
id: z.cuid2()
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
projectId: z.cuid2().openapi({ example: "proj_abc456" }),
|
|
181
|
-
parentCommentId: z
|
|
182
|
-
.cuid2()
|
|
183
|
-
.optional()
|
|
184
|
-
.openapi({ example: "comment_id_parent_1" }),
|
|
185
|
-
content: z
|
|
186
|
-
.string()
|
|
187
|
-
.min(1)
|
|
188
|
-
.openapi({ example: "Amazing work on the color palette!" }),
|
|
163
|
+
id: z.cuid2(),
|
|
164
|
+
projectId: z.cuid2(),
|
|
165
|
+
userId: z.cuid2(),
|
|
166
|
+
parentCommentId: z.cuid2().optional(),
|
|
167
|
+
content: z.string().min(1),
|
|
168
|
+
createdAt: z.coerce.date().optional(),
|
|
189
169
|
})
|
|
190
170
|
.openapi("ProjectCommentEntity");
|
|
191
171
|
|
|
192
172
|
export const ProjectBookmarkEntitySchema = z
|
|
193
173
|
.object({
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
.openapi({ example: "2025-10-13T13:00:00.000Z" }),
|
|
198
|
-
userId: z.cuid2().openapi({ example: "user_bookmark_789" }),
|
|
199
|
-
projectId: z.cuid2().openapi({ example: "proj_abc456" }),
|
|
174
|
+
projectId: z.cuid2(),
|
|
175
|
+
userId: z.cuid2(),
|
|
176
|
+
createdAt: z.coerce.date().optional(),
|
|
200
177
|
})
|
|
201
178
|
.openapi("ProjectBookmarkEntity");
|
|
202
179
|
|
|
203
180
|
export const ProjectUpdateOutputEntitySchema = z
|
|
204
|
-
.object({
|
|
205
|
-
id: z.cuid2().openapi({ example: "cksd0v6q0000s9a5y8z7p3x9" }),
|
|
206
|
-
})
|
|
181
|
+
.object({ id: z.cuid2() })
|
|
207
182
|
.openapi("ProjectUpdateOutputEntity");
|
|
208
183
|
|
|
184
|
+
|
|
209
185
|
export const CreateProjectInputSchema = z
|
|
210
186
|
.object({
|
|
211
|
-
title: z.string().min(1).max(100)
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
description: "Array of tags associated with the project.",
|
|
230
|
-
example: ["react-native", "e-commerce", "mobile"],
|
|
231
|
-
}),
|
|
232
|
-
startDate: z.coerce.date().openapi({
|
|
233
|
-
description: "Start date of the project.",
|
|
234
|
-
example: new Date("2024-01-01"),
|
|
235
|
-
}),
|
|
236
|
-
endDate: z.coerce
|
|
237
|
-
.date()
|
|
238
|
-
.optional()
|
|
239
|
-
.openapi({
|
|
240
|
-
description: "End date of the project.",
|
|
241
|
-
example: new Date("2024-06-30"),
|
|
242
|
-
}),
|
|
243
|
-
overview: z.string().optional().openapi({
|
|
244
|
-
description: "Brief overview of the project.",
|
|
245
|
-
example: "A comprehensive e-commerce solution for mobile devices.",
|
|
246
|
-
}),
|
|
247
|
-
projectCreatorType: z.enum(ROLES).default(ROLES.CREATIVE).openapi({
|
|
248
|
-
description: "Type of creator who made this project.",
|
|
249
|
-
example: "CREATIVE",
|
|
250
|
-
}),
|
|
251
|
-
clientId: z.string().optional().openapi({
|
|
252
|
-
description: "CUID2 of the client if this is a client project.",
|
|
253
|
-
example: "ckl1y9xyz0000qv7a0h1efgh4",
|
|
254
|
-
}),
|
|
255
|
-
clientType: z.enum(CLIENT_TYPES).default(CLIENT_TYPES.NONE).openapi({
|
|
256
|
-
description: "Type of client for this project.",
|
|
257
|
-
example: "BRAND",
|
|
258
|
-
}),
|
|
259
|
-
clientName: z.string().optional().openapi({
|
|
260
|
-
description: "Name of the client.",
|
|
261
|
-
example: "Acme Corp",
|
|
262
|
-
}),
|
|
263
|
-
files: z
|
|
264
|
-
.array(
|
|
265
|
-
CreateFileInputSchema.extend({
|
|
266
|
-
isPlaceholder: z.boolean().default(false),
|
|
267
|
-
order: z.int().default(1),
|
|
268
|
-
})
|
|
269
|
-
)
|
|
270
|
-
.openapi({
|
|
271
|
-
description: "Array of files/images for the project.",
|
|
272
|
-
example: [],
|
|
273
|
-
}),
|
|
187
|
+
title: z.string().min(1).max(100),
|
|
188
|
+
description: z.string().max(1000).optional(),
|
|
189
|
+
overview: z.string().optional(),
|
|
190
|
+
url: z.string(),
|
|
191
|
+
imagePlaceholderUrl: z.url(),
|
|
192
|
+
tags: z.array(z.string()).default([]),
|
|
193
|
+
startDate: z.coerce.date(),
|
|
194
|
+
endDate: z.coerce.date().optional(),
|
|
195
|
+
projectCreatorType: z.enum(ROLES).default(ROLES.CREATIVE),
|
|
196
|
+
clientId: z.string().optional(),
|
|
197
|
+
clientType: z.enum(CLIENT_TYPES).default(CLIENT_TYPES.NONE),
|
|
198
|
+
clientName: z.string().optional(),
|
|
199
|
+
files: z.array(
|
|
200
|
+
CreateFileInputSchema.extend({
|
|
201
|
+
isPlaceholder: z.boolean().default(false),
|
|
202
|
+
order: z.int().default(1),
|
|
203
|
+
})
|
|
204
|
+
),
|
|
274
205
|
})
|
|
275
206
|
.superRefine(({ startDate, endDate }, ctx) => {
|
|
276
207
|
const today = new Date();
|
|
277
208
|
today.setHours(0, 0, 0, 0);
|
|
278
|
-
if (startDate > today)
|
|
209
|
+
if (startDate > today)
|
|
279
210
|
ctx.addIssue({
|
|
280
211
|
path: ["startDate"],
|
|
281
212
|
code: "custom",
|
|
282
213
|
message: "Start date cannot be in the future",
|
|
283
214
|
});
|
|
284
|
-
}
|
|
285
215
|
if (endDate) {
|
|
286
|
-
if (endDate > today)
|
|
216
|
+
if (endDate > today)
|
|
287
217
|
ctx.addIssue({
|
|
288
218
|
path: ["endDate"],
|
|
289
219
|
code: "custom",
|
|
290
220
|
message: "End date cannot be in the future",
|
|
291
221
|
});
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
if (startDate > endDate) {
|
|
222
|
+
if (startDate > endDate)
|
|
295
223
|
ctx.addIssue({
|
|
296
224
|
path: ["startDate"],
|
|
297
225
|
code: "custom",
|
|
298
226
|
message: "Start date cannot be after end date",
|
|
299
227
|
});
|
|
300
|
-
}
|
|
301
228
|
}
|
|
302
229
|
})
|
|
303
|
-
.openapi({
|
|
304
|
-
title: "Create Project",
|
|
305
|
-
description: "Schema for creating a new project.",
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
export const CreateProjectOutputSchema = ProjectEntitySchema;
|
|
230
|
+
.openapi({ title: "Create Project" });
|
|
309
231
|
|
|
310
232
|
export const UpdateProjectInputSchema = z
|
|
311
233
|
.object({
|
|
312
|
-
id: z.cuid2()
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
description: "Updated overview of the project.",
|
|
329
|
-
example: "Updated project overview.",
|
|
330
|
-
}),
|
|
331
|
-
url: z.url().optional().openapi({
|
|
332
|
-
description: "Updated URL to the project or live demo.",
|
|
333
|
-
example: "https://updated-example.com/project",
|
|
334
|
-
}),
|
|
335
|
-
clientId: z.cuid2().optional().openapi({
|
|
336
|
-
description: "Updated client ID.",
|
|
337
|
-
example: "ckl1y9xyz0000qv7a0h1efgh5",
|
|
338
|
-
}),
|
|
339
|
-
clientType: z.enum(["CREATIVE", "BRAND", "NONE"]).optional().openapi({
|
|
340
|
-
description: "Updated client type.",
|
|
341
|
-
example: "BRAND",
|
|
342
|
-
}),
|
|
343
|
-
clientName: z.string().optional().openapi({
|
|
344
|
-
description: "Updated client name.",
|
|
345
|
-
example: "Updated Acme Corp",
|
|
346
|
-
}),
|
|
347
|
-
projectCreatorType: z
|
|
348
|
-
.enum(["CREATIVE", "BRAND", "INVESTOR", "ADMIN"])
|
|
349
|
-
.optional()
|
|
350
|
-
.openapi({
|
|
351
|
-
description: "Updated project creator type.",
|
|
352
|
-
example: "CREATIVE",
|
|
353
|
-
}),
|
|
354
|
-
tags: z
|
|
355
|
-
.array(z.string())
|
|
356
|
-
.optional()
|
|
357
|
-
.openapi({
|
|
358
|
-
description: "Updated array of tags.",
|
|
359
|
-
example: ["react-native", "e-commerce", "mobile", "updated"],
|
|
360
|
-
}),
|
|
361
|
-
isFeatured: z.boolean().optional().openapi({
|
|
362
|
-
description: "Whether the project should be featured.",
|
|
363
|
-
example: true,
|
|
364
|
-
}),
|
|
365
|
-
startDate: z
|
|
366
|
-
.date()
|
|
367
|
-
.optional()
|
|
368
|
-
.openapi({
|
|
369
|
-
description: "Updated start date of the project.",
|
|
370
|
-
example: new Date("2024-02-01"),
|
|
371
|
-
}),
|
|
372
|
-
endDate: z
|
|
373
|
-
.date()
|
|
374
|
-
.optional()
|
|
375
|
-
.openapi({
|
|
376
|
-
description: "Updated end date of the project.",
|
|
377
|
-
example: new Date("2024-07-30"),
|
|
378
|
-
}),
|
|
379
|
-
createdAt: z
|
|
380
|
-
.date()
|
|
381
|
-
.optional()
|
|
382
|
-
.openapi({
|
|
383
|
-
description: "Creation date (read-only).",
|
|
384
|
-
example: new Date("2024-01-01T12:00:00Z"),
|
|
385
|
-
}),
|
|
386
|
-
updatedAt: z
|
|
387
|
-
.date()
|
|
388
|
-
.optional()
|
|
389
|
-
.openapi({
|
|
390
|
-
description: "Last update date (read-only).",
|
|
391
|
-
example: new Date("2024-06-30T18:00:00Z"),
|
|
392
|
-
}),
|
|
234
|
+
id: z.cuid2(),
|
|
235
|
+
title: z.string().optional(),
|
|
236
|
+
description: z.string().optional(),
|
|
237
|
+
overview: z.string().optional(),
|
|
238
|
+
url: z.url().optional(),
|
|
239
|
+
imagePlaceholderUrl: z.url().optional(),
|
|
240
|
+
tags: z.array(z.string()).optional(),
|
|
241
|
+
projectCreatorType: z.enum(ROLES).optional(),
|
|
242
|
+
clientId: z.cuid2().optional(),
|
|
243
|
+
clientType: z.enum(CLIENT_TYPES).optional(),
|
|
244
|
+
clientName: z.string().optional(),
|
|
245
|
+
isFeatured: z.boolean().optional(),
|
|
246
|
+
startDate: z.date().optional(),
|
|
247
|
+
endDate: z.date().optional(),
|
|
248
|
+
createdAt: z.date().optional(),
|
|
249
|
+
updatedAt: z.date().optional(),
|
|
393
250
|
})
|
|
394
|
-
.openapi({
|
|
395
|
-
title: "Update Project",
|
|
396
|
-
description: "Schema for updating an existing project.",
|
|
397
|
-
});
|
|
251
|
+
.openapi({ title: "Update Project" });
|
|
398
252
|
|
|
399
|
-
export const
|
|
400
|
-
export const ProjectIdSchema = z.object({
|
|
401
|
-
projectId: z.cuid2(),
|
|
402
|
-
});
|
|
403
|
-
export const CommentOnProjectParamsSchema = ProjectIdSchema;
|
|
404
|
-
export const CommentOnProjectInputSchema = z
|
|
253
|
+
export const ViewProjectInputSchema = z
|
|
405
254
|
.object({
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
255
|
+
projectId: z.cuid2(),
|
|
256
|
+
id: z.cuid2().optional(),
|
|
257
|
+
userId: z.cuid2().optional(),
|
|
258
|
+
sessionId: z.string().optional(),
|
|
259
|
+
ipAddress: z.string().optional(),
|
|
260
|
+
userAgent: z.string().optional(),
|
|
261
|
+
viewedAt: z.date().optional(),
|
|
262
|
+
viewDate: z.date().optional(),
|
|
414
263
|
})
|
|
415
|
-
.openapi({
|
|
416
|
-
title: "Comment on Project",
|
|
417
|
-
description: "Schema for commenting on a project.",
|
|
418
|
-
});
|
|
419
|
-
export const CommentOnProjectOutputSchema = ProjectCommentEntitySchema;
|
|
264
|
+
.openapi({ title: "View Project" });
|
|
420
265
|
|
|
421
|
-
export const
|
|
266
|
+
export const CommentOnProjectInputSchema = z
|
|
267
|
+
.object({
|
|
268
|
+
content: z.string(),
|
|
269
|
+
parentCommentId: z.cuid2().optional(),
|
|
270
|
+
})
|
|
271
|
+
.openapi({ title: "Comment on Project" });
|
|
422
272
|
|
|
423
|
-
export const
|
|
273
|
+
export const DeleteProjectCommentInputSchema = z.object({
|
|
424
274
|
commentId: z.cuid2(),
|
|
425
275
|
});
|
|
426
276
|
|
|
277
|
+
/* ------------------------------ Output Schemas ------------------------------ */
|
|
278
|
+
export const CreateProjectOutputSchema = ProjectEntitySchema;
|
|
279
|
+
export const UpdateProjectOutputSchema = ProjectEntitySchema;
|
|
280
|
+
export const CommentOnProjectOutputSchema = ProjectCommentEntitySchema;
|
|
427
281
|
export const DeleteProjectCommentOutputSchema = ProjectCommentEntitySchema;
|
|
428
|
-
|
|
429
282
|
export const DeleteProjectOutputSchema = ProjectEntitySchema;
|
|
430
|
-
|
|
431
|
-
export const GetProjectParamsSchema = ProjectIdSchema;
|
|
432
|
-
|
|
433
283
|
export const GetProjectOutputSchema = ProjectWithFilesEntitySchema;
|
|
434
|
-
|
|
435
|
-
export const BookmarkProjectParamsSchema = ProjectIdSchema;
|
|
436
|
-
|
|
437
284
|
export const BookmarkProjectOutputSchema = ProjectBookmarkEntitySchema;
|
|
438
285
|
|
|
439
|
-
export const LikeProjectParamsSchema = ProjectIdSchema;
|
|
440
286
|
|
|
441
|
-
export const
|
|
442
|
-
|
|
443
|
-
export const ViewProjectInputSchema = z
|
|
444
|
-
.object({
|
|
445
|
-
projectId: z.cuid2().openapi({
|
|
446
|
-
description: "CUID2 identifier of the project being viewed.",
|
|
447
|
-
example: "ckl1z0abc0000qv7a0h1abcd2",
|
|
448
|
-
}),
|
|
449
|
-
id: z.cuid2().optional().openapi({
|
|
450
|
-
description: "CUID2 identifier of the view record (auto-generated).",
|
|
451
|
-
example: "ckl1z0abc0000qv7a0h1abcd5",
|
|
452
|
-
}),
|
|
453
|
-
userId: z.cuid2().optional().openapi({
|
|
454
|
-
description: "CUID2 of the user who viewed the project.",
|
|
455
|
-
example: "ckl1y9xyz0000qv7a0h1efgh3",
|
|
456
|
-
}),
|
|
457
|
-
sessionId: z.string().optional().openapi({
|
|
458
|
-
description: "Session ID for anonymous users.",
|
|
459
|
-
example: "sess_123456789",
|
|
460
|
-
}),
|
|
461
|
-
ipAddress: z.string().optional().openapi({
|
|
462
|
-
description: "IP address of the viewer.",
|
|
463
|
-
example: "192.168.1.1",
|
|
464
|
-
}),
|
|
465
|
-
userAgent: z.string().optional().openapi({
|
|
466
|
-
description: "User agent string of the viewer.",
|
|
467
|
-
example: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
|
468
|
-
}),
|
|
469
|
-
viewedAt: z
|
|
470
|
-
.date()
|
|
471
|
-
.optional()
|
|
472
|
-
.openapi({
|
|
473
|
-
description: "Date and time when the project was viewed.",
|
|
474
|
-
example: new Date("2024-01-15T14:30:00Z"),
|
|
475
|
-
}),
|
|
476
|
-
viewDate: z
|
|
477
|
-
.date()
|
|
478
|
-
.optional()
|
|
479
|
-
.openapi({
|
|
480
|
-
description: "Date when the project was viewed.",
|
|
481
|
-
example: new Date("2024-01-15"),
|
|
482
|
-
}),
|
|
483
|
-
})
|
|
484
|
-
.openapi({
|
|
485
|
-
title: "View Project",
|
|
486
|
-
description: "Schema for recording a project view.",
|
|
487
|
-
});
|
|
287
|
+
export const ProjectIdSchema = z.object({ projectId: z.cuid2() });
|
|
288
|
+
export const CommentOnProjectParamsSchema = ProjectIdSchema;
|
|
488
289
|
|
|
489
290
|
export const MinimalProjectSchema = ProjectEntitySchema.pick({
|
|
490
291
|
id: true,
|
|
@@ -496,78 +297,44 @@ export const MinimalProjectSchema = ProjectEntitySchema.pick({
|
|
|
496
297
|
imagePlaceholderUrl: true,
|
|
497
298
|
}).openapi({
|
|
498
299
|
title: "MinimalProject",
|
|
499
|
-
description: "Subset of project fields for lightweight listings.",
|
|
500
300
|
});
|
|
501
301
|
|
|
502
302
|
export const ListProjectsInputSchema = z
|
|
503
303
|
.object({
|
|
504
|
-
query: z.string().optional()
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
.optional()
|
|
511
|
-
.openapi({
|
|
512
|
-
description: "Tags to filter projects by.",
|
|
513
|
-
example: ["react", "design"],
|
|
514
|
-
}),
|
|
515
|
-
clientName: z.string().optional().openapi({
|
|
516
|
-
description: "Client name to filter projects by.",
|
|
517
|
-
example: "Acme Corp",
|
|
518
|
-
}),
|
|
519
|
-
userId: z.string().optional().openapi({
|
|
520
|
-
description: "Filter projects by user ID.",
|
|
521
|
-
example: "ckl1y9xyz0000qv7a0h1efgh4",
|
|
522
|
-
}),
|
|
523
|
-
page: z.number().int().optional().default(1).openapi({
|
|
524
|
-
description: "Page number for pagination.",
|
|
525
|
-
example: 1,
|
|
526
|
-
}),
|
|
527
|
-
perPage: z.number().int().optional().default(10).openapi({
|
|
528
|
-
description: "Number of items per page.",
|
|
529
|
-
example: 10,
|
|
530
|
-
}),
|
|
304
|
+
query: z.string().optional(),
|
|
305
|
+
tags: z.array(z.string()).optional(),
|
|
306
|
+
clientName: z.string().optional(),
|
|
307
|
+
userId: z.string().optional(),
|
|
308
|
+
page: z.number().int().optional().default(1),
|
|
309
|
+
perPage: z.number().int().optional().default(10),
|
|
531
310
|
})
|
|
532
311
|
.openapi({
|
|
533
312
|
title: "ListProjectsInput",
|
|
534
|
-
description: "Parameters for listing or searching projects.",
|
|
535
313
|
});
|
|
536
314
|
|
|
315
|
+
/* ------------------------------ Aggregates ------------------------------ */
|
|
537
316
|
export const ProjectWithProjectViewsEntitySchema = MinimalProjectSchema.extend({
|
|
538
|
-
views: z.array(ProjectViewEntitySchema)
|
|
539
|
-
description: "Array of project view records.",
|
|
540
|
-
}),
|
|
317
|
+
views: z.array(ProjectViewEntitySchema),
|
|
541
318
|
}).openapi({
|
|
542
319
|
title: "ProjectWithProjectViewsEntity",
|
|
543
|
-
description: "Project entity with associated views.",
|
|
544
320
|
});
|
|
545
321
|
|
|
546
322
|
export const ProjectWithProjectCommentsEntitySchema =
|
|
547
323
|
MinimalProjectSchema.extend({
|
|
548
|
-
comments: z.array(ProjectCommentEntitySchema)
|
|
549
|
-
description: "Array of comments on the project.",
|
|
550
|
-
}),
|
|
324
|
+
comments: z.array(ProjectCommentEntitySchema),
|
|
551
325
|
}).openapi({
|
|
552
326
|
title: "ProjectWithProjectCommentsEntity",
|
|
553
|
-
description: "Project entity with associated comments.",
|
|
554
327
|
});
|
|
555
328
|
|
|
556
329
|
export const ProjectWithProjectLikesEntitySchema = MinimalProjectSchema.extend({
|
|
557
|
-
likes: z.array(ProjectLikeEntitySchema)
|
|
558
|
-
description: "Array of likes on the project.",
|
|
559
|
-
}),
|
|
330
|
+
likes: z.array(ProjectLikeEntitySchema),
|
|
560
331
|
}).openapi({
|
|
561
332
|
title: "ProjectWithProjectLikesEntity",
|
|
562
|
-
description: "Project entity with associated likes.",
|
|
563
333
|
});
|
|
564
334
|
|
|
565
335
|
export const ProjectWithProjectBookmarksEntitySchema =
|
|
566
336
|
MinimalProjectSchema.extend({
|
|
567
|
-
bookmarks: z.array(ProjectBookmarkEntitySchema)
|
|
568
|
-
description: "Array of bookmarks for the project.",
|
|
569
|
-
}),
|
|
337
|
+
bookmarks: z.array(ProjectBookmarkEntitySchema),
|
|
570
338
|
}).openapi({
|
|
571
339
|
title: "ProjectWithProjectBookmarksEntity",
|
|
572
|
-
description: "Project entity with associated bookmarks.",
|
|
573
340
|
});
|