feat(api): read-all takes an optional up_to cutoff (M489)
release / govulncheck (push) Successful in 16s
release / web (push) Successful in 1m22s
release / go (push) Successful in 1m40s
release / integration (push) Successful in 4m40s
release / android (push) Successful in 5m1s
release / Build signed APK (releases and dev) (push) Successful in 5m12s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 25s
release / Verify release artifacts (tag releases only) (push) Skipped
release / govulncheck (push) Successful in 16s
release / web (push) Successful in 1m22s
release / go (push) Successful in 1m40s
release / integration (push) Successful in 4m40s
release / android (push) Successful in 5m1s
release / Build signed APK (releases and dev) (push) Successful in 5m12s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 25s
release / Verify release artifacts (tag releases only) (push) Skipped
POST /api/me/notifications/read-all accepts {"up_to": RFC3339}. Android
queues "mark all read" for replay when offline, and a replay landing later
must not mark notices that arrived in between, which the user never saw.
A coalesced notice updated since then has a newer created_at, so it stays
unread. An empty body still marks everything.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -214,11 +214,22 @@ func (q *Queries) ListNotifications(ctx context.Context, arg ListNotificationsPa
|
||||
const markAllNotificationsRead = `-- name: MarkAllNotificationsRead :execrows
|
||||
UPDATE user_notifications
|
||||
SET read_at = now()
|
||||
WHERE user_id = $1 AND read_at IS NULL
|
||||
WHERE user_id = $1
|
||||
AND read_at IS NULL
|
||||
AND ($2::timestamptz IS NULL OR created_at <= $2)
|
||||
`
|
||||
|
||||
func (q *Queries) MarkAllNotificationsRead(ctx context.Context, userID pgtype.UUID) (int64, error) {
|
||||
result, err := q.db.Exec(ctx, markAllNotificationsRead, userID)
|
||||
type MarkAllNotificationsReadParams struct {
|
||||
UserID pgtype.UUID
|
||||
UpTo pgtype.Timestamptz
|
||||
}
|
||||
|
||||
// up_to, when set, limits it to what existed when the user asked: a "mark
|
||||
// all read" queued offline and replayed later must not mark notices that
|
||||
// arrived in between, which the user never saw. A coalesced row updated
|
||||
// since then carries a newer created_at, so it stays unread too.
|
||||
func (q *Queries) MarkAllNotificationsRead(ctx context.Context, arg MarkAllNotificationsReadParams) (int64, error) {
|
||||
result, err := q.db.Exec(ctx, markAllNotificationsRead, arg.UserID, arg.UpTo)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user