mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-20 05:28:13 +02:00
feat: add external API for publishing posts with image URL and scheduling
- New POST /api/v1/publish endpoint: download image from URL, create post and schedule it per page - New GET /api/v1/pages endpoint: list available pages for external callers - API key auth via X-API-Key header, configurable from admin settings (stored in DB) - New app_config table (migration included) to store the external API key - Admin-only settings section (desktop + mobile) to set/revoke the key - Fallback to EXTERNAL_API_KEY env var if no DB key is configured Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
9e6fe9fe31
commit
391acfdb83
9 files changed
+539
-2
No files matched your search
@@ -37,6 +37,8 @@ import {
|
||||
audioTracks,
|
||||
type AudioTrack,
|
||||
type InsertAudioTrack,
|
||||
appConfig,
|
||||
type AppConfig,
|
||||
} from "@shared/schema";
|
||||
import { db } from "./db";
|
||||
import { eq, and, gte, lte, desc, asc, isNull, inArray } from "drizzle-orm";
|
||||
@@ -126,6 +128,10 @@ export interface IStorage {
|
||||
getFreesoundConfig(userId: string): Promise<FreesoundConfig | undefined>;
|
||||
createFreesoundConfig(config: InsertFreesoundConfig): Promise<FreesoundConfig>;
|
||||
updateFreesoundConfig(userId: string, config: Partial<InsertFreesoundConfig>): Promise<FreesoundConfig>;
|
||||
|
||||
// App Config
|
||||
getAppConfig(): Promise<AppConfig | undefined>;
|
||||
upsertAppConfig(data: Partial<Pick<AppConfig, 'externalApiKey'>>): Promise<AppConfig>;
|
||||
}
|
||||
|
||||
export class DatabaseStorage implements IStorage {
|
||||
@@ -584,6 +590,25 @@ export class DatabaseStorage implements IStorage {
|
||||
.returning();
|
||||
return updated;
|
||||
}
|
||||
|
||||
// App Config
|
||||
async getAppConfig(): Promise<AppConfig | undefined> {
|
||||
const [config] = await db.select().from(appConfig).limit(1);
|
||||
return config || undefined;
|
||||
}
|
||||
|
||||
async upsertAppConfig(data: Partial<Pick<AppConfig, 'externalApiKey'>>): Promise<AppConfig> {
|
||||
const existing = await this.getAppConfig();
|
||||
if (existing) {
|
||||
const [updated] = await db.update(appConfig)
|
||||
.set({ ...data, updatedAt: new Date() })
|
||||
.where(eq(appConfig.id, existing.id))
|
||||
.returning();
|
||||
return updated;
|
||||
}
|
||||
const [created] = await db.insert(appConfig).values(data).returning();
|
||||
return created;
|
||||
}
|
||||
}
|
||||
|
||||
export const storage = new DatabaseStorage();
|
||||
Reference in new issue
Block a user