Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
"rank": "everyone",
"leaderboard": "everyone",
"profile": "everyone",
"remind": "everyone",
"challenge": "everyone",
"review": "everyone",
"showcase": "everyone"
Expand Down Expand Up @@ -260,5 +261,9 @@
"channelId": null,
"staleAfterDays": 7,
"xpReward": 50
},
"reminders": {
"enabled": false,
"maxPerUser": 25
}
}
}
46 changes: 46 additions & 0 deletions migrations/015_reminders.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Migration 015 — Reminders
* Creates the reminders table for the personal reminder system.
*
* @see https://github.com/VolvoxLLC/volvox-bot/issues/137
*/

'use strict';

/**
* @param {import('pg').Pool} pool
*/
async function up(pool) {
await pool.query(`
CREATE TABLE IF NOT EXISTS reminders (
id SERIAL PRIMARY KEY,
guild_id VARCHAR NOT NULL,
user_id VARCHAR NOT NULL,
channel_id VARCHAR NOT NULL,
message TEXT NOT NULL,
remind_at TIMESTAMPTZ NOT NULL,
recurring_cron VARCHAR,
snoozed_count INT NOT NULL DEFAULT 0,
failed_delivery_count INT NOT NULL DEFAULT 0,
completed BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
`);

await pool.query(`
CREATE INDEX IF NOT EXISTS idx_reminders_due
ON reminders(remind_at) WHERE completed = false;
`);

await pool.query(`
CREATE INDEX IF NOT EXISTS idx_reminders_user_active
ON reminders(guild_id, user_id) WHERE completed = false;
`);

await pool.query(`
CREATE INDEX IF NOT EXISTS idx_reminders_user
ON reminders(guild_id, user_id, completed);
`);
}

module.exports = { up };
1 change: 1 addition & 0 deletions src/api/utils/configAllowlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const SAFE_CONFIG_KEYS = new Set([
'github',
'challenges',
'review',
'reminders',
]);

export const READABLE_CONFIG_KEYS = [...SAFE_CONFIG_KEYS, 'logging'];
Expand Down
11 changes: 10 additions & 1 deletion src/api/utils/configValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,13 @@ export const CONFIG_SCHEMA = {
moderationLogChannel: { type: 'string', nullable: true },
},
},
reminders: {
type: 'object',
properties: {
enabled: { type: 'boolean' },
maxPerUser: { type: 'number' },
},
},
};

/**
Expand Down Expand Up @@ -193,7 +200,9 @@ export function validateValue(value, schema, path) {
}
} else if (schema.items.type === 'object') {
if (typeof item !== 'object' || item === null || Array.isArray(item)) {
errors.push(`${path}[${i}]: expected object, got ${Array.isArray(item) ? 'array' : item === null ? 'null' : typeof item}`);
errors.push(
`${path}[${i}]: expected object, got ${Array.isArray(item) ? 'array' : item === null ? 'null' : typeof item}`,
);
} else if (schema.items.required) {
for (const key of schema.items.required) {
if (!(key in item)) {
Expand Down
Loading