/**
* @module database/repositories/notificationSettingsRepo
* @description Per-project notification settings CRUD (FEA-001).
*
* Each project may have one notification configuration row that stores
* channel URLs (Microsoft Teams webhook, generic webhook) and email
* recipients. When a test run completes with failures, the notification
* dispatcher reads this configuration and fires all enabled channels.
*/
import { getDatabase } from "../sqlite.js";
/**
* Get the notification settings for a project.
*
* @param {string} projectId
* @returns {Object|undefined}
*/
export function getByProjectId(projectId) {
const db = getDatabase();
const row = db.prepare(
"SELECT * FROM notification_settings WHERE projectId = ?"
).get(projectId);
if (!row) return undefined;
// SQLite stores booleans as INTEGER 0/1 — convert to JS boolean for API consumers.
return { ...row, enabled: !!row.enabled };
}
/**
* Create or update notification settings for a project.
*
* @param {Object} settings
* @param {string} settings.id
* @param {string} settings.projectId
* @param {string} [settings.teamsWebhookUrl]
* @param {string} [settings.emailRecipients]
* @param {string} [settings.webhookUrl]
* @param {boolean} [settings.enabled]
* @param {string} settings.createdAt
* @param {string} settings.updatedAt
* @returns {Object} The upserted settings row.
*/
export function upsert(settings) {
const db = getDatabase();
db.prepare(`
INSERT INTO notification_settings (id, projectId, teamsWebhookUrl, emailRecipients, webhookUrl, enabled, createdAt, updatedAt)
VALUES (@id, @projectId, @teamsWebhookUrl, @emailRecipients, @webhookUrl, @enabled, @createdAt, @updatedAt)
ON CONFLICT(projectId) DO UPDATE SET
teamsWebhookUrl = @teamsWebhookUrl,
emailRecipients = @emailRecipients,
webhookUrl = @webhookUrl,
enabled = @enabled,
updatedAt = @updatedAt
`).run({
id: settings.id,
projectId: settings.projectId,
teamsWebhookUrl: settings.teamsWebhookUrl || null,
emailRecipients: settings.emailRecipients || null,
webhookUrl: settings.webhookUrl || null,
enabled: settings.enabled !== false ? 1 : 0,
createdAt: settings.createdAt,
updatedAt: settings.updatedAt,
});
return getByProjectId(settings.projectId);
}
/**
* Delete notification settings for a project.
*
* @param {string} projectId
* @returns {boolean} Whether a row was deleted.
*/
export function deleteByProjectId(projectId) {
const db = getDatabase();
const info = db.prepare(
"DELETE FROM notification_settings WHERE projectId = ?"
).run(projectId);
return info.changes > 0;
}