data&device ready
This commit is contained in:
294
scripts/api.js
Normal file
294
scripts/api.js
Normal file
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* TalkingQ Platform - API Interface Layer
|
||||
* All API calls are defined here as stubs.
|
||||
* Replace BASE_URL and implement fetch calls to connect backend.
|
||||
*/
|
||||
|
||||
const API = {
|
||||
BASE_URL: '/api/v1', // TODO: Replace with actual backend URL
|
||||
|
||||
// ─── Auth ───────────────────────────────────────────────────────
|
||||
auth: {
|
||||
login: (credentials) => API._post('/auth/login', credentials),
|
||||
logout: () => API._post('/auth/logout'),
|
||||
me: () => API._get('/auth/me'),
|
||||
getPermissions: () => API._get('/auth/permissions'),
|
||||
refreshToken: () => API._post('/auth/refresh'),
|
||||
},
|
||||
|
||||
// ─── Dashboard ──────────────────────────────────────────────────
|
||||
dashboard: {
|
||||
getOverview: (params) => API._get('/dashboard/overview', params),
|
||||
getDAUTrend: (params) => API._get('/dashboard/dau-trend', params),
|
||||
getSessionStats: (params) => API._get('/dashboard/sessions', params),
|
||||
getTurnsPerSession: (params) => API._get('/dashboard/turns', params),
|
||||
getActivationRate: (params) => API._get('/dashboard/activation', params),
|
||||
getRetentionCohort: (params) => API._get('/dashboard/retention', params),
|
||||
getIntentDistribution: (params) => API._get('/dashboard/intents', params),
|
||||
getLanguageStats: (params) => API._get('/dashboard/languages', params),
|
||||
},
|
||||
|
||||
// ─── Agent Development ──────────────────────────────────────────
|
||||
agentDev: {
|
||||
// ASR (Automatic Speech Recognition)
|
||||
getASRProviders: () => API._get('/agent-dev/asr/providers'),
|
||||
getASRConfig: (agentId) => API._get(`/agent-dev/${agentId}/asr`),
|
||||
updateASRConfig: (agentId, config) => API._put(`/agent-dev/${agentId}/asr`, config),
|
||||
testASR: (agentId, audioBlob) => API._post(`/agent-dev/${agentId}/asr/test`, { audio: audioBlob }),
|
||||
getHotwordGroups: (params) => API._get('/agent-dev/asr/hotword-groups', params),
|
||||
createHotwordGroup: (data) => API._post('/agent-dev/asr/hotword-groups', data),
|
||||
updateHotwordGroup: (id, data) => API._put(`/agent-dev/asr/hotword-groups/${id}`, data),
|
||||
deleteHotwordGroup: (id) => API._delete(`/agent-dev/asr/hotword-groups/${id}`),
|
||||
getAgentHotwordGroups: (agentId) => API._get(`/agent-dev/${agentId}/asr/hotword-groups`),
|
||||
bindHotwordGroups: (agentId, groupIds) => API._put(`/agent-dev/${agentId}/asr/hotword-groups`, { groupIds }),
|
||||
|
||||
// TTS (Text-to-Speech)
|
||||
getTTSProviders: () => API._get('/agent-dev/tts/providers'),
|
||||
getTTSConfig: (agentId) => API._get(`/agent-dev/${agentId}/tts`),
|
||||
updateTTSConfig: (agentId, config) => API._put(`/agent-dev/${agentId}/tts`, config),
|
||||
testTTS: (agentId, text) => API._post(`/agent-dev/${agentId}/tts/test`, { text }),
|
||||
previewVoice: (provider, voiceId, text) => API._post('/agent-dev/tts/preview', { provider, voiceId, text }),
|
||||
|
||||
// RAG (Retrieval Augmented Generation)
|
||||
getKnowledgeBases: () => API._get('/agent-dev/rag/knowledge-bases'),
|
||||
getAgentRAG: (agentId) => API._get(`/agent-dev/${agentId}/rag`),
|
||||
attachKnowledgeBase: (agentId, kbId) => API._post(`/agent-dev/${agentId}/rag/attach`, { kbId }),
|
||||
detachKnowledgeBase: (agentId, kbId) => API._delete(`/agent-dev/${agentId}/rag/detach/${kbId}`),
|
||||
createKnowledgeBase: (data) => API._post('/agent-dev/rag/knowledge-bases', data),
|
||||
uploadDocument: (kbId, file) => API._upload(`/agent-dev/rag/knowledge-bases/${kbId}/docs`, file),
|
||||
deleteDocument: (kbId, docId) => API._delete(`/agent-dev/rag/knowledge-bases/${kbId}/docs/${docId}`),
|
||||
testRAGQuery: (agentId, query) => API._post(`/agent-dev/${agentId}/rag/test`, { query }),
|
||||
|
||||
// Language
|
||||
getSupportedLanguages: () => API._get('/agent-dev/languages'),
|
||||
getAgentLanguages: (agentId) => API._get(`/agent-dev/${agentId}/languages`),
|
||||
updateAgentLanguages: (agentId, langs) => API._put(`/agent-dev/${agentId}/languages`, { languages: langs }),
|
||||
setPrimaryLanguage: (agentId, lang) => API._put(`/agent-dev/${agentId}/languages/primary`, { language: lang }),
|
||||
|
||||
// General agent config
|
||||
saveConfig: (agentId, config) => API._put(`/agent-dev/${agentId}/config`, config),
|
||||
deployAgent: (agentId, data = {}) => API._post(`/agent-dev/${agentId}/deploy`, data),
|
||||
getDeployStatus: (agentId) => API._get(`/agent-dev/${agentId}/deploy/status`),
|
||||
},
|
||||
|
||||
// ─── Agent Management ───────────────────────────────────────────
|
||||
agents: {
|
||||
list: (params) => API._get('/agents', params),
|
||||
get: (id) => API._get(`/agents/${id}`),
|
||||
create: (data) => API._post('/agents', data),
|
||||
update: (id, data) => API._put(`/agents/${id}`, data),
|
||||
delete: (id) => API._post(`/agents/${id}/recycle`, { retentionDays: 7 }),
|
||||
listRecycleBin: (params) => API._get('/agents/recycle-bin', params),
|
||||
restore: (id) => API._post(`/agents/${id}/restore`),
|
||||
purge: (id) => API._delete(`/agents/${id}`),
|
||||
cleanupRecycleBin: () => API._post('/agents/recycle-bin/cleanup'),
|
||||
getVersions: (id) => API._get(`/agents/${id}/versions`),
|
||||
rollback: (id, version) => API._post(`/agents/${id}/rollback`, { version }),
|
||||
},
|
||||
|
||||
// ─── Prompt Management ──────────────────────────────────────────
|
||||
prompts: {
|
||||
list: (params) => API._get('/prompts', params),
|
||||
get: (id) => API._get(`/prompts/${id}`),
|
||||
create: (data) => API._post('/prompts', data),
|
||||
update: (id, data) => API._put(`/prompts/${id}`, data),
|
||||
delete: (id) => API._delete(`/prompts/${id}`),
|
||||
publish: (id) => API._post(`/prompts/${id}/publish`),
|
||||
getVersions: (id) => API._get(`/prompts/${id}/versions`),
|
||||
startABTest: (data) => API._post('/prompts/ab-test', data),
|
||||
getABTestResults: (testId) => API._get(`/prompts/ab-test/${testId}/results`),
|
||||
},
|
||||
|
||||
// ─── Products ───────────────────────────────────────────────────
|
||||
products: {
|
||||
list: (params) => API._get('/products', params),
|
||||
get: (id) => API._get(`/products/${id}`),
|
||||
create: (data) => API._post('/products', data),
|
||||
update: (id, data) => API._put(`/products/${id}`, data),
|
||||
delete: (id) => API._delete(`/products/${id}`),
|
||||
},
|
||||
|
||||
// ─── Tenant / Company Scope ─────────────────────────────────────
|
||||
tenants: {
|
||||
listCompanies: (params) => API._get('/tenants/companies', params),
|
||||
createCompany: (data) => API._post('/tenants/companies', data),
|
||||
updateCompany: (companyId, data) => API._put(`/tenants/companies/${companyId}`, data),
|
||||
deleteCompany: (companyId) => API._delete(`/tenants/companies/${companyId}`),
|
||||
deleteCompanyWithTransfer: (companyId, data = {}) => API._post(`/tenants/companies/${companyId}/delete`, data),
|
||||
getMyCompany: () => API._get('/tenants/me/company'),
|
||||
getMyScope: () => API._get('/tenants/me/scope'),
|
||||
switchCompany: (companyId) => API._post('/tenants/switch-company', { companyId }),
|
||||
},
|
||||
|
||||
// ─── Devices ────────────────────────────────────────────────────
|
||||
devices: {
|
||||
list: (params) => API._get('/devices', params),
|
||||
get: (id) => API._get(`/devices/${id}`),
|
||||
create: (data) => API._post('/devices', data),
|
||||
batchCreate: (data) => API._post('/devices/batch', data),
|
||||
validateBatch: (data) => API._post('/devices/batch/validate', data),
|
||||
importFile: (file, meta) => API._upload('/devices/import', file, meta),
|
||||
update: (id, data) => API._put(`/devices/${id}`, data),
|
||||
delete: (id) => API._delete(`/devices/${id}`),
|
||||
getHeartbeat: (id) => API._get(`/devices/${id}/heartbeat`),
|
||||
reboot: (id) => API._post(`/devices/${id}/reboot`),
|
||||
getLogs: (id, params) => API._get(`/devices/${id}/logs`, params),
|
||||
bindProduct: (id, productId) => API._post(`/devices/${id}/bind`, { productId }),
|
||||
unbind: (id) => API._post(`/devices/${id}/unbind`),
|
||||
export: (params) => API._get('/devices/export', params),
|
||||
},
|
||||
|
||||
// ─── OTA ────────────────────────────────────────────────────────
|
||||
ota: {
|
||||
list: (params) => API._get('/ota/tasks', params),
|
||||
get: (id) => API._get(`/ota/tasks/${id}`),
|
||||
create: (data) => API._post('/ota/tasks', data),
|
||||
cancel: (id) => API._post(`/ota/tasks/${id}/cancel`),
|
||||
resume: (id) => API._post(`/ota/tasks/${id}/resume`),
|
||||
getProgress: (id) => API._get(`/ota/tasks/${id}/progress`),
|
||||
getFirmwares: (params) => API._get('/ota/firmwares', params),
|
||||
getFirmwaresByProduct: (productId) => API._get('/ota/firmwares', { productId }),
|
||||
uploadFirmware: (file, meta) => API._upload('/ota/firmwares', file, meta),
|
||||
setLatestFirmware: (id, data) => API._post(`/ota/firmwares/${id}/set-latest`, data),
|
||||
setLatestAndCreateTask: (id, data) => API._post(`/ota/firmwares/${id}/set-latest-and-upgrade`, data),
|
||||
deleteFirmware: (id) => API._delete(`/ota/firmwares/${id}`),
|
||||
upgradeSingle: (deviceId, data) => API._post('/ota/single', { device_id: deviceId, ...data }),
|
||||
},
|
||||
|
||||
// ─── Sessions ───────────────────────────────────────────────────
|
||||
sessions: {
|
||||
list: (params) => API._get('/sessions', params),
|
||||
get: (id) => API._get(`/sessions/${id}`),
|
||||
getMessages: (id) => API._get(`/sessions/${id}/messages`),
|
||||
replay: (id) => API._get(`/sessions/${id}/replay`),
|
||||
export: (params) => API._get('/sessions/export', params),
|
||||
getStats: (params) => API._get('/sessions/stats', params),
|
||||
},
|
||||
|
||||
// ─── Bad Cases ──────────────────────────────────────────────────
|
||||
badCases: {
|
||||
list: (params) => API._get('/bad-cases', params),
|
||||
get: (id) => API._get(`/bad-cases/${id}`),
|
||||
tag: (id, tags) => API._put(`/bad-cases/${id}/tags`, { tags }),
|
||||
review: (id, data) => API._post(`/bad-cases/${id}/review`, data),
|
||||
close: (id, resolution) => API._post(`/bad-cases/${id}/close`, { resolution }),
|
||||
export: (params) => API._get('/bad-cases/export', params),
|
||||
getStats: (params) => API._get('/bad-cases/stats', params),
|
||||
},
|
||||
|
||||
// ─── Notifications ──────────────────────────────────────────────
|
||||
notifications: {
|
||||
// Backend should return tenant/company-scoped notifications only.
|
||||
// Notification item shape:
|
||||
// {
|
||||
// id, eventType, category, severity, title, detail, objectType,
|
||||
// objectId, companyId, companyName, metric, read, createdAt, actionPage
|
||||
// }
|
||||
list: (params) => API._get('/notifications', params),
|
||||
get: (id) => API._get(`/notifications/${id}`),
|
||||
getCatalog: () => API._get('/notifications/catalog'),
|
||||
create: (data) => API._post('/notifications', data),
|
||||
markRead: (id) => API._post(`/notifications/${id}/read`),
|
||||
markAllRead: (params) => API._post('/notifications/read-all', params),
|
||||
archive: (id) => API._post(`/notifications/${id}/archive`),
|
||||
getStats: (params) => API._get('/notifications/stats', params),
|
||||
},
|
||||
|
||||
// ─── RBAC ───────────────────────────────────────────────────────
|
||||
rbac: {
|
||||
getUsers: (params) => API._get('/rbac/users', params),
|
||||
createUser: (data) => API._post('/rbac/users', data),
|
||||
updateUser: (id, data) => API._put(`/rbac/users/${id}`, data),
|
||||
deleteUser: (id) => API._delete(`/rbac/users/${id}`),
|
||||
getRoles: () => API._get('/rbac/roles'),
|
||||
getCurrentPermissions: () => API._get('/rbac/me/permissions'),
|
||||
createRole: (data) => API._post('/rbac/roles', data),
|
||||
updateRole: (id, data) => API._put(`/rbac/roles/${id}`, data),
|
||||
deleteRole: (id) => API._delete(`/rbac/roles/${id}`),
|
||||
getPermissions: () => API._get('/rbac/permissions'),
|
||||
assignRole: (userId, roleId) => API._post('/rbac/users/assign-role', { userId, roleId }),
|
||||
getAuditLogs: (params) => API._get('/rbac/audit-logs', params),
|
||||
},
|
||||
|
||||
// ─── Privacy / PII ──────────────────────────────────────────────
|
||||
privacy: {
|
||||
getConfig: () => API._get('/privacy/config'),
|
||||
updateConfig: (data) => API._put('/privacy/config', data),
|
||||
getRules: () => API._get('/privacy/pii-rules'),
|
||||
createRule: (data) => API._post('/privacy/pii-rules', data),
|
||||
updateRule: (id, data) => API._put(`/privacy/pii-rules/${id}`, data),
|
||||
deleteRule: (id) => API._delete(`/privacy/pii-rules/${id}`),
|
||||
getDataRequests: (params) => API._get('/privacy/data-requests', params),
|
||||
processDataRequest: (id, action) => API._post(`/privacy/data-requests/${id}/${action}`),
|
||||
getRetentionPolicies: () => API._get('/privacy/retention-policies'),
|
||||
updateRetentionPolicy: (id, data) => API._put(`/privacy/retention-policies/${id}`, data),
|
||||
},
|
||||
|
||||
// ─── Settings ───────────────────────────────────────────────────
|
||||
settings: {
|
||||
getTenantInfo: () => API._get('/settings/tenant'),
|
||||
updateTenantInfo: (data) => API._put('/settings/tenant', data),
|
||||
getNotifications: () => API._get('/settings/notifications'),
|
||||
// Notification settings shape:
|
||||
// {
|
||||
// rules: {
|
||||
// [eventType]: { enabled, threshold?, thresholdUnit?, channels: ['in_app','email','webhook'] }
|
||||
// }
|
||||
// }
|
||||
updateNotifications: (data) => API._put('/settings/notifications', data),
|
||||
getIntegrations: () => API._get('/settings/integrations'),
|
||||
testWebhook: (url) => API._post('/settings/webhooks/test', { url }),
|
||||
getApiKeys: () => API._get('/settings/api-keys'),
|
||||
createApiKey: (data) => API._post('/settings/api-keys', data),
|
||||
revokeApiKey: (id) => API._delete(`/settings/api-keys/${id}`),
|
||||
},
|
||||
|
||||
// ─── Internal helpers ───────────────────────────────────────────
|
||||
_headers() {
|
||||
const token = localStorage.getItem('tq_token');
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
|
||||
};
|
||||
},
|
||||
|
||||
async _request(method, path, body, params) {
|
||||
// TODO: Replace with actual fetch when backend is ready
|
||||
// Simulated delay for demo
|
||||
await new Promise(r => setTimeout(r, 150 + Math.random() * 100));
|
||||
// Return mock success
|
||||
return { success: true, data: null, message: 'OK (mock)' };
|
||||
|
||||
/* Real implementation (uncomment when backend ready):
|
||||
const url = new URL(API.BASE_URL + path, window.location.origin);
|
||||
if (params) Object.entries(params).forEach(([k,v]) => v != null && url.searchParams.set(k, v));
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers: API._headers(),
|
||||
...(body ? { body: JSON.stringify(body) } : {}),
|
||||
});
|
||||
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
|
||||
return res.json();
|
||||
*/
|
||||
},
|
||||
|
||||
_get: (path, params) => API._request('GET', path, null, params),
|
||||
_post: (path, body) => API._request('POST', path, body),
|
||||
_put: (path, body) => API._request('PUT', path, body),
|
||||
_delete: (path) => API._request('DELETE', path),
|
||||
|
||||
async _upload(path, file, meta = {}) {
|
||||
// TODO: Implement multipart upload when backend ready
|
||||
await new Promise(r => setTimeout(r, 300));
|
||||
return { success: true, data: { fileId: 'mock-file-id', filename: file?.name }, message: 'OK (mock)' };
|
||||
},
|
||||
};
|
||||
|
||||
// Global error handler
|
||||
window.addEventListener('unhandledrejection', e => {
|
||||
if (e.reason?.message?.includes('401')) {
|
||||
// Redirect to login
|
||||
console.warn('Session expired');
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user