BillTracker/services/userSettings.cts

116 lines
3.1 KiB
TypeScript
Raw Normal View History

2026-05-15 22:45:38 -05:00
'use strict';
import type { Db } from '../types/db';
const { getDb, getSetting } = require('../db/database.cts');
2026-05-15 22:45:38 -05:00
const USER_SETTING_KEYS = [
'currency',
'date_format',
'week_start',
'default_landing_page',
2026-05-15 22:45:38 -05:00
'grace_period_days',
'due_soon_days',
2026-05-15 22:45:38 -05:00
'notify_days_before',
'drift_threshold_pct',
'bank_tracking_enabled',
'bank_tracking_account_id',
'bank_tracking_pending_days',
'bank_late_attribution_days',
'search_bars_collapsed',
'tracker_show_bank_projection_banner',
'tracker_bank_projection_banner_snoozed_until',
'tracker_show_search_sort',
'tracker_show_summary_cards',
'tracker_show_safe_to_spend',
'tracker_show_overdue_command_center',
'tracker_show_drift_insights',
'tracker_overdue_collapsed',
'tracker_drift_collapsed',
'tracker_table_columns',
'bank_auto_categorize_merchants',
'spending_show_ready_to_assign',
'spending_show_avg',
'spending_show_cover_overspend',
'spending_group_categories',
2026-05-15 22:45:38 -05:00
];
const USER_SETTING_DEFAULTS: Record<string, string> = {
week_start: '0',
default_landing_page: 'tracker',
due_soon_days: '3',
search_bars_collapsed: 'false',
bank_auto_categorize_merchants: 'true',
tracker_show_bank_projection_banner: 'true',
tracker_bank_projection_banner_snoozed_until: '',
tracker_show_search_sort: 'true',
tracker_show_summary_cards: 'true',
tracker_show_safe_to_spend: 'true',
tracker_show_overdue_command_center: 'true',
tracker_show_drift_insights: 'true',
tracker_overdue_collapsed: 'false',
tracker_drift_collapsed: 'false',
tracker_table_columns:
'["due","expected","previous","paid","paid_date","status","action","notes"]',
spending_show_ready_to_assign: 'true',
spending_show_avg: 'true',
spending_show_cover_overspend: 'true',
spending_group_categories: 'false',
};
function defaultUserSettings(): Record<string, any> {
const defaults: Record<string, any> = {};
2026-05-15 22:45:38 -05:00
for (const key of USER_SETTING_KEYS) {
defaults[key] = USER_SETTING_DEFAULTS[key] ?? getSetting(key);
2026-05-15 22:45:38 -05:00
}
return defaults;
}
function getUserSettings(userId: number): Record<string, any> {
const db: Db = getDb();
2026-05-15 22:45:38 -05:00
const settings = defaultUserSettings();
const rows = db
.prepare(
`
2026-05-15 22:45:38 -05:00
SELECT key, value
FROM user_settings
WHERE user_id = ?
`,
)
.all(userId);
2026-05-15 22:45:38 -05:00
for (const row of rows) {
if (USER_SETTING_KEYS.includes(row.key)) settings[row.key] = row.value;
}
return settings;
}
function setUserSettings(userId: number, data: Record<string, any>): Record<string, any> {
const db: Db = getDb();
2026-05-15 22:45:38 -05:00
const upsert = db.prepare(`
INSERT INTO user_settings (user_id, key, value, updated_at)
VALUES (?, ?, ?, datetime('now'))
ON CONFLICT(user_id, key) DO UPDATE SET
value = excluded.value,
updated_at = datetime('now')
`);
const save = db.transaction(() => {
for (const [key, value] of Object.entries(data || {})) {
if (USER_SETTING_KEYS.includes(key)) {
upsert.run(userId, key, String(value));
}
}
});
save();
return getUserSettings(userId);
}
module.exports = {
USER_SETTING_KEYS,
getUserSettings,
setUserSettings,
};