Files
Socialflow/server/storage.ts
T
michaelschal 3971c6f912 Add support for publishing posts to both feed and stories simultaneously
Introduce a new 'both' post type allowing simultaneous publishing to Facebook and Instagram feeds and stories. This includes UI updates for selecting post types, backend logic for splitting 'both' posts into separate feed and story entries, and the ability to delete scheduled posts. The changes also include a new 'Pages gérées' link in the sidebar and necessary database schema updates.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: ae4037a0-2a6f-4530-9bac-79b543286bda
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/397bca8c-984f-43ff-841a-10897aeb8140/ae4037a0-2a6f-4530-9bac-79b543286bda/WuFXYmm
2025-10-08 13:16:55 +00:00

296 lines
10 KiB
TypeScript

import {
users,
socialPages,
media,
posts,
postMedia,
scheduledPosts,
aiGenerations,
cloudinaryConfig,
openrouterConfig,
type User,
type InsertUser,
type SocialPage,
type InsertSocialPage,
type Media,
type InsertMedia,
type Post,
type InsertPost,
type PostMedia,
type ScheduledPost,
type InsertScheduledPost,
type AiGeneration,
type InsertAiGeneration,
type CloudinaryConfig,
type InsertCloudinaryConfig,
type OpenrouterConfig,
type InsertOpenrouterConfig,
} from "@shared/schema";
import { db } from "./db";
import { eq, and, gte, lte, desc, isNull } from "drizzle-orm";
export interface IStorage {
// Users
getUser(id: string): Promise<User | undefined>;
getUserByUsername(username: string): Promise<User | undefined>;
getAllUsers(): Promise<User[]>;
createUser(user: InsertUser): Promise<User>;
updateUser(id: string, user: Partial<InsertUser>): Promise<User>;
deleteUser(id: string): Promise<void>;
// Social Pages
getSocialPages(userId: string): Promise<SocialPage[]>;
getSocialPage(id: string): Promise<SocialPage | undefined>;
createSocialPage(page: InsertSocialPage): Promise<SocialPage>;
updateSocialPage(id: string, page: Partial<InsertSocialPage>): Promise<SocialPage>;
deleteSocialPage(id: string): Promise<void>;
// Media
getMedia(userId: string): Promise<Media[]>;
getMediaById(id: string): Promise<Media | undefined>;
createMedia(media: InsertMedia): Promise<Media>;
deleteMedia(id: string): Promise<void>;
getPostMedia(postId: string): Promise<PostMedia[]>;
// Posts
getPosts(userId: string): Promise<Post[]>;
getPost(id: string): Promise<Post | undefined>;
createPost(post: InsertPost): Promise<Post>;
updatePost(id: string, post: Partial<InsertPost>): Promise<Post>;
deletePost(id: string): Promise<void>;
// Scheduled Posts
getScheduledPosts(userId: string, startDate?: Date, endDate?: Date): Promise<ScheduledPost[]>;
getScheduledPost(id: string): Promise<ScheduledPost | undefined>;
getScheduledPostsByPost(postId: string): Promise<ScheduledPost[]>;
createScheduledPost(scheduledPost: InsertScheduledPost): Promise<ScheduledPost>;
updateScheduledPost(id: string, scheduledPost: Partial<ScheduledPost>): Promise<ScheduledPost>;
deleteScheduledPost(id: string): Promise<void>;
getPendingScheduledPosts(): Promise<ScheduledPost[]>;
// AI Generations
getAiGenerations(userId: string): Promise<AiGeneration[]>;
createAiGeneration(generation: InsertAiGeneration): Promise<AiGeneration>;
// Cloudinary Config
getCloudinaryConfig(userId: string): Promise<CloudinaryConfig | undefined>;
createCloudinaryConfig(config: InsertCloudinaryConfig): Promise<CloudinaryConfig>;
updateCloudinaryConfig(userId: string, config: Partial<InsertCloudinaryConfig>): Promise<CloudinaryConfig>;
// OpenRouter Config
getOpenrouterConfig(userId: string): Promise<OpenrouterConfig | undefined>;
createOpenrouterConfig(config: InsertOpenrouterConfig): Promise<OpenrouterConfig>;
updateOpenrouterConfig(userId: string, config: Partial<InsertOpenrouterConfig>): Promise<OpenrouterConfig>;
}
export class DatabaseStorage implements IStorage {
// Users
async getUser(id: string): Promise<User | undefined> {
const [user] = await db.select().from(users).where(eq(users.id, id));
return user || undefined;
}
async getUserByUsername(username: string): Promise<User | undefined> {
const [user] = await db.select().from(users).where(eq(users.username, username));
return user || undefined;
}
async getAllUsers(): Promise<User[]> {
return await db.select().from(users);
}
async createUser(insertUser: InsertUser): Promise<User> {
const [user] = await db.insert(users).values(insertUser).returning();
return user;
}
async updateUser(id: string, updateData: Partial<InsertUser>): Promise<User> {
const [updated] = await db.update(users).set(updateData).where(eq(users.id, id)).returning();
return updated;
}
async deleteUser(id: string): Promise<void> {
await db.delete(users).where(eq(users.id, id));
}
// Social Pages
async getSocialPages(userId: string): Promise<SocialPage[]> {
return await db.select().from(socialPages).where(eq(socialPages.userId, userId));
}
async getSocialPage(id: string): Promise<SocialPage | undefined> {
const [page] = await db.select().from(socialPages).where(eq(socialPages.id, id));
return page || undefined;
}
async createSocialPage(page: InsertSocialPage): Promise<SocialPage> {
const [newPage] = await db.insert(socialPages).values(page).returning();
return newPage;
}
async updateSocialPage(id: string, page: Partial<InsertSocialPage>): Promise<SocialPage> {
const [updated] = await db.update(socialPages).set(page).where(eq(socialPages.id, id)).returning();
return updated;
}
async deleteSocialPage(id: string): Promise<void> {
await db.delete(socialPages).where(eq(socialPages.id, id));
}
// Media
async getMedia(userId: string): Promise<Media[]> {
return await db.select().from(media).where(eq(media.userId, userId)).orderBy(desc(media.createdAt));
}
async getMediaById(id: string): Promise<Media | undefined> {
const [mediaItem] = await db.select().from(media).where(eq(media.id, id));
return mediaItem || undefined;
}
async createMedia(mediaItem: InsertMedia): Promise<Media> {
const [newMedia] = await db.insert(media).values(mediaItem).returning();
return newMedia;
}
async deleteMedia(id: string): Promise<void> {
await db.delete(media).where(eq(media.id, id));
}
async getPostMedia(postId: string): Promise<PostMedia[]> {
return await db.select().from(postMedia).where(eq(postMedia.postId, postId));
}
// Posts
async getPosts(userId: string): Promise<Post[]> {
return await db.select().from(posts).where(eq(posts.userId, userId)).orderBy(desc(posts.createdAt));
}
async getPost(id: string): Promise<Post | undefined> {
const [post] = await db.select().from(posts).where(eq(posts.id, id));
return post || undefined;
}
async createPost(post: InsertPost): Promise<Post> {
const [newPost] = await db.insert(posts).values(post).returning();
return newPost;
}
async updatePost(id: string, post: Partial<InsertPost>): Promise<Post> {
const [updated] = await db.update(posts).set({ ...post, updatedAt: new Date() }).where(eq(posts.id, id)).returning();
return updated;
}
async deletePost(id: string): Promise<void> {
await db.delete(posts).where(eq(posts.id, id));
}
// Scheduled Posts
async getScheduledPosts(userId: string, startDate?: Date, endDate?: Date): Promise<ScheduledPost[]> {
let query = db
.select()
.from(scheduledPosts)
.innerJoin(posts, eq(scheduledPosts.postId, posts.id))
.where(eq(posts.userId, userId));
if (startDate && endDate) {
const results = await query;
return results
.filter(r => {
const scheduledAt = new Date(r.scheduled_posts.scheduledAt);
return scheduledAt >= startDate && scheduledAt <= endDate;
})
.map(r => r.scheduled_posts);
}
const results = await query;
return results.map(r => r.scheduled_posts);
}
async getScheduledPost(id: string): Promise<ScheduledPost | undefined> {
const [scheduledPost] = await db.select().from(scheduledPosts).where(eq(scheduledPosts.id, id));
return scheduledPost || undefined;
}
async getScheduledPostsByPost(postId: string): Promise<ScheduledPost[]> {
return await db.select().from(scheduledPosts).where(eq(scheduledPosts.postId, postId));
}
async createScheduledPost(scheduledPost: InsertScheduledPost): Promise<ScheduledPost> {
const [newScheduledPost] = await db.insert(scheduledPosts).values(scheduledPost).returning();
return newScheduledPost;
}
async updateScheduledPost(id: string, scheduledPost: Partial<ScheduledPost>): Promise<ScheduledPost> {
const [updated] = await db.update(scheduledPosts).set(scheduledPost).where(eq(scheduledPosts.id, id)).returning();
return updated;
}
async deleteScheduledPost(id: string): Promise<void> {
await db.delete(scheduledPosts).where(eq(scheduledPosts.id, id));
}
async getPendingScheduledPosts(): Promise<ScheduledPost[]> {
const now = new Date();
const results = await db
.select()
.from(scheduledPosts)
.where(
and(
isNull(scheduledPosts.publishedAt),
lte(scheduledPosts.scheduledAt, now)
)
);
return results;
}
// AI Generations
async getAiGenerations(userId: string): Promise<AiGeneration[]> {
return await db.select().from(aiGenerations).where(eq(aiGenerations.userId, userId)).orderBy(desc(aiGenerations.createdAt));
}
async createAiGeneration(generation: InsertAiGeneration): Promise<AiGeneration> {
const [newGeneration] = await db.insert(aiGenerations).values(generation).returning();
return newGeneration;
}
// Cloudinary Config
async getCloudinaryConfig(userId: string): Promise<CloudinaryConfig | undefined> {
const [config] = await db.select().from(cloudinaryConfig).where(eq(cloudinaryConfig.userId, userId));
return config || undefined;
}
async createCloudinaryConfig(config: InsertCloudinaryConfig): Promise<CloudinaryConfig> {
const [newConfig] = await db.insert(cloudinaryConfig).values(config).returning();
return newConfig;
}
async updateCloudinaryConfig(userId: string, config: Partial<InsertCloudinaryConfig>): Promise<CloudinaryConfig> {
const [updated] = await db.update(cloudinaryConfig)
.set({ ...config, updatedAt: new Date() })
.where(eq(cloudinaryConfig.userId, userId))
.returning();
return updated;
}
// OpenRouter Config
async getOpenrouterConfig(userId: string): Promise<OpenrouterConfig | undefined> {
const [config] = await db.select().from(openrouterConfig).where(eq(openrouterConfig.userId, userId));
return config || undefined;
}
async createOpenrouterConfig(config: InsertOpenrouterConfig): Promise<OpenrouterConfig> {
const [newConfig] = await db.insert(openrouterConfig).values(config).returning();
return newConfig;
}
async updateOpenrouterConfig(userId: string, config: Partial<InsertOpenrouterConfig>): Promise<OpenrouterConfig> {
const [updated] = await db.update(openrouterConfig)
.set({ ...config, updatedAt: new Date() })
.where(eq(openrouterConfig.userId, userId))
.returning();
return updated;
}
}
export const storage = new DatabaseStorage();