feat(telegram): add prompt-context table for mood-note correlation

Add TelegramPromptContext (migration 0187) mapping a bot force-reply
prompt to the entry a free-text reply attaches to, keyed on
(chatId, promptMsgId) and scoped to the owning user. MoodEntry.source
already accepts the free-text TELEGRAM value, so no enum change is
needed.
This commit is contained in:
Marc-André Bombeck committed 2026-06-21 11:13:17 +02:00
1 parent 9cc84e2209
commit 7f7ee2c013
2 files changed
+47

No files matched your search

@@ -0,0 +1,20 @@
-- v1.19.0 — force-reply correlation for the interactive mood reminder.
-- Maps a bot prompt message to the entry a free-text reply attaches to.
CREATE TABLE "telegram_prompt_contexts" (
"id" TEXT NOT NULL,
"user_id" TEXT NOT NULL,
"chat_id" TEXT NOT NULL,
"prompt_msg_id" INTEGER NOT NULL,
"kind" TEXT NOT NULL,
"ref_id" TEXT NOT NULL,
"expires_at" TIMESTAMP(3) NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "telegram_prompt_contexts_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "telegram_prompt_contexts_chat_id_prompt_msg_id_key" ON "telegram_prompt_contexts"("chat_id", "prompt_msg_id");
-- CreateIndex
CREATE INDEX "telegram_prompt_contexts_expires_at_idx" ON "telegram_prompt_contexts"("expires_at");
+27
View File
@@ -2262,6 +2262,33 @@ model TelegramScheduledDeletion {
@@map("telegram_scheduled_deletions")
}
// v1.19.0 — force-reply correlation for the interactive mood reminder.
//
// When a user taps "Notiz…" on a mood prompt the bot sends a force_reply
// message; the user's free-text reply then arrives as a normal `message`
// whose `reply_to_message.message_id` points back at that prompt. This
// row maps `(chatId, promptMessageId)` to the mood entry the note should
// attach to, so the inbound note handler can resolve "what was this a
// reply to" without trusting any client-supplied id. Rows are short-lived
// (`expiresAt`) and best-effort deleted once consumed; the deletion sweep
// is keyed on `expiresAt` so an unanswered note prompt self-cleans.
model TelegramPromptContext {
id String @id @default(cuid())
userId String @map("user_id")
chatId String @map("chat_id")
// The bot's prompt message the user is expected to reply to.
promptMsgId Int @map("prompt_msg_id")
// What the reply attaches to. "mood_note" carries `refId = moodEntryId`.
kind String
refId String @map("ref_id")
expiresAt DateTime @map("expires_at")
createdAt DateTime @default(now()) @map("created_at")
@@unique([chatId, promptMsgId])
@@index([expiresAt])
@@map("telegram_prompt_contexts")
}
// ─── API Tokens (for external ingest) ──────────────────────
model ApiToken {