Implement automatic reminder engine with admin and company UI.
Add schema v6, read-only scan rules for unsubmitted flows, gaps and pending reviews, deduplicated delivery with append-only event history, daily scan thread, and full API/frontend integration with 18 new tests. Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Cursor
multica-agent
parent
951b353765
commit
f17636183d
@@ -569,6 +569,78 @@ MIGRATIONS: tuple[Migration, ...] = (
|
||||
ALTER TABLE import_batches DROP COLUMN upload_bank_account_id;
|
||||
""",
|
||||
),
|
||||
Migration(
|
||||
version=6,
|
||||
name="0006_reminders",
|
||||
up="""
|
||||
CREATE TABLE reminder_settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO reminder_settings (key, value, updated_at) VALUES
|
||||
('monthly_start_day', '5', datetime('now')),
|
||||
('gap_days', '5', datetime('now')),
|
||||
('scan_time', '08:00', datetime('now'));
|
||||
|
||||
CREATE TABLE reminders (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
company_id INTEGER NOT NULL REFERENCES companies (id),
|
||||
rule_key TEXT NOT NULL CHECK (rule_key IN (
|
||||
'unsubmitted', 'gap', 'pending_review', 'manual'
|
||||
)),
|
||||
dedupe_key TEXT NOT NULL UNIQUE,
|
||||
rule_params TEXT NOT NULL DEFAULT '{}',
|
||||
title TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
deadline TEXT,
|
||||
source TEXT NOT NULL CHECK (source IN ('auto', 'manual')),
|
||||
status TEXT NOT NULL DEFAULT 'open'
|
||||
CHECK (status IN ('open', 'acknowledged', 'resolved')),
|
||||
send_count INTEGER NOT NULL DEFAULT 0,
|
||||
first_sent_at TEXT,
|
||||
last_sent_at TEXT,
|
||||
created_by TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
action_link TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX idx_reminders_company ON reminders (company_id);
|
||||
CREATE INDEX idx_reminders_status ON reminders (status);
|
||||
|
||||
CREATE TABLE reminder_events (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
reminder_id INTEGER NOT NULL REFERENCES reminders (id),
|
||||
event_type TEXT NOT NULL CHECK (event_type IN (
|
||||
'sent', 'acknowledged', 'resolved', 'escalated'
|
||||
)),
|
||||
actor TEXT NOT NULL,
|
||||
detail TEXT,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_reminder_events_reminder ON reminder_events (reminder_id);
|
||||
|
||||
CREATE TRIGGER reminder_events_no_update BEFORE UPDATE ON reminder_events
|
||||
BEGIN SELECT RAISE (ABORT, 'reminder_events rows are append-only'); END;
|
||||
CREATE TRIGGER reminder_events_no_delete BEFORE DELETE ON reminder_events
|
||||
BEGIN SELECT RAISE (ABORT, 'reminder_events rows are append-only'); END;
|
||||
CREATE TRIGGER reminders_no_delete BEFORE DELETE ON reminders
|
||||
BEGIN SELECT RAISE (ABORT, 'reminders rows are immutable history'); END;
|
||||
""",
|
||||
down="""
|
||||
DROP TRIGGER IF EXISTS reminders_no_delete;
|
||||
DROP TRIGGER IF EXISTS reminder_events_no_delete;
|
||||
DROP TRIGGER IF EXISTS reminder_events_no_update;
|
||||
DROP INDEX IF EXISTS idx_reminder_events_reminder;
|
||||
DROP TABLE IF EXISTS reminder_events;
|
||||
DROP INDEX IF EXISTS idx_reminders_status;
|
||||
DROP INDEX IF EXISTS idx_reminders_company;
|
||||
DROP TABLE IF EXISTS reminders;
|
||||
DROP TABLE IF EXISTS reminder_settings;
|
||||
""",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user