From 7726f6063de078cfd48e102fca10df071e874e3e Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Wed, 8 Oct 2025 14:31:27 +0000 Subject: [PATCH] Add user permissions for managing social media pages Introduces the `user_page_permissions` table to manage user access to social media pages, updates relations for `users` and `social_pages`, and defines new schema types for `UserPagePermission`. Replit-Commit-Author: Agent Replit-Commit-Session-Id: ae4037a0-2a6f-4530-9bac-79b543286bda Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/397bca8c-984f-43ff-841a-10897aeb8140/ae4037a0-2a6f-4530-9bac-79b543286bda/u2SCNAb --- .replit | 4 ++++ shared/schema.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/.replit b/.replit index 518307b..087ac91 100644 --- a/.replit +++ b/.replit @@ -14,6 +14,10 @@ run = ["npm", "run", "start"] localPort = 5000 externalPort = 80 +[[ports]] +localPort = 32831 +externalPort = 3003 + [[ports]] localPort = 35357 externalPort = 3002 diff --git a/shared/schema.ts b/shared/schema.ts index 12e6b21..d9f44cd 100644 --- a/shared/schema.ts +++ b/shared/schema.ts @@ -101,12 +101,20 @@ export const aiGenerations = pgTable("ai_generations", { createdAt: timestamp("created_at").defaultNow(), }); +export const userPagePermissions = pgTable("user_page_permissions", { + id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), + userId: varchar("user_id").notNull().references(() => users.id, { onDelete: "cascade" }), + pageId: varchar("page_id").notNull().references(() => socialPages.id, { onDelete: "cascade" }), + createdAt: timestamp("created_at").defaultNow(), +}); + // Relations export const usersRelations = relations(users, ({ many, one }) => ({ socialPages: many(socialPages), media: many(media), posts: many(posts), aiGenerations: many(aiGenerations), + pagePermissions: many(userPagePermissions), cloudinaryConfig: one(cloudinaryConfig), openrouterConfig: one(openrouterConfig), })); @@ -131,6 +139,7 @@ export const socialPagesRelations = relations(socialPages, ({ one, many }) => ({ references: [users.id], }), scheduledPosts: many(scheduledPosts), + userPermissions: many(userPagePermissions), })); export const mediaRelations = relations(media, ({ one, many }) => ({ @@ -179,6 +188,17 @@ export const aiGenerationsRelations = relations(aiGenerations, ({ one }) => ({ }), })); +export const userPagePermissionsRelations = relations(userPagePermissions, ({ one }) => ({ + user: one(users, { + fields: [userPagePermissions.userId], + references: [users.id], + }), + page: one(socialPages, { + fields: [userPagePermissions.pageId], + references: [socialPages.id], + }), +})); + // Insert schemas export const insertUserSchema = createInsertSchema(users).pick({ username: true, @@ -235,6 +255,11 @@ export const updateCloudinaryConfigSchema = insertCloudinaryConfigSchema.partial apiSecret: true, }); +export const insertUserPagePermissionSchema = createInsertSchema(userPagePermissions).omit({ + id: true, + createdAt: true, +}); + // Types export type User = typeof users.$inferSelect; export type InsertUser = z.infer; @@ -263,3 +288,6 @@ export type InsertOpenrouterConfig = z.infer; export type PostMedia = typeof postMedia.$inferSelect; + +export type UserPagePermission = typeof userPagePermissions.$inferSelect; +export type InsertUserPagePermission = z.infer;