import type { HttpContext } from '@adonisjs/core/http' import FirmwareCatalogService, { type CreateFirmwareEntryDto, type CreateMigrationRouteDto, } from '#services/firmware_catalog_service' import logger from '@adonisjs/core/services/logger' /** * Firmware Catalog API Controller * * Handles REST endpoints for Firmware Catalog management: * - GET /api/v1/firmware-catalog (list entries grouped by productClass) * - POST /api/v1/firmware-catalog/entries (create firmware entry) * - DELETE /api/v1/firmware-catalog/entries/:id (delete firmware entry) * - POST /api/v1/firmware-catalog/routes (create migration route) * - PUT /api/v1/firmware-catalog/routes/:id (update migration route) * - DELETE /api/v1/firmware-catalog/routes/:id (delete migration route) */ export default class FirmwareCatalogController { private catalogService: FirmwareCatalogService constructor() { this.catalogService = new FirmwareCatalogService() } /** * GET /api/v1/firmware-catalog/entries * List firmware entries with optional search */ async listEntries({ request, response }: HttpContext) { try { const productClass = request.input('productClass') const entries = await this.catalogService.findEntries(productClass || undefined) return response.ok({ data: entries, total: entries.length }) } catch (error: any) { logger.error({ error: error.message }, '[FirmwareAPI] List entries failed') return response.status(500).json({ message: 'Failed to list firmware entries' }) } } /** * GET /api/v1/firmware-catalog/entries/:id * Get a single firmware entry by identifier */ async showEntry({ params, response }: HttpContext) { try { const entries = await this.catalogService.findEntries() const entry = entries.find((e) => e.identifier === params.id) if (!entry) return response.status(404).json({ message: 'Firmware entry not found' }) return response.ok({ data: entry }) } catch (error: any) { logger.error({ error: error.message }, '[FirmwareAPI] Show entry failed') return response.status(500).json({ message: 'Failed to load firmware entry' }) } } /** * GET /api/v1/firmware-catalog/routes * List all migration routes */ async listRoutes({ response }: HttpContext) { try { const routes = await this.catalogService.findAllRoutes() return response.ok({ data: routes, total: routes.length }) } catch (error: any) { logger.error({ error: error.message }, '[FirmwareAPI] List routes failed') return response.status(500).json({ message: 'Failed to list migration routes' }) } } /** * PUT /api/v1/firmware-catalog/entries/:id * Update a firmware entry */ async updateEntry({ params, request, response }: HttpContext) { try { const data = request.only([ 'productClass', 'version', 'downloadUrl', 'checksum', 'checksumType', 'fileSize', ]) const entry = await this.catalogService.updateEntry(params.id, data) return response.ok(entry) } catch (error: any) { logger.error({ error: error.message }, '[FirmwareAPI] Update entry failed') return response.status(400).json({ message: error.message }) } } /** * GET /api/v1/firmware-catalog * List all firmware entries, optionally filtered by productClass */ async index({ request, response }: HttpContext) { try { const productClass = request.input('productClass') const entries = await this.catalogService.findEntries(productClass) return response.ok({ entries }) } catch (error: any) { logger.error({ error: error.message }, '[FirmwareAPI] List entries failed') return response.status(500).json({ message: 'Failed to list firmware entries' }) } } /** * POST /api/v1/firmware-catalog/entries * Create new firmware entry */ async createEntry({ request, response }: HttpContext) { try { const data = request.only([ 'identifier', 'productClass', 'version', 'downloadUrl', 'checksum', 'checksumType', 'fileSize', ]) as CreateFirmwareEntryDto const entry = await this.catalogService.createEntry(data) return response.status(201).json(entry) } catch (error: any) { logger.error({ error: error.message }, '[FirmwareAPI] Create entry failed') return response.status(400).json({ message: error.message }) } } /** * DELETE /api/v1/firmware-catalog/entries/:id * Delete firmware entry */ async deleteEntry({ params, response }: HttpContext) { try { await this.catalogService.deleteEntry(params.id) return response.status(204).send(null) } catch (error: any) { logger.error({ error: error.message, id: params.id }, '[FirmwareAPI] Delete entry failed') return response.status(500).json({ message: 'Failed to delete firmware entry' }) } } /** * POST /api/v1/firmware-catalog/routes * Create new migration route */ async createRoute({ request, response }: HttpContext) { try { const data = request.only([ 'identifier', 'productClass', 'sourceVersionPattern', 'targetVersion', 'downloadUrl', 'priority', ]) as CreateMigrationRouteDto const route = await this.catalogService.createMigrationRoute(data) return response.status(201).json(route) } catch (error: any) { logger.error({ error: error.message }, '[FirmwareAPI] Create route failed') return response.status(400).json({ message: error.message }) } } /** * PUT /api/v1/firmware-catalog/routes/:id * Update migration route */ async updateRoute({ params: _params, request: _request, response }: HttpContext) { try { // TODO: Implement update method in FirmwareCatalogService // For now, return not implemented return response.status(501).json({ message: 'Not implemented' }) } catch (error: any) { logger.error({ error: error.message, id: _params.id }, '[FirmwareAPI] Update route failed') return response.status(500).json({ message: 'Failed to update migration route' }) } } /** * DELETE /api/v1/firmware-catalog/routes/:id * Delete migration route */ async deleteRoute({ params, response }: HttpContext) { try { await this.catalogService.deleteMigrationRoute(params.id) return response.status(204).send(null) } catch (error: any) { logger.error({ error: error.message, id: params.id }, '[FirmwareAPI] Delete route failed') return response.status(500).json({ message: 'Failed to delete migration route' }) } } }