/** * Anvil Regions Repository * Handles CRUD operations for Anvil-branded regional datacenters */ import { BaseRepository } from './base'; import { AnvilRegion, AnvilRegionInput, RepositoryError, ErrorCodes } from '../types'; import { createLogger } from '../utils/logger'; export class AnvilRegionsRepository extends BaseRepository { protected tableName = 'anvil_regions'; protected logger = createLogger('[AnvilRegionsRepository]'); protected allowedColumns = [ 'name', 'display_name', 'country_code', 'source_provider', 'source_region_code', 'source_region_id', 'active', ]; /** * Find a region by name (e.g., "anvil-tyo1") */ async findByName(name: string): Promise { try { const result = await this.db .prepare('SELECT * FROM anvil_regions WHERE name = ?') .bind(name) .first(); return result || null; } catch (error) { this.logger.error('findByName failed', { name, error: error instanceof Error ? error.message : 'Unknown error' }); throw new RepositoryError( `Failed to find Anvil region by name: ${name}`, ErrorCodes.DATABASE_ERROR, error ); } } /** * Find all regions for a country */ async findByCountry(countryCode: string): Promise { try { const result = await this.db .prepare('SELECT * FROM anvil_regions WHERE country_code = ? ORDER BY name') .bind(countryCode) .all(); return result.results; } catch (error) { this.logger.error('findByCountry failed', { countryCode, error: error instanceof Error ? error.message : 'Unknown error' }); throw new RepositoryError( `Failed to find Anvil regions for country: ${countryCode}`, ErrorCodes.DATABASE_ERROR, error ); } } /** * Find region by source region ID */ async findBySourceRegion(sourceRegionId: number): Promise { try { const result = await this.db .prepare('SELECT * FROM anvil_regions WHERE source_region_id = ?') .bind(sourceRegionId) .first(); return result || null; } catch (error) { this.logger.error('findBySourceRegion failed', { sourceRegionId, error: error instanceof Error ? error.message : 'Unknown error' }); throw new RepositoryError( `Failed to find Anvil region by source region: ${sourceRegionId}`, ErrorCodes.DATABASE_ERROR, error ); } } /** * Get all active regions */ async findActive(): Promise { try { const result = await this.db .prepare('SELECT * FROM anvil_regions WHERE active = 1 ORDER BY name') .all(); return result.results; } catch (error) { this.logger.error('findActive failed', { error: error instanceof Error ? error.message : 'Unknown error' }); throw new RepositoryError( 'Failed to find active Anvil regions', ErrorCodes.DATABASE_ERROR, error ); } } /** * Update region active status */ async updateActive(id: number, active: boolean): Promise { try { const result = await this.db .prepare('UPDATE anvil_regions SET active = ? WHERE id = ? RETURNING *') .bind(active ? 1 : 0, id) .first(); if (!result) { throw new RepositoryError( `Anvil region not found: ${id}`, ErrorCodes.NOT_FOUND ); } return result; } catch (error) { this.logger.error('updateActive failed', { id, active, error: error instanceof Error ? error.message : 'Unknown error' }); if (error instanceof RepositoryError) { throw error; } throw new RepositoryError( `Failed to update Anvil region active status: ${id}`, ErrorCodes.DATABASE_ERROR, error ); } } /** * Bulk upsert regions * Uses batch operations for efficiency */ async upsertMany(regions: AnvilRegionInput[]): Promise { if (regions.length === 0) { return 0; } try { const statements = regions.map((region) => { return this.db.prepare( `INSERT INTO anvil_regions ( name, display_name, country_code, source_provider, source_region_code, source_region_id, active ) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT(name) DO UPDATE SET display_name = excluded.display_name, country_code = excluded.country_code, source_provider = excluded.source_provider, source_region_code = excluded.source_region_code, source_region_id = excluded.source_region_id, active = excluded.active` ).bind( region.name, region.display_name, region.country_code, region.source_provider, region.source_region_code, region.source_region_id, region.active ); }); const results = await this.executeBatch(statements); const successCount = results.reduce( (sum, result) => sum + (result.meta.changes ?? 0), 0 ); this.logger.info('Upserted Anvil regions', { count: successCount }); return successCount; } catch (error) { this.logger.error('upsertMany failed', { count: regions.length, error: error instanceof Error ? error.message : 'Unknown error' }); throw new RepositoryError( 'Failed to upsert Anvil regions', ErrorCodes.TRANSACTION_FAILED, error ); } } }