feat: anvil_transfer_pricing 동기화 로직 추가
- syncAnvilTransferPricing 메서드 구현 - 프로바이더별 도매 비용: Linode $0.005/GB, Vultr $0.01/GB, AWS $0.09/GB - 소매 가격 계산: cost × 1.21 (21% 마진) - Stage 8.5에서 자동 실행 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -377,6 +377,21 @@ export class SyncOrchestrator {
|
||||
});
|
||||
}
|
||||
|
||||
// Stage 8.5: Sync Anvil Transfer Pricing
|
||||
let anvilTransferPricingCount = 0;
|
||||
try {
|
||||
anvilTransferPricingCount = await this.syncAnvilTransferPricing(provider);
|
||||
if (anvilTransferPricingCount > 0) {
|
||||
this.logger.info(`${provider} → SYNC_ANVIL_TRANSFER_PRICING`, { anvil_transfer_pricing: anvilTransferPricingCount });
|
||||
}
|
||||
} catch (transferError) {
|
||||
// Log error but don't fail the entire sync
|
||||
this.logger.error('Anvil transfer pricing sync failed', {
|
||||
provider,
|
||||
error: transferError instanceof Error ? transferError.message : String(transferError)
|
||||
});
|
||||
}
|
||||
|
||||
// Stage 9: Complete - Update provider status to success
|
||||
stage = SyncStage.COMPLETE;
|
||||
await this.repos.providers.updateSyncStatus(provider, 'success');
|
||||
@@ -1121,6 +1136,84 @@ export class SyncOrchestrator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize Anvil transfer pricing based on source provider
|
||||
*
|
||||
* Updates anvil_transfer_pricing table with retail transfer costs
|
||||
* Formula: retail = cost × 1.21 (21% margin)
|
||||
*
|
||||
* Provider costs (per GB):
|
||||
* - Linode: $0.005/GB
|
||||
* - Vultr: $0.01/GB
|
||||
* - AWS: $0.09/GB (Asia regions)
|
||||
*
|
||||
* @param provider - Source provider name (linode, vultr, aws)
|
||||
* @returns Number of anvil_transfer_pricing records updated
|
||||
*/
|
||||
private async syncAnvilTransferPricing(provider: string): Promise<number> {
|
||||
this.logger.info('Starting Anvil transfer pricing sync', { provider });
|
||||
|
||||
try {
|
||||
// Step 1: Define provider costs per GB (wholesale)
|
||||
const providerCosts: Record<string, number> = {
|
||||
linode: 0.005, // $0.005/GB
|
||||
vultr: 0.01, // $0.01/GB
|
||||
aws: 0.09, // $0.09/GB (Asia regions)
|
||||
};
|
||||
|
||||
const costPerGb = providerCosts[provider.toLowerCase()];
|
||||
if (!costPerGb) {
|
||||
this.logger.info('No transfer pricing defined for provider', { provider });
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Step 2: Find all anvil_regions sourced from this provider
|
||||
const anvilRegionsResult = await this.repos.db
|
||||
.prepare('SELECT id, source_region_id FROM anvil_regions WHERE source_provider = ?')
|
||||
.bind(provider)
|
||||
.all<{ id: number; source_region_id: number }>();
|
||||
|
||||
if (!anvilRegionsResult.success || anvilRegionsResult.results.length === 0) {
|
||||
this.logger.info('No anvil_regions found for provider', { provider });
|
||||
return 0;
|
||||
}
|
||||
|
||||
const anvilRegions = anvilRegionsResult.results;
|
||||
this.logger.info('Found anvil_regions for transfer pricing', {
|
||||
provider,
|
||||
count: anvilRegions.length
|
||||
});
|
||||
|
||||
// Step 3: Calculate retail price (cost × 1.21 for 21% margin)
|
||||
const retailPricePerGb = costPerGb * 1.21;
|
||||
|
||||
// Step 4: Prepare upsert data for all regions
|
||||
const transferPricingData = anvilRegions.map(region => ({
|
||||
anvil_region_id: region.id,
|
||||
price_per_gb: retailPricePerGb,
|
||||
}));
|
||||
|
||||
// Step 5: Batch upsert using repository
|
||||
const upsertCount = await this.repos.anvilTransferPricing.upsertMany(transferPricingData);
|
||||
|
||||
this.logger.info('Anvil transfer pricing sync completed', {
|
||||
provider,
|
||||
cost_per_gb: costPerGb,
|
||||
retail_price_per_gb: retailPricePerGb,
|
||||
regions_updated: upsertCount,
|
||||
});
|
||||
|
||||
return upsertCount;
|
||||
|
||||
} catch (error) {
|
||||
this.logger.error('Anvil transfer pricing sync failed', {
|
||||
provider,
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create connector for a specific provider
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user