Initial Commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import { sortMigrations } from "../../planner/migration-planner/migration-planner.js";
|
||||
import type {
|
||||
ExtendedMigrationStatus,
|
||||
MigrationHealthCheck,
|
||||
MigrationHistoryEntry,
|
||||
MigrationSummary,
|
||||
StatusConfig,
|
||||
} from "../../types/migration.types.js";
|
||||
|
||||
/**
|
||||
* Provides a read-only dashboard over the migration store: per-migration
|
||||
* status, aggregate summaries, health checks, and history per migration id.
|
||||
*/
|
||||
export class MigrationStatusDashboard {
|
||||
protected readonly config: StatusConfig;
|
||||
|
||||
constructor(config: StatusConfig) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
async getAll(): Promise<ExtendedMigrationStatus[]> {
|
||||
const { store, migrations } = this.config;
|
||||
const applied = await store.getApplied();
|
||||
const appliedMap = new Map(applied.map((r) => [r.id, r]));
|
||||
return sortMigrations(migrations).map((m): ExtendedMigrationStatus => {
|
||||
const record = appliedMap.get(m.id);
|
||||
const status = record
|
||||
? record.direction === "down"
|
||||
? ("rolled-back" as const)
|
||||
: ("applied" as const)
|
||||
: ("pending" as const);
|
||||
return {
|
||||
id: m.id,
|
||||
name: m.name,
|
||||
status,
|
||||
...(record !== undefined && { appliedAt: record.appliedAt }),
|
||||
...(record?.checksum !== undefined && {
|
||||
checksum: record.checksum,
|
||||
}),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async getSummary(): Promise<MigrationSummary> {
|
||||
const all = await this.getAll();
|
||||
return {
|
||||
total: all.length,
|
||||
applied: all.filter((s) => s.status === "applied").length,
|
||||
pending: all.filter((s) => s.status === "pending").length,
|
||||
failed: all.filter((s) => s.status === "failed").length,
|
||||
};
|
||||
}
|
||||
|
||||
async healthCheck(): Promise<MigrationHealthCheck> {
|
||||
const summary = await this.getSummary();
|
||||
return {
|
||||
healthy: summary.pending === 0 && summary.failed === 0,
|
||||
pendingCount: summary.pending,
|
||||
failedCount: summary.failed,
|
||||
};
|
||||
}
|
||||
|
||||
async getHistory(id: string): Promise<MigrationHistoryEntry[]> {
|
||||
const { store } = this.config;
|
||||
const applied = await store.getApplied();
|
||||
return applied
|
||||
.filter((r) => r.id === id)
|
||||
.map(
|
||||
(r): MigrationHistoryEntry => ({
|
||||
id: r.id,
|
||||
direction: r.direction,
|
||||
appliedAt: r.appliedAt,
|
||||
...(r.checksum !== undefined && { checksum: r.checksum }),
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user