Implement data sync and cleanup

This commit is contained in:
2026-01-09 13:48:38 -06:00
parent dc6bcad83f
commit d28898cb81
12 changed files with 596 additions and 50 deletions

117
backend/lib/database.dart Normal file
View File

@@ -0,0 +1,117 @@
import 'dart:io';
import 'package:sqlite3/sqlite3.dart' as sql;
import 'package:path/path.dart' as p;
class TrackerDatabase {
late final sql.Database _db;
TrackerDatabase() {
_init();
}
void _init() {
// Ensure data directory exists
final dataDir = Directory('data');
if (!dataDir.existsSync()) {
dataDir.createSync();
}
final dbPath = p.join('data', 'tracker.db');
print('Opening database at $dbPath');
_db = sql.sqlite3.open(dbPath);
_createTables();
}
void _createTables() {
print('Creating tables if not exist...');
// Users table
_db.execute('''
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
role TEXT NOT NULL,
name TEXT,
email TEXT,
partner_id TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
)
''');
// Cycle Entries table
_db.execute('''
CREATE TABLE IF NOT EXISTS cycle_entries (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
date TEXT NOT NULL,
flow_intensity TEXT,
is_period_day INTEGER DEFAULT 0,
symptoms TEXT, -- JSON string
moods TEXT, -- JSON string
notes TEXT,
updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
UNIQUE(user_id, date)
)
''');
// Teaching Plans table
_db.execute('''
CREATE TABLE IF NOT EXISTS teaching_plans (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
date TEXT NOT NULL,
topic TEXT,
scripture_reference TEXT,
notes TEXT,
application_question TEXT,
prayer_points TEXT, -- JSON string
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
)
''');
print('Tables created.');
}
// Basic CRUD placeholders for sync
void upsertCycleEntry(String userId, Map<String, dynamic> entry) {
// Assuming entry contains fields matching DB
final stmt = _db.prepare('''
INSERT OR REPLACE INTO cycle_entries (
id, user_id, date, flow_intensity, is_period_day, symptoms, moods, notes, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
''');
stmt.execute([
entry['id'],
userId,
entry['date'],
entry['flowIntensity'],
entry['isPeriodDay'] == true ? 1 : 0,
entry['symptoms'], // JSON
entry['moods'], // JSON
entry['notes'],
]);
stmt.dispose();
}
List<Map<String, dynamic>> getCycleEntries(String userId, {String? since}) {
// If since is provided, filter by updated_at
// For MVP sync, we might just return all or a simple diff
final result =
_db.select('SELECT * FROM cycle_entries WHERE user_id = ?', [userId]);
return result
.map((row) => {
'id': row['id'],
'date': row['date'],
'flowIntensity': row['flow_intensity'],
'isPeriodDay': row['is_period_day'] == 1,
'symptoms': row['symptoms'],
'moods': row['moods'],
'notes': row['notes'],
'updatedAt': row['updated_at']
})
.toList();
}
}