import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import test from 'node:test'; const root = process.cwd(); const android = (...segments: string[]) => path.join(root, '..', 'android-app', 'app', 'src', 'main', 'java', 'com', 'korexlabs', 'dhinspeccion', ...segments); const read = (...segments: string[]) => fs.readFileSync(android(...segments), 'utf8'); const mobileCore = read('data', 'DhMobile.kt'); const mobileActs = read('data', 'MobileActs.kt'); const viewModel = read('MainViewModel.kt'); test('F4 Android inspection contract has no title or planned end field', () => { const summary = mobileCore.slice(mobileCore.indexOf('data class VisitSummary('), mobileCore.indexOf('data class VisitMeta(')); const detail = mobileCore.slice(mobileCore.indexOf('data class VisitDetail('), mobileCore.indexOf('// ---------- Field inventory ----------')); assert.doesNotMatch(summary, /\btitle\s*:/); assert.doesNotMatch(summary, /\bplannedEndAt\b/); assert.doesNotMatch(detail, /\btitle\s*:/); assert.doesNotMatch(detail, /\bplannedEndAt\b/); assert.match(summary, /plannedStartAt/); assert.match(detail, /plannedStartAt/); }); test('F4 Android uses only lock and seal endpoints for the active Act lifecycle', () => { assert.match(mobileActs, /inspection-acts\/\{actId\}\/lock/); assert.match(mobileActs, /inspection-acts\/\{actId\}\/seal/); assert.doesNotMatch(mobileActs, /inspection-acts\/\{actId\}\/ready/); assert.doesNotMatch(mobileActs, /inspection-acts\/\{actId\}\/reopen/); assert.doesNotMatch(mobileActs, /inspection-acts\/\{actId\}\/close["']/); assert.doesNotMatch(mobileActs, /suspend fun prepare\(/); assert.doesNotMatch(mobileActs, /suspend fun reopen\(/); assert.doesNotMatch(mobileActs, /suspend fun closeAct\(/); }); test('F4 Android ViewModel calls lock and seal directly', () => { assert.match(viewModel, /actsRepository\.lock\(actId\)/); assert.match(viewModel, /actsRepository\.seal\(actId\)/); assert.doesNotMatch(viewModel, /actsRepository\.prepare\(/); assert.doesNotMatch(viewModel, /actsRepository\.reopen\(/); assert.doesNotMatch(viewModel, /actsRepository\.closeAct\(/); });