Skip to content

Implement batch delete operation for CRUD API#614

Open
Copilot wants to merge 5 commits into
mainfrom
copilot/implement-delete-many-operation
Open

Implement batch delete operation for CRUD API#614
Copilot wants to merge 5 commits into
mainfrom
copilot/implement-delete-many-operation

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Dec 24, 2025

Adds DELETE /records/{resource}/many endpoint to delete multiple records in a single request.

Implementation

  • dynamodb.rs:

    • Added delete_many() using batch_write_item API with chunking (25 items per batch) and exponential backoff retry for unprocessed items
    • Enhanced get_many() with 100-item chunking and retry logic for unprocessed keys
    • Both functions now return errors (not warnings) when unprocessed items/keys remain after retries
    • Returns deleted IDs in sorted order for deterministic responses
    • Added 9 unit tests covering chunking behavior for both functions
  • main.rs:

    • Added delete_many_records_handler with user ownership verification
    • Accepts query params: ?id=id1&id=id2&id=id3
    • Enforces maximum of 100 IDs per request (returns 400 Bad Request if exceeded)
    • Detects and rejects duplicate IDs with clear error message (400 Bad Request)
    • Returns 503 Service Unavailable for throttling errors instead of 500
    • Returns {"deleted": [...], "count": n} with IDs in sorted order

Usage

DELETE /records/streams/many?id=abc123&id=def456&id=ghi789

{
  "deleted": ["abc123", "def456", "ghi789"],
  "count": 3
}

Features

  • Automatic Chunking: Handles DynamoDB batch limits (25 for writes, 100 for reads)
  • Retry Logic: Exponential backoff (100ms, 200ms, 400ms) for throttled requests
  • Robust Error Handling: Returns 503 for throttling, fails operation if unprocessed items remain after retries
  • Security: Verifies all requested IDs exist and belong to user for user-scoped resources
  • Validation: Returns 404 if any ID not found, 403 if not owned, 400 if >100 IDs requested or duplicates provided
  • Deterministic Responses: Returns deleted IDs in sorted order for consistent behavior

Testing

  • ✅ 11 unit tests pass (9 new tests for chunking logic)
  • ✅ Code builds successfully
  • ✅ Clippy checks pass
Original prompt

This section details on the original issue you should resolve

<issue_title>Implement delete many operation</issue_title>
<issue_description>in our crud_api service, so that we can delete multiple records in a single request from the frontend.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Add delete many operation to CRUD API service Implement batch delete operation for CRUD API Dec 24, 2025
Copilot AI requested a review from saebyn December 24, 2025 16:56
@saebyn saebyn force-pushed the copilot/implement-delete-many-operation branch from 78041e9 to 5a83c9f Compare December 24, 2025 19:44
@saebyn saebyn marked this pull request as ready for review December 24, 2025 19:44
Copilot AI review requested due to automatic review settings December 24, 2025 19:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a batch delete operation for the CRUD API, adding a DELETE /records/{resource}/many endpoint that allows deletion of multiple records in a single request using query parameters.

Key Changes:

  • Adds delete_many() function in dynamodb.rs that uses DynamoDB's batch_write_item API with automatic chunking (25 items per batch)
  • Adds delete_many_records_handler() in main.rs with ownership verification for user-scoped resources
  • Updates route configuration to support DELETE method on /records/{resource}/many endpoint

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
crud_api/src/dynamodb.rs Implements delete_many() function using DynamoDB batch_write_item API with chunking and unprocessed item tracking
crud_api/src/main.rs Adds delete_many_records_handler() with user ownership verification, updates route to include DELETE method, and modifies unused parameter naming in get_many_related_records_handler

Comment thread crud_api/src/dynamodb.rs Outdated
Comment thread crud_api/src/dynamodb.rs
Comment thread crud_api/src/main.rs
Comment thread crud_api/src/main.rs Outdated
Comment thread crud_api/src/main.rs Outdated
Comment thread crud_api/src/main.rs Outdated
Comment thread crud_api/src/dynamodb.rs Outdated
@saebyn saebyn force-pushed the copilot/implement-delete-many-operation branch from 5a83c9f to c332e00 Compare February 8, 2026 18:39
@saebyn
Copy link
Copy Markdown
Owner

saebyn commented Feb 8, 2026

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

Comment thread crud_api/src/main.rs
Comment thread crud_api/src/dynamodb.rs
Comment thread crud_api/src/dynamodb.rs
@saebyn
Copy link
Copy Markdown
Owner

saebyn commented Feb 9, 2026

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

Comment thread crud_api/src/dynamodb.rs Outdated
Comment thread crud_api/src/dynamodb.rs
Comment thread crud_api/src/main.rs
Comment on lines +733 to +757
let ids = query_params
.id
.iter()
.map(String::as_str)
.collect::<Vec<_>>();

// Enforce a maximum of 100 IDs per request to align with DynamoDB batch limits
if ids.len() > 100 {
return (
StatusCode::BAD_REQUEST,
[(header::CONTENT_TYPE, "application/json")],
Json(json!({
"message": "Too many IDs provided. Maximum of 100 IDs per request.",
})),
);
}

// If user_scoped, verify ownership of all items before deleting
if table_config.user_scoped {
match dynamodb::get_many(&state.dynamodb, &table_config, &ids).await {
Ok(items) => {
if let Some(user) = &user_id {
// Verify all requested IDs exist and belong to the user
if items.len() != ids.len() {
return (
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete_many_records_handler treats duplicate IDs as an error because items.len() != ids.len() will trip even when all records exist (BatchGet returns one item per unique key). Consider de-duplicating the requested IDs (while optionally preserving original order) before doing existence/ownership checks and before calling delete_many, or return a 400 with a clear message when duplicates are provided.

Copilot uses AI. Check for mistakes.
Comment thread crud_api/src/dynamodb.rs Outdated
Comment thread crud_api/src/dynamodb.rs Outdated
@saebyn
Copy link
Copy Markdown
Owner

saebyn commented Mar 30, 2026

@copilot apply changes based on the comments in this thread

Copilot AI and others added 2 commits March 29, 2026 19:46
Co-authored-by: saebyn <185030+saebyn@users.noreply.github.com>
…fy deletion tracking

Co-authored-by: saebyn <185030+saebyn@users.noreply.github.com>
Copilot AI and others added 3 commits March 29, 2026 19:46
… fix security gap, and improve consistency

Co-authored-by: saebyn <185030+saebyn@users.noreply.github.com>
… chunking logic

Co-authored-by: saebyn <185030+saebyn@users.noreply.github.com>
…lts, return 503 on errors

Agent-Logs-Url: https://github.com/saebyn/glowing-telegram/sessions/328fedef-f215-42a7-81f1-18941b6f2c7e

Co-authored-by: saebyn <185030+saebyn@users.noreply.github.com>
@saebyn saebyn force-pushed the copilot/implement-delete-many-operation branch from aa2dbb5 to 1274a4e Compare March 30, 2026 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement delete many operation

3 participants