Severity: Low (performance / scalability)
Both are fine at today's data volumes; worth addressing before scale.
-
Per-row INSERT loops. TicketRepository.insertItems / replaceItems insert ticket items one statement at a time in a for loop (backend/src/main/java/th/co/glr/hr/ticket/TicketRepository.java:260). Use NamedParameterJdbcTemplate.batchUpdate for a single round-trip. (reWriteBatchedInserts=true is already set on the datasource, so this pays off immediately.)
-
List endpoints return everything (no pagination). GET /api/employees (EmployeeRepository.findEmployees) and GET /api/tickets have no LIMIT/offset or keyset pagination. Response and memory grow linearly with the table. Add pagination + a sane default page size.
Non-issues confirmed during review (no action): EmployeeService.list batches pending-counts (no N+1); ticket detail is a bounded 4-query fetch; the frontend parallelizes initial loads with Promise.all.
Severity: Low (performance / scalability)
Both are fine at today's data volumes; worth addressing before scale.
Per-row INSERT loops.
TicketRepository.insertItems/replaceItemsinsert ticket items one statement at a time in aforloop (backend/src/main/java/th/co/glr/hr/ticket/TicketRepository.java:260). UseNamedParameterJdbcTemplate.batchUpdatefor a single round-trip. (reWriteBatchedInserts=trueis already set on the datasource, so this pays off immediately.)List endpoints return everything (no pagination).
GET /api/employees(EmployeeRepository.findEmployees) andGET /api/ticketshave noLIMIT/offset or keyset pagination. Response and memory grow linearly with the table. Add pagination + a sane default page size.Non-issues confirmed during review (no action):
EmployeeService.listbatches pending-counts (no N+1); ticket detail is a bounded 4-query fetch; the frontend parallelizes initial loads withPromise.all.