Bulk operations available where needed
Why it matters
When bulk UI affordances (select-all-and-delete, bulk publish, batch price update) exist but the API offers only single-record endpoints, clients must fire N sequential requests to complete the operation. This is both a performance problem (N round trips, N transaction commits) and a data integrity risk: a network failure partway through leaves records in an inconsistent state with no rollback. ISO-25010:2011 performance-efficiency.resource-utilization is directly undermined, and the user experience degrades as dataset size grows.
Severity rationale
Low because the absence of bulk endpoints degrades performance and UX rather than enabling immediate security exploits, but data integrity risk from partial-batch failures can be severe.
Remediation
Add a batch endpoint in app/api/ for each resource type where your UI or business logic already implies multi-record operations. A practical pattern:
// POST /api/messages/bulk
const { action, ids } = bulkSchema.parse(await req.json())
// bulkSchema enforces: action is one of ['delete', 'archive'], ids.length <= 100
if (action === 'delete') {
await db.$transaction(
ids.map((id) => db.message.delete({ where: { id, userId } }))
)
}
Always enforce a maximum batch size (100 records is a reasonable default) to prevent abuse. Wrap all operations in a database transaction so partial failures roll back atomically rather than leaving records in an inconsistent state.
Detection
- ID:
bulk-operations - Severity:
low - What to look for: Enumerate all resource types in the codebase. Identify use cases where multiple records of the same type are likely to be created, updated, or deleted together — look at the app's domain (e.g., a todo app would need bulk complete, a CMS would need bulk publish, an e-commerce app would need bulk price updates). Check whether bulk operation endpoints exist for those use cases. Also check: if bulk ops exist, do they have appropriate limits on the number of records per request?
- Pass criteria: Either (a) at least 1 bulk operation endpoint exists for primary resource types where batch operations are meaningful, or (b) the application domain genuinely does not require batch operations (single-record operations cover all use cases).
- Fail criteria: Client code or UI patterns suggest bulk operations are needed (e.g., "select all and delete" UI exists) but the API requires N individual requests; or bulk operations exist but have no limit on batch size.
- Skip (N/A) when: The application clearly operates on single records by design (e.g., a single-user personal tool, a single-item workflow). Signal: no UI patterns or business logic suggesting multi-record batch operations.
- Detail on fail: Example:
UI supports bulk delete but API requires N individual requests. Describe the gap (e.g., "UI supports bulk delete of messages but API only has DELETE /api/messages/:id, requiring N separate requests"). Max 500 chars. - Remediation: Add bulk operation endpoints in
app/api/for high-value use cases. A practical pattern is a batch endpoint that accepts an array of IDs and an operation:POST /api/messages/bulk { action: "delete", ids: ["id1", "id2"] }. Validate and enforce a maximum batch size (e.g., 100 records per request) to prevent abuse. Wrap bulk operations in a database transaction so they succeed or fail atomically — partial success states are a common source of data integrity issues.
External references
- iso-25010:2011 · performance-efficiency.resource-utilization — Resource Utilization
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-api-design·automated