/** * Design System Server (DSS) - Discovery Service * * Project analysis interface for the admin dashboard. * No mocks - requires backend connection. */ class DiscoveryService { constructor() { this.apiBase = '/api/discovery'; this.connected = null; this.cache = new Map(); this.cacheExpiry = 5 * 60 * 1000; // 5 minutes } async checkConnection() { try { const response = await fetch('/health', { method: 'GET' }); this.connected = response.ok; } catch { this.connected = false; } return this.connected; } _requireConnection() { if (this.connected === false) { throw new Error('API unavailable. Start DSS server first.'); } } async discover(projectPath = '.', fullScan = false) { const cacheKey = `${projectPath}:${fullScan}`; // Check cache if (this.cache.has(cacheKey)) { const cached = this.cache.get(cacheKey); if (Date.now() - cached.timestamp < this.cacheExpiry) { return cached.data; } } const response = await fetch(`${this.apiBase}/scan`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ path: projectPath, full_scan: fullScan }) }); if (!response.ok) { const err = await response.json().catch(() => ({})); throw new Error(err.detail || 'Discovery scan failed'); } const result = await response.json(); this.cache.set(cacheKey, { data: result, timestamp: Date.now() }); return result; } async getHealth() { const response = await fetch('/health'); if (!response.ok) { throw new Error('Health check failed'); } return response.json(); } async getRecentActivity() { const response = await fetch(`${this.apiBase}/activity`); if (!response.ok) { return { items: [] }; } return response.json(); } async getProjectStats() { const response = await fetch(`${this.apiBase}/stats`); if (!response.ok) { return { projects: {}, tokens: {}, components: {}, syncs: {} }; } return response.json(); } invalidateCache() { this.cache.clear(); } } const discoveryService = new DiscoveryService(); export { DiscoveryService }; export default discoveryService;