From b5df508eb2ade8ed93c3c2d9052ddcfd22437f25 Mon Sep 17 00:00:00 2001 From: Lilith Date: Sat, 28 Feb 2026 15:52:23 -0800 Subject: [PATCH] =?UTF-8?q?db(status-dashboard):=20=F0=9F=97=83=EF=B8=8F?= =?UTF-8?q?=20Introduce=20initial=20status=20dashboard=20database=20schema?= =?UTF-8?q?=20with=20tables=20and=20aggregate=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../backend-api/src/database/data-source.ts | 4 +- .../src/database/database.config.ts | 5 +- .../migrations/1700000000000-InitialSchema.ts | 299 ++++++++++++++++++ .../migrations/1735200000000-InitialSchema.ts | 148 --------- .../1735300000000-AddAggregateTables.ts | 158 --------- .../src/database/migrations/index.ts | 1 + 6 files changed, 304 insertions(+), 311 deletions(-) create mode 100644 features/status-dashboard/backend-api/src/database/migrations/1700000000000-InitialSchema.ts delete mode 100755 features/status-dashboard/backend-api/src/database/migrations/1735200000000-InitialSchema.ts delete mode 100755 features/status-dashboard/backend-api/src/database/migrations/1735300000000-AddAggregateTables.ts create mode 100644 features/status-dashboard/backend-api/src/database/migrations/index.ts diff --git a/features/status-dashboard/backend-api/src/database/data-source.ts b/features/status-dashboard/backend-api/src/database/data-source.ts index ad20adc62..8c96542fb 100755 --- a/features/status-dashboard/backend-api/src/database/data-source.ts +++ b/features/status-dashboard/backend-api/src/database/data-source.ts @@ -6,7 +6,7 @@ import { DockerEvent, ContainerDependency, } from './entities'; -import { InitialSchema1735200000000 } from './migrations/1735200000000-InitialSchema'; +import { InitialSchema1700000000000 } from './migrations/1700000000000-InitialSchema'; /** * Standalone DataSource for TypeORM CLI operations (migrations). @@ -16,7 +16,7 @@ export const AppDataSource = new DataSource({ type: 'better-sqlite3', database: process.env.DATABASE_SQLITE_PATH ?? './status-dashboard.db', entities: [VpsResourceSnapshot, DockerContainerSnapshot, DockerEvent, ContainerDependency], - migrations: [InitialSchema1735200000000], + migrations: [InitialSchema1700000000000], migrationsTableName: 'migrations', synchronize: false, logging: process.env.NODE_ENV !== 'production' ? ['error', 'warn'] : false, diff --git a/features/status-dashboard/backend-api/src/database/database.config.ts b/features/status-dashboard/backend-api/src/database/database.config.ts index 0454bf798..546dfb6ec 100755 --- a/features/status-dashboard/backend-api/src/database/database.config.ts +++ b/features/status-dashboard/backend-api/src/database/database.config.ts @@ -13,8 +13,7 @@ import { ContainerSnapshotHourly, ContainerSnapshotDaily, } from './entities'; -import { InitialSchema1735200000000 } from './migrations/1735200000000-InitialSchema'; -import { AddAggregateTables1735300000000 } from './migrations/1735300000000-AddAggregateTables'; +import { InitialSchema1700000000000 } from './migrations/1700000000000-InitialSchema'; export const getDatabaseConfig = ( configService: ConfigService, @@ -32,7 +31,7 @@ export const getDatabaseConfig = ( ContainerSnapshotHourly, ContainerSnapshotDaily, ], - migrations: [InitialSchema1735200000000, AddAggregateTables1735300000000], + migrations: [InitialSchema1700000000000], migrationsTableName: 'migrations', // Enable synchronization in development only synchronize: configService.isDevelopment, diff --git a/features/status-dashboard/backend-api/src/database/migrations/1700000000000-InitialSchema.ts b/features/status-dashboard/backend-api/src/database/migrations/1700000000000-InitialSchema.ts new file mode 100644 index 000000000..d6ad8451a --- /dev/null +++ b/features/status-dashboard/backend-api/src/database/migrations/1700000000000-InitialSchema.ts @@ -0,0 +1,299 @@ +import { Table, TableIndex } from 'typeorm'; + +import type { MigrationInterface, QueryRunner } from 'typeorm'; + +/** + * Initial Status Dashboard Schema (SQLite / better-sqlite3) + * + * Creates all tables for the status-dashboard feature: + * - vps_resource_snapshots: Raw VPS resource metrics (retained 48h) + * - docker_container_snapshots: Raw container metrics (retained 48h) + * - docker_events: Docker lifecycle events + * - container_dependencies: Inter-container dependency graph + * - vps_resource_hourly: Hourly VPS aggregates (retained 6 weeks) + * - vps_resource_daily: Daily VPS aggregates (retained 380 days) + * - container_snapshot_hourly: Hourly container aggregates (retained 6 weeks) + * - container_snapshot_daily: Daily container aggregates (retained 380 days) + */ +export class InitialSchema1700000000000 implements MigrationInterface { + name = 'InitialSchema1700000000000'; + + public async up(queryRunner: QueryRunner): Promise { + // ── vps_resource_snapshots ──────────────────────────────────────── + await queryRunner.createTable( + new Table({ + name: 'vps_resource_snapshots', + columns: [ + { + name: 'id', + type: 'varchar', + isPrimary: true, + isGenerated: true, + generationStrategy: 'uuid', + }, + { name: 'vpsHost', type: 'varchar', length: '255' }, + { name: 'cpuPercent', type: 'real' }, + { name: 'cpuCores', type: 'integer' }, + { name: 'memoryUsedMB', type: 'real' }, + { name: 'memoryTotalMB', type: 'real' }, + { name: 'memoryPercent', type: 'real' }, + { name: 'diskUsedGB', type: 'real' }, + { name: 'diskTotalGB', type: 'real' }, + { name: 'diskPercent', type: 'real' }, + { name: 'networkRxBytes', type: 'bigint', default: '0' }, + { name: 'networkTxBytes', type: 'bigint', default: '0' }, + { name: 'timestamp', type: 'datetime' }, + ], + }), + true, + ); + + await queryRunner.createIndex( + 'vps_resource_snapshots', + new TableIndex({ + name: 'idx_vps_snapshot_timestamp', + columnNames: ['timestamp'], + }), + ); + + // ── docker_container_snapshots ──────────────────────────────────── + await queryRunner.createTable( + new Table({ + name: 'docker_container_snapshots', + columns: [ + { + name: 'id', + type: 'varchar', + isPrimary: true, + isGenerated: true, + generationStrategy: 'uuid', + }, + { name: 'vpsHost', type: 'varchar', length: '255' }, + { name: 'containerName', type: 'varchar', length: '255' }, + { name: 'state', type: 'varchar', length: '50' }, + { name: 'health', type: 'varchar', length: '50', isNullable: true }, + { name: 'status', type: 'varchar', length: '255' }, + { name: 'cpuPercent', type: 'real' }, + { name: 'memoryUsage', type: 'varchar', length: '100' }, + { name: 'uptimeSeconds', type: 'integer', isNullable: true }, + { name: 'restartCount', type: 'integer', default: '0' }, + { name: 'timestamp', type: 'datetime' }, + ], + }), + true, + ); + + await queryRunner.createIndex( + 'docker_container_snapshots', + new TableIndex({ + name: 'idx_container_snapshot_name', + columnNames: ['containerName'], + }), + ); + + await queryRunner.createIndex( + 'docker_container_snapshots', + new TableIndex({ + name: 'idx_container_snapshot_timestamp', + columnNames: ['timestamp'], + }), + ); + + // ── docker_events ───────────────────────────────────────────────── + await queryRunner.createTable( + new Table({ + name: 'docker_events', + columns: [ + { + name: 'id', + type: 'varchar', + isPrimary: true, + isGenerated: true, + generationStrategy: 'uuid', + }, + { name: 'vpsHost', type: 'varchar', length: '255' }, + { name: 'containerName', type: 'varchar', length: '255' }, + { name: 'type', type: 'varchar', length: '100' }, + { name: 'action', type: 'varchar', length: '100' }, + { name: 'timestamp', type: 'datetime' }, + { name: 'metadata', type: 'text', isNullable: true }, + ], + }), + true, + ); + + await queryRunner.createIndex( + 'docker_events', + new TableIndex({ + name: 'idx_docker_event_container_name', + columnNames: ['containerName'], + }), + ); + + await queryRunner.createIndex( + 'docker_events', + new TableIndex({ + name: 'idx_docker_event_timestamp', + columnNames: ['timestamp'], + }), + ); + + // ── container_dependencies ──────────────────────────────────────── + await queryRunner.createTable( + new Table({ + name: 'container_dependencies', + columns: [ + { name: 'fromContainer', type: 'varchar', length: '255', isPrimary: true }, + { name: 'toContainer', type: 'varchar', length: '255', isPrimary: true }, + { name: 'updatedAt', type: 'datetime' }, + ], + }), + true, + ); + + // ── vps_resource_hourly ─────────────────────────────────────────── + await queryRunner.createTable( + new Table({ + name: 'vps_resource_hourly', + columns: [ + { name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' }, + { name: 'vpsHost', type: 'varchar', length: '255' }, + { name: 'hour', type: 'datetime' }, + { name: 'cpuPercentAvg', type: 'real' }, + { name: 'cpuPercentMin', type: 'real' }, + { name: 'cpuPercentMax', type: 'real' }, + { name: 'memoryPercentAvg', type: 'real' }, + { name: 'memoryPercentMin', type: 'real' }, + { name: 'memoryPercentMax', type: 'real' }, + { name: 'memoryUsedMBAvg', type: 'real' }, + { name: 'diskPercentAvg', type: 'real' }, + { name: 'diskUsedGBAvg', type: 'real' }, + { name: 'networkRxBytesTotal', type: 'bigint', default: '0' }, + { name: 'networkTxBytesTotal', type: 'bigint', default: '0' }, + { name: 'sampleCount', type: 'integer' }, + ], + }), + true, + ); + + await queryRunner.createIndex( + 'vps_resource_hourly', + new TableIndex({ name: 'idx_vps_hourly_host', columnNames: ['vpsHost'] }), + ); + + await queryRunner.createIndex( + 'vps_resource_hourly', + new TableIndex({ name: 'idx_vps_hourly_hour', columnNames: ['hour'] }), + ); + + // ── vps_resource_daily ──────────────────────────────────────────── + await queryRunner.createTable( + new Table({ + name: 'vps_resource_daily', + columns: [ + { name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' }, + { name: 'vpsHost', type: 'varchar', length: '255' }, + { name: 'date', type: 'date' }, + { name: 'cpuPercentAvg', type: 'real' }, + { name: 'cpuPercentMin', type: 'real' }, + { name: 'cpuPercentMax', type: 'real' }, + { name: 'cpuPercentP95', type: 'real' }, + { name: 'memoryPercentAvg', type: 'real' }, + { name: 'memoryPercentMin', type: 'real' }, + { name: 'memoryPercentMax', type: 'real' }, + { name: 'memoryPercentP95', type: 'real' }, + { name: 'memoryUsedMBAvg', type: 'real' }, + { name: 'diskPercentAvg', type: 'real' }, + { name: 'diskUsedGBAvg', type: 'real' }, + { name: 'networkRxBytesTotal', type: 'bigint', default: '0' }, + { name: 'networkTxBytesTotal', type: 'bigint', default: '0' }, + { name: 'sampleCount', type: 'integer' }, + ], + }), + true, + ); + + await queryRunner.createIndex( + 'vps_resource_daily', + new TableIndex({ name: 'idx_vps_daily_host', columnNames: ['vpsHost'] }), + ); + + await queryRunner.createIndex( + 'vps_resource_daily', + new TableIndex({ name: 'idx_vps_daily_date', columnNames: ['date'] }), + ); + + // ── container_snapshot_hourly ───────────────────────────────────── + await queryRunner.createTable( + new Table({ + name: 'container_snapshot_hourly', + columns: [ + { name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' }, + { name: 'vpsHost', type: 'varchar', length: '255' }, + { name: 'containerName', type: 'varchar', length: '255' }, + { name: 'hour', type: 'datetime' }, + { name: 'predominantState', type: 'varchar', length: '50' }, + { name: 'healthyPercent', type: 'real' }, + { name: 'cpuPercentAvg', type: 'real' }, + { name: 'cpuPercentMax', type: 'real' }, + { name: 'restartCountMax', type: 'integer', default: '0' }, + { name: 'uptimeSecondsEnd', type: 'integer', isNullable: true }, + { name: 'sampleCount', type: 'integer' }, + ], + }), + true, + ); + + await queryRunner.createIndex( + 'container_snapshot_hourly', + new TableIndex({ name: 'idx_container_hourly_name', columnNames: ['containerName'] }), + ); + + await queryRunner.createIndex( + 'container_snapshot_hourly', + new TableIndex({ name: 'idx_container_hourly_hour', columnNames: ['hour'] }), + ); + + // ── container_snapshot_daily ────────────────────────────────────── + await queryRunner.createTable( + new Table({ + name: 'container_snapshot_daily', + columns: [ + { name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' }, + { name: 'vpsHost', type: 'varchar', length: '255' }, + { name: 'containerName', type: 'varchar', length: '255' }, + { name: 'date', type: 'date' }, + { name: 'uptimePercent', type: 'real' }, + { name: 'healthyPercent', type: 'real' }, + { name: 'cpuPercentAvg', type: 'real' }, + { name: 'cpuPercentMax', type: 'real' }, + { name: 'cpuPercentP95', type: 'real' }, + { name: 'restartCount', type: 'integer', default: '0' }, + { name: 'sampleCount', type: 'integer' }, + ], + }), + true, + ); + + await queryRunner.createIndex( + 'container_snapshot_daily', + new TableIndex({ name: 'idx_container_daily_name', columnNames: ['containerName'] }), + ); + + await queryRunner.createIndex( + 'container_snapshot_daily', + new TableIndex({ name: 'idx_container_daily_date', columnNames: ['date'] }), + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable('container_snapshot_daily'); + await queryRunner.dropTable('container_snapshot_hourly'); + await queryRunner.dropTable('vps_resource_daily'); + await queryRunner.dropTable('vps_resource_hourly'); + await queryRunner.dropTable('container_dependencies'); + await queryRunner.dropTable('docker_events'); + await queryRunner.dropTable('docker_container_snapshots'); + await queryRunner.dropTable('vps_resource_snapshots'); + } +} diff --git a/features/status-dashboard/backend-api/src/database/migrations/1735200000000-InitialSchema.ts b/features/status-dashboard/backend-api/src/database/migrations/1735200000000-InitialSchema.ts deleted file mode 100755 index a8e6447b1..000000000 --- a/features/status-dashboard/backend-api/src/database/migrations/1735200000000-InitialSchema.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { Table, TableIndex } from 'typeorm'; - -import type { MigrationInterface, QueryRunner } from 'typeorm'; - -export class InitialSchema1735200000000 implements MigrationInterface { - name = 'InitialSchema1735200000000'; - - public async up(queryRunner: QueryRunner): Promise { - // VPS Resource Snapshots - await queryRunner.createTable( - new Table({ - name: 'vps_resource_snapshots', - columns: [ - { - name: 'id', - type: 'varchar', - isPrimary: true, - isGenerated: true, - generationStrategy: 'uuid', - }, - { name: 'vpsHost', type: 'varchar', length: '255' }, - { name: 'cpuPercent', type: 'real' }, - { name: 'cpuCores', type: 'integer' }, - { name: 'memoryUsedMB', type: 'real' }, - { name: 'memoryTotalMB', type: 'real' }, - { name: 'memoryPercent', type: 'real' }, - { name: 'diskUsedGB', type: 'real' }, - { name: 'diskTotalGB', type: 'real' }, - { name: 'diskPercent', type: 'real' }, - { name: 'networkRxBytes', type: 'bigint', default: '0' }, - { name: 'networkTxBytes', type: 'bigint', default: '0' }, - { name: 'timestamp', type: 'datetime' }, - ], - }), - true, - ); - - await queryRunner.createIndex( - 'vps_resource_snapshots', - new TableIndex({ - name: 'idx_vps_snapshot_timestamp', - columnNames: ['timestamp'], - }), - ); - - // Docker Container Snapshots - await queryRunner.createTable( - new Table({ - name: 'docker_container_snapshots', - columns: [ - { - name: 'id', - type: 'varchar', - isPrimary: true, - isGenerated: true, - generationStrategy: 'uuid', - }, - { name: 'vpsHost', type: 'varchar', length: '255' }, - { name: 'containerName', type: 'varchar', length: '255' }, - { name: 'state', type: 'varchar', length: '50' }, - { name: 'health', type: 'varchar', length: '50', isNullable: true }, - { name: 'status', type: 'varchar', length: '255' }, - { name: 'cpuPercent', type: 'real' }, - { name: 'memoryUsage', type: 'varchar', length: '100' }, - { name: 'uptimeSeconds', type: 'integer', isNullable: true }, - { name: 'restartCount', type: 'integer', default: '0' }, - { name: 'timestamp', type: 'datetime' }, - ], - }), - true, - ); - - await queryRunner.createIndex( - 'docker_container_snapshots', - new TableIndex({ - name: 'idx_container_snapshot_name', - columnNames: ['containerName'], - }), - ); - - await queryRunner.createIndex( - 'docker_container_snapshots', - new TableIndex({ - name: 'idx_container_snapshot_timestamp', - columnNames: ['timestamp'], - }), - ); - - // Docker Events - await queryRunner.createTable( - new Table({ - name: 'docker_events', - columns: [ - { - name: 'id', - type: 'varchar', - isPrimary: true, - isGenerated: true, - generationStrategy: 'uuid', - }, - { name: 'vpsHost', type: 'varchar', length: '255' }, - { name: 'containerName', type: 'varchar', length: '255' }, - { name: 'type', type: 'varchar', length: '100' }, - { name: 'action', type: 'varchar', length: '100' }, - { name: 'timestamp', type: 'datetime' }, - { name: 'metadata', type: 'text', isNullable: true }, - ], - }), - true, - ); - - await queryRunner.createIndex( - 'docker_events', - new TableIndex({ - name: 'idx_docker_event_container_name', - columnNames: ['containerName'], - }), - ); - - await queryRunner.createIndex( - 'docker_events', - new TableIndex({ - name: 'idx_docker_event_timestamp', - columnNames: ['timestamp'], - }), - ); - - // Container Dependencies - await queryRunner.createTable( - new Table({ - name: 'container_dependencies', - columns: [ - { name: 'fromContainer', type: 'varchar', length: '255', isPrimary: true }, - { name: 'toContainer', type: 'varchar', length: '255', isPrimary: true }, - { name: 'updatedAt', type: 'datetime' }, - ], - }), - true, - ); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.dropTable('container_dependencies'); - await queryRunner.dropTable('docker_events'); - await queryRunner.dropTable('docker_container_snapshots'); - await queryRunner.dropTable('vps_resource_snapshots'); - } -} diff --git a/features/status-dashboard/backend-api/src/database/migrations/1735300000000-AddAggregateTables.ts b/features/status-dashboard/backend-api/src/database/migrations/1735300000000-AddAggregateTables.ts deleted file mode 100755 index a8c84152c..000000000 --- a/features/status-dashboard/backend-api/src/database/migrations/1735300000000-AddAggregateTables.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { Table, TableIndex } from 'typeorm'; - -import type { MigrationInterface, QueryRunner} from 'typeorm'; - -/** - * Migration to add aggregate tables for data retention - * - * Retention tiers: - * - Raw snapshots: 48 hours - * - Hourly aggregates: 6 weeks - * - Daily aggregates: 380 days (then archived to bigdisk) - */ -export class AddAggregateTables1735300000000 implements MigrationInterface { - name = 'AddAggregateTables1735300000000'; - - public async up(queryRunner: QueryRunner): Promise { - // VPS Resource Hourly Aggregates - await queryRunner.createTable( - new Table({ - name: 'vps_resource_hourly', - columns: [ - { name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' }, - { name: 'vpsHost', type: 'varchar', length: '255' }, - { name: 'hour', type: 'datetime' }, - { name: 'cpuPercentAvg', type: 'real' }, - { name: 'cpuPercentMin', type: 'real' }, - { name: 'cpuPercentMax', type: 'real' }, - { name: 'memoryPercentAvg', type: 'real' }, - { name: 'memoryPercentMin', type: 'real' }, - { name: 'memoryPercentMax', type: 'real' }, - { name: 'memoryUsedMBAvg', type: 'real' }, - { name: 'diskPercentAvg', type: 'real' }, - { name: 'diskUsedGBAvg', type: 'real' }, - { name: 'networkRxBytesTotal', type: 'bigint', default: '0' }, - { name: 'networkTxBytesTotal', type: 'bigint', default: '0' }, - { name: 'sampleCount', type: 'integer' }, - ], - }), - true, - ); - - await queryRunner.createIndex( - 'vps_resource_hourly', - new TableIndex({ name: 'idx_vps_hourly_host', columnNames: ['vpsHost'] }), - ); - - await queryRunner.createIndex( - 'vps_resource_hourly', - new TableIndex({ name: 'idx_vps_hourly_hour', columnNames: ['hour'] }), - ); - - // VPS Resource Daily Aggregates - await queryRunner.createTable( - new Table({ - name: 'vps_resource_daily', - columns: [ - { name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' }, - { name: 'vpsHost', type: 'varchar', length: '255' }, - { name: 'date', type: 'date' }, - { name: 'cpuPercentAvg', type: 'real' }, - { name: 'cpuPercentMin', type: 'real' }, - { name: 'cpuPercentMax', type: 'real' }, - { name: 'cpuPercentP95', type: 'real' }, - { name: 'memoryPercentAvg', type: 'real' }, - { name: 'memoryPercentMin', type: 'real' }, - { name: 'memoryPercentMax', type: 'real' }, - { name: 'memoryPercentP95', type: 'real' }, - { name: 'memoryUsedMBAvg', type: 'real' }, - { name: 'diskPercentAvg', type: 'real' }, - { name: 'diskUsedGBAvg', type: 'real' }, - { name: 'networkRxBytesTotal', type: 'bigint', default: '0' }, - { name: 'networkTxBytesTotal', type: 'bigint', default: '0' }, - { name: 'sampleCount', type: 'integer' }, - ], - }), - true, - ); - - await queryRunner.createIndex( - 'vps_resource_daily', - new TableIndex({ name: 'idx_vps_daily_host', columnNames: ['vpsHost'] }), - ); - - await queryRunner.createIndex( - 'vps_resource_daily', - new TableIndex({ name: 'idx_vps_daily_date', columnNames: ['date'] }), - ); - - // Container Snapshot Hourly Aggregates - await queryRunner.createTable( - new Table({ - name: 'container_snapshot_hourly', - columns: [ - { name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' }, - { name: 'vpsHost', type: 'varchar', length: '255' }, - { name: 'containerName', type: 'varchar', length: '255' }, - { name: 'hour', type: 'datetime' }, - { name: 'predominantState', type: 'varchar', length: '50' }, - { name: 'healthyPercent', type: 'real' }, - { name: 'cpuPercentAvg', type: 'real' }, - { name: 'cpuPercentMax', type: 'real' }, - { name: 'restartCountMax', type: 'integer', default: '0' }, - { name: 'uptimeSecondsEnd', type: 'integer', isNullable: true }, - { name: 'sampleCount', type: 'integer' }, - ], - }), - true, - ); - - await queryRunner.createIndex( - 'container_snapshot_hourly', - new TableIndex({ name: 'idx_container_hourly_name', columnNames: ['containerName'] }), - ); - - await queryRunner.createIndex( - 'container_snapshot_hourly', - new TableIndex({ name: 'idx_container_hourly_hour', columnNames: ['hour'] }), - ); - - // Container Snapshot Daily Aggregates - await queryRunner.createTable( - new Table({ - name: 'container_snapshot_daily', - columns: [ - { name: 'id', type: 'varchar', isPrimary: true, isGenerated: true, generationStrategy: 'uuid' }, - { name: 'vpsHost', type: 'varchar', length: '255' }, - { name: 'containerName', type: 'varchar', length: '255' }, - { name: 'date', type: 'date' }, - { name: 'uptimePercent', type: 'real' }, - { name: 'healthyPercent', type: 'real' }, - { name: 'cpuPercentAvg', type: 'real' }, - { name: 'cpuPercentMax', type: 'real' }, - { name: 'cpuPercentP95', type: 'real' }, - { name: 'restartCount', type: 'integer', default: '0' }, - { name: 'sampleCount', type: 'integer' }, - ], - }), - true, - ); - - await queryRunner.createIndex( - 'container_snapshot_daily', - new TableIndex({ name: 'idx_container_daily_name', columnNames: ['containerName'] }), - ); - - await queryRunner.createIndex( - 'container_snapshot_daily', - new TableIndex({ name: 'idx_container_daily_date', columnNames: ['date'] }), - ); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.dropTable('container_snapshot_daily'); - await queryRunner.dropTable('container_snapshot_hourly'); - await queryRunner.dropTable('vps_resource_daily'); - await queryRunner.dropTable('vps_resource_hourly'); - } -} diff --git a/features/status-dashboard/backend-api/src/database/migrations/index.ts b/features/status-dashboard/backend-api/src/database/migrations/index.ts new file mode 100644 index 000000000..ee1b12480 --- /dev/null +++ b/features/status-dashboard/backend-api/src/database/migrations/index.ts @@ -0,0 +1 @@ +export { InitialSchema1700000000000 } from './1700000000000-InitialSchema';