89946fcef9
Initializes project structure, adds core components, and configures essential dependencies. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 3a22ac80-cd1d-4441-9e36-f24fc2f4c3de Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3478f7c3-db8c-4fca-9165-3adbdf1b5829/e8da43e7-d99c-4328-9fdc-485bdeecffc1.jpg
339 lines
11 KiB
TypeScript
339 lines
11 KiB
TypeScript
import {
|
|
pgTable,
|
|
text,
|
|
varchar,
|
|
timestamp,
|
|
jsonb,
|
|
index,
|
|
serial,
|
|
boolean,
|
|
integer,
|
|
date,
|
|
time,
|
|
pgEnum,
|
|
} from "drizzle-orm/pg-core";
|
|
import { relations } from "drizzle-orm";
|
|
import { createInsertSchema } from "drizzle-zod";
|
|
import { z } from "zod";
|
|
|
|
// Session storage table.
|
|
// (IMPORTANT) This table is mandatory for Replit Auth, don't drop it.
|
|
export const sessions = pgTable(
|
|
"sessions",
|
|
{
|
|
sid: varchar("sid").primaryKey(),
|
|
sess: jsonb("sess").notNull(),
|
|
expire: timestamp("expire").notNull(),
|
|
},
|
|
(table) => [index("IDX_session_expire").on(table.expire)],
|
|
);
|
|
|
|
// User roles enum
|
|
export const userRoleEnum = pgEnum("user_role", ["dj", "admin"]);
|
|
|
|
// User storage table.
|
|
// (IMPORTANT) This table is mandatory for Replit Auth, don't drop it.
|
|
export const users = pgTable("users", {
|
|
id: varchar("id").primaryKey().notNull(),
|
|
email: varchar("email").unique(),
|
|
firstName: varchar("first_name"),
|
|
lastName: varchar("last_name"),
|
|
profileImageUrl: varchar("profile_image_url"),
|
|
displayName: varchar("display_name"),
|
|
role: userRoleEnum("role").default("dj").notNull(),
|
|
isActive: boolean("is_active").default(true).notNull(),
|
|
maxEventsPerMonth: integer("max_events_per_month").default(2).notNull(),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
updatedAt: timestamp("updated_at").defaultNow(),
|
|
});
|
|
|
|
// Event types table
|
|
export const eventTypes = pgTable("event_types", {
|
|
id: serial("id").primaryKey(),
|
|
name: varchar("name").notNull(),
|
|
description: text("description"),
|
|
isActive: boolean("is_active").default(true).notNull(),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
});
|
|
|
|
// Schedule templates table
|
|
export const scheduleTemplates = pgTable("schedule_templates", {
|
|
id: serial("id").primaryKey(),
|
|
name: varchar("name").notNull(),
|
|
description: text("description"),
|
|
isActive: boolean("is_active").default(true).notNull(),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
});
|
|
|
|
// Schedule template slots table
|
|
export const scheduleTemplateSlots = pgTable("schedule_template_slots", {
|
|
id: serial("id").primaryKey(),
|
|
templateId: integer("template_id").references(() => scheduleTemplates.id).notNull(),
|
|
dayOfWeek: integer("day_of_week").notNull(), // 0=Sunday, 1=Monday, etc.
|
|
startTime: time("start_time").notNull(),
|
|
endTime: time("end_time").notNull(),
|
|
eventTypeId: integer("event_type_id").references(() => eventTypes.id).notNull(),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
});
|
|
|
|
// Events table
|
|
export const events = pgTable("events", {
|
|
id: serial("id").primaryKey(),
|
|
name: varchar("name").notNull(),
|
|
eventTypeId: integer("event_type_id").references(() => eventTypes.id).notNull(),
|
|
djId: varchar("dj_id").references(() => users.id).notNull(),
|
|
date: date("date").notNull(),
|
|
startTime: time("start_time").notNull(),
|
|
endTime: time("end_time").notNull(),
|
|
locationName: varchar("location_name").notNull(),
|
|
locationAddress: text("location_address"),
|
|
description: text("description"),
|
|
isAssignedByAdmin: boolean("is_assigned_by_admin").default(false).notNull(),
|
|
templateSlotId: integer("template_slot_id").references(() => scheduleTemplateSlots.id),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
updatedAt: timestamp("updated_at").defaultNow(),
|
|
});
|
|
|
|
// DJ social links table
|
|
export const socialLinks = pgTable("social_links", {
|
|
id: serial("id").primaryKey(),
|
|
djId: varchar("dj_id").references(() => users.id).notNull(),
|
|
label: varchar("label").notNull(),
|
|
url: varchar("url").notNull(),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
});
|
|
|
|
// DJ availability table
|
|
export const availability = pgTable("availability", {
|
|
id: serial("id").primaryKey(),
|
|
djId: varchar("dj_id").references(() => users.id).notNull(),
|
|
startDate: date("start_date").notNull(),
|
|
endDate: date("end_date").notNull(),
|
|
reason: text("reason"),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
});
|
|
|
|
// DJ slot eligibility table
|
|
export const slotEligibility = pgTable("slot_eligibility", {
|
|
id: serial("id").primaryKey(),
|
|
djId: varchar("dj_id").references(() => users.id).notNull(),
|
|
templateSlotId: integer("template_slot_id").references(() => scheduleTemplateSlots.id).notNull(),
|
|
isEligible: boolean("is_eligible").default(true).notNull(),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
});
|
|
|
|
// Event removal requests table
|
|
export const removalRequests = pgTable("removal_requests", {
|
|
id: serial("id").primaryKey(),
|
|
eventId: integer("event_id").references(() => events.id).notNull(),
|
|
djId: varchar("dj_id").references(() => users.id).notNull(),
|
|
reason: text("reason"),
|
|
status: varchar("status").default("pending").notNull(), // pending, approved, denied
|
|
reviewedBy: varchar("reviewed_by").references(() => users.id),
|
|
reviewedAt: timestamp("reviewed_at"),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
});
|
|
|
|
// DJ invitations table
|
|
export const invitations = pgTable("invitations", {
|
|
id: serial("id").primaryKey(),
|
|
email: varchar("email").notNull(),
|
|
token: varchar("token").notNull().unique(),
|
|
name: varchar("name").notNull(),
|
|
isUsed: boolean("is_used").default(false).notNull(),
|
|
expiresAt: timestamp("expires_at").notNull(),
|
|
createdBy: varchar("created_by").references(() => users.id).notNull(),
|
|
createdAt: timestamp("created_at").defaultNow(),
|
|
});
|
|
|
|
// Relations
|
|
export const userRelations = relations(users, ({ many }) => ({
|
|
events: many(events),
|
|
socialLinks: many(socialLinks),
|
|
availability: many(availability),
|
|
slotEligibility: many(slotEligibility),
|
|
removalRequests: many(removalRequests),
|
|
invitations: many(invitations),
|
|
}));
|
|
|
|
export const eventTypeRelations = relations(eventTypes, ({ many }) => ({
|
|
events: many(events),
|
|
templateSlots: many(scheduleTemplateSlots),
|
|
}));
|
|
|
|
export const scheduleTemplateRelations = relations(scheduleTemplates, ({ many }) => ({
|
|
slots: many(scheduleTemplateSlots),
|
|
}));
|
|
|
|
export const scheduleTemplateSlotRelations = relations(scheduleTemplateSlots, ({ one, many }) => ({
|
|
template: one(scheduleTemplates, {
|
|
fields: [scheduleTemplateSlots.templateId],
|
|
references: [scheduleTemplates.id],
|
|
}),
|
|
eventType: one(eventTypes, {
|
|
fields: [scheduleTemplateSlots.eventTypeId],
|
|
references: [eventTypes.id],
|
|
}),
|
|
events: many(events),
|
|
eligibility: many(slotEligibility),
|
|
}));
|
|
|
|
export const eventRelations = relations(events, ({ one, many }) => ({
|
|
dj: one(users, {
|
|
fields: [events.djId],
|
|
references: [users.id],
|
|
}),
|
|
eventType: one(eventTypes, {
|
|
fields: [events.eventTypeId],
|
|
references: [eventTypes.id],
|
|
}),
|
|
templateSlot: one(scheduleTemplateSlots, {
|
|
fields: [events.templateSlotId],
|
|
references: [scheduleTemplateSlots.id],
|
|
}),
|
|
removalRequests: many(removalRequests),
|
|
}));
|
|
|
|
export const socialLinkRelations = relations(socialLinks, ({ one }) => ({
|
|
dj: one(users, {
|
|
fields: [socialLinks.djId],
|
|
references: [users.id],
|
|
}),
|
|
}));
|
|
|
|
export const availabilityRelations = relations(availability, ({ one }) => ({
|
|
dj: one(users, {
|
|
fields: [availability.djId],
|
|
references: [users.id],
|
|
}),
|
|
}));
|
|
|
|
export const slotEligibilityRelations = relations(slotEligibility, ({ one }) => ({
|
|
dj: one(users, {
|
|
fields: [slotEligibility.djId],
|
|
references: [users.id],
|
|
}),
|
|
templateSlot: one(scheduleTemplateSlots, {
|
|
fields: [slotEligibility.templateSlotId],
|
|
references: [scheduleTemplateSlots.id],
|
|
}),
|
|
}));
|
|
|
|
export const removalRequestRelations = relations(removalRequests, ({ one }) => ({
|
|
event: one(events, {
|
|
fields: [removalRequests.eventId],
|
|
references: [events.id],
|
|
}),
|
|
dj: one(users, {
|
|
fields: [removalRequests.djId],
|
|
references: [users.id],
|
|
}),
|
|
reviewer: one(users, {
|
|
fields: [removalRequests.reviewedBy],
|
|
references: [users.id],
|
|
}),
|
|
}));
|
|
|
|
export const invitationRelations = relations(invitations, ({ one }) => ({
|
|
createdBy: one(users, {
|
|
fields: [invitations.createdBy],
|
|
references: [users.id],
|
|
}),
|
|
}));
|
|
|
|
// Insert schemas
|
|
export const insertUserSchema = createInsertSchema(users).omit({
|
|
createdAt: true,
|
|
updatedAt: true,
|
|
});
|
|
|
|
export const insertEventTypeSchema = createInsertSchema(eventTypes).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
export const insertScheduleTemplateSchema = createInsertSchema(scheduleTemplates).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
export const insertScheduleTemplateSlotSchema = createInsertSchema(scheduleTemplateSlots).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
export const insertEventSchema = createInsertSchema(events).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
updatedAt: true,
|
|
});
|
|
|
|
export const insertSocialLinkSchema = createInsertSchema(socialLinks).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
export const insertAvailabilitySchema = createInsertSchema(availability).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
export const insertSlotEligibilitySchema = createInsertSchema(slotEligibility).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
export const insertRemovalRequestSchema = createInsertSchema(removalRequests).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
export const insertInvitationSchema = createInsertSchema(invitations).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
// Update schemas
|
|
export const updateUserSchema = insertUserSchema.partial();
|
|
export const updateEventSchema = insertEventSchema.partial();
|
|
export const updateEventTypeSchema = insertEventTypeSchema.partial();
|
|
export const updateScheduleTemplateSchema = insertScheduleTemplateSchema.partial();
|
|
export const updateRemovalRequestSchema = insertRemovalRequestSchema.partial();
|
|
|
|
// Type exports
|
|
export type UpsertUser = z.infer<typeof insertUserSchema>;
|
|
export type User = typeof users.$inferSelect;
|
|
export type InsertUser = z.infer<typeof insertUserSchema>;
|
|
export type UpdateUser = z.infer<typeof updateUserSchema>;
|
|
|
|
export type EventType = typeof eventTypes.$inferSelect;
|
|
export type InsertEventType = z.infer<typeof insertEventTypeSchema>;
|
|
export type UpdateEventType = z.infer<typeof updateEventTypeSchema>;
|
|
|
|
export type ScheduleTemplate = typeof scheduleTemplates.$inferSelect;
|
|
export type InsertScheduleTemplate = z.infer<typeof insertScheduleTemplateSchema>;
|
|
export type UpdateScheduleTemplate = z.infer<typeof updateScheduleTemplateSchema>;
|
|
|
|
export type ScheduleTemplateSlot = typeof scheduleTemplateSlots.$inferSelect;
|
|
export type InsertScheduleTemplateSlot = z.infer<typeof insertScheduleTemplateSlotSchema>;
|
|
|
|
export type Event = typeof events.$inferSelect;
|
|
export type InsertEvent = z.infer<typeof insertEventSchema>;
|
|
export type UpdateEvent = z.infer<typeof updateEventSchema>;
|
|
|
|
export type SocialLink = typeof socialLinks.$inferSelect;
|
|
export type InsertSocialLink = z.infer<typeof insertSocialLinkSchema>;
|
|
|
|
export type Availability = typeof availability.$inferSelect;
|
|
export type InsertAvailability = z.infer<typeof insertAvailabilitySchema>;
|
|
|
|
export type SlotEligibility = typeof slotEligibility.$inferSelect;
|
|
export type InsertSlotEligibility = z.infer<typeof insertSlotEligibilitySchema>;
|
|
|
|
export type RemovalRequest = typeof removalRequests.$inferSelect;
|
|
export type InsertRemovalRequest = z.infer<typeof insertRemovalRequestSchema>;
|
|
export type UpdateRemovalRequest = z.infer<typeof updateRemovalRequestSchema>;
|
|
|
|
export type Invitation = typeof invitations.$inferSelect;
|
|
export type InsertInvitation = z.infer<typeof insertInvitationSchema>;
|