import { sql } from "drizzle-orm"; import { pgTable, text, varchar, integer, timestamp, boolean, json } from "drizzle-orm/pg-core"; import { createInsertSchema } from "drizzle-zod"; import { z } from "zod"; export const pixels = pgTable("pixels", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), x: integer("x").notNull(), y: integer("y").notNull(), color: varchar("color", { length: 7 }).notNull(), // hex color userId: varchar("user_id").notNull(), username: varchar("username").notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), }); export const canvasConfig = pgTable("canvas_config", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), canvasWidth: integer("canvas_width").notNull().default(100), canvasHeight: integer("canvas_height").notNull().default(100), defaultCooldown: integer("default_cooldown").notNull().default(5), // seconds enableAutomaticEvents: boolean("enable_automatic_events").notNull().default(false), eventDuration: integer("event_duration").notNull().default(30), // minutes eventInterval: integer("event_interval").notNull().default(6), // hours updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const userCooldowns = pgTable("user_cooldowns", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), userId: varchar("user_id").notNull(), lastPlacement: timestamp("last_placement").defaultNow().notNull(), cooldownEnds: timestamp("cooldown_ends").notNull(), }); export const insertPixelSchema = createInsertSchema(pixels).omit({ id: true, createdAt: true, }); export const insertCanvasConfigSchema = createInsertSchema(canvasConfig).omit({ id: true, updatedAt: true, }); export const insertUserCooldownSchema = createInsertSchema(userCooldowns).omit({ id: true, lastPlacement: true, }); export type Pixel = typeof pixels.$inferSelect; export type InsertPixel = z.infer; export type CanvasConfig = typeof canvasConfig.$inferSelect; export type InsertCanvasConfig = z.infer; export type UserCooldown = typeof userCooldowns.$inferSelect; export type InsertUserCooldown = z.infer; // WebSocket message types export const wsMessageSchema = z.union([ z.object({ type: z.literal("pixel_placed"), data: z.object({ x: z.number(), y: z.number(), color: z.string(), userId: z.string(), username: z.string(), timestamp: z.string(), }), }), z.object({ type: z.literal("user_count"), data: z.object({ count: z.number(), }), }), z.object({ type: z.literal("cooldown_update"), data: z.object({ userId: z.string(), remainingSeconds: z.number(), }), }), ]); export type WSMessage = z.infer;