feat(shop): silo s3 storage grants#42
Open
deployor wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
Adds support for issuing “SILO S3 storage” grants from the admin fulfillment UI, mirroring the existing HCB card-grant flow, and persists the resulting SILO grant id on orders for idempotency/safety.
Changes:
- Adds a SILO admin API (status, prefill, grant) and wires it into the backend app module.
- Extends orders with
siloGrantId(DB migration + entity) and blocks refund/merge/ban-refund flows once a SILO grant exists. - Updates the admin fulfillment UI to display SILO configuration status and issue SILO grants via a new modal.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/routes/admin/+page.svelte | Adds SILO status loading/banner and a SILO grant action + modal wiring in fulfillment UI. |
| frontend/src/lib/components/admin/SiloGrantModal.svelte | New modal to prefill and submit a SILO storage grant. |
| backend/src/silo/silo.service.ts | Implements SILO grant creation with transaction locking + audit logging. |
| backend/src/silo/silo.module.ts | Registers SILO controller/service and dependencies. |
| backend/src/silo/silo.controller.ts | Exposes super-admin SILO status/prefill/grant endpoints. |
| backend/src/shop/shop.service.ts | Includes siloGrantId in admin fulfillment payload and blocks refund/merge if present. |
| backend/src/migrations/1780000000000-AddSiloGrantId.ts | Adds silo_grant_id column + unique partial index. |
| backend/src/entities/order.entity.ts | Adds siloGrantId field mapping on Order. |
| backend/src/entities/audit-log.entity.ts | Adds silo_grant_issued audit action constant. |
| backend/src/app.module.ts | Imports SiloModule. |
| backend/src/admin/admin.service.ts | Excludes SILO-granted orders from the ban flow’s refund loop. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+3324
to
+3328
| <SiloGrantModal | ||
| order={siloGrantModalOrder} | ||
| onClose={() => (siloGrantModalOrder = null)} | ||
| onGranted={() => { siloGrantModalOrder = null; onSiloGrantIssued(); }} | ||
| /> |
Comment on lines
+81
to
+83
| onkeydown={(e) => { | ||
| if (e.key === 'Escape') onClose(); | ||
| }} |
Comment on lines
+99
to
+123
| const recipientEmail = (orderForRecipient?.user?.email ?? '').trim().toLowerCase(); | ||
|
|
||
| let issuedGrantId: string | null = null; | ||
| let recipientUserId: string | undefined; | ||
| let transactionResult: { grantId: string; amount: number; unit: string } | undefined; | ||
|
|
||
| try { | ||
| transactionResult = await this.orderRepo.manager.transaction(async (em) => { | ||
| const order = await em.findOne(Order, { | ||
| where: { id: orderId }, | ||
| relations: ['user'], | ||
| lock: { mode: 'pessimistic_write' }, | ||
| }); | ||
| if (!order) throw new NotFoundException('Order not found'); | ||
| if (order.siloGrantId) { | ||
| throw new ConflictException( | ||
| `A SILO grant (${order.siloGrantId}) was already issued for this order`, | ||
| ); | ||
| } | ||
|
|
||
| const email = (order.user?.email ?? '').trim().toLowerCase(); | ||
| if (!EMAIL_RE.test(email)) { | ||
| throw new BadRequestException('Order owner has no valid email'); | ||
| } | ||
| if (email === admin.email.trim().toLowerCase()) { |
Comment on lines
+203
to
+204
|
|
||
| try { |
Author
|
cc @EDRipper |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
same deal as hcb card grants but calls silo instead for 60gb s3 storage
after merge:
for the shop item:
right now hcb is 1 pipe = (HCB_CENTS_PER_PIPE=500), so = 2 pipes
create a shop item for "60 GB SILO Storage" costing 2 pipes
if hcb rate ever changes just tweak the pipe cost to match
for fulfillers it's the exact same flow — they just click "SILO grant" instead of "Card grant"
safety copied from hcb: can't double grant, can't refund/merge after, ban flow excludes them, locks the row in a transaction, etc