feat: add server lifecycle management and D1 logging

- Add start/stop/reboot endpoints for server power management
- Add D1-based logging system (logs table + db-logger utility)
- Add idempotency_key validation for order deduplication
- Extend VPS provider interface with lifecycle methods

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-30 08:27:34 +09:00
parent f62712af37
commit 6385b5cab6
13 changed files with 767 additions and 7 deletions

View File

@@ -185,7 +185,12 @@ export class ProvisioningRepository {
}
async getOrdersByUserId(userId: number, limit: number = 20): Promise<ServerOrder[]> {
const result = await this.userDb
// Query uses two databases:
// - this.userDb (telegram-conversations): server_orders
// - this.db (cloud-instances-db): anvil_pricing, anvil_instances
// Step 1: Get orders from user DB
const ordersResult = await this.userDb
.prepare(
`SELECT * FROM server_orders
WHERE user_id = ? AND status NOT IN ('terminated', 'cancelled')
@@ -194,7 +199,49 @@ export class ProvisioningRepository {
.bind(userId, limit)
.all();
return result.results as unknown as ServerOrder[];
const orders = ordersResult.results as unknown as ServerOrder[];
if (orders.length === 0) {
return [];
}
// Step 2: Get spec details from cloud-instances-db
const specIds = orders.map(o => o.spec_id);
const placeholders = specIds.map(() => '?').join(',');
const specsResult = await this.db
.prepare(
`SELECT
ap.id as spec_id,
ai.vcpus as vcpu,
ai.memory_gb,
ai.disk_gb,
ai.transfer_tb as bandwidth_tb,
ai.display_name as spec_name
FROM anvil_pricing ap
JOIN anvil_instances ai ON ap.anvil_instance_id = ai.id
WHERE ap.id IN (${placeholders})`
)
.bind(...specIds)
.all();
// Step 3: Create a map for efficient lookup
const specsMap = new Map(
(specsResult.results as unknown as any[]).map(s => [s.spec_id, s])
);
// Step 4: Merge spec details into orders
return orders.map(order => {
const spec = specsMap.get(order.spec_id);
return {
...order,
vcpu: spec?.vcpu,
memory_gb: spec?.memory_gb,
disk_gb: spec?.disk_gb,
bandwidth_tb: spec?.bandwidth_tb,
spec_name: spec?.spec_name
};
});
}
/**