refactor: simplify pricing tables to USD-only
- Remove KRW pricing calculations from all pricing tables - Simplify pricing table to store only wholesale USD prices - Simplify anvil_pricing to store only retail USD prices - Remove KRW environment variables (KRW_EXCHANGE_RATE, KRW_MARGIN_RATE) - Remove KRW functions from constants.ts - Update GPU/G8/VPU pricing repositories to match - Add Anvil tables and repositories for branded product support Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
91
src/repositories/anvil-transfer-pricing.ts
Normal file
91
src/repositories/anvil-transfer-pricing.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Anvil Transfer Pricing Repository
|
||||
* Handles CRUD operations for data transfer pricing per region (USD only)
|
||||
*/
|
||||
|
||||
import { BaseRepository } from './base';
|
||||
import { AnvilTransferPricing, AnvilTransferPricingInput, RepositoryError, ErrorCodes } from '../types';
|
||||
import { createLogger } from '../utils/logger';
|
||||
|
||||
export class AnvilTransferPricingRepository extends BaseRepository<AnvilTransferPricing> {
|
||||
protected tableName = 'anvil_transfer_pricing';
|
||||
protected logger = createLogger('[AnvilTransferPricingRepository]');
|
||||
protected allowedColumns = [
|
||||
'anvil_region_id',
|
||||
'price_per_gb',
|
||||
];
|
||||
|
||||
constructor(db: D1Database) {
|
||||
super(db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find transfer pricing for a specific region
|
||||
*/
|
||||
async findByRegion(anvilRegionId: number): Promise<AnvilTransferPricing | null> {
|
||||
try {
|
||||
const result = await this.db
|
||||
.prepare('SELECT * FROM anvil_transfer_pricing WHERE anvil_region_id = ?')
|
||||
.bind(anvilRegionId)
|
||||
.first<AnvilTransferPricing>();
|
||||
|
||||
return result || null;
|
||||
} catch (error) {
|
||||
this.logger.error('findByRegion failed', {
|
||||
anvilRegionId,
|
||||
error: error instanceof Error ? error.message : 'Unknown error'
|
||||
});
|
||||
throw new RepositoryError(
|
||||
`Failed to find transfer pricing for Anvil region: ${anvilRegionId}`,
|
||||
ErrorCodes.DATABASE_ERROR,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk upsert transfer pricing records
|
||||
* Uses batch operations for efficiency
|
||||
*/
|
||||
async upsertMany(pricing: AnvilTransferPricingInput[]): Promise<number> {
|
||||
if (pricing.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
const statements = pricing.map((price) => {
|
||||
return this.db.prepare(
|
||||
`INSERT INTO anvil_transfer_pricing (
|
||||
anvil_region_id, price_per_gb
|
||||
) VALUES (?, ?)
|
||||
ON CONFLICT(anvil_region_id)
|
||||
DO UPDATE SET
|
||||
price_per_gb = excluded.price_per_gb`
|
||||
).bind(
|
||||
price.anvil_region_id,
|
||||
price.price_per_gb
|
||||
);
|
||||
});
|
||||
|
||||
const results = await this.executeBatch(statements);
|
||||
|
||||
const successCount = results.reduce(
|
||||
(sum, result) => sum + (result.meta.changes ?? 0),
|
||||
0
|
||||
);
|
||||
|
||||
this.logger.info('Upserted Anvil transfer pricing records', { count: successCount });
|
||||
return successCount;
|
||||
} catch (error) {
|
||||
this.logger.error('upsertMany failed', {
|
||||
count: pricing.length,
|
||||
error: error instanceof Error ? error.message : 'Unknown error'
|
||||
});
|
||||
throw new RepositoryError(
|
||||
'Failed to upsert Anvil transfer pricing records',
|
||||
ErrorCodes.TRANSACTION_FAILED,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user