Geplante Erinnerungen (Feature-Parität mit Urlaubsverwaltung): - APScheduler (AsyncIOScheduler) in der FastAPI-Lifespan; tägliche Jobs ab settings.reminder_hour. Redis-Tageslock gegen Doppelversand bei mehreren Prozessen; jeder Job mit eigener Session + RLS-Bypass. - Drei Jobs (auch einzeln aufrufbar): offene Anträge an Genehmiger, Resturlaub-Verfall-Vorwarnung an Mitarbeiter, fehlende AU an HR. - Pro-User notification_prefs (JSONB, opt-out); GET/PATCH /users/me/notification-prefs + ProfilePage-UI; Vertreter-Mail respektiert die Prefs. - Manueller Trigger POST /companies/me/run-reminders (Admin) – gleiche Logik, firmen-scoped (testbar ohne Warten). - Bugfix: GET-/PATCH-Urlaubskonto (update_balance) nutzte nicht existente Felder (base_days/carried_over_days/ip_address) → korrigiert auf entitled_days/carried_over/ip + company_id; available_days ergänzt. Migration 0037 (users.notification_prefs). 188/188 Tests grün. Deployed 137 + 164. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
25 lines
547 B
Python
25 lines
547 B
Python
"""User notification preferences (agent-11 PR3)
|
|
|
|
Revision ID: 0037
|
|
Revises: 0036
|
|
Create Date: 2026-06-23
|
|
|
|
users.notification_prefs JSONB (opt-out je Benachrichtigungstyp; '{}' = alle an).
|
|
"""
|
|
from alembic import op
|
|
|
|
revision = "0037"
|
|
down_revision = "0036"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.execute(
|
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS notification_prefs JSONB NOT NULL DEFAULT '{}'"
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.execute("ALTER TABLE users DROP COLUMN IF EXISTS notification_prefs")
|