import { Body, Controller, Delete, Get, Inject, Param, Post, UseGuards } from '@nestjs/common'; import type { RoutingCriteria } from '@mosaic/types'; import { AuthGuard } from '../auth/auth.guard.js'; import { CurrentUser } from '../auth/current-user.decorator.js'; import { ProviderService } from './provider.service.js'; import { ProviderCredentialsService } from './provider-credentials.service.js'; import { RoutingService } from './routing.service.js'; import type { TestConnectionDto, TestConnectionResultDto } from './provider.dto.js'; import type { StoreCredentialDto, ProviderCredentialSummaryDto, } from './provider-credentials.dto.js'; @Controller('api/providers') @UseGuards(AuthGuard) export class ProvidersController { constructor( @Inject(ProviderService) private readonly providerService: ProviderService, @Inject(ProviderCredentialsService) private readonly credentialsService: ProviderCredentialsService, @Inject(RoutingService) private readonly routingService: RoutingService, ) {} @Get() list() { return this.providerService.listProviders(); } @Get('models') listModels() { return this.providerService.listAvailableModels(); } @Get('health') health() { return { providers: this.providerService.getProvidersHealth() }; } @Post('test') testConnection(@Body() body: TestConnectionDto): Promise { return this.providerService.testConnection(body.providerId, body.baseUrl); } @Post('route') route(@Body() criteria: RoutingCriteria) { return this.routingService.route(criteria); } @Post('rank') rank(@Body() criteria: RoutingCriteria) { return this.routingService.rank(criteria); } // ── Credential CRUD ────────────────────────────────────────────────────── /** * GET /api/providers/credentials * List all provider credentials for the authenticated user. * Returns provider names, types, and metadata — never decrypted values. */ @Get('credentials') listCredentials(@CurrentUser() user: { id: string }): Promise { return this.credentialsService.listProviders(user.id); } /** * POST /api/providers/credentials * Store or update a provider credential for the authenticated user. * The value is encrypted before storage and never returned. */ @Post('credentials') async storeCredential( @CurrentUser() user: { id: string }, @Body() body: StoreCredentialDto, ): Promise<{ success: boolean; provider: string }> { await this.credentialsService.store( user.id, body.provider, body.type, body.value, body.metadata, ); return { success: true, provider: body.provider }; } /** * DELETE /api/providers/credentials/:provider * Remove a stored credential for the authenticated user. */ @Delete('credentials/:provider') async removeCredential( @CurrentUser() user: { id: string }, @Param('provider') provider: string, ): Promise<{ success: boolean; provider: string }> { await this.credentialsService.remove(user.id, provider); return { success: true, provider }; } }