f0dbabc409
CI / Build, lint & test (push) Failing after 58s
New notifications table (migration 0009) stores event-driven alerts alongside the existing dynamic state notifications (unclaimed objectives, expiring loans, season ending soon). Persistent notifications are created automatically during match processing: one per level gained, one per expired loan card, one per objective newly completed, and one when a season ends (with promotion/relegation result and rewards in the body). GET /notifications now returns a merged list — persistent entries (newest-first, limit 50) followed by dynamic entries — plus an unread_count for the badge. Each item carries type, title, body, is_read, and (for persistent) id and created_at. PATCH /notifications/:id/read marks a single persistent notification read. POST /notifications/read-all marks all persistent ones read. Four new tests: unread_count field, level-up notification creation, mark-all-read, single-read PATCH. Core now at 77 tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
26 lines
610 B
Rust
26 lines
610 B
Rust
use serde::Serialize;
|
|
use uuid::Uuid;
|
|
|
|
#[derive(Debug, Clone, Serialize, sqlx::FromRow)]
|
|
pub struct Notification {
|
|
pub id: String,
|
|
pub kind: String,
|
|
pub title: String,
|
|
pub body: String,
|
|
pub is_read: bool,
|
|
pub created_at: String,
|
|
}
|
|
|
|
impl Notification {
|
|
pub fn new(kind: &str, title: &str, body: &str) -> Self {
|
|
Self {
|
|
id: Uuid::new_v4().to_string(),
|
|
kind: kind.to_string(),
|
|
title: title.to_string(),
|
|
body: body.to_string(),
|
|
is_read: false,
|
|
created_at: chrono::Utc::now().to_rfc3339(),
|
|
}
|
|
}
|
|
}
|