Files
playzer/packages/api-contract/src/admin.ts
Jose Selesan 1318e3bf57 feat: add recurring bookings feature with related handlers and services
- Introduced recurring booking groups with the ability to create and cancel them.
- Added database migrations for recurring bookings, including new tables and relationships.
- Implemented handlers for creating and canceling recurring bookings in the admin booking module.
- Enhanced existing booking services to support recurring bookings logic.
- Updated API contract to include new schemas for recurring bookings.
- Refactored existing code for improved readability and maintainability.
2026-06-16 11:58:06 -03:00

117 lines
3.8 KiB
TypeScript

import { z } from 'zod';
export const adminPaymentStatusSchema = z.enum(['active', 'no_plan', 'expired']);
export const adminComplexListItemSchema = z.object({
id: z.string(),
complexName: z.string(),
complexSlug: z.string(),
city: z.string().nullable(),
planCode: z.string().nullable(),
planName: z.string().nullable(),
userCount: z.number().int().nonnegative(),
courtCount: z.number().int().nonnegative(),
avgBookingsPerDay: z.number().nonnegative(),
paymentStatus: adminPaymentStatusSchema,
});
export const adminComplexStatsSchema = z.object({
id: z.string(),
complexName: z.string(),
complexSlug: z.string(),
city: z.string().nullable(),
adminEmail: z.string(),
planCode: z.string().nullable(),
planName: z.string().nullable(),
userCount: z.number().int().nonnegative(),
courtCount: z.number().int().nonnegative(),
totalBookings: z.number().int().nonnegative(),
avgBookingsPerDay: z.number().nonnegative(),
bookingsByStatus: z.object({
confirmed: z.number().int().nonnegative(),
cancelled: z.number().int().nonnegative(),
completed: z.number().int().nonnegative(),
noshow: z.number().int().nonnegative(),
}),
paymentStatus: adminPaymentStatusSchema,
});
export const adminCreatePlanSchema = z.object({
code: z.string().trim().min(1).max(10),
name: z.string().trim().min(1).max(30),
price: z.number().nonnegative(),
rules: z.any(),
});
export const adminUpdatePlanSchema = z.object({
name: z.string().trim().min(1).max(30).optional(),
price: z.number().nonnegative().optional(),
rules: z.any().optional(),
});
export const adminUserSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string(),
role: z.string(),
banned: z.boolean(),
bannedAt: z.string().datetime().nullable(),
banReason: z.string().nullable(),
createdAt: z.string().datetime(),
complexCount: z.number().int().nonnegative(),
activeSessions: z.number().int().nonnegative(),
});
export const adminBlockUserSchema = z.object({
banReason: z.string().max(500).optional(),
});
export const adminGlobalStatsSchema = z.object({
totalComplexes: z.number().int().nonnegative(),
totalUsers: z.number().int().nonnegative(),
totalCourts: z.number().int().nonnegative(),
totalBookings: z.number().int().nonnegative(),
});
export const adminUserSessionSchema = z.object({
id: z.string(),
createdAt: z.string().datetime(),
expiresAt: z.string().datetime(),
ipAddress: z.string().nullable(),
userAgent: z.string().nullable(),
city: z.string().nullable(),
country: z.string().nullable(),
countryCode: z.string().nullable(),
});
export type AdminComplexListItem = z.infer<typeof adminComplexListItemSchema>;
export type AdminComplexStats = z.infer<typeof adminComplexStatsSchema>;
export type AdminCreatePlanInput = z.infer<typeof adminCreatePlanSchema>;
export type AdminUpdatePlanInput = z.infer<typeof adminUpdatePlanSchema>;
export type AdminUser = z.infer<typeof adminUserSchema>;
export type AdminBlockUserInput = z.infer<typeof adminBlockUserSchema>;
export type AdminGlobalStats = z.infer<typeof adminGlobalStatsSchema>;
export type AdminPaymentStatus = z.infer<typeof adminPaymentStatusSchema>;
export type AdminUserSession = z.infer<typeof adminUserSessionSchema>;
export const adminGeoCitySchema = z.object({
city: z.string(),
userCount: z.number().int().nonnegative(),
});
export const adminGeoCountrySchema = z.object({
country: z.string(),
countryCode: z.string(),
totalUsers: z.number().int().nonnegative(),
cities: z.array(adminGeoCitySchema),
});
export const adminGeoStatsSchema = z.object({
countries: z.array(adminGeoCountrySchema),
totalUniqueCountries: z.number().int().nonnegative(),
});
export type AdminGeoCity = z.infer<typeof adminGeoCitySchema>;
export type AdminGeoCountry = z.infer<typeof adminGeoCountrySchema>;
export type AdminGeoStats = z.infer<typeof adminGeoStatsSchema>;