AI AUtomtaion, Schudelign and publishign fromt and backe end refoactr
This commit is contained in:
@@ -22,6 +22,15 @@ export interface AutomationConfig {
|
||||
stage_6_batch_size: number;
|
||||
within_stage_delay: number;
|
||||
between_stage_delay: number;
|
||||
// Per-run limits (0 = unlimited)
|
||||
max_keywords_per_run: number;
|
||||
max_clusters_per_run: number;
|
||||
max_ideas_per_run: number;
|
||||
max_tasks_per_run: number;
|
||||
max_content_per_run: number;
|
||||
max_images_per_run: number;
|
||||
max_approvals_per_run: number;
|
||||
max_credits_per_run: number;
|
||||
last_run_at: string | null;
|
||||
next_run_at: string | null;
|
||||
}
|
||||
|
||||
162
frontend/src/services/unifiedSettings.api.ts
Normal file
162
frontend/src/services/unifiedSettings.api.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Unified Settings API Service
|
||||
* Per SETTINGS-CONSOLIDATION-PLAN.md
|
||||
*
|
||||
* Consolidates AI & Automation settings into a single API endpoint.
|
||||
*/
|
||||
import { fetchAPI } from './api';
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// TYPES
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
export interface StageConfig {
|
||||
number: number;
|
||||
name: string;
|
||||
has_ai: boolean;
|
||||
enabled: boolean;
|
||||
batch_size: number;
|
||||
per_run_limit: number;
|
||||
use_testing?: boolean;
|
||||
budget_pct?: number;
|
||||
}
|
||||
|
||||
export interface AvailableModel {
|
||||
id: number | null;
|
||||
name: string | null;
|
||||
model_name: string | null;
|
||||
}
|
||||
|
||||
export interface UnifiedSiteSettings {
|
||||
site_id: number;
|
||||
site_name: string;
|
||||
automation: {
|
||||
enabled: boolean;
|
||||
frequency: 'hourly' | 'daily' | 'weekly';
|
||||
time: string; // HH:MM format
|
||||
last_run_at: string | null;
|
||||
next_run_at: string | null;
|
||||
};
|
||||
stages: StageConfig[];
|
||||
delays: {
|
||||
within_stage: number;
|
||||
between_stage: number;
|
||||
};
|
||||
publishing: {
|
||||
auto_approval_enabled: boolean;
|
||||
auto_publish_enabled: boolean;
|
||||
publish_days: string[]; // ['mon', 'tue', ...]
|
||||
time_slots: string[]; // ['09:00', '14:00', ...]
|
||||
daily_capacity: number;
|
||||
weekly_capacity: number;
|
||||
monthly_capacity: number;
|
||||
};
|
||||
available_models: {
|
||||
text: {
|
||||
testing: AvailableModel | null;
|
||||
live: AvailableModel | null;
|
||||
};
|
||||
image: {
|
||||
testing: AvailableModel | null;
|
||||
live: AvailableModel | null;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface UpdateUnifiedSettingsRequest {
|
||||
automation?: {
|
||||
enabled?: boolean;
|
||||
frequency?: 'hourly' | 'daily' | 'weekly';
|
||||
time?: string;
|
||||
};
|
||||
stages?: Array<{
|
||||
number: number;
|
||||
enabled?: boolean;
|
||||
batch_size?: number;
|
||||
per_run_limit?: number;
|
||||
use_testing?: boolean;
|
||||
budget_pct?: number;
|
||||
}>;
|
||||
delays?: {
|
||||
within_stage?: number;
|
||||
between_stage?: number;
|
||||
};
|
||||
publishing?: {
|
||||
auto_approval_enabled?: boolean;
|
||||
auto_publish_enabled?: boolean;
|
||||
publish_days?: string[];
|
||||
time_slots?: string[];
|
||||
};
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// API FUNCTIONS
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* Get unified site settings (AI & Automation consolidated)
|
||||
*/
|
||||
export async function getUnifiedSiteSettings(siteId: number): Promise<UnifiedSiteSettings> {
|
||||
const response = await fetchAPI(`/v1/integration/sites/${siteId}/unified-settings/`);
|
||||
return response.data || response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update unified site settings
|
||||
*/
|
||||
export async function updateUnifiedSiteSettings(
|
||||
siteId: number,
|
||||
data: UpdateUnifiedSettingsRequest
|
||||
): Promise<UnifiedSiteSettings> {
|
||||
const response = await fetchAPI(`/v1/integration/sites/${siteId}/unified-settings/`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
return response.data || response;
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// HELPER FUNCTIONS
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* Days of week for publishing schedule
|
||||
*/
|
||||
export const DAYS_OF_WEEK = [
|
||||
{ value: 'mon', label: 'Mon' },
|
||||
{ value: 'tue', label: 'Tue' },
|
||||
{ value: 'wed', label: 'Wed' },
|
||||
{ value: 'thu', label: 'Thu' },
|
||||
{ value: 'fri', label: 'Fri' },
|
||||
{ value: 'sat', label: 'Sat' },
|
||||
{ value: 'sun', label: 'Sun' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Frequency options for automation
|
||||
*/
|
||||
export const FREQUENCY_OPTIONS = [
|
||||
{ value: 'hourly', label: 'Hourly' },
|
||||
{ value: 'daily', label: 'Daily' },
|
||||
{ value: 'weekly', label: 'Weekly' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Format time for display
|
||||
*/
|
||||
export function formatTime(time: string): string {
|
||||
const [hours, minutes] = time.split(':');
|
||||
const h = parseInt(hours);
|
||||
const ampm = h >= 12 ? 'PM' : 'AM';
|
||||
const displayHour = h > 12 ? h - 12 : h === 0 ? 12 : h;
|
||||
return `${displayHour}:${minutes} ${ampm}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate total budget percentage from stages
|
||||
*/
|
||||
export function calculateTotalBudget(stages: StageConfig[]): number {
|
||||
return stages
|
||||
.filter(s => s.has_ai && s.budget_pct)
|
||||
.reduce((sum, s) => sum + (s.budget_pct || 0), 0);
|
||||
}
|
||||
Reference in New Issue
Block a user