mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-11 17:26:45 +02:00
Add Docker support and installation guide for easy server deployment
Includes a Dockerfile for building the application image and an INSTALLATION.md file detailing the setup process, prerequisites, and helpful commands for managing the application on a private server. 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/ds3R7vP
This commit is contained in:
1 parent
bbad954935
commit
f881f668a6
89 files changed
+17095
No files matched your search
@@ -0,0 +1,194 @@
|
||||
import { sql } from "drizzle-orm";
|
||||
import { pgTable, text, varchar, timestamp, jsonb, pgEnum, integer } from "drizzle-orm/pg-core";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
export const platformEnum = pgEnum("platform", ["facebook", "instagram"]);
|
||||
export const postTypeEnum = pgEnum("post_type", ["feed", "story"]);
|
||||
export const postStatusEnum = pgEnum("post_status", ["draft", "scheduled", "published", "failed"]);
|
||||
export const mediaTypeEnum = pgEnum("media_type", ["image", "video"]);
|
||||
|
||||
export const users = pgTable("users", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
username: text("username").notNull().unique(),
|
||||
password: text("password").notNull(),
|
||||
});
|
||||
|
||||
export const socialPages = pgTable("social_pages", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
userId: varchar("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
||||
platform: platformEnum("platform").notNull(),
|
||||
pageId: text("page_id").notNull(),
|
||||
pageName: text("page_name").notNull(),
|
||||
accessToken: text("access_token").notNull(),
|
||||
followersCount: integer("followers_count").default(0),
|
||||
isActive: text("is_active").notNull().default("true"),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
});
|
||||
|
||||
export const media = pgTable("media", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
userId: varchar("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
||||
type: mediaTypeEnum("type").notNull(),
|
||||
originalUrl: text("original_url").notNull(),
|
||||
facebookFeedUrl: text("facebook_feed_url"),
|
||||
instagramFeedUrl: text("instagram_feed_url"),
|
||||
instagramStoryUrl: text("instagram_story_url"),
|
||||
fileName: text("file_name").notNull(),
|
||||
fileSize: integer("file_size").notNull(),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
});
|
||||
|
||||
export const posts = pgTable("posts", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
userId: varchar("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
||||
content: text("content").notNull(),
|
||||
aiGenerated: text("ai_generated").notNull().default("false"),
|
||||
productInfo: jsonb("product_info"),
|
||||
status: postStatusEnum("status").notNull().default("draft"),
|
||||
scheduledFor: timestamp("scheduled_for"),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
updatedAt: timestamp("updated_at").defaultNow(),
|
||||
});
|
||||
|
||||
export const postMedia = pgTable("post_media", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
postId: varchar("post_id").notNull().references(() => posts.id, { onDelete: "cascade" }),
|
||||
mediaId: varchar("media_id").notNull().references(() => media.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const scheduledPosts = pgTable("scheduled_posts", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
postId: varchar("post_id").notNull().references(() => posts.id, { onDelete: "cascade" }),
|
||||
pageId: varchar("page_id").notNull().references(() => socialPages.id, { onDelete: "cascade" }),
|
||||
postType: postTypeEnum("post_type").notNull(),
|
||||
scheduledAt: timestamp("scheduled_at").notNull(),
|
||||
publishedAt: timestamp("published_at"),
|
||||
externalPostId: text("external_post_id"),
|
||||
error: text("error"),
|
||||
});
|
||||
|
||||
export const aiGenerations = pgTable("ai_generations", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
userId: varchar("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
||||
productInfo: jsonb("product_info").notNull(),
|
||||
generatedTexts: jsonb("generated_texts").notNull(),
|
||||
selectedText: text("selected_text"),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
});
|
||||
|
||||
// Relations
|
||||
export const usersRelations = relations(users, ({ many }) => ({
|
||||
socialPages: many(socialPages),
|
||||
media: many(media),
|
||||
posts: many(posts),
|
||||
aiGenerations: many(aiGenerations),
|
||||
}));
|
||||
|
||||
export const socialPagesRelations = relations(socialPages, ({ one, many }) => ({
|
||||
user: one(users, {
|
||||
fields: [socialPages.userId],
|
||||
references: [users.id],
|
||||
}),
|
||||
scheduledPosts: many(scheduledPosts),
|
||||
}));
|
||||
|
||||
export const mediaRelations = relations(media, ({ one, many }) => ({
|
||||
user: one(users, {
|
||||
fields: [media.userId],
|
||||
references: [users.id],
|
||||
}),
|
||||
postMedia: many(postMedia),
|
||||
}));
|
||||
|
||||
export const postsRelations = relations(posts, ({ one, many }) => ({
|
||||
user: one(users, {
|
||||
fields: [posts.userId],
|
||||
references: [users.id],
|
||||
}),
|
||||
postMedia: many(postMedia),
|
||||
scheduledPosts: many(scheduledPosts),
|
||||
}));
|
||||
|
||||
export const postMediaRelations = relations(postMedia, ({ one }) => ({
|
||||
post: one(posts, {
|
||||
fields: [postMedia.postId],
|
||||
references: [posts.id],
|
||||
}),
|
||||
media: one(media, {
|
||||
fields: [postMedia.mediaId],
|
||||
references: [media.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const scheduledPostsRelations = relations(scheduledPosts, ({ one }) => ({
|
||||
post: one(posts, {
|
||||
fields: [scheduledPosts.postId],
|
||||
references: [posts.id],
|
||||
}),
|
||||
page: one(socialPages, {
|
||||
fields: [scheduledPosts.pageId],
|
||||
references: [socialPages.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const aiGenerationsRelations = relations(aiGenerations, ({ one }) => ({
|
||||
user: one(users, {
|
||||
fields: [aiGenerations.userId],
|
||||
references: [users.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
// Insert schemas
|
||||
export const insertUserSchema = createInsertSchema(users).pick({
|
||||
username: true,
|
||||
password: true,
|
||||
});
|
||||
|
||||
export const insertSocialPageSchema = createInsertSchema(socialPages).omit({
|
||||
id: true,
|
||||
createdAt: true,
|
||||
});
|
||||
|
||||
export const insertMediaSchema = createInsertSchema(media).omit({
|
||||
id: true,
|
||||
createdAt: true,
|
||||
});
|
||||
|
||||
export const insertPostSchema = createInsertSchema(posts).omit({
|
||||
id: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
});
|
||||
|
||||
export const insertScheduledPostSchema = createInsertSchema(scheduledPosts).omit({
|
||||
id: true,
|
||||
publishedAt: true,
|
||||
externalPostId: true,
|
||||
error: true,
|
||||
});
|
||||
|
||||
export const insertAiGenerationSchema = createInsertSchema(aiGenerations).omit({
|
||||
id: true,
|
||||
createdAt: true,
|
||||
});
|
||||
|
||||
// Types
|
||||
export type User = typeof users.$inferSelect;
|
||||
export type InsertUser = z.infer<typeof insertUserSchema>;
|
||||
|
||||
export type SocialPage = typeof socialPages.$inferSelect;
|
||||
export type InsertSocialPage = z.infer<typeof insertSocialPageSchema>;
|
||||
|
||||
export type Media = typeof media.$inferSelect;
|
||||
export type InsertMedia = z.infer<typeof insertMediaSchema>;
|
||||
|
||||
export type Post = typeof posts.$inferSelect;
|
||||
export type InsertPost = z.infer<typeof insertPostSchema>;
|
||||
|
||||
export type ScheduledPost = typeof scheduledPosts.$inferSelect;
|
||||
export type InsertScheduledPost = z.infer<typeof insertScheduledPostSchema>;
|
||||
|
||||
export type AiGeneration = typeof aiGenerations.$inferSelect;
|
||||
export type InsertAiGeneration = z.infer<typeof insertAiGenerationSchema>;
|
||||
Reference in new issue
Block a user