Root cause: In apps/backend/src/routes/event.ts, the attendees endpoint fetches the event using a single findUnique with include: { attendees: { skip, take, ... } }. The skip and take clauses are applied to the nested attendees relation, so event.attendees only contains the records for the current page. Line 267 then computes total: event.attendees.length, which gives the count of records on that page (e.g. 10), not the count of all attendees in the database. A caller requesting page 2 gets total: 10 regardless of actual size, making any client-side pagination logic wrong.
Why it matters: Any frontend or mobile client using pagination.total to compute totalPages will show a wrong page count. On the last page with fewer results, total will be even smaller, making it impossible to build correct pagination UI. This is a quiet data correctness bug visible on every paginated attendees request with more than one page of results.
Affected files/functions: apps/backend/src/routes/event.ts, the GET /api/events/:slug/attendees handler, line 267.
Current behaviour: pagination.total equals event.attendees.length which is bounded by take (max 50). A 200-person event with limit=10 returns total: 10 on page 1, total: 10 on page 2, etc.
Expected behaviour: pagination.total should equal the real number of attendees for the event. If there are 200 attendees and you request page 2 with limit 10, total should be 200.
Minimal fix plan:
Replace the single findUnique with two queries run in parallel via Promise.all: (1) the existing paginated findUnique for the attendee page, and (2) a prisma.eventAttendee.count({ where: { eventId: event.id } }) for the real total. Use the count result in the pagination.total field. This requires a preliminary lookup of the event ID, which is already done anyway since the event is fetched first for the 404 check — use that event.id to run the count.
Suggested tests: Add a test in event.test.ts that mocks a full 25-attendee event, requests page 1 with limit 10, and asserts pagination.total === 25 (not 10). Also assert pagination.page === 1 and pagination.limit === 10.
Root cause: In
apps/backend/src/routes/event.ts, the attendees endpoint fetches the event using a singlefindUniquewithinclude: { attendees: { skip, take, ... } }. Theskipandtakeclauses are applied to the nestedattendeesrelation, soevent.attendeesonly contains the records for the current page. Line 267 then computestotal: event.attendees.length, which gives the count of records on that page (e.g. 10), not the count of all attendees in the database. A caller requesting page 2 getstotal: 10regardless of actual size, making any client-side pagination logic wrong.Why it matters: Any frontend or mobile client using
pagination.totalto computetotalPageswill show a wrong page count. On the last page with fewer results,totalwill be even smaller, making it impossible to build correct pagination UI. This is a quiet data correctness bug visible on every paginated attendees request with more than one page of results.Affected files/functions:
apps/backend/src/routes/event.ts, theGET /api/events/:slug/attendeeshandler, line 267.Current behaviour:
pagination.totalequalsevent.attendees.lengthwhich is bounded bytake(max 50). A 200-person event withlimit=10returnstotal: 10on page 1,total: 10on page 2, etc.Expected behaviour:
pagination.totalshould equal the real number of attendees for the event. If there are 200 attendees and you request page 2 with limit 10,totalshould be200.Minimal fix plan:
Replace the single
findUniquewith two queries run in parallel viaPromise.all: (1) the existing paginatedfindUniquefor the attendee page, and (2) aprisma.eventAttendee.count({ where: { eventId: event.id } })for the real total. Use the count result in thepagination.totalfield. This requires a preliminary lookup of the event ID, which is already done anyway since the event is fetched first for the 404 check — use thatevent.idto run the count.Suggested tests: Add a test in
event.test.tsthat mocks a full 25-attendee event, requests page 1 with limit 10, and assertspagination.total === 25(not 10). Also assertpagination.page === 1andpagination.limit === 10.