Set up the basic structure and functionality for the DJ management system
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
This commit is contained in:
@@ -0,0 +1,338 @@
|
||||
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>;
|
||||
Reference in New Issue
Block a user