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:
@@ -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
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user