PR 6: Database migration validation - fresh/upgrade test complete
✅ Database Setup: - Created PostgreSQL kartselldb with kartsell user - SSH port forward established (localhost:5432 → 178.104.200.7:5432) ✅ DbMigrator Fixes: - Fixed migration path discovery (AppContext.BaseDirectory fallback) - Added empty variable dictionary to suppress DbUp preprocessing - Fixed PostgreSQL dollar quoting conflict ($policy$ → $$) ✅ Migration Results: - All 21 migrations executed successfully - Schema versions journal created and tracked - 21 scripts processed in order, no rollback needed Status: FRESH DATABASE DEPLOYMENT SUCCESSFUL - kartselldb fully initialized with v16 schema - Ready for application startup Next: Deploy application and run integration tests Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import { computed } from 'vue';
|
||||
import DataGridShell from '../../../shared/ui/DataGridShell.vue';
|
||||
// Template fixture only. Production data must come from DAT-03 and pass Zod validation.
|
||||
const rows = [];
|
||||
const columns = computed(() => [
|
||||
{ field: 'source', header: 'Source' },
|
||||
{ field: 'session', header: 'Session' },
|
||||
{ field: 'status', header: 'DQ' },
|
||||
{ field: 'rowCount', header: 'Rows' },
|
||||
{ field: 'failedRows', header: 'Failed' },
|
||||
{ field: 'sourceWatermark', header: 'Watermark' },
|
||||
{ field: 'datasetId', header: 'Dataset' },
|
||||
{ field: 'completedAt', header: 'Completed' }
|
||||
]);
|
||||
const __VLS_ctx = {
|
||||
...{},
|
||||
...{},
|
||||
};
|
||||
let __VLS_components;
|
||||
let __VLS_intrinsics;
|
||||
let __VLS_directives;
|
||||
__VLS_asFunctionalElement1(__VLS_intrinsics.main, __VLS_intrinsics.main)({});
|
||||
__VLS_asFunctionalElement1(__VLS_intrinsics.header, __VLS_intrinsics.header)({});
|
||||
__VLS_asFunctionalElement1(__VLS_intrinsics.h1, __VLS_intrinsics.h1)({});
|
||||
__VLS_asFunctionalElement1(__VLS_intrinsics.p, __VLS_intrinsics.p)({});
|
||||
const __VLS_0 = DataGridShell;
|
||||
// @ts-ignore
|
||||
const __VLS_1 = __VLS_asFunctionalComponent1(__VLS_0, new __VLS_0({
|
||||
rows: (__VLS_ctx.rows),
|
||||
columns: (__VLS_ctx.columns),
|
||||
emptyMessage: "DAT-03 계약이 구현되면 서버 검증 결과가 표시됩니다.",
|
||||
}));
|
||||
const __VLS_2 = __VLS_1({
|
||||
rows: (__VLS_ctx.rows),
|
||||
columns: (__VLS_ctx.columns),
|
||||
emptyMessage: "DAT-03 계약이 구현되면 서버 검증 결과가 표시됩니다.",
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_1));
|
||||
// @ts-ignore
|
||||
[rows, columns,];
|
||||
const __VLS_export = (await import('vue')).defineComponent({});
|
||||
export default {};
|
||||
@@ -0,0 +1,23 @@
|
||||
import { z } from 'zod';
|
||||
export const dataQualityStatusSchema = z.enum(['PASS', 'WARN', 'QUARANTINED']);
|
||||
export const dataQualityRunSchema = z.object({
|
||||
runId: z.string().uuid(),
|
||||
source: z.string().min(1),
|
||||
session: z.string().min(1),
|
||||
status: dataQualityStatusSchema,
|
||||
rowCount: z.number().int().nonnegative(),
|
||||
failedRows: z.number().int().nonnegative(),
|
||||
sourceWatermark: z.string().min(1),
|
||||
datasetId: z.string().min(1),
|
||||
contentHash: z.string().min(1),
|
||||
completedAt: z.string().datetime({ offset: true })
|
||||
}).superRefine((value, ctx) => {
|
||||
if (value.failedRows > value.rowCount) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: '실패 행 수는 전체 행 수를 초과할 수 없습니다.',
|
||||
path: ['failedRows']
|
||||
});
|
||||
}
|
||||
});
|
||||
export const dataQualityRunsSchema = z.array(dataQualityRunSchema);
|
||||
@@ -0,0 +1,22 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { dataQualityRunSchema } from '../schema';
|
||||
const valid = {
|
||||
runId: '00000000-0000-0000-0000-000000000001',
|
||||
source: 'KRX',
|
||||
session: '2026-08-01',
|
||||
status: 'PASS',
|
||||
rowCount: 100,
|
||||
failedRows: 0,
|
||||
sourceWatermark: 'KRX:2026-08-01',
|
||||
datasetId: 'dataset-1',
|
||||
contentHash: 'hash-1',
|
||||
completedAt: '2026-08-01T09:00:00Z'
|
||||
};
|
||||
describe('data quality contract', () => {
|
||||
it('accepts a valid run', () => {
|
||||
expect(dataQualityRunSchema.safeParse(valid).success).toBe(true);
|
||||
});
|
||||
it('rejects failed rows greater than total rows', () => {
|
||||
expect(dataQualityRunSchema.safeParse({ ...valid, failedRows: 101 }).success).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user