From 53a091823379bb7c1f6552c3bc2187b1407fc1fb Mon Sep 17 00:00:00 2001 From: Kelly Date: Tue, 2 Dec 2025 10:19:44 -0700 Subject: [PATCH] Expose AZ data under neutral /api/az and update frontend routes --- frontend/src/App.tsx | 6 +-- frontend/src/components/Layout.tsx | 10 ++--- frontend/src/lib/api.ts | 48 ++++++++++----------- frontend/src/pages/DutchieAZSchedule.tsx | 9 +++- frontend/src/pages/DutchieAZStoreDetail.tsx | 4 +- frontend/src/pages/DutchieAZStores.tsx | 2 +- 6 files changed, 43 insertions(+), 36 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 4c50568d..dae4888a 100755 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -49,9 +49,9 @@ export default function App() { } /> } /> } /> - } /> - } /> - } /> + } /> + } /> + } /> } /> } /> diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index 1e52d805..6c4b9b9e 100755 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -163,18 +163,18 @@ export function Layout({ children }: LayoutProps) { /> - + } label="AZ Stores" - isActive={isActive('/dutchie-az', false)} + isActive={isActive('/az', false)} /> } label="AZ Schedule" - isActive={isActive('/dutchie-az-schedule')} + isActive={isActive('/az-schedule')} /> diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 91c2e367..d8d595f0 100755 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -527,7 +527,7 @@ class ApiClient { } // ============================================================ - // DUTCHIE AZ API + // AZ DATA API (formerly dutchie-az) // ============================================================ // Dutchie AZ Dashboard @@ -540,7 +540,7 @@ class ApiClient { failedJobCount: number; brandCount: number; categoryCount: number; - }>('/api/dutchie-az/dashboard'); + }>('/api/az/dashboard'); } // Dutchie AZ Schedules (CRUD) @@ -562,7 +562,7 @@ class ApiClient { createdAt: string; updatedAt: string; }>; - }>('/api/dutchie-az/admin/schedules'); + }>('/api/az/admin/schedules'); } async getDutchieAZSchedule(id: number) { @@ -581,7 +581,7 @@ class ApiClient { jobConfig: Record | null; createdAt: string; updatedAt: string; - }>(`/api/dutchie-az/admin/schedules/${id}`); + }>(`/api/az/admin/schedules/${id}`); } async createDutchieAZSchedule(data: { @@ -593,7 +593,7 @@ class ApiClient { jobConfig?: Record; startImmediately?: boolean; }) { - return this.request('/api/dutchie-az/admin/schedules', { + return this.request('/api/az/admin/schedules', { method: 'POST', body: JSON.stringify(data), }); @@ -606,26 +606,26 @@ class ApiClient { jitterMinutes?: number; jobConfig?: Record; }) { - return this.request(`/api/dutchie-az/admin/schedules/${id}`, { + return this.request(`/api/az/admin/schedules/${id}`, { method: 'PUT', body: JSON.stringify(data), }); } async deleteDutchieAZSchedule(id: number) { - return this.request<{ success: boolean; message: string }>(`/api/dutchie-az/admin/schedules/${id}`, { + return this.request<{ success: boolean; message: string }>(`/api/az/admin/schedules/${id}`, { method: 'DELETE', }); } async triggerDutchieAZSchedule(id: number) { - return this.request<{ success: boolean; message: string }>(`/api/dutchie-az/admin/schedules/${id}/trigger`, { + return this.request<{ success: boolean; message: string }>(`/api/az/admin/schedules/${id}/trigger`, { method: 'POST', }); } async initDutchieAZSchedules() { - return this.request<{ success: boolean; schedules: any[] }>('/api/dutchie-az/admin/schedules/init', { + return this.request<{ success: boolean; schedules: any[] }>('/api/az/admin/schedules/init', { method: 'POST', }); } @@ -636,7 +636,7 @@ class ApiClient { if (limit) params.append('limit', limit.toString()); if (offset) params.append('offset', offset.toString()); const queryString = params.toString() ? `?${params.toString()}` : ''; - return this.request<{ logs: any[]; total: number }>(`/api/dutchie-az/admin/schedules/${scheduleId}/logs${queryString}`); + return this.request<{ logs: any[]; total: number }>(`/api/az/admin/schedules/${scheduleId}/logs${queryString}`); } async getDutchieAZRunLogs(options?: { scheduleId?: number; jobName?: string; limit?: number; offset?: number }) { @@ -646,28 +646,28 @@ class ApiClient { if (options?.limit) params.append('limit', options.limit.toString()); if (options?.offset) params.append('offset', options.offset.toString()); const queryString = params.toString() ? `?${params.toString()}` : ''; - return this.request<{ logs: any[]; total: number }>(`/api/dutchie-az/admin/run-logs${queryString}`); + return this.request<{ logs: any[]; total: number }>(`/api/az/admin/run-logs${queryString}`); } // Dutchie AZ Scheduler Control async getDutchieAZSchedulerStatus() { - return this.request<{ running: boolean; pollIntervalMs: number }>('/api/dutchie-az/admin/scheduler/status'); + return this.request<{ running: boolean; pollIntervalMs: number }>('/api/az/admin/scheduler/status'); } async startDutchieAZScheduler() { - return this.request<{ success: boolean; message: string }>('/api/dutchie-az/admin/scheduler/start', { + return this.request<{ success: boolean; message: string }>('/api/az/admin/scheduler/start', { method: 'POST', }); } async stopDutchieAZScheduler() { - return this.request<{ success: boolean; message: string }>('/api/dutchie-az/admin/scheduler/stop', { + return this.request<{ success: boolean; message: string }>('/api/az/admin/scheduler/stop', { method: 'POST', }); } async triggerDutchieAZImmediateCrawl() { - return this.request<{ success: boolean; message: string }>('/api/dutchie-az/admin/scheduler/trigger', { + return this.request<{ success: boolean; message: string }>('/api/az/admin/scheduler/trigger', { method: 'POST', }); } @@ -680,11 +680,11 @@ class ApiClient { if (params?.limit) searchParams.append('limit', params.limit.toString()); if (params?.offset) searchParams.append('offset', params.offset.toString()); const queryString = searchParams.toString() ? `?${searchParams.toString()}` : ''; - return this.request<{ stores: any[]; total: number }>(`/api/dutchie-az/stores${queryString}`); + return this.request<{ stores: any[]; total: number }>(`/api/az/stores${queryString}`); } async getDutchieAZStore(id: number) { - return this.request(`/api/dutchie-az/stores/${id}`); + return this.request(`/api/az/stores/${id}`); } async getDutchieAZStoreSummary(id: number) { @@ -700,7 +700,7 @@ class ApiClient { brandCount: number; categoryCount: number; lastCrawl: any | null; - }>(`/api/dutchie-az/stores/${id}/summary`); + }>(`/api/az/stores/${id}/summary`); } async getDutchieAZStoreProducts(id: number, params?: { @@ -752,19 +752,19 @@ class ApiClient { total: number; limit: number; offset: number; - }>(`/api/dutchie-az/stores/${id}/products${queryString}`); + }>(`/api/az/stores/${id}/products${queryString}`); } async getDutchieAZStoreBrands(id: number) { return this.request<{ brands: Array<{ brand: string; product_count: number }>; - }>(`/api/dutchie-az/stores/${id}/brands`); + }>(`/api/az/stores/${id}/brands`); } async getDutchieAZStoreCategories(id: number) { return this.request<{ categories: Array<{ type: string; subcategory: string; product_count: number }>; - }>(`/api/dutchie-az/stores/${id}/categories`); + }>(`/api/az/stores/${id}/categories`); } // Dutchie AZ Debug @@ -795,7 +795,7 @@ class ApiClient { dispensary_name: string; crawled_at: string; }>; - }>('/api/dutchie-az/debug/summary'); + }>('/api/az/debug/summary'); } async getDutchieAZDebugStore(id: number) { @@ -823,11 +823,11 @@ class ApiClient { outOfStock: any[]; }; categories: Array<{ type: string; subcategory: string; count: string }>; - }>(`/api/dutchie-az/debug/store/${id}`); + }>(`/api/az/debug/store/${id}`); } async triggerDutchieAZCrawl(id: number, options?: { pricingType?: string; useBothModes?: boolean }) { - return this.request(`/api/dutchie-az/admin/crawl/${id}`, { + return this.request(`/api/az/admin/crawl/${id}`, { method: 'POST', body: JSON.stringify(options || {}), }); diff --git a/frontend/src/pages/DutchieAZSchedule.tsx b/frontend/src/pages/DutchieAZSchedule.tsx index 8b3726ad..fcdf7a8a 100644 --- a/frontend/src/pages/DutchieAZSchedule.tsx +++ b/frontend/src/pages/DutchieAZSchedule.tsx @@ -114,7 +114,14 @@ export function DutchieAZSchedule() { const handleUpdateSchedule = async (id: number, updates: Partial) => { try { - await api.updateDutchieAZSchedule(id, updates); + const payload = { + description: updates.description ?? undefined, + enabled: updates.enabled, + baseIntervalMinutes: updates.baseIntervalMinutes, + jitterMinutes: updates.jitterMinutes, + jobConfig: updates.jobConfig ?? undefined, + }; + await api.updateDutchieAZSchedule(id, payload); setEditingSchedule(null); await loadData(); } catch (error) { diff --git a/frontend/src/pages/DutchieAZStoreDetail.tsx b/frontend/src/pages/DutchieAZStoreDetail.tsx index 22ce0d2d..db0ddcc5 100644 --- a/frontend/src/pages/DutchieAZStoreDetail.tsx +++ b/frontend/src/pages/DutchieAZStoreDetail.tsx @@ -140,11 +140,11 @@ export function DutchieAZStoreDetail() { {/* Header */}
{/* Update Button */} diff --git a/frontend/src/pages/DutchieAZStores.tsx b/frontend/src/pages/DutchieAZStores.tsx index 1efe29ed..ac2104c5 100644 --- a/frontend/src/pages/DutchieAZStores.tsx +++ b/frontend/src/pages/DutchieAZStores.tsx @@ -175,7 +175,7 @@ export function DutchieAZStores() {