Skip to main content

NIIA-Watcher Database

Tracks file system events from the detached watcher daemon.
╔═════════════════════════════════════════════════════════════════════╗
║                     NIIA-WATCHER.DB OVERVIEW                         ║
╠═════════════════════════════════════════════════════════════════════╣
║                                                                      ║
║   ┌───────────────────┐  ┌───────────────────┐  ┌───────────────────┐║
║   │   file_events     │  │   watch_paths     │  │  worker_status    │║
║   │                   │  │                   │  │                   │║
║   │ - ts (timestamp)  │  │ - path (UNIQUE)   │  │ - pid (PK)        │║
║   │ - event_type      │  │ - depth           │  │ - start_time      │║
║   │ - abs_path        │  │ - active          │  │ - last_ping       │║
║   │ - rel_path        │  │ - ignore_patterns │  │ - queue_size      │║
║   │ - basename        │  │ - is_auto_added   │  │ - watcher_count   │║
║   │ - file_size       │  │                   │  │ - memory_usage    │║
║   │ - is_directory    │  │                   │  │ - status          │║
║   └───────────────────┘  └───────────────────┘  └───────────────────┘║
║                                                                      ║
║   ┌───────────────────┐  ┌───────────────────┐                       ║
║   │   daily_stats     │  │ user_exclusions   │                       ║
║   │                   │  │                   │                       ║
║   │ - date (PK)       │  │ - exclusion_type  │                       ║
║   │ - total_events    │  │ - pattern         │                       ║
║   │ - create_count    │  │ - created_at      │                       ║
║   │ - change_count    │  │                   │                       ║
║   │ - unlink_count    │  │                   │                       ║
║   │ - rename_count    │  │                   │                       ║
║   └───────────────────┘  └───────────────────┘                       ║
║                                                                      ║
║                        niia-watcher.db                               ║
╚═════════════════════════════════════════════════════════════════════╝

Architecture

The watcher runs as a detached sidecar process with direct database access.
╔═════════════════════════════════════════════════════════════════════╗
║                    DAEMON ARCHITECTURE                               ║
╠═════════════════════════════════════════════════════════════════════╣
║                                                                      ║
║   Tauri App Start                                                    ║
║        │                                                             ║
║        │ spawn_daemon()                                              ║
║        ▼                                                             ║
║   ┌──────────────────────────────────────────────────────────────┐   ║
║   │  File Watcher Daemon (Detached Sidecar Process)              │   ║
║   │                                                              │   ║
║   │  ┌────────────────────────┐  ┌────────────────────────┐      │   ║
║   │  │  Control Socket        │  │  Database Writer       │      │   ║
║   │  │  /tmp/niia-watcher.sock│  │  rusqlite WAL mode     │      │   ║
║   │  └────────────────────────┘  └────────────────────────┘      │   ║
║   │              │                           │                   │   ║
║   │              │                           │                   │   ║
║   │  ┌────────────────────────┐  ┌────────────────────────┐      │   ║
║   │  │  File Watcher Pool     │  │  Heartbeat Timer       │      │   ║
║   │  │  Rust notify crate     │  │  Every 10 seconds      │      │   ║
║   │  │  (FSEvents/inotify)    │  │  UPDATE worker_status  │      │   ║
║   │  └────────────────────────┘  └────────────────────────┘      │   ║
║   │                                                              │   ║
║   └──────────────────────────────────────────────────────────────┘   ║
║                                                                      ║
║   KEY BENEFIT: Daemon survives app crash                             ║
║                                                                      ║
║   Tauri App Crash                                                    ║
║        │                                                             ║
║        ✕── Daemon continues running (detached)                       ║
║        │   File events still captured                                ║
║        │                                                             ║
║   Tauri App Restart                                                  ║
║        │                                                             ║
║        │ Check worker_status.pid                                     ║
║        │ Process still alive? ──▶ Reuse existing daemon              ║
║        │ Process dead? ──▶ Spawn new daemon                          ║
║                                                                      ║
╚═════════════════════════════════════════════════════════════════════╝

Write/Read Separation

╔═════════════════════════════════════════════════════════════════════╗
║                   WRITE/READ ARCHITECTURE                            ║
╠═════════════════════════════════════════════════════════════════════╣
║                                                                      ║
║   WRITE (Daemon Only - NO IPC)                                       ║
║   ┌───────────────────────────────────────────────────────────────┐  ║
║   │                                                               │  ║
║   │   File Watcher Daemon                                         │  ║
║   │        │                                                      │  ║
║   │        │ OS File System Event (FSEvents/inotify)              │  ║
║   │        ▼                                                      │  ║
║   │   Event Handler                                               │  ║
║   │        │                                                      │  ║
║   │        │ Debounce + Filter                                    │  ║
║   │        ▼                                                      │  ║
║   │   Direct rusqlite INSERT                                      │  ║
║   │        │                                                      │  ║
║   │        ▼                                                      │  ║
║   │   file_events table                                           │  ║
║   │                                                               │  ║
║   │   BENEFIT: No IPC overhead = Maximum performance              │  ║
║   └───────────────────────────────────────────────────────────────┘  ║
║                                                                      ║
║   READ (Tauri Commands ──▶ Frontend)                                 ║
║   ┌───────────────────────────────────────────────────────────────┐  ║
║   │                                                               │  ║
║   │   Frontend                                                    │  ║
║   │        │                                                      │  ║
║   │        │ invoke("query_niia_watcher")                         │  ║
║   │        ▼                                                      │  ║
║   │   Tauri Command ──▶ Rust Module                               │  ║
║   │        │                                                      │  ║
║   │        │ SELECT FROM file_events WHERE ts > ?                 │  ║
║   │        ▼                                                      │  ║
║   │   JSON Response ──▶ UI Update                                 │  ║
║   │                                                               │  ║
║   └───────────────────────────────────────────────────────────────┘  ║
║                                                                      ║
╚═════════════════════════════════════════════════════════════════════╝

File Event Types

╔═════════════════════════════════════════════════════════════════════╗
║                      FILE EVENT TYPES                                ║
╠═════════════════════════════════════════════════════════════════════╣
║                                                                      ║
║   EVENT       │ DESCRIPTION                                          ║
║   ════════════│══════════════════════════════════════════════════════║
║   Create      │ New file or directory created                        ║
║   Change      │ File content modified                                ║
║   Unlink      │ File or directory deleted                            ║
║   Rename      │ File renamed (old_path populated)                    ║
║                                                                      ║
║   RENAME EVENT HANDLING                                              ║
║   ┌───────────────────────────────────────────────────────────────┐  ║
║   │  Rename events generate TWO records:                          │  ║
║   │                                                               │  ║
║   │  Record 1: Unlink event                                       │  ║
║   │     - abs_path = old path                                     │  ║
║   │     - correlation_id = X                                      │  ║
║   │                                                               │  ║
║   │  Record 2: Create event                                       │  ║
║   │     - abs_path = new path                                     │  ║
║   │     - correlation_id = X                                      │  ║
║   │                                                               │  ║
║   │  Frontend can GROUP BY correlation_id for atomic display      │  ║
║   └───────────────────────────────────────────────────────────────┘  ║
║                                                                      ║
╚═════════════════════════════════════════════════════════════════════╝

Cross-Database Relationship

The watcher database helps resolve truncated paths in terminal output.
╔═════════════════════════════════════════════════════════════════════╗
║                   CROSS-DB PATH RESOLUTION                           ║
╠═════════════════════════════════════════════════════════════════════╣
║                                                                      ║
║   atomic-term.db                        niia-watcher.db              ║
║   ┌───────────────────────────┐         ┌───────────────────────────┐║
║   │                           │         │                           │║
║   │  parsed_activities        │  QUERY  │  file_events              │║
║   │  ┌─────────────────────┐  │────────▶│  ┌─────────────────────┐  │║
║   │  │ target (truncated)  │  │         │  │ basename            │  │║
║   │  │ timestamp           │  │         │  │ abs_path            │  │║
║   │  └─────────────────────┘  │         │  │ ts                  │  │║
║   │             │             │         │  └─────────────────────┘  │║
║   │             │             │         │                           │║
║   │  UPDATE     │             │         └───────────────────────────┘║
║   │             ▼             │                                      ║
║   │  ┌─────────────────────┐  │                                      ║
║   │  │ path (resolved)     │  │                                      ║
║   │  │ rel_path            │  │                                      ║
║   │  └─────────────────────┘  │                                      ║
║   │                           │                                      ║
║   └───────────────────────────┘                                      ║
║                                                                      ║
║   Auto-fix query:                                                    ║
║   ┌───────────────────────────────────────────────────────────────┐  ║
║   │  SELECT abs_path FROM file_events                             │  ║
║   │  WHERE basename = ?                                           │  ║
║   │  AND ts BETWEEN (activity_ts - window) AND (activity_ts + w)  │  ║
║   └───────────────────────────────────────────────────────────────┘  ║
║                                                                      ║
║   PURPOSE: Terminal shows truncated paths. Watcher provides full     ║
║            paths based on filename + timestamp correlation.          ║
║                                                                      ║
╚═════════════════════════════════════════════════════════════════════╝

Worker Status Monitoring

╔═════════════════════════════════════════════════════════════════════╗
║                   WORKER STATUS TABLE                                ║
╠═════════════════════════════════════════════════════════════════════╣
║                                                                      ║
║   Column        │ Type     │ Description                             ║
║   ══════════════│══════════│═════════════════════════════════════════║
║   pid           │ INTEGER  │ Process ID (Primary Key)                ║
║   start_time    │ INTEGER  │ When daemon started                     ║
║   last_ping     │ INTEGER  │ Last heartbeat timestamp                ║
║   queue_size    │ INTEGER  │ Pending events in queue                 ║
║   watcher_count │ INTEGER  │ Number of active file watchers          ║
║   memory_usage  │ INTEGER  │ Memory consumption in bytes             ║
║   status        │ TEXT     │ running/paused/error                    ║
║   error_message │ TEXT     │ Last error (if any)                     ║
║                                                                      ║
║   HEARTBEAT MECHANISM                                                ║
║   ┌───────────────────────────────────────────────────────────────┐  ║
║   │  Daemon updates worker_status every 10 seconds                │  ║
║   │                                                               │  ║
║   │  App checks: last_ping > (NOW - 30 seconds)?                  │  ║
║   │  YES ──▶ Daemon is alive, reuse                               │  ║
║   │  NO  ──▶ Daemon is dead, spawn new                            │  ║
║   └───────────────────────────────────────────────────────────────┘  ║
║                                                                      ║
╚═════════════════════════════════════════════════════════════════════╝

Design Principles Applied

╔═════════════════════════════════════════════════════════════════════╗
║                      DESIGN PRINCIPLES                               ║
╠═════════════════════════════════════════════════════════════════════╣
║                                                                      ║
║   SIMPLICITY (SMPC)                                                  ║
║   ┌───────────────────────────────────────────────────────────────┐  ║
║   │ [x] Daemon writes directly via rusqlite (no IPC overhead)     │  ║
║   │ [x] 5 tables with clear, single responsibilities              │  ║
║   │ [x] WAL mode for concurrent read/write                        │  ║
║   │ [x] Simple event types (Create/Change/Unlink/Rename)          │  ║
║   └───────────────────────────────────────────────────────────────┘  ║
║                                                                      ║
║   ORDER FROM CHAOS (OFAC)                                            ║
║   ┌───────────────────────────────────────────────────────────────┐  ║
║   │ [x] Detached daemon survives app crash                        │  ║
║   │ [x] Control socket for runtime commands                       │  ║
║   │ [x] Auto-added default watch paths on startup                 │  ║
║   │ [x] Heartbeat ping for daemon health monitoring               │  ║
║   │ [x] user_exclusions for user-customizable filtering           │  ║
║   └───────────────────────────────────────────────────────────────┘  ║
║                                                                      ║
╚═════════════════════════════════════════════════════════════════════╝

Quick Reference

AspectValue
Location~/Library/Application Support/monolex/protocols/niia/database/niia-watcher.db
Primary OwnerFile Watcher Daemon (sidecar)
Write MethodDirect rusqlite (no IPC)
Read ByFrontend watcher tab, Auto-fix module
Survives CrashYes (detached process)