feat(notifications): implement notification system with CRUD operations and UI integration
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m27s
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m27s
This commit is contained in:
@@ -617,6 +617,38 @@ export async function initDatabase() {
|
||||
`);
|
||||
}
|
||||
|
||||
// ── Notifications table ──────────────────────────────────────────────────
|
||||
if (isPostgres) {
|
||||
await db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS notifications (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
type TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
body TEXT,
|
||||
link TEXT,
|
||||
read INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON notifications(user_id);
|
||||
`);
|
||||
} else {
|
||||
await db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS notifications (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
body TEXT,
|
||||
link TEXT,
|
||||
read INTEGER DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON notifications(user_id);
|
||||
`);
|
||||
}
|
||||
|
||||
// ── Default admin (only on very first start) ────────────────────────────
|
||||
const adminAlreadySeeded = await db.get("SELECT value FROM settings WHERE key = 'admin_seeded'");
|
||||
if (!adminAlreadySeeded) {
|
||||
|
||||
23
server/config/notifications.js
Normal file
23
server/config/notifications.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { getDb } from './database.js';
|
||||
|
||||
/**
|
||||
* Create an in-app notification for a user.
|
||||
* Non-fatal — exceptions are swallowed so that the main operation is never blocked.
|
||||
*
|
||||
* @param {number} userId - Recipient user ID
|
||||
* @param {string} type - Notification type (room_share_added | room_share_removed | federation_invite_received)
|
||||
* @param {string} title - Short title (e.g. room name or "from" address)
|
||||
* @param {string|null} body - Optional longer message
|
||||
* @param {string|null} link - Optional frontend path to navigate to when clicked
|
||||
*/
|
||||
export async function createNotification(userId, type, title, body = null, link = null) {
|
||||
try {
|
||||
const db = getDb();
|
||||
await db.run(
|
||||
'INSERT INTO notifications (user_id, type, title, body, link) VALUES (?, ?, ?, ?, ?)',
|
||||
[userId, type, title, body, link],
|
||||
);
|
||||
} catch {
|
||||
// Notifications are non-critical — never break main functionality
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user