Feat/sqs batch operations and queue management (#72)#96
Feat/sqs batch operations and queue management (#72)#96alancoosta wants to merge 7 commits intoDaviReisVieira:mainfrom
Conversation
…batch-operations-and-queue-management
DaviReisVieira
left a comment
There was a problem hiding this comment.
Hey @alancoosta, thanks for this awesome PR! 🎉 This is a massive contribution — full SQS queue management, batch operations, DLQ auto-creation, favorites system, and 34 backend tests. Really impressive scope and quality overall.
I did a thorough review and wanted to share some findings. Here's the breakdown:
Bugs
1. 🔴 CRITICAL — DLQ auto-creation gets empty ARN (backend/routes/sqs.py:189)
The SQS create_queue API only returns QueueUrl, never QueueArn. This means dlq_arn will always be "", producing a broken redrive policy with deadLetterTargetArn: "".
# Current (broken):
dlq_arn = dlq_response.get("QueueArn", "")
# Fix — fetch ARN after creation (like the "DLQ already exists" branch does):
dlq_url = dlq_response["QueueUrl"]
dlq_attrs = client.get_queue_attributes(QueueUrl=dlq_url, AttributeNames=["QueueArn"])
dlq_arn = dlq_attrs["Attributes"]["QueueArn"]The same issue exists on line 220 for the main queue's ARN (queue_arn = response.get("QueueArn", "")).
2. 🟡 Redundant get_queue_url call (backend/routes/sqs.py:170-172)
Two consecutive identical calls — the first result is discarded:
client.get_queue_url(QueueName=dlq_queue_name) # line 170 — result thrown away
dlq_url_response = client.get_queue_url(QueueName=dlq_queue_name) # line 172 — same call3. 🟡 window.prompt() / window.confirm() mixed with Sheet confirmations (SQSBrowser.tsx:2133, 1631)
The PR adds great Sheet-based confirmation dialogs for purge/delete queue/delete favorite, but then uses window.prompt("Type DELETE...") for batch message deletion and window.confirm() for single message deletion. This breaks the dark theme UX and is inconsistent. Both should use Sheet-based confirmations matching the other patterns in the PR.
4. 🟡 EditSettingsSheet always sends redrive policy update (SQSBrowser.tsx:726-734)
When dlqEnabled is false, it calls updateSQSRedrivePolicy(queue.name, null) which sends {"deadLetterTargetArn": null, "maxReceiveCount": null}. The backend then raises 400 because deadLetterTargetArn is empty (line 690-691). This causes a toast error every time you save settings on a queue without a DLQ. Fix: only call updateSQSRedrivePolicy when the DLQ state actually changed.
Code Quality
5. No Pydantic models for request bodies
All new endpoints use body: dict[str, Any] with manual validation. Other routes (dynamodb.py, s3.py) use Pydantic BaseModel classes — which gives automatic validation, better /api/docs output, and type safety. Not a blocker but a deviation from project conventions.
6. SQSBrowser.tsx is 3,025 lines
Nearly 3x the largest existing browser (S3Browser.tsx at 1,163 lines). I see the PR description acknowledges this. The 10+ sub-components (CreateQueueSheet, SendMessageSheet, EditSettingsSheet, etc.) would benefit from extraction to separate files. Could be a follow-up.
7. Duplicated queue card rendering
The queue card JSX is nearly identical between the favorites section (lines 2871-2923) and the all-queues section (lines 2934-2997). A shared QueueCard component would eliminate the duplication.
8. Redundant .filter() on already-filtered data (SQSBrowser.tsx:2937)
{paginatedQueues
.filter((queue) => !favorites.has(queue.name)) // redundant — paginatedQueues comes from nonFavoriteQueues
.map((queue) => { ... })}paginatedQueues is sliced from nonFavoriteQueues which already excludes favorites.
Missing from Issue #72
- Batch send FIFO params: The batch send sheet doesn't pass
messageGroupIdormessageDeduplicationIdthrough to the backend. OnlyidandmessageBodyare extracted (line 964-975). The issue calls for "per-message delay and attributes." - Test for DLQ auto-creation path: This is why the ARN bug wasn't caught. A test with
dlqEnabled=truewould verify the full flow.
Files to Reconsider
SQS_FEATURES_README.md— Duplicates the PR description content. The PR description is the right place for this; the file shouldn't go into the repo.Makefile— Introduces a new build system not documented inCLAUDE.md, duplicating existing instructions. If desired, it should be a separate PR.
What Looks Great
- Backend architecture follows the existing patterns perfectly (router,
get_client, error handling) - 34 tests with good coverage of happy paths, validation, 404s, batch limits, partial failures
- TypeScript types are clean and well-structured
- Favorites system is a nice UX addition beyond the issue scope
- DLQ auto-creation is a thoughtful convenience feature
- Queue favorites (pinning) is a nice touch
- Export dropdown integration
- All ESLint/TypeScript checks pass clean (no new errors)
Priority Summary
| Priority | Item |
|---|---|
| P0 | Fix DLQ ARN bug (lines 189, 220) |
| P1 | Fix redundant get_queue_url (line 170) |
| P1 | Fix EditSettingsSheet null redrive policy causing 400 |
| P1 | Replace window.prompt/window.confirm with Sheets |
| P1 | Add test for DLQ auto-creation |
| P2 | Remove SQS_FEATURES_README.md and Makefile |
| P2 | Pass FIFO params through batch send |
| P2 | Remove redundant .filter() |
| P3 | Extract sub-components (can be follow-up) |
| P3 | Deduplicate queue card JSX |
| P3 | Consider Pydantic models (can be follow-up) |
This is really great work — the feature is comprehensive and well thought out. If you'd like any help tackling these fixes, I'm happy to jump in and help get this across the finish line. Or if you'd prefer to handle it yourself, totally works too — just let me know! 🚀
|
@DaviReisVieira Thank you!! One more suggestion for this PR is to create an option "Brach Create Queues" |
|
Closing this cross-fork PR — reopening from the main repo branch to fix CI targeting the wrong merge ref. All original work preserved, plus additional improvements (schema extraction, UI polish, multi-endpoint fixes). |

Summary
Implements full SQS queue management in StackPort: create/delete queues (Standard & FIFO), batch message operations (send/delete), queue attributes editing, dead-letter queue (DLQ) auto-creation, and a favorites system for saving message templates. Compatible with LocalStack, MiniStack, Moto, or any AWS-compatible endpoint.
Closes #72
What changed
Backend (
backend/routes/sqs.py)GET/api/sqs/queuesPOST/api/sqs/queuesGET/api/sqs/queues/{queue_name}DELETE/api/sqs/queues/{queue_name}PUT/api/sqs/queues/{queue_name}/attributesPUT/api/sqs/queues/{queue_name}/redrive-policyPOST/api/sqs/queues/{queue_name}/purgePOST/api/sqs/queues/{queue_name}/messagesPOST/api/sqs/queues/{queue_name}/messages/batchGET/api/sqs/queues/{queue_name}/messagesDELETE/api/sqs/queues/{queue_name}/messagesDELETE/api/sqs/queues/{queue_name}/messages/batchKey features:
.fifosuffix appended{queueName}-dlq(or.fifofor FIFO queues) is automatically createdFrontend (
ui/src/components/service-views/SQSBrowser.tsx)All components were created inside this component; we could move to another folder's components as soon.
Queue Management:
.fifosuffix (user can still type it manually)Message Operations:
Favorites System:
UI Components:
Hooks (
ui/src/hooks/useSQSFavoriteMessages.ts)addFavorite,addFavorites,removeFavorite,updateFavoriteAPI (
ui/src/lib/api.ts)New SQS functions:
fetchSQSQueues,fetchSQSQueueDetailcreateSQSQueue,deleteSQSQueuesendSQSMessage,sendSQSMessagesBatchreceiveSQSMessages,deleteSQSMessage,deleteSQSMessagesBatchpurgeSQSQueueupdateSQSQueueAttributes,updateSQSRedrivePolicyTypes (
ui/src/lib/types.ts)New interfaces:
SQSQueue,SQSQueueDetailSQSMessage,SQSSendMessageRequestSQSCreateQueueRequest,SQSCreateQueueResponseSQSBatchSendRequest,SQSBatchSendResponseSQSUpdateAttributesRequestSQSFavoriteMessageTests (
tests/test_sqs_routes.py)Comprehensive backend tests (34 tests):
.fifosuffix is added automaticallyBuild
ui/dist/updated with bundled assetsMakefileadded for convenience (install, dev, build, lint)Out of scope (per issue)
How to verify
ministackorlocalstackon:4566)STACKPORT_PORT=8080 python -m backend.mainorders→ verify it becomesorders.fifo{name}-dlq.fifois auto-createdpytest tests/test_sqs_routes.py -v(34 tests should pass)Technical notes
.fifoif queue type is FIFO and name doesn't already end with it{parentQueueName}-dlq(or-dlq.fifofor FIFO queues)sqs-favorite-messageskeysqs-favorites) for pinning queues to top of listRelated commits
576d71c- Initial implementation: create/delete/update queues, batch operations, favorites8251972- DLQ auto-creation and favorites improvements053aceb- FIFO auto-append fix and this READMEThanks for reviewing — happy to tweak wording or split changes if that helps review.