@zyacreatives/shared 1.0.1 → 1.1.1

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 (51) hide show
  1. package/dist/constants.d.ts +277 -0
  2. package/dist/constants.js +268 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +19 -1
  5. package/dist/schemas/brand.d.ts +84 -0
  6. package/dist/schemas/brand.js +68 -0
  7. package/dist/schemas/common.d.ts +33 -0
  8. package/dist/schemas/common.js +58 -0
  9. package/dist/schemas/creative.d.ts +113 -0
  10. package/dist/schemas/creative.js +102 -0
  11. package/dist/schemas/index.d.ts +4 -0
  12. package/dist/schemas/index.js +20 -0
  13. package/dist/schemas/user.d.ts +179 -0
  14. package/dist/schemas/user.js +93 -0
  15. package/dist/types/brand.d.ts +24 -0
  16. package/dist/types/brand.js +2 -0
  17. package/dist/types/common.d.ts +10 -0
  18. package/dist/types/common.js +2 -0
  19. package/dist/types/creative.d.ts +28 -0
  20. package/dist/types/creative.js +2 -0
  21. package/dist/types/discipline.d.ts +8 -0
  22. package/dist/types/discipline.js +2 -0
  23. package/dist/types/file.d.ts +12 -0
  24. package/dist/types/file.js +2 -0
  25. package/dist/types/index.d.ts +8 -1
  26. package/dist/types/index.js +24 -1
  27. package/dist/types/investor.d.ts +30 -0
  28. package/dist/types/investor.js +2 -0
  29. package/dist/types/project.d.ts +79 -0
  30. package/dist/types/project.js +2 -0
  31. package/dist/types/user.d.ts +42 -0
  32. package/dist/types/user.js +2 -0
  33. package/package.json +7 -3
  34. package/src/constants.ts +300 -0
  35. package/src/index.ts +2 -0
  36. package/src/schemas/brand.ts +91 -0
  37. package/src/schemas/common.ts +67 -0
  38. package/src/schemas/creative.ts +125 -0
  39. package/src/schemas/index.ts +4 -0
  40. package/src/schemas/user.ts +125 -0
  41. package/src/types/brand.ts +27 -0
  42. package/src/types/common.ts +11 -0
  43. package/src/types/creative.ts +32 -0
  44. package/src/types/discipline.ts +9 -0
  45. package/src/types/file.ts +13 -0
  46. package/src/types/index.ts +8 -1
  47. package/src/types/investor.ts +38 -0
  48. package/src/types/project.ts +101 -0
  49. package/src/types/user.ts +60 -0
  50. package/tsconfig.json +5 -3
  51. package/src/types/enums.ts +0 -109
@@ -0,0 +1,91 @@
1
+ import { z } from "@hono/zod-openapi";
2
+ import { CuidSchema, ProfileIdentifierSchema } from "./common";
3
+ import { MinimalUserSchema } from "./user";
4
+
5
+ export const BrandEntitySchema = z
6
+ .object({
7
+ id: z.cuid2().openapi({ example: "cksd0v6q0000s9a5y8z7p3x9" }),
8
+ userId: z.cuid2().openapi({ example: "cksd0v6q0000s9a5y8z7p3x9" }),
9
+ brandName: z.string().min(1).openapi({ example: "Acme Creative Studio" }),
10
+ searchVector: z.string().optional(),
11
+ bio: z.string().optional().openapi({
12
+ example: "A creative studio specializing in product design.",
13
+ }),
14
+ tags: z
15
+ .array(z.string())
16
+ .optional()
17
+ .openapi({ example: ["branding", "design", "marketing"] }),
18
+ createdAt: z.iso
19
+ .datetime()
20
+ .openapi({ example: "2025-10-13T09:00:00.000Z" }),
21
+ updatedAt: z.iso
22
+ .datetime()
23
+ .openapi({ example: "2025-10-13T09:00:00.000Z" }),
24
+ })
25
+ .openapi("BrandEntity");
26
+
27
+ export const CreateBrandProfileSchema = z
28
+ .object({
29
+ brandName: z
30
+ .string()
31
+ .min(1, "Brand name is required")
32
+ .openapi({ example: "Acme Creative Studio" }),
33
+ bio: z.string().max(210).optional().default("").openapi({
34
+ example: "We help brands tell their stories through design.",
35
+ }),
36
+ tags: z
37
+ .array(z.string())
38
+ .optional()
39
+ .default([])
40
+ .openapi({ example: ["branding", "ux", "campaigns"] }),
41
+ })
42
+ .openapi({
43
+ title: "create brand profile",
44
+ });
45
+
46
+ export const UpdateBrandProfileSchema = z
47
+ .object({
48
+ brandName: z.string().min(1).optional().openapi({ example: "Acme Studio" }),
49
+ bio: z.string().max(210).optional().openapi({
50
+ example: "Updated bio for our creative agency.",
51
+ }),
52
+ tags: z
53
+ .array(z.string())
54
+ .optional()
55
+ .openapi({ example: ["branding", "product", "illustration"] }),
56
+ })
57
+ .openapi({
58
+ title: "update brand profile",
59
+ });
60
+
61
+ export const GetBrandParamsSchema = z.object({
62
+ value: CuidSchema,
63
+ });
64
+
65
+ export const GetBrandQuerySchema = ProfileIdentifierSchema;
66
+
67
+ export const CreateBrandEndpointResponseSchema = BrandEntitySchema;
68
+ export const GetBrandEndpointResponseSchema = BrandEntitySchema.extend({
69
+ user: MinimalUserSchema,
70
+ });
71
+ export const UpdateBrandEndpointResponseSchema = BrandEntitySchema;
72
+
73
+ export type CreateBrandDto = z.infer<typeof CreateBrandProfileSchema> & {
74
+ userId: string;
75
+ };
76
+ export type UpdateBrandDto = z.infer<typeof UpdateBrandProfileSchema> & {
77
+ userId: string;
78
+ };
79
+
80
+ export type GetBrandParams = z.infer<typeof GetBrandParamsSchema>;
81
+ export type GetBrandQuery = z.infer<typeof GetBrandQuerySchema>;
82
+
83
+ export type CreateBrandEndpointResponse = z.infer<
84
+ typeof CreateBrandEndpointResponseSchema
85
+ >;
86
+ export type GetBrandEndpointResponse = z.infer<
87
+ typeof GetBrandEndpointResponseSchema
88
+ >;
89
+ export type UpdateBrandEndpointResponse = z.infer<
90
+ typeof UpdateBrandEndpointResponseSchema
91
+ >;
@@ -0,0 +1,67 @@
1
+ import { z } from "@hono/zod-openapi";
2
+
3
+ export const CuidSchema = z.cuid2({ error: "Invalid CUID2 is written." });
4
+
5
+ export const UserIdentifierSchema = z.object({
6
+ by: z.enum(["id", "username"]).optional().default("id"),
7
+ });
8
+
9
+ export type UserIdentifier = z.infer<typeof UserIdentifierSchema>;
10
+
11
+ export const ProfileIdentifierSchema = z.object({
12
+ by: z.enum(["id", "userId"]).optional().default("id"),
13
+ });
14
+
15
+ export type ProfileIdentifier = z.infer<typeof ProfileIdentifierSchema>;
16
+
17
+ export const ProjectIdentifierSchema = z.object({
18
+ by: z.enum(["id", "userId"]).optional().default("id"),
19
+ });
20
+
21
+ export type ProjectIdentifier = z.infer<typeof ProjectIdentifierSchema>;
22
+
23
+ export const ProjectSocialGraphEntitySchema = z
24
+ .object({
25
+ noOfLikes: z
26
+ .number()
27
+ .int()
28
+ .nonnegative()
29
+ .optional()
30
+ .openapi({ example: 350 }),
31
+ noOfComments: z
32
+ .number()
33
+ .int()
34
+ .nonnegative()
35
+ .optional()
36
+ .openapi({ example: 78 }),
37
+ noOfBookmarks: z
38
+ .number()
39
+ .int()
40
+ .nonnegative()
41
+ .optional()
42
+ .openapi({ example: 25 }),
43
+ noOfViews: z
44
+ .number()
45
+ .int()
46
+ .nonnegative()
47
+ .optional()
48
+ .openapi({ example: 1024 }),
49
+ })
50
+ .openapi("ProjectSocialGraphEntity");
51
+
52
+ export const UserSocialGraphEntitySchema = z
53
+ .object({
54
+ followerCount: z
55
+ .number()
56
+ .int()
57
+ .nonnegative()
58
+ .optional()
59
+ .openapi({ example: 120 }),
60
+ followingCount: z
61
+ .number()
62
+ .int()
63
+ .nonnegative()
64
+ .optional()
65
+ .openapi({ example: 45 }),
66
+ })
67
+ .openapi("UserSocialGraphEntity");
@@ -0,0 +1,125 @@
1
+ import { z } from "@hono/zod-openapi";
2
+ import { EXPERIENCE_LEVELS } from "../constants";
3
+ import { CuidSchema, ProfileIdentifierSchema } from "./common";
4
+ import { MinimalUserSchema } from "./user";
5
+
6
+ export const CreativeEntitySchema = z
7
+ .object({
8
+ id: z.cuid2().openapi({ example: "cksd0v6q0000s9a5y8z7p3x9" }),
9
+ userId: z.cuid2().openapi({ example: "cksd0v6q0000s9a5y8z7p3x9" }),
10
+ bio: z
11
+ .string()
12
+ .optional()
13
+ .openapi({ example: "Passionate visual artist." }),
14
+ location: z.string().optional().openapi({ example: "Lagos, Nigeria" }),
15
+ searchVector: z.string().optional(),
16
+ experienceLevel: z
17
+ .enum(Object.values(EXPERIENCE_LEVELS) as [string, ...string[]])
18
+ .optional()
19
+ .openapi({ example: "1-3 years" }),
20
+ tags: z
21
+ .array(z.string())
22
+ .optional()
23
+ .openapi({ example: ["digital-art", "illustration"] }),
24
+ disciplines: z
25
+ .array(z.string())
26
+ .optional()
27
+ .openapi({ example: ["painting", "animation"] }),
28
+ createdAt: z.iso
29
+ .datetime()
30
+ .openapi({ example: "2025-10-13T09:00:00.000Z" }),
31
+ updatedAt: z.iso
32
+ .datetime()
33
+ .openapi({ example: "2025-10-13T09:00:00.000Z" }),
34
+ })
35
+ .openapi("CreativeEntity");
36
+
37
+ export const CreateCreativeProfileSchema = z
38
+ .object({
39
+ experienceLevel: z
40
+ .enum(EXPERIENCE_LEVELS)
41
+ .default(EXPERIENCE_LEVELS.YEAR_0_1)
42
+ .openapi({ example: EXPERIENCE_LEVELS.YEAR_1_3 }),
43
+ bio: z
44
+ .string()
45
+ .max(210)
46
+ .optional()
47
+ .default("")
48
+ .openapi({ example: "I am a freelance UI/UX designer." }),
49
+ location: z
50
+ .string()
51
+ .max(100)
52
+ .optional()
53
+ .default("")
54
+ .openapi({ example: "Lagos, Nigeria" }),
55
+ disciplineSlugs: z
56
+ .array(z.string())
57
+ .min(1, "At least one discipline is required")
58
+ .default([])
59
+ .openapi({ example: ["ui-ux", "frontend"] }),
60
+ })
61
+ .openapi({
62
+ title: "create creative profile",
63
+ });
64
+
65
+ export const UpdateCreativeProfileSchema = z
66
+ .object({
67
+ experienceLevel: z
68
+ .enum(EXPERIENCE_LEVELS)
69
+ .optional()
70
+ .openapi({ example: EXPERIENCE_LEVELS.YEAR_3_5 }),
71
+ tags: z
72
+ .array(z.string())
73
+ .optional()
74
+ .openapi({ example: ["react", "design", "product"] }),
75
+ bio: z
76
+ .string()
77
+ .max(210)
78
+ .optional()
79
+ .openapi({ example: "I am a freelance UI/UX designer." }),
80
+ location: z
81
+ .string()
82
+ .max(100)
83
+ .optional()
84
+ .openapi({ example: "Lagos, Nigeria" }),
85
+ disciplineSlugs: z
86
+ .array(z.string())
87
+ .min(1, "At least one discipline is required")
88
+ .optional()
89
+ .openapi({ example: ["frontend", "ui-ux"] }),
90
+ })
91
+ .openapi({
92
+ title: "update creative profile",
93
+ });
94
+
95
+ export const GetCreativeParamsSchema = z.object({
96
+ value: CuidSchema,
97
+ });
98
+
99
+ export const GetCreativeQuerySchema = ProfileIdentifierSchema;
100
+
101
+ export const CreateCreativeEndpointResponseSchema = CreativeEntitySchema;
102
+ export const GetCreativeEndpointResponseSchema = CreativeEntitySchema.extend({
103
+ user: MinimalUserSchema,
104
+ })
105
+ export const UpdateCreativeEndpointResponseSchema = CreativeEntitySchema;
106
+
107
+ export type CreateCreativeDto = z.infer<typeof CreateCreativeProfileSchema> & {
108
+ userId: string;
109
+ };
110
+ export type UpdateCreativeDto = z.infer<typeof UpdateCreativeProfileSchema> & {
111
+ userId: string;
112
+ };
113
+
114
+ export type GetCreativeParams = z.infer<typeof GetCreativeParamsSchema>;
115
+ export type GetCreativeQuery = z.infer<typeof GetCreativeQuerySchema>;
116
+
117
+ export type CreateCreativeEndpointResponse = z.infer<
118
+ typeof CreateCreativeEndpointResponseSchema
119
+ >;
120
+ export type GetCreativeEndpointResponse = z.infer<
121
+ typeof GetCreativeEndpointResponseSchema
122
+ >;
123
+ export type UpdateCreativeEndpointResponse = z.infer<
124
+ typeof UpdateCreativeEndpointResponseSchema
125
+ >;
@@ -0,0 +1,4 @@
1
+ export * from "./brand";
2
+ export * from "./common";
3
+ export * from "./creative";
4
+ export * from "./user";
@@ -0,0 +1,125 @@
1
+ import { z } from "@hono/zod-openapi";
2
+
3
+ import {
4
+ ROLES,
5
+ USER_STATUSES,
6
+ ONBOARDING_PAGES,
7
+ EXPERIENCE_LEVELS,
8
+ INVESTOR_TYPES,
9
+ INVESTMENT_SIZES,
10
+ GEOGRAPHIC_FOCUS,
11
+ } from "../constants";
12
+ import type {
13
+ Role,
14
+ UserStatus,
15
+ OnboardingPage,
16
+ ExperienceLevel,
17
+ InvestorType,
18
+ InvestmentSize,
19
+ GeographicFocus,
20
+ } from "../constants";
21
+ import { UserSocialGraphEntitySchema } from "./common";
22
+
23
+ export const BaseUserEntitySchema = z
24
+ .object({
25
+ id: z.cuid2().openapi({ example: "cksd0v6q0000s9a5y8z7p3x9" }),
26
+ email: z.email().openapi({ example: "user@example.com" }),
27
+ emailVerified: z.boolean().openapi({ example: true }),
28
+ name: z.string().optional().openapi({ example: "John Doe" }),
29
+ image: z
30
+ .string()
31
+ .optional()
32
+ .openapi({ example: "https://example.com/avatar.png" }),
33
+ username: z.string().optional().openapi({ example: "johndoe" }),
34
+ displayUsername: z.string().optional().openapi({ example: "@johndoe" }),
35
+ role: z.enum(Object.values(ROLES) as [Role, ...Role[]]).openapi({
36
+ example: "CREATIVE",
37
+ }),
38
+ status: z
39
+ .enum(Object.values(USER_STATUSES) as [UserStatus, ...UserStatus[]])
40
+ .openapi({
41
+ example: "ACTIVE",
42
+ }),
43
+ onboardingPage: z
44
+ .enum(
45
+ Object.values(ONBOARDING_PAGES) as [OnboardingPage, ...OnboardingPage[]]
46
+ )
47
+ .openapi({
48
+ example: "DONE",
49
+ }),
50
+ createdAt: z.iso
51
+ .datetime()
52
+ .openapi({ example: "2025-10-13T09:00:00.000Z" }),
53
+ updatedAt: z.iso
54
+ .datetime()
55
+ .openapi({ example: "2025-10-13T09:00:00.000Z" }),
56
+ })
57
+ .openapi("BaseUserEntity");
58
+
59
+ export const MinimalUserSchema = BaseUserEntitySchema.pick({
60
+ id: true,
61
+ name: true,
62
+ email: true,
63
+ image: true,
64
+ username: true,
65
+ role: true,
66
+ }).openapi("MinimalUser");
67
+
68
+ export const UserEntitySchema = BaseUserEntitySchema.merge(
69
+ UserSocialGraphEntitySchema
70
+ ).openapi("UserEntity");
71
+
72
+ export const UserProfileEntitySchema = UserEntitySchema.extend({
73
+ profileType: z.enum(["creative", "brand", "investor"]).optional().openapi({
74
+ example: "creative",
75
+ }),
76
+ bio: z.string().optional().openapi({
77
+ example: "Passionate digital artist focusing on UI/UX.",
78
+ }),
79
+ location: z.string().optional().openapi({
80
+ example: "Lagos, Nigeria",
81
+ }),
82
+ experienceLevel: z
83
+ .enum(
84
+ Object.values(EXPERIENCE_LEVELS) as [
85
+ ExperienceLevel,
86
+ ...ExperienceLevel[]
87
+ ]
88
+ )
89
+ .optional()
90
+ .openapi({ example: EXPERIENCE_LEVELS.YEAR_1_3 }),
91
+ disciplines: z
92
+ .array(z.string())
93
+ .optional()
94
+ .openapi({
95
+ example: ["ui-ux", "frontend"],
96
+ }),
97
+ tags: z
98
+ .array(z.string())
99
+ .optional()
100
+ .openapi({
101
+ example: ["react", "design", "product"],
102
+ }),
103
+ brandName: z.string().optional().openapi({
104
+ example: "Acme Creative Studio",
105
+ }),
106
+ websiteURL: z.string().optional().openapi({
107
+ example: "https://acme-creative.com",
108
+ }),
109
+ investorType: z
110
+ .enum(Object.values(INVESTOR_TYPES) as [InvestorType, ...InvestorType[]])
111
+ .optional()
112
+ .openapi({ example: INVESTOR_TYPES.ANGEL_INVESTOR }),
113
+ investmentSize: z
114
+ .enum(
115
+ Object.values(INVESTMENT_SIZES) as [InvestmentSize, ...InvestmentSize[]]
116
+ )
117
+ .optional()
118
+ .openapi({ example: INVESTMENT_SIZES.BETWEEN_25K_100K }),
119
+ geographicFocus: z
120
+ .enum(
121
+ Object.values(GEOGRAPHIC_FOCUS) as [GeographicFocus, ...GeographicFocus[]]
122
+ )
123
+ .optional()
124
+ .openapi({ example: GEOGRAPHIC_FOCUS.AFRICA }),
125
+ }).openapi("UserProfileEntity");
@@ -0,0 +1,27 @@
1
+ import type { MinimalUser } from "./user";
2
+
3
+ export type BrandEntity = {
4
+ id: string;
5
+ userId: string;
6
+ brandName: string;
7
+ searchVector?: string;
8
+ bio?: string;
9
+ tags?: string[];
10
+ createdAt: Date;
11
+ updatedAt: Date;
12
+ };
13
+
14
+ export type BrandWithUserEntity = BrandEntity & {
15
+ user: MinimalUser;
16
+ disciplines: string[];
17
+ };
18
+
19
+ export type ListBrandsInput = {
20
+ query?: string;
21
+ disciplines?: string[];
22
+ experienceLevels?: string[];
23
+ location?: string;
24
+ tags?: string[];
25
+ page?: number;
26
+ perPage?: number;
27
+ };
@@ -0,0 +1,11 @@
1
+ export type ProjectSocialGraphEntity = {
2
+ noOfLikes?: number;
3
+ noOfComments?: number;
4
+ noOfBookmarks?: number;
5
+ noOfViews?: number;
6
+ };
7
+
8
+ export type UserSocialGraphEntity = {
9
+ followerCount?: number;
10
+ followingCount?: number;
11
+ };
@@ -0,0 +1,32 @@
1
+ import type { ExperienceLevel } from "../constants";
2
+ import type { MinimalUser } from "./user";
3
+
4
+ export type BaseCreativeEntity = {
5
+ id: string;
6
+ userId: string;
7
+ bio?: string;
8
+ location?: string;
9
+ experienceLevel?: ExperienceLevel;
10
+ tags?: string[];
11
+ disciplines?: string[];
12
+ user?: any;
13
+ createdAt: Date;
14
+ updatedAt: Date;
15
+ };
16
+
17
+ export type CreativeEntity = BaseCreativeEntity;
18
+
19
+ export type CreativeWithUserEntity = CreativeEntity & {
20
+ user: MinimalUser;
21
+ disciplines: string[];
22
+ };
23
+
24
+ export type ListCreativesInput = {
25
+ query?: string;
26
+ disciplines?: string[];
27
+ experienceLevels?: string[];
28
+ location?: string;
29
+ tags?: string[];
30
+ page?: number;
31
+ perPage?: number;
32
+ };
@@ -0,0 +1,9 @@
1
+ export type DisciplineEntity = {
2
+ slug: string;
3
+ name: string;
4
+ tags?: string[];
5
+ };
6
+
7
+ export type DisciplineUpdateOutputEntity = {
8
+ slug: string;
9
+ };
@@ -0,0 +1,13 @@
1
+ export type FileEntity = {
2
+ key: string;
3
+ id: string;
4
+ url?: string;
5
+ createdAt: Date;
6
+ updatedAt: Date;
7
+ userId: string;
8
+ mimeType: string;
9
+ };
10
+
11
+ export type FileUpdateOutputEntity = {
12
+ id: string;
13
+ };
@@ -1 +1,8 @@
1
- export * from "./enums";
1
+ export * from "./brand";
2
+ export * from "./common";
3
+ export * from "./creative";
4
+ export * from "./discipline";
5
+ export * from "./file";
6
+ export * from "./investor";
7
+ export * from "./project";
8
+ export * from "./user";
@@ -0,0 +1,38 @@
1
+ import type {
2
+ ExperienceLevel,
3
+ GeographicFocus,
4
+ InvestmentSize,
5
+ InvestorType,
6
+ } from "../constants";
7
+ import type { MinimalUser } from "./user";
8
+
9
+ export type InvestorEntity = {
10
+ id: string;
11
+ userId: string;
12
+ bio?: string;
13
+ location?: string;
14
+ experienceLevel?: ExperienceLevel;
15
+ geographicFocus?: GeographicFocus;
16
+ investmentSize?: InvestmentSize;
17
+ investorType?: InvestorType;
18
+ websiteURL?: string;
19
+ disciplines?: string[];
20
+ user?: any;
21
+ createdAt: Date;
22
+ updatedAt: Date;
23
+ };
24
+
25
+ export type InvestorWithUserEntity = InvestorEntity & {
26
+ user: MinimalUser;
27
+ disciplines: string[];
28
+ };
29
+
30
+ export type ListInvestorsInput = {
31
+ query?: string;
32
+ disciplines?: string[];
33
+ experienceLevels?: string[];
34
+ location?: string;
35
+ tags?: string[];
36
+ page?: number;
37
+ perPage?: number;
38
+ };
@@ -0,0 +1,101 @@
1
+ import type { ClientType, CommentStatus, Role } from "../constants";
2
+ import type { ProjectSocialGraphEntity } from "./common";
3
+ import type { BaseUserEntity, MinimalUser } from "./user";
4
+
5
+ export type ProjectFileEntity = {
6
+ id: string;
7
+ projectId: string;
8
+ fileId: string;
9
+ order: number;
10
+ isPlaceholder: boolean;
11
+ };
12
+
13
+ export type ProjectEntity = {
14
+ id: string;
15
+ createdAt: Date;
16
+ updatedAt: Date;
17
+ userId: string;
18
+ title: string;
19
+ description?: string;
20
+ overview?: string;
21
+ url?: string;
22
+ clientId?: string;
23
+ clientType?: ClientType;
24
+ clientName?: string;
25
+ projectCreatorType: Role;
26
+ tags?: string[];
27
+ isFeatured?: boolean;
28
+ startDate?: Date | null;
29
+ imagePlaceholderUrl?: string;
30
+ endDate?: Date | null;
31
+ };
32
+
33
+ export type ProjectWithFilesEntity = ProjectEntity &
34
+ ProjectSocialGraphEntity & {
35
+ projectFiles?: ProjectFileEntity[];
36
+ };
37
+
38
+ export type ProjectViewEntity = {
39
+ id: string;
40
+ userId?: string;
41
+ ipAddress?: string;
42
+ userAgent?: string;
43
+ projectId: string;
44
+ sessionId?: string;
45
+ viewedAt: Date;
46
+ viewDate: Date;
47
+ };
48
+
49
+ export type ProjectLikeEntity = {
50
+ createdAt: Date;
51
+ userId: string;
52
+ projectId: string;
53
+ };
54
+
55
+ export type ProjectCommentEntity = {
56
+ id: string;
57
+ status: CommentStatus;
58
+ createdAt: Date;
59
+ userId: string;
60
+ projectId: string;
61
+ parentCommentId?: string;
62
+ content: string;
63
+ };
64
+
65
+ export type ProjectBookmarkEntity = {
66
+ createdAt: Date;
67
+ userId: string;
68
+ projectId: string;
69
+ };
70
+
71
+ export type MinimalProject = Pick<
72
+ ProjectEntity,
73
+ | "id"
74
+ | "title"
75
+ | "description"
76
+ | "tags"
77
+ | "startDate"
78
+ | "endDate"
79
+ | "imagePlaceholderUrl"
80
+ >;
81
+
82
+ export type ProjectWithClientEntity = MinimalProject & {
83
+ client: MinimalUser;
84
+ };
85
+
86
+ export type ProjectWithUserEntity = MinimalProject & {
87
+ user: Pick<
88
+ BaseUserEntity,
89
+ "id" | "name" | "email" | "image" | "username" | "role"
90
+ >;
91
+ projectFiles: (ProjectFileEntity & { fileUrl: string })[];
92
+ } & Partial<ProjectSocialGraphEntity>;
93
+
94
+ export type ListProjectsDto = {
95
+ query?: string;
96
+ tags?: string[];
97
+ clientName?: string;
98
+ userId?: string;
99
+ page?: number;
100
+ perPage?: number;
101
+ };