feat : Création de toutes les entités
This commit is contained in:
18
package-lock.json
generated
18
package-lock.json
generated
@@ -44,7 +44,8 @@
|
|||||||
"react-native-svg": "15.15.4",
|
"react-native-svg": "15.15.4",
|
||||||
"react-native-web": "~0.21.0",
|
"react-native-web": "~0.21.0",
|
||||||
"react-native-worklets": "0.8.3",
|
"react-native-worklets": "0.8.3",
|
||||||
"tailwindcss": "^3.4.19"
|
"tailwindcss": "^3.4.19",
|
||||||
|
"zod": "^4.5.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "~19.2.2",
|
"@types/react": "~19.2.2",
|
||||||
@@ -5329,6 +5330,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/expo/node_modules/zod": {
|
||||||
|
"version": "3.25.76",
|
||||||
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||||
|
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/exponential-backoff": {
|
"node_modules/exponential-backoff": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz",
|
||||||
@@ -10156,9 +10166,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/zod": {
|
"node_modules/zod": {
|
||||||
"version": "3.25.76",
|
"version": "4.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-4.5.4.tgz",
|
||||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
"integrity": "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
|
|||||||
@@ -39,7 +39,8 @@
|
|||||||
"react-native-svg": "15.15.4",
|
"react-native-svg": "15.15.4",
|
||||||
"react-native-web": "~0.21.0",
|
"react-native-web": "~0.21.0",
|
||||||
"react-native-worklets": "0.8.3",
|
"react-native-worklets": "0.8.3",
|
||||||
"tailwindcss": "^3.4.19"
|
"tailwindcss": "^3.4.19",
|
||||||
|
"zod": "^4.5.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "~19.2.2",
|
"@types/react": "~19.2.2",
|
||||||
|
|||||||
17
src/models/_shared.ts
Normal file
17
src/models/_shared.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const uuidSchema = z.string().uuid();
|
||||||
|
|
||||||
|
export const timestampSchema = z.coerce.date();
|
||||||
|
|
||||||
|
export const sqlDateSchema = z
|
||||||
|
.string()
|
||||||
|
.regex(/^\d{4}-\d{2}-\d{2}$/, 'Expected date format YYYY-MM-DD');
|
||||||
|
|
||||||
|
export const nullableText = z.string().trim().min(1).nullable();
|
||||||
|
|
||||||
|
export const nullableUrl = z.string().url().nullable();
|
||||||
|
|
||||||
|
export const nullableLatitude = z.number().min(-90).max(90).nullable();
|
||||||
|
|
||||||
|
export const nullableLongitude = z.number().min(-180).max(180).nullable();
|
||||||
16
src/models/animators.ts
Normal file
16
src/models/animators.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { nullableUrl, timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const animatorSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
name: z.string().trim().min(1).max(255),
|
||||||
|
profile_picture: nullableUrl,
|
||||||
|
genre: z.string().trim().min(1).max(100).nullable(),
|
||||||
|
city: z.string().trim().min(1).max(100).nullable(),
|
||||||
|
bio: z.string().trim().min(1).nullable(),
|
||||||
|
created_at: timestampSchema,
|
||||||
|
updated_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Animator = z.infer<typeof animatorSchema>;
|
||||||
11
src/models/comment_likes.ts
Normal file
11
src/models/comment_likes.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const commentLikeSchema = z.object({
|
||||||
|
user_id: uuidSchema,
|
||||||
|
comment_id: uuidSchema,
|
||||||
|
created_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type CommentLike = z.infer<typeof commentLikeSchema>;
|
||||||
15
src/models/comments.ts
Normal file
15
src/models/comments.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const commentSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
post_id: uuidSchema,
|
||||||
|
user_id: uuidSchema,
|
||||||
|
parent_comment_id: uuidSchema.nullable(),
|
||||||
|
content: z.string().trim().min(1),
|
||||||
|
created_at: timestampSchema,
|
||||||
|
updated_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Comment = z.infer<typeof commentSchema>;
|
||||||
13
src/models/event_external_links.ts
Normal file
13
src/models/event_external_links.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const eventExternalLinkSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
event_id: uuidSchema,
|
||||||
|
url: z.string().trim().min(1),
|
||||||
|
label: z.string().trim().min(1).max(100).nullable(),
|
||||||
|
display_order: z.number().int().default(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type EventExternalLink = z.infer<typeof eventExternalLinkSchema>;
|
||||||
10
src/models/event_hashtags.ts
Normal file
10
src/models/event_hashtags.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const eventHashtagSchema = z.object({
|
||||||
|
event_id: uuidSchema,
|
||||||
|
hashtag_id: uuidSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type EventHashtag = z.infer<typeof eventHashtagSchema>;
|
||||||
14
src/models/event_images.ts
Normal file
14
src/models/event_images.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const eventImageSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
event_id: uuidSchema,
|
||||||
|
url: z.string().url(),
|
||||||
|
is_cover: z.boolean().default(false),
|
||||||
|
display_order: z.number().int().default(0),
|
||||||
|
created_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type EventImage = z.infer<typeof eventImageSchema>;
|
||||||
18
src/models/event_lineup.ts
Normal file
18
src/models/event_lineup.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const eventLineupRoleSchema = z.enum(['HEADLINER', 'OPENING', 'CLOSING']);
|
||||||
|
|
||||||
|
export const eventLineupSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
event_id: uuidSchema,
|
||||||
|
animator_id: uuidSchema,
|
||||||
|
stage_name: z.string().trim().min(1).max(100).nullable(),
|
||||||
|
start_time: timestampSchema.nullable(),
|
||||||
|
end_time: timestampSchema.nullable(),
|
||||||
|
role: eventLineupRoleSchema.nullable(),
|
||||||
|
display_order: z.number().int().default(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type EventLineup = z.infer<typeof eventLineupSchema>;
|
||||||
15
src/models/event_stats_snapshots.ts
Normal file
15
src/models/event_stats_snapshots.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { sqlDateSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const eventStatsSnapshotSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
event_id: uuidSchema,
|
||||||
|
snapshot_date: sqlDateSchema,
|
||||||
|
view_count: z.number().int().min(0).default(0),
|
||||||
|
participant_count: z.number().int().min(0).default(0),
|
||||||
|
interested_count: z.number().int().min(0).default(0),
|
||||||
|
share_count: z.number().int().min(0).default(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type EventStatsSnapshot = z.infer<typeof eventStatsSnapshotSchema>;
|
||||||
10
src/models/event_themes.ts
Normal file
10
src/models/event_themes.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const eventThemeSchema = z.object({
|
||||||
|
event_id: uuidSchema,
|
||||||
|
theme_id: uuidSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type EventTheme = z.infer<typeof eventThemeSchema>;
|
||||||
40
src/models/events.ts
Normal file
40
src/models/events.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import {
|
||||||
|
nullableLatitude,
|
||||||
|
nullableLongitude,
|
||||||
|
nullableText,
|
||||||
|
timestampSchema,
|
||||||
|
uuidSchema,
|
||||||
|
} from './_shared';
|
||||||
|
|
||||||
|
export const eventStatusSchema = z.enum(['DRAFT', 'PUBLISHED', 'CANCELLED']);
|
||||||
|
|
||||||
|
export const eventSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
organizer_id: uuidSchema,
|
||||||
|
name: z.string().trim().min(1).max(255),
|
||||||
|
description: z.string().trim().max(600).nullable(),
|
||||||
|
start_date: timestampSchema,
|
||||||
|
end_date: timestampSchema,
|
||||||
|
doors_open_time: timestampSchema.nullable(),
|
||||||
|
min_age: z.number().int().min(0).nullable(),
|
||||||
|
address: nullableText,
|
||||||
|
city: z.string().trim().min(1).max(100).nullable(),
|
||||||
|
latitude: nullableLatitude,
|
||||||
|
longitude: nullableLongitude,
|
||||||
|
price_presale: z.number().min(0).nullable(),
|
||||||
|
price_door: z.number().min(0).nullable(),
|
||||||
|
is_free: z.boolean().default(false),
|
||||||
|
presale_total: z.number().int().min(0).nullable(),
|
||||||
|
presale_sold: z.number().int().min(0).default(0),
|
||||||
|
ticketing_enabled: z.boolean().default(false),
|
||||||
|
ticketing_commission: z.number().min(0).max(100).nullable(),
|
||||||
|
status: eventStatusSchema,
|
||||||
|
featured_image_id: uuidSchema.nullable(),
|
||||||
|
published_at: timestampSchema.nullable(),
|
||||||
|
created_at: timestampSchema,
|
||||||
|
updated_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Event = z.infer<typeof eventSchema>;
|
||||||
10
src/models/hashtags.ts
Normal file
10
src/models/hashtags.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const hashtagSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
name: z.string().trim().min(1).max(100),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Hashtag = z.infer<typeof hashtagSchema>;
|
||||||
30
src/models/index.ts
Normal file
30
src/models/index.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
export * from './_shared';
|
||||||
|
export * from './animators';
|
||||||
|
export * from './comment_likes';
|
||||||
|
export * from './comments';
|
||||||
|
export * from './event_external_links';
|
||||||
|
export * from './event_hashtags';
|
||||||
|
export * from './event_images';
|
||||||
|
export * from './event_lineup';
|
||||||
|
export * from './event_stats_snapshots';
|
||||||
|
export * from './event_themes';
|
||||||
|
export * from './events';
|
||||||
|
export * from './hashtags';
|
||||||
|
export * from './organizer_members';
|
||||||
|
export * from './organizer_subscriptions';
|
||||||
|
export * from './organizers';
|
||||||
|
export * from './plans';
|
||||||
|
export * from './post_likes';
|
||||||
|
export * from './post_media';
|
||||||
|
export * from './posts';
|
||||||
|
export * from './search_history';
|
||||||
|
export * from './social_auth_providers';
|
||||||
|
export * from './themes';
|
||||||
|
export * from './tickets';
|
||||||
|
export * from './user_animator_follows';
|
||||||
|
export * from './user_event_interactions';
|
||||||
|
export * from './user_event_shares';
|
||||||
|
export * from './user_organizer_follows';
|
||||||
|
export * from './user_theme_preferences';
|
||||||
|
export * from './users';
|
||||||
|
|
||||||
20
src/models/organizer_members.ts
Normal file
20
src/models/organizer_members.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const organizerMemberRoleSchema = z.enum(['ADMIN', 'EDITOR']);
|
||||||
|
|
||||||
|
export const organizerMemberStatusSchema = z.enum(['ACTIVE', 'PENDING']);
|
||||||
|
|
||||||
|
export const organizerMemberSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
organizer_id: uuidSchema,
|
||||||
|
user_id: uuidSchema.nullable(),
|
||||||
|
email: z.string().trim().email().max(255),
|
||||||
|
role: organizerMemberRoleSchema,
|
||||||
|
status: organizerMemberStatusSchema,
|
||||||
|
invited_at: timestampSchema,
|
||||||
|
joined_at: timestampSchema.nullable(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type OrganizerMember = z.infer<typeof organizerMemberSchema>;
|
||||||
21
src/models/organizer_subscriptions.ts
Normal file
21
src/models/organizer_subscriptions.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { sqlDateSchema, timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const organizerSubscriptionStatusSchema = z.enum([
|
||||||
|
'ACTIVE',
|
||||||
|
'CANCELLED',
|
||||||
|
'EXPIRED',
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const organizerSubscriptionSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
organizer_id: uuidSchema,
|
||||||
|
plan_id: uuidSchema,
|
||||||
|
status: organizerSubscriptionStatusSchema,
|
||||||
|
started_at: timestampSchema,
|
||||||
|
renewal_date: sqlDateSchema.nullable(),
|
||||||
|
cancelled_at: timestampSchema.nullable(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type OrganizerSubscription = z.infer<typeof organizerSubscriptionSchema>;
|
||||||
23
src/models/organizers.ts
Normal file
23
src/models/organizers.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { nullableUrl, timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const organizerSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
name: z.string().trim().min(1).max(255),
|
||||||
|
email: z.string().trim().email().max(255),
|
||||||
|
profile_picture: nullableUrl,
|
||||||
|
cover_picture: nullableUrl,
|
||||||
|
city: z.string().trim().min(1).max(100).nullable(),
|
||||||
|
is_verified: z.boolean().default(false),
|
||||||
|
verified_at: timestampSchema.nullable(),
|
||||||
|
verified_by: uuidSchema.nullable(),
|
||||||
|
instagram_handle: z.string().trim().min(1).max(100).nullable(),
|
||||||
|
tiktok_handle: z.string().trim().min(1).max(100).nullable(),
|
||||||
|
facebook_handle: z.string().trim().min(1).max(100).nullable(),
|
||||||
|
plan_id: uuidSchema.nullable(),
|
||||||
|
created_at: timestampSchema,
|
||||||
|
updated_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Organizer = z.infer<typeof organizerSchema>;
|
||||||
16
src/models/plans.ts
Normal file
16
src/models/plans.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const planNameSchema = z.enum(['FREE', 'PRO', 'TICKETING']);
|
||||||
|
|
||||||
|
export const planSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
name: planNameSchema,
|
||||||
|
price_monthly: z.number().min(0),
|
||||||
|
max_active_events: z.number().int().min(0).nullable(),
|
||||||
|
ticketing_enabled: z.boolean().default(false),
|
||||||
|
ticketing_commission: z.number().min(0).max(100).nullable(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Plan = z.infer<typeof planSchema>;
|
||||||
11
src/models/post_likes.ts
Normal file
11
src/models/post_likes.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const postLikeSchema = z.object({
|
||||||
|
user_id: uuidSchema,
|
||||||
|
post_id: uuidSchema,
|
||||||
|
created_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type PostLike = z.infer<typeof postLikeSchema>;
|
||||||
16
src/models/post_media.ts
Normal file
16
src/models/post_media.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const postMediaTypeSchema = z.enum(['IMAGE', 'VIDEO']);
|
||||||
|
|
||||||
|
export const postMediaSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
post_id: uuidSchema,
|
||||||
|
url: z.string().url(),
|
||||||
|
type: postMediaTypeSchema,
|
||||||
|
duration_seconds: z.number().int().min(0).nullable(),
|
||||||
|
display_order: z.number().int().default(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type PostMedia = z.infer<typeof postMediaSchema>;
|
||||||
31
src/models/posts.ts
Normal file
31
src/models/posts.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const postTypeSchema = z.enum([
|
||||||
|
'TEXT',
|
||||||
|
'PHOTO',
|
||||||
|
'VIDEO',
|
||||||
|
'ANNOUNCEMENT',
|
||||||
|
'TEASER',
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const postStatusSchema = z.enum(['DRAFT', 'SCHEDULED', 'PUBLISHED']);
|
||||||
|
|
||||||
|
export const postSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
organizer_id: uuidSchema,
|
||||||
|
event_id: uuidSchema.nullable(),
|
||||||
|
content: z.string().trim().max(500).nullable(),
|
||||||
|
type: postTypeSchema,
|
||||||
|
status: postStatusSchema,
|
||||||
|
scheduled_at: timestampSchema.nullable(),
|
||||||
|
published_at: timestampSchema.nullable(),
|
||||||
|
rediffusion_instagram: z.boolean().default(false),
|
||||||
|
rediffusion_tiktok: z.boolean().default(false),
|
||||||
|
rediffusion_facebook: z.boolean().default(false),
|
||||||
|
created_at: timestampSchema,
|
||||||
|
updated_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Post = z.infer<typeof postSchema>;
|
||||||
12
src/models/search_history.ts
Normal file
12
src/models/search_history.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const searchHistorySchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
user_id: uuidSchema,
|
||||||
|
query: z.string().trim().min(1).max(255),
|
||||||
|
searched_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type SearchHistory = z.infer<typeof searchHistorySchema>;
|
||||||
13
src/models/social_auth_providers.ts
Normal file
13
src/models/social_auth_providers.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const socialAuthProviderSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
user_id: uuidSchema,
|
||||||
|
provider: z.enum(['google', 'apple']),
|
||||||
|
provider_user_id: z.string().trim().min(1).max(255),
|
||||||
|
created_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type SocialAuthProvider = z.infer<typeof socialAuthProviderSchema>;
|
||||||
15
src/models/themes.ts
Normal file
15
src/models/themes.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const themesSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
name: z.string().trim().min(1).max(100),
|
||||||
|
color_hex: z
|
||||||
|
.string()
|
||||||
|
.regex(/^#[0-9A-Fa-f]{6}$/, 'Expected color format #RRGGBB')
|
||||||
|
.nullable(),
|
||||||
|
display_order: z.number().int().default(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Theme = z.infer<typeof themesSchema>;
|
||||||
22
src/models/tickets.ts
Normal file
22
src/models/tickets.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const ticketTypeSchema = z.enum(['PRESALE', 'DOOR']);
|
||||||
|
|
||||||
|
export const ticketStatusSchema = z.enum(['VALID', 'USED', 'CANCELLED']);
|
||||||
|
|
||||||
|
export const ticketSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
event_id: uuidSchema,
|
||||||
|
user_id: uuidSchema,
|
||||||
|
type: ticketTypeSchema,
|
||||||
|
price_paid: z.number().min(0),
|
||||||
|
bahla_commission: z.number().min(0),
|
||||||
|
status: ticketStatusSchema,
|
||||||
|
purchased_at: timestampSchema,
|
||||||
|
used_at: timestampSchema.nullable(),
|
||||||
|
qr_code: z.string().trim().min(1).nullable(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Ticket = z.infer<typeof ticketSchema>;
|
||||||
11
src/models/user_animator_follows.ts
Normal file
11
src/models/user_animator_follows.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const userAnimatorFollowSchema = z.object({
|
||||||
|
user_id: uuidSchema,
|
||||||
|
animator_id: uuidSchema,
|
||||||
|
created_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UserAnimatorFollow = z.infer<typeof userAnimatorFollowSchema>;
|
||||||
19
src/models/user_event_interactions.ts
Normal file
19
src/models/user_event_interactions.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const userEventInteractionStatusSchema = z.enum([
|
||||||
|
'PARTICIPATING',
|
||||||
|
'INTERESTED',
|
||||||
|
'SAVED',
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const userEventInteractionSchema = z.object({
|
||||||
|
user_id: uuidSchema,
|
||||||
|
event_id: uuidSchema,
|
||||||
|
status: userEventInteractionStatusSchema,
|
||||||
|
created_at: timestampSchema,
|
||||||
|
updated_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UserEventInteraction = z.infer<typeof userEventInteractionSchema>;
|
||||||
12
src/models/user_event_shares.ts
Normal file
12
src/models/user_event_shares.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const userEventShareSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
user_id: uuidSchema.nullable(),
|
||||||
|
event_id: uuidSchema,
|
||||||
|
shared_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UserEventShare = z.infer<typeof userEventShareSchema>;
|
||||||
11
src/models/user_organizer_follows.ts
Normal file
11
src/models/user_organizer_follows.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { timestampSchema, uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const userOrganizerFollowSchema = z.object({
|
||||||
|
user_id: uuidSchema,
|
||||||
|
organizer_id: uuidSchema,
|
||||||
|
created_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UserOrganizerFollow = z.infer<typeof userOrganizerFollowSchema>;
|
||||||
10
src/models/user_theme_preferences.ts
Normal file
10
src/models/user_theme_preferences.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { uuidSchema } from './_shared';
|
||||||
|
|
||||||
|
export const userThemePreferenceSchema = z.object({
|
||||||
|
user_id: uuidSchema,
|
||||||
|
theme_id: uuidSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UserThemePreference = z.infer<typeof userThemePreferenceSchema>;
|
||||||
31
src/models/users.ts
Normal file
31
src/models/users.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import {
|
||||||
|
nullableLatitude,
|
||||||
|
nullableLongitude,
|
||||||
|
nullableText,
|
||||||
|
nullableUrl,
|
||||||
|
timestampSchema,
|
||||||
|
uuidSchema,
|
||||||
|
} from './_shared';
|
||||||
|
|
||||||
|
export const userSchema = z.object({
|
||||||
|
id: uuidSchema,
|
||||||
|
first_name: z.string().trim().min(1).max(100),
|
||||||
|
last_name: z.string().trim().min(1).max(100),
|
||||||
|
email: z.string().trim().email().max(255),
|
||||||
|
password_hash: z.string().trim().min(1).max(255).nullable(),
|
||||||
|
profile_picture: nullableUrl,
|
||||||
|
address: nullableText,
|
||||||
|
city: z.string().trim().min(1).max(100).nullable(),
|
||||||
|
latitude: nullableLatitude,
|
||||||
|
longitude: nullableLongitude,
|
||||||
|
default_radius_km: z.number().int().min(0).default(25),
|
||||||
|
language: z.string().trim().min(2).max(10).default('fr'),
|
||||||
|
notifications_enabled: z.boolean().default(true),
|
||||||
|
calendar_sync_enabled: z.boolean().default(false),
|
||||||
|
created_at: timestampSchema,
|
||||||
|
updated_at: timestampSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type User = z.infer<typeof userSchema>;
|
||||||
Reference in New Issue
Block a user