Skip to main content

February 18th, 2026

Building the Local Foundation: expo-sqlite is Live Following the architectural decision on Day 17, today we put it all into practice. We set up the local SQLite database, wired task CRUD to sync between Convex and local, created a native AlarmModule, and fixed a subtle scheduling bug.

Local SQLite Database Setup

Commit: feat: set up local SQLite database for alarm system We installed expo-sqlite, configured the Expo plugin, and created a production-grade local database layer.

Database Module (lib/local-db.ts)

Built with a versioned migration system so we can evolve the schema over time without data loss.

Tables Created

App Integration

  • Root Layout: Wrapped with SQLiteProvider for app-wide database access.
  • Performance: Enabled WAL journal mode for concurrent read/write performance.
  • Integrity: Enabled foreign keys to enforce referential integrity between tables.

Task CRUD Sync (Convex → Local SQLite)

Commit: feat(native): sync task CRUD to local SQLite database Wired all task operations to write to both Convex and the local DB:

Design Principles

  • Convex is source of truth. Local writes are non-blocking and fail gracefully with console errors if the local DB is unavailable.
  • Schema parity. Local schema mirrors Convex exactly (assigner_id, assignee_id, title, description, visibility, recurrence, conditions, timestamps).
  • Nested data. Complex objects (recurrence, conditions) stored as JSON strings.
  • Debug FAB. Added a floating debug button that lets us inspect the local DB contents at any time during development.

AlarmModule (Native Expo Module)

Commit: feat(native): add AlarmModule with Expo Modules API + global Alarm FAB Created a local Expo Module using the modern Expo Modules Kotlin DSL (expo.modules.kotlin.modules.Module).

What Was Built

  • AlarmModule: Exposes showToast() as a proof-of-concept native function (displays an Android Toast).
  • AlarmFab: Global floating button added in _layout.tsx, accessible from every screen.
  • Auto-linking: Uses expo-module.config.json — no manual MainApplication.kt patching needed.

What Was Removed (Legacy Cleanup)

We completely refactored away from the old Config Plugin injection pattern:
  • Removed plugins/withAlarmModule/ (legacy ReactContextBaseJavaModule approach).
  • Cleaned up injected AlarmModule.kt and AlarmPackage.kt from android/.
  • Removed add(AlarmPackage()) from MainApplication.kt.

Files Added


Sunday Scheduling Fix

Commit: fix(scheduler): normalize ISO-8601 Sunday (7) to JS convention (0)

The Bug

Weekly recurrences set to Sunday sent days_of_week: [7] (ISO-8601 standard), but the scheduler used JavaScript’s getDay() which returns 0 for Sunday.

Why It Was Subtle

Monday through Saturday were completely unaffected because both ISO-8601 and JavaScript conventions align for those days (Mon=1, Tue=2, …, Sat=6). Only Sunday diverged: ISO says 7, JS says 0.

The Fix

Added a normalization step that converts ISO-8601 day 7 to JavaScript day 0 before comparison, ensuring Sunday tasks fire correctly.