mirror of
https://github.com/kuhyx/wake-alarm.git
synced 2026-11-10 19:27:02 +01:00
- Sick days screen (own name, sick icon, cat-2 fill): tap today or a later day to mark it sick, tap again to clear; past days inert. Writes the sickdays wire format (state sick/cleared + actor, one HLC per write) to sickdays-sync/devices via crdt_sync syncLog. - Mutual exclusion in both pickers: each syncs the other pool on open and refuses a date it holds, naming the pool; an unreadable pool refuses all. - Native SickDays cache (fail closed via DayCache); AlarmReceiver skips the ring with reason "sick_day" (no markFired, no ring_started); StickCheck verdict sick_day, streak skips sick days; stakes card says so. - Pre-alarm pool sync: allow-while-idle alarm at 21:00 and A-30 (request code 1006) runs a headless engine (poolSyncMain) that pulls both pools from RTDB and rewrites both native caches, so a PC mark arrives with the app closed. The ring decision stays a cache read. - JVM unit tests (JUnit 4.13.2) for DayCache, RingDecision, PoolSyncSchedule, StickCheck; Dart tests; Dart->Python interop check. pylint hook skipped: verify.py imports sickdays, not in the hook env until the sickdays-v0.1.0 tag exists; run by hand in a sickdays venv (10.00/10). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xfj1sxKH9VBPqpcAni8Jry
44 lines
1.5 KiB
Dart
44 lines
1.5 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:crdt_sync/crdt_sync.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:wake_alarm_sync/services/sick_day_pool.dart';
|
|
|
|
/// Half of the cross-language check (`scripts/sick_days_interop/check.sh`).
|
|
///
|
|
/// Writes a pool through the Dart rules to `SICK_DAYS_INTEROP_OUT`; the
|
|
/// script reads it back with `sickdays` (Python) and replays the same edits
|
|
/// there. Under a plain `flutter test` the variable is unset and this does
|
|
/// nothing.
|
|
class _FilePersistence implements LogPersistence {
|
|
_FilePersistence(this.file);
|
|
|
|
final File file;
|
|
|
|
@override
|
|
Future<String?> read() async =>
|
|
file.existsSync() ? file.readAsStringSync() : null;
|
|
|
|
@override
|
|
Future<void> write(String text) async => file.writeAsStringSync(text);
|
|
}
|
|
|
|
void main() {
|
|
test('writes the interop fixture when asked', () async {
|
|
final out = Platform.environment['SICK_DAYS_INTEROP_OUT'];
|
|
if (out == null) return;
|
|
final pool = await SickDayPool.open(
|
|
persistence: _FilePersistence(File(out)),
|
|
deviceId: 'dart-interop',
|
|
);
|
|
final now = DateTime(2026, 10, 16);
|
|
bool never(DateTime _) => false;
|
|
// Today sick; a future day sick; a future day marked then cleared;
|
|
// 2026-10-23 untouched.
|
|
await pool.add(now, isFree: never, now: now);
|
|
await pool.add(DateTime(2026, 10, 20), isFree: never, now: now);
|
|
await pool.add(DateTime(2026, 10, 21), isFree: never, now: now);
|
|
await pool.remove(DateTime(2026, 10, 21), now: now);
|
|
});
|
|
}
|