feat(calendar): v5.8.0 calendrier & rappels + v5.7.0 database avancee (pt.2)
FlowDeck CI / lint (push) Successful in 49s
FlowDeck CI / test (push) Successful in 5m26s
FlowDeck CI / docker (push) Successful in 43s

v5.8.0 (release 5.11.7) — Calendrier & Rappels :
- moteur de recurrence RRULE subset (daily/weekly/monthly, interval,
  count, until, byweekday, timezone) — app/services/recurrence.py
- vues calendar Jour / Semaine / Mois avec expansion des occurrences
  cote serveur (GET /db/{id}/calendar/api) et popover evenement
  (Time / Timezone / Repeat / Remind)
- rappels avant echeance (scan 60 s, table reminder_log, in-app +
  email, cible = personnes assignees) — app/services/reminders.py
- fuseaux horaires : users.timezone + reglages in-app, timezone par
  evenement, liste de zones (GET /db/timezones/api)
- notifications d'assignation sur PUT /db/pages/{id}/api et
  preferences etendues (reminders, assignments)
- template Meeting notes enrichi (Agenda, Notes — migration 12)
- migrations 11-12 ; 20 tests dedies ; suite complete 523 verte

v5.7.0 (release 5.11.6, termine avant cette session, reste dans
l'arbre sans commit) — Database Avancée Pt.2 :
- proprietes person + auto-proprietes (created/last-edited time & by)
- groupes de proprietes, vues sauvegardees par utilisateur
- swimlanes, WIP limits, cartes configurables, calendar drag & drop,
  gallery couvertures ; 12 tests dedies
This commit is contained in:
2026-09-13 22:49:14 -04:00
parent 055956a351
commit d4adf89db5
18 changed files with 3301 additions and 366 deletions
+27 -1
View File
@@ -97,13 +97,39 @@ async def set_prefs(request: Request):
from app.services import notifications as notif
body = await request.json() if request.headers.get("content-type") else {}
prefs = notif.get_user_prefs(user["id"])
for key in ("comments", "mentions"):
for key in ("comments", "mentions", "reminders", "assignments"):
if key in body:
prefs[key] = bool(body[key])
notif.set_user_prefs(user["id"], prefs)
return {"status": "ok", "prefs": prefs}
@router.get("/timezone")
async def get_timezone(request: Request):
"""Return the current user's IANA timezone ('' = UTC)."""
user = _current_user(request)
with get_conn() as conn:
row = conn.execute("SELECT timezone FROM users WHERE id=?", (user["id"],)).fetchone()
tz = (row["timezone"] if row and "timezone" in row.keys() else "") or ""
from app.services.recurrence import common_timezones
return {"timezone": tz, "zones": common_timezones()}
@router.post("/timezone")
async def set_timezone(request: Request):
"""Update the current user's IANA timezone (empty string = UTC)."""
user = _current_user(request)
body = await request.json() if request.headers.get("content-type") else {}
tz = (body.get("timezone") or "").strip()
from app.services.recurrence import is_valid_timezone
if tz and not is_valid_timezone(tz):
raise HTTPException(status_code=400, detail=f"Unknown timezone '{tz}'")
with get_conn() as conn:
conn.execute("UPDATE users SET timezone=? WHERE id=?", (tz, user["id"]))
conn.commit()
return {"status": "ok", "timezone": tz}
@router.get("/users/search")
async def search_users(request: Request, q: str = ""):
"""User autocomplete for @mentions."""