|
|
|
@ -15,11 +15,12 @@ export function initializeDatabase(instance: Database) {
|
|
|
|
|
instance.exec(`PRAGMA foreign_keys = ON;`);
|
|
|
|
|
|
|
|
|
|
// Create users table first as others depend on it
|
|
|
|
|
// Use TEXT for timestamps to store higher precision ISO8601 format easily
|
|
|
|
|
instance.exec(`
|
|
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
|
|
|
id TEXT PRIMARY KEY, -- WhatsApp user ID (normalized)
|
|
|
|
|
first_seen TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
|
last_seen TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
|
|
|
first_seen TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
|
|
|
|
last_seen TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now'))
|
|
|
|
|
);
|
|
|
|
|
`);
|
|
|
|
|
|
|
|
|
@ -29,7 +30,7 @@ export function initializeDatabase(instance: Database) {
|
|
|
|
|
id TEXT PRIMARY KEY, -- Group ID (normalized)
|
|
|
|
|
community_id TEXT NOT NULL,
|
|
|
|
|
name TEXT,
|
|
|
|
|
last_verified TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
|
last_verified TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
|
|
|
|
active BOOLEAN DEFAULT TRUE
|
|
|
|
|
);
|
|
|
|
|
`);
|
|
|
|
@ -39,10 +40,10 @@ export function initializeDatabase(instance: Database) {
|
|
|
|
|
CREATE TABLE IF NOT EXISTS tasks (
|
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
description TEXT NOT NULL,
|
|
|
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
|
due_date TIMESTAMP NULL,
|
|
|
|
|
created_at TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
|
|
|
|
due_date TEXT NULL, -- Store dates as ISO8601 strings or YYYY-MM-DD
|
|
|
|
|
completed BOOLEAN DEFAULT FALSE,
|
|
|
|
|
completed_at TIMESTAMP NULL,
|
|
|
|
|
completed_at TEXT NULL,
|
|
|
|
|
group_id TEXT NULL, -- Normalized group ID
|
|
|
|
|
created_by TEXT NOT NULL, -- Normalized user ID
|
|
|
|
|
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE CASCADE,
|
|
|
|
@ -56,7 +57,7 @@ export function initializeDatabase(instance: Database) {
|
|
|
|
|
task_id INTEGER NOT NULL,
|
|
|
|
|
user_id TEXT NOT NULL, -- Normalized user ID
|
|
|
|
|
assigned_by TEXT NOT NULL, -- Normalized user ID
|
|
|
|
|
assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
|
assigned_at TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
|
|
|
|
PRIMARY KEY (task_id, user_id),
|
|
|
|
|
FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
|
|
|
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
|
|
@ -70,6 +71,7 @@ export function initializeDatabase(instance: Database) {
|
|
|
|
|
* If the user exists, updates their last_seen timestamp.
|
|
|
|
|
* If the user does not exist, creates them.
|
|
|
|
|
* Uses the normalizeWhatsAppId utility.
|
|
|
|
|
* Stores timestamps with millisecond precision.
|
|
|
|
|
*
|
|
|
|
|
* @param rawUserId The raw WhatsApp ID (e.g., '12345@s.whatsapp.net').
|
|
|
|
|
* @param instance The database instance to use (defaults to the main db).
|
|
|
|
@ -84,24 +86,23 @@ export function ensureUserExists(rawUserId: string | null | undefined, instance:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Use INSERT OR IGNORE to add the user only if they don't exist,
|
|
|
|
|
// then UPDATE their last_seen timestamp regardless.
|
|
|
|
|
// This is often more efficient than SELECT followed by INSERT/UPDATE.
|
|
|
|
|
// Use strftime for millisecond precision timestamps
|
|
|
|
|
const insertStmt = instance.prepare(`
|
|
|
|
|
INSERT INTO users (id, first_seen, last_seen)
|
|
|
|
|
VALUES (?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
|
|
|
|
VALUES (?, strftime('%Y-%m-%d %H:%M:%f', 'now'), strftime('%Y-%m-%d %H:%M:%f', 'now'))
|
|
|
|
|
ON CONFLICT(id) DO NOTHING;
|
|
|
|
|
`);
|
|
|
|
|
|
|
|
|
|
const updateStmt = instance.prepare(`
|
|
|
|
|
UPDATE users
|
|
|
|
|
SET last_seen = CURRENT_TIMESTAMP
|
|
|
|
|
SET last_seen = strftime('%Y-%m-%d %H:%M:%f', 'now')
|
|
|
|
|
WHERE id = ?;
|
|
|
|
|
`);
|
|
|
|
|
|
|
|
|
|
// Run as transaction for atomicity
|
|
|
|
|
instance.transaction(() => {
|
|
|
|
|
insertStmt.run(normalizedId);
|
|
|
|
|
// Update last_seen even if the user was just inserted or already existed
|
|
|
|
|
updateStmt.run(normalizedId);
|
|
|
|
|
})(); // Immediately invoke the transaction
|
|
|
|
|
|
|
|
|
|