BIO.RE
Notifications

Mark All Notifications Read

Bulk-flip every unread notification for the calling user to read=true. Returns the count actually updated. Scoped to caller — no cross-user leak.

POST /api/v1/notifications/read-all — 🔑 Bearer · Rate limit: 60 req / minute

Bulk-marks all of the calling user's unread notifications as read in a single updateMany. Returns the number of rows actually updated. Server-scopes the update to userId = caller AND read = false, so already-read rows are untouched and no other user's data is affected.

No filtering parameters. This endpoint marks everything unread → read. There is no "mark by event type" or "mark by date range". If you need scoped clearing, iterate over PATCH /:id/read per item from the filtered list.

Request

No body, no params. Identity comes from the bearer token.

HeaderRequiredNotes
Authorization: Bearer <accessToken>JWT from POST /auth/login

Response

200 OKApiResponseOf<MarkAllReadResponseDto>

{
  "success": true,
  "data": {
    "updated": 12
  }
}
FieldTypeNotes
updatednumberCount of rows actually flipped from unread → read. 0 is a normal result when there are no unread notifications.

Errors

HTTPcode / i18nKeyReason
401(guard)Missing / invalid bearer token
429(throttle)Rate limit exceeded (60 req/min)

Side effects

  1. prisma.notification.updateMany({ where: { userId, read: false }, data: { read: true, readAt: new Date() } }).
  2. Return { updated: result.count }. The same readAt timestamp is applied to every row in the batch.
  3. Already-read rows are not touched (filter excludes them, so their original readAt is preserved).

Code samples

curl -X POST https://api.bio.re/api/v1/notifications/read-all \
  -H "Authorization: Bearer $ACCESS_TOKEN"
async function markAllNotificationsRead(accessToken: string): Promise<number> {
  const res = await fetch('https://api.bio.re/api/v1/notifications/read-all', {
    method: 'POST',
    headers: { Authorization: `Bearer ${accessToken}` },
  });
  const json = await res.json();
  if (!res.ok || !json.success) {
    throw Object.assign(new Error(json?.error?.message ?? 'Mark all read failed'), {
      code: json?.error?.code,
    });
  }
  return json.data.updated as number;
}
import { useMutation, useQueryClient } from '@tanstack/react-query';

export function useMarkAllNotificationsRead() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: async () => {
      const res = await fetch('/api/v1/notifications/read-all', { method: 'POST' });
      const json = await res.json();
      if (!res.ok || !json.success) {
        throw Object.assign(new Error(json?.error?.message ?? 'Mark all read failed'), {
          code: json?.error?.code,
          i18nKey: json?.error?.i18nKey,
        });
      }
      return json.data.updated as number;
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['notifications'] });
    },
  });
}

Try it

POST
/api/v1/notifications/read-all
AuthorizationBearer <token>

In: header

Response Body

application/json

application/json

curl -X POST "https://loading/api/v1/notifications/read-all"
{
  "success": true,
  "data": {
    "updated": 0
  }
}
{
  "success": false,
  "error": {
    "code": "AUTH_UNAUTHORIZED",
    "message": "Invalid credentials",
    "i18nKey": "auth.login.invalid_credentials",
    "i18nVars": {
      "field": "email"
    },
    "details": [
      {
        "message": "email must be an email"
      }
    ],
    "correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Source

SourcePathLines
Controller (inline impl)apps/api-core/src/modules/notification/user-notification.controller.ts107–118 (markAllRead — direct Prisma updateMany)
DTO (response)apps/api-core/src/modules/notification/dto/notification-client-response.dto.ts49–52 (MarkAllReadResponseDto)
Prisma modelpackages/prisma/prisma/schema.prismaNotification.read, Notification.readAt

On this page