feat(notify): 站内通知补齐完成、到期逾期与知识事件
CI / backend (push) Waiting to run

This commit is contained in:
Steven
2026-11-10 13:47:56 +08:00
parent 4b7627d70e
commit f54df70811
15 changed files with 791 additions and 32 deletions
+14
View File
@@ -26,6 +26,7 @@ from sqlalchemy import (
Text,
UniqueConstraint,
func,
text,
)
from sqlalchemy.dialects.postgresql import UUID as PgUUID
from sqlalchemy.orm import Mapped, mapped_column
@@ -121,6 +122,16 @@ class Notification(Base, Timestamps):
__table_args__ = (
Index("ix_notification_ws_user_read", "workspace_id", "user_id", "read_at"),
Index("ix_notification_ws_created", "workspace_id", "created_at"),
# 到期/逾期提醒由后台循环生成,可能被重复触发;带 dedupe_key 的写入用
# ON CONFLICT DO NOTHING,把"同一件事只提醒一次"交给数据库保证。
Index(
"uq_notification_dedupe",
"workspace_id",
"user_id",
"dedupe_key",
unique=True,
postgresql_where=text("dedupe_key IS NOT NULL"),
),
)
id: Mapped[uuid.UUID] = mapped_column(PgUUID(as_uuid=True), primary_key=True, default=new_uuid)
@@ -137,6 +148,9 @@ class Notification(Base, Timestamps):
title: Mapped[str] = mapped_column(String(120), nullable=False)
body: Mapped[str] = mapped_column(String(300), nullable=False, default="")
read_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
# 提醒类通知的幂等键(如 task_due_soon:<item>:<due_at>)。
# 普通通知为空,不参与唯一约束。
dedupe_key: Mapped[str | None] = mapped_column(String(120))
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now()
)