fix(schedule): route daily set-remind phrases through ITL with recurrence
Memind CI / Test, build, and release guards (push) Failing after 3m4s
Memind CI / Test, build, and release guards (push) Failing after 3m4s
Support colloquial forms like「设置每天18:00提醒打卡」, persist daily metadata on commit, and schedule the next reminder after each delivery. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -29,6 +29,16 @@ function nowMs() {
|
||||
|
||||
function rowToItem(row) {
|
||||
if (!row) return null;
|
||||
let metadata = null;
|
||||
if (row.metadata_json != null && row.metadata_json !== '') {
|
||||
try {
|
||||
metadata = typeof row.metadata_json === 'object'
|
||||
? row.metadata_json
|
||||
: JSON.parse(row.metadata_json);
|
||||
} catch {
|
||||
metadata = null;
|
||||
}
|
||||
}
|
||||
return {
|
||||
id: row.id,
|
||||
userId: row.user_id,
|
||||
@@ -42,6 +52,7 @@ function rowToItem(row) {
|
||||
allDay: Boolean(row.all_day),
|
||||
timezone: row.timezone || DEFAULT_TIMEZONE,
|
||||
location: row.location ?? null,
|
||||
metadata,
|
||||
createdAt: Number(row.created_at),
|
||||
updatedAt: Number(row.updated_at),
|
||||
};
|
||||
@@ -660,6 +671,28 @@ export function createScheduleService(pool, options = {}) {
|
||||
return { ...reminder, status: 'sent', sentAt: now, lockedUntil: null };
|
||||
};
|
||||
|
||||
const scheduleNextDailyReminder = async (reminder) => {
|
||||
if (!reminder?.userId || !reminder?.itemId) return null;
|
||||
const item = await getItem({ userId: reminder.userId, itemId: reminder.itemId });
|
||||
if (!item || item.status !== 'active' || item.metadata?.recurrence !== 'daily') return null;
|
||||
const hour = Number(item.metadata.dailyHour);
|
||||
const minute = Number(item.metadata.dailyMinute ?? 0);
|
||||
if (!Number.isInteger(hour) || hour < 0 || hour > 23) return null;
|
||||
if (!Number.isInteger(minute) || minute < 0 || minute > 59) return null;
|
||||
const remindAt = nextDailyRunAt({
|
||||
hour,
|
||||
minute,
|
||||
timezone: item.timezone || defaultTimezone,
|
||||
now: clock.now() + 1000,
|
||||
});
|
||||
return createReminder({
|
||||
userId: reminder.userId,
|
||||
itemId: item.id,
|
||||
remindAt,
|
||||
channel: reminder.channel ?? 'wechat',
|
||||
});
|
||||
};
|
||||
|
||||
const markReminderCancelled = async (reminder, reason, { now = clock.now() } = {}) => {
|
||||
const lastError = String(reason ?? '已取消').slice(0, 500);
|
||||
await pool.query(
|
||||
@@ -978,6 +1011,7 @@ export function createScheduleService(pool, options = {}) {
|
||||
listDueReminders,
|
||||
lockReminder,
|
||||
markReminderSent,
|
||||
scheduleNextDailyReminder,
|
||||
markReminderCancelled,
|
||||
markReminderFailed,
|
||||
buildReminderText,
|
||||
|
||||
Reference in New Issue
Block a user