From c07a7691be436b9c91883c344d48be511874a9e2 Mon Sep 17 00:00:00 2001 From: naindev Date: Tue, 20 Oct 2026 17:17:45 +0200 Subject: [PATCH 1/4] docs: propose the drop engine direction (spec 002, ADR-0008) Specifies drops with expiring holds as the product's commercial use: spec, plan and tasks under specs/002-drops, ADR-0008 as Proposed, and open questions Q-005 to Q-007 on buyer identity, payment and hold persistence. No code; blocked until the owner approves the scope change. --- docs/11-open-questions.md | 24 ++++++--- .../ADR-0008-drops-with-expiring-holds.md | 39 +++++++++++++++ docs/30-decisions/README.md | 1 + specs/002-drops/plan.md | 36 ++++++++++++++ specs/002-drops/spec.md | 49 +++++++++++++++++++ specs/002-drops/tasks.md | 16 ++++++ 6 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 docs/30-decisions/ADR-0008-drops-with-expiring-holds.md create mode 100644 specs/002-drops/plan.md create mode 100644 specs/002-drops/spec.md create mode 100644 specs/002-drops/tasks.md diff --git a/docs/11-open-questions.md b/docs/11-open-questions.md index 2b20da9..56e9df7 100644 --- a/docs/11-open-questions.md +++ b/docs/11-open-questions.md @@ -1,10 +1,22 @@ # Open questions -**Status:** Resolved +**Status:** Open (Q-005 to Q-007); earlier questions resolved -Historical log of design questions and their resolved decisions. +## Open -## Q-001 — Test coverage gaps recorded in traceability +These block the requirements of [specs/002-drops](../specs/002-drops/spec.md). + +- **Q-005 — Buyer identity without accounts.** The charter excludes authentication. Options: + (a) an anonymous per-visitor token in a cookie, limits enforced per token and per IP; + (b) an email address entered at checkout. Blocks REQ-088 and the webhooks. +- **Q-006 — Payment.** Keep `confirm` as the existing `MarkAsPaid` transition (no gateway), or add a + payment provider in test mode. Blocks any claim of real commerce. +- **Q-007 — Hold persistence.** Holds survive a restart (persisted, recommended) or are in-memory only. + Blocks the migration design. + +## Resolved + +### Q-001 — Test coverage gaps recorded in traceability **Resolution:** Resolved via automated test suite expansion. - `REQ-004` is covered by `StockLevelsTests.Classify_maps_stock_quantities_to_expected_classification`. @@ -13,17 +25,17 @@ Historical log of design questions and their resolved decisions. - `REQ-051` is covered by `GlobalExceptionHandlerTests` asserting status 500, code `internal_error`, and internal exception message suppression outside development. - `REQ-054` is covered by `OrderFlowTests.Order_list_endpoint_honors_pagination_contract_and_filters`. -## Q-002 — Business rule: a repeated product in an order +### Q-002 — Business rule: a repeated product in an order **Resolution:** Option (a) approved by owner. `Order.AddItem` continues to strictly enforce line uniqueness within an order (`DuplicateOrderItemException`), keeping the domain invariant explicit. Quantity modifications are performed via `ChangeItemQuantity`. -## Q-003 — Stock is reserved on adding a line, not on payment +### Q-003 — Stock is reserved on adding a line, not on payment **Resolution:** Option (a) approved by owner. Units continue to be reserved immediately upon line addition within the transaction, demonstrating deterministic reservation and restitution upon cancellation for this bounded scope. -## Q-004 — Where money is rounded +### Q-004 — Where money is rounded **Resolution:** Option (b) approved by owner. Keep both domain rounding on entity construction and `MoneyConverter` rounding as defense in depth, ensuring exact integer cent representation across all boundaries. diff --git a/docs/30-decisions/ADR-0008-drops-with-expiring-holds.md b/docs/30-decisions/ADR-0008-drops-with-expiring-holds.md new file mode 100644 index 0000000..dc011e3 --- /dev/null +++ b/docs/30-decisions/ADR-0008-drops-with-expiring-holds.md @@ -0,0 +1,39 @@ +# ADR-0008 — Drops with expiring holds + +**Status:** Proposed + +## Context + +NainOrder reserves stock when a line is added to an order and never releases it unless the order is +cancelled. That is correct for a basket, but a limited launch needs the opposite pressure: units must +be held only briefly while the buyer decides, then return to the crowd. Without expiry, abandoned +carts lock stock and the drop never sells out honestly. + +## Decision + +Introduce a `Drop` aggregate that owns a fixed number of units, and a `Hold` that reserves some of +them for a short window. A confirmed hold becomes an order through the existing `OrderService`; +an unconfirmed one expires and its units return to the drop. + +- **Where the stock lives.** The drop owns its units; it does not borrow from `Product.StockQuantity` + while the drop is live. This keeps catalogue stock and drop stock from interfering. +- **Concurrency.** `Drop.Version` is an optimistic concurrency token, the same pattern as + [ADR-0007](ADR-0007-optimistic-concurrency-on-order-aggregate.md). A losing writer gets + `concurrency_conflict` and retries, as in the stock race. +- **Expiry.** Checked lazily on every read and write of the drop, and swept every second by a + background service. Correctness depends only on the lazy check; the sweeper keeps the live state fresh. +- **Time.** All decisions use an injected `TimeProvider`, so expiry is tested without sleeping. + +## Alternatives considered + +- **Reuse `Product.StockQuantity` for drops.** Rejected: a drop would race the catalogue's own + reservations and could not guarantee "exactly N units". +- **Expiry only in a background job.** Rejected: a stopped job would make units unavailable forever. +- **Redis with key TTLs.** Rejected for now: adds a service and breaks the single-process, + zero-cost deployment constraint in the charter. + +## Consequences + +- Scope grows from a basket engine to a launch engine; the charter's objective needs a matching update. +- A new aggregate, migration and background service to maintain and test. +- Restarting the process must not lose holds, so they are persisted, not kept in memory (Q-007). diff --git a/docs/30-decisions/README.md b/docs/30-decisions/README.md index b8a2e9c..16f9f1c 100644 --- a/docs/30-decisions/README.md +++ b/docs/30-decisions/README.md @@ -11,3 +11,4 @@ Records of significant architectural and design decisions for NainOrder. | [ADR-0005](ADR-0005-problem-details-error-contract.md) | RFC 7807 Problem Details error contract | Proposed | | [ADR-0006](ADR-0006-dependency-free-client-panel.md) | Dependency-free client panel | Proposed | | [ADR-0007](ADR-0007-optimistic-concurrency-on-order-aggregate.md) | Optimistic concurrency on the order aggregate | Proposed | +| [ADR-0008](ADR-0008-drops-with-expiring-holds.md) | Drops with expiring holds | Proposed | diff --git a/specs/002-drops/plan.md b/specs/002-drops/plan.md new file mode 100644 index 0000000..618996b --- /dev/null +++ b/specs/002-drops/plan.md @@ -0,0 +1,36 @@ +# 002 — Plan + +## Domain (no packages) + +- `Drop` aggregate: `Id`, `ProductId`, `TotalUnits`, `OpensAt`, `PerBuyerLimit`, `HoldSeconds`, `Version`. + Status is derived from the clock and the counters, never stored. +- `Hold` entity: `DropId`, `BuyerToken`, `Quantity`, `ExpiresAt`, `State` (`Active`, `Confirmed`, `Expired`). +- Invariant: `active holds + confirmed units <= TotalUnits`, enforced inside `Drop`. + +## Application + +`DropService`: create, get, take (creates a hold), confirm (creates and pays the order through the +existing `OrderService`), and `ExpireHolds`. One unit of work per use case, like the rest. + +## Infrastructure + +- EF Core mapping, migration `AddDrops`, `Drop.Version` as concurrency token (same pattern as ADR-0007). +- `HoldExpiryService : BackgroundService` sweeps expired holds every second. Expiry is also checked + lazily when a drop is read, so correctness never depends on the sweeper running. + +## Api + +`POST /api/drops`, `GET /api/drops/{id}`, `POST /api/drops/{id}/holds`, +`POST /api/drops/{id}/holds/{holdId}/confirm`, `GET /api/drops/{id}/stream` (SSE, phase 2). +Errors keep the RFC 7807 contract with new codes: `drop_not_live`, `buyer_limit_reached`, `hold_expired`. + +## Panel + +New `Drop` view with the layout in the spec's visual contract. Renders API state only; computes +nothing (AGENTS.md rule). The existing stock race becomes the crowd simulator of a drop. + +## Verification + +Test first, per task: a concurrency test with many buyers taking from one drop (never more than +`TotalUnits` held plus sold), a clock-controlled test for hold expiry (inject `TimeProvider`), +and property tests for the invariant in `Drop`. diff --git a/specs/002-drops/spec.md b/specs/002-drops/spec.md new file mode 100644 index 0000000..e9bda41 --- /dev/null +++ b/specs/002-drops/spec.md @@ -0,0 +1,49 @@ +# 002 — Drops + +**Status:** Draft — pending owner approval. Changes the product scope: see [ADR-0008](../../docs/30-decisions/ADR-0008-drops-with-expiring-holds.md) and the open questions Q-005 to Q-007. + +## Problem + +Limited-stock launches (sneakers, merch, tickets) fail in one predictable way: when thousands arrive at +the same second, the shop oversells, or locks stock behind abandoned carts. Shops with a generic +platform have no tool that guarantees *exactly N units, no more, no stuck stock*. + +## Product + +NainOrder becomes a **drop engine**: a headless service plus a live page that sells a fixed number of +units to a crowd, fairly and without overselling. The existing guarantees (reservation, optimistic +concurrency, state machine) are the engine; this feature adds the commercial surface. + +## Users + +- **Shop owner** — configures a drop and watches it sell out. +- **Buyer** — takes a unit, then has a short window to confirm it. + +## Requirements (EARS) + +- **REQ-080** — When a shop owner creates a drop with a product, a number of units, an opening time and a per-buyer limit, the system shall publish it as `Scheduled` until it opens. +- **REQ-081** — While a drop is not `Live`, the system shall reject any attempt to take a unit with `409 drop_not_live`. +- **REQ-082** — When a buyer takes units from a live drop, the system shall create a hold of at most the per-buyer limit, reserving those units atomically. +- **REQ-083** — When a hold is not confirmed within its time window, the system shall expire it and return its units to the drop. +- **REQ-084** — When a buyer confirms an unexpired hold, the system shall turn it into a paid order for that buyer. +- **REQ-085** — The system shall never hold or sell more units than the drop contains, whatever the concurrency. +- **REQ-086** — When a drop's units are all sold or held, the system shall report it `SoldOut`; when expired holds free units again, it shall report it `Live`. +- **REQ-087** — The system shall publish the live state of a drop (available, held, sold) as a stream that clients can subscribe to. +- **REQ-088** — If a buyer exceeds the per-buyer limit across holds and orders of one drop, then the system shall reject the request with `409 buyer_limit_reached`. + +## Visual contract (panel) + +One page per drop: a countdown, a grid with one cell per unit coloured *available / held / sold*, +and a single button. No explanatory text beyond labels. It updates from the stream (REQ-087). + +## Phases + +1. **MVP** — REQ-080 to REQ-086, REQ-088; live page polling the drop state. +2. **Live** — REQ-087 (stream); crowd simulator on the page (extends the stock race). +3. **Integrate** — webhooks (`drop.sold_out`, `hold.expired`) and an embeddable widget. Needs Q-005. + +## Non-goals + +- Real payment capture: `confirm` stays the existing `MarkAsPaid` transition (Q-006). +- Accounts and login. Buyers are identified by a per-visitor token (Q-005). +- Queues ordered by arrival (waiting-room fairness). Revisit after MVP. diff --git a/specs/002-drops/tasks.md b/specs/002-drops/tasks.md new file mode 100644 index 0000000..ff744d1 --- /dev/null +++ b/specs/002-drops/tasks.md @@ -0,0 +1,16 @@ +# 002 — Tasks + +Blocked until the owner approves the spec, [ADR-0008](../../docs/30-decisions/ADR-0008-drops-with-expiring-holds.md) +and answers Q-005 to Q-007. Labels: `[A]` agent alone, `[M]` mixed, `[H]` owner only. + +| ID | Task | Label | Done when | +| :--- | :--- | :--- | :--- | +| T-040 | Approve scope change, ADR-0008 and Q-005 to Q-007 | `[H]` | Statuses updated in `docs/` | +| T-041 | `Drop` and `Hold` domain with `TimeProvider`, property tests first | `[A]` | Invariant REQ-085 holds for generated sequences | +| T-042 | `DropService` and persistence, migration `AddDrops` | `[A]` | Concurrency test: never more than `TotalUnits` held plus sold | +| T-043 | Hold expiry, lazy plus background sweeper | `[A]` | Clock-controlled test returns units after the window | +| T-044 | Drop endpoints and error codes | `[A]` | `openapi.json` regenerated, error contract tests green | +| T-045 | Drop view in the panel, minimal text | `[A]` | Verified in a browser against a running API | +| T-046 | Live stream and crowd simulator | `[A]` | Page updates without polling | +| T-047 | Webhooks and embeddable widget | `[M]` | Needs Q-005; receiver URL supplied by the owner | +| T-048 | README rebuilt around the drop, with an animated capture | `[A]` | Product understood from the first screen | From fc1adbcc96f100afdb85016275848d928c207d0f Mon Sep 17 00:00:00 2001 From: naindev Date: Tue, 20 Oct 2026 17:31:12 +0200 Subject: [PATCH 2/4] feat(drops): add drops with expiring holds, API and in-browser engine Drop aggregate with Hold entities (units owned by the drop, optimistic concurrency token, clock supplied by the caller), DropService, EF Core mapping with the AddDrops migration, expiry both lazy and swept by a background service, /api/drops endpoints with RFC 7807 error codes, and a matching in-browser engine for the static demo. Spec: specs/002-drops (REQ-080 to REQ-086, REQ-088). --- NainOrder.Api/Controllers/DropsController.cs | 75 ++++ .../Infrastructure/GlobalExceptionHandler.cs | 6 + .../Infrastructure/HoldExpirySweeper.cs | 51 +++ NainOrder.Api/Program.cs | 4 + NainOrder.Api/wwwroot/assets/js/api.js | 45 ++- .../wwwroot/assets/js/mock-backend.js | 173 ++++++++- NainOrder.Api/wwwroot/assets/js/views/drop.js | 353 +++++++++++++++++ NainOrder.Application/Common/DropDefaults.cs | 10 + NainOrder.Application/DTOs/DropDtos.cs | 39 ++ NainOrder.Application/DependencyInjection.cs | 5 + .../Interfaces/IRepositories.cs | 13 + NainOrder.Application/Interfaces/IServices.cs | 12 + NainOrder.Application/Services/DropService.cs | 127 ++++++ NainOrder.Domain/Entities/Drop.cs | 131 +++++++ NainOrder.Domain/Entities/Hold.cs | 45 +++ NainOrder.Domain/Enums/DropEnums.cs | 16 + .../Exceptions/DomainException.cs | 52 +++ .../DependencyInjection.cs | 1 + .../Configurations/DropConfigurations.cs | 52 +++ .../20261020152656_AddDrops.Designer.cs | 323 ++++++++++++++++ .../Migrations/20261020152656_AddDrops.cs | 96 +++++ .../NainOrderDbContextModelSnapshot.cs | 109 ++++++ .../Persistence/NainOrderDbContext.cs | 2 + .../Repositories/DropRepository.cs | 35 ++ .../Persistence/Seeding/DatabaseSeeder.cs | 14 + NainOrder.Tests/Api/DropFlowTests.cs | 244 ++++++++++++ NainOrder.Tests/Domain/DropTests.cs | 228 +++++++++++ docs/11-open-questions.md | 27 +- .../ADR-0008-drops-with-expiring-holds.md | 2 +- docs/30-decisions/README.md | 2 +- docs/openapi.json | 366 ++++++++++++++++++ specs/002-drops/spec.md | 2 +- specs/002-drops/tasks.md | 6 +- 33 files changed, 2642 insertions(+), 24 deletions(-) create mode 100644 NainOrder.Api/Controllers/DropsController.cs create mode 100644 NainOrder.Api/Infrastructure/HoldExpirySweeper.cs create mode 100644 NainOrder.Api/wwwroot/assets/js/views/drop.js create mode 100644 NainOrder.Application/Common/DropDefaults.cs create mode 100644 NainOrder.Application/DTOs/DropDtos.cs create mode 100644 NainOrder.Application/Services/DropService.cs create mode 100644 NainOrder.Domain/Entities/Drop.cs create mode 100644 NainOrder.Domain/Entities/Hold.cs create mode 100644 NainOrder.Domain/Enums/DropEnums.cs create mode 100644 NainOrder.Infrastructure/Persistence/Configurations/DropConfigurations.cs create mode 100644 NainOrder.Infrastructure/Persistence/Migrations/20261020152656_AddDrops.Designer.cs create mode 100644 NainOrder.Infrastructure/Persistence/Migrations/20261020152656_AddDrops.cs create mode 100644 NainOrder.Infrastructure/Persistence/Repositories/DropRepository.cs create mode 100644 NainOrder.Tests/Api/DropFlowTests.cs create mode 100644 NainOrder.Tests/Domain/DropTests.cs diff --git a/NainOrder.Api/Controllers/DropsController.cs b/NainOrder.Api/Controllers/DropsController.cs new file mode 100644 index 0000000..9876a2a --- /dev/null +++ b/NainOrder.Api/Controllers/DropsController.cs @@ -0,0 +1,75 @@ +using Microsoft.AspNetCore.Mvc; +using NainOrder.Application.DTOs; +using NainOrder.Application.Interfaces; + +namespace NainOrder.Api.Controllers; + +/// Limited-stock drops: a fixed number of units sold to a crowd with short expiring holds. +[ApiController] +[Route("api/[controller]")] +[Produces("application/json")] +public class DropsController : ControllerBase +{ + private const string BuyerTokenHeader = "X-Buyer-Token"; + + private readonly IDropService _dropService; + + public DropsController(IDropService dropService) => _dropService = dropService; + + /// Most recent drops. + [HttpGet] + [ProducesResponseType>(StatusCodes.Status200OK)] + public async Task>> List(CancellationToken cancellationToken) => + Ok(await _dropService.ListAsync(cancellationToken)); + + /// Live state of a drop. With X-Buyer-Token, also the caller's own holds. + [HttpGet("{id:guid}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> GetById(Guid id, CancellationToken cancellationToken) => + Ok(await _dropService.GetAsync(id, BuyerToken(), cancellationToken)); + + /// Creates a drop for a catalogue product. It opens after opensInSeconds. + [HttpPost] + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> Create(CreateDropRequest request, CancellationToken cancellationToken) + { + var drop = await _dropService.CreateAsync(request, cancellationToken); + return CreatedAtAction(nameof(GetById), new { id = drop.Id }, drop); + } + + /// Takes units from a live drop: an expiring hold for the caller's buyer token. + [HttpPost("{id:guid}/holds")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status409Conflict)] + public async Task> Take( + Guid id, TakeUnitsRequest request, CancellationToken cancellationToken) + { + if (BuyerToken() is not { } token) return MissingToken(); + return Ok(await _dropService.TakeAsync(id, token, request, cancellationToken)); + } + + /// Confirms an unexpired hold; it becomes a paid order. + [HttpPost("{id:guid}/holds/{holdId:guid}/confirm")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status409Conflict)] + public async Task> Confirm(Guid id, Guid holdId, CancellationToken cancellationToken) + { + if (BuyerToken() is not { } token) return MissingToken(); + return Ok(await _dropService.ConfirmAsync(id, holdId, token, cancellationToken)); + } + + private string? BuyerToken() + { + var value = Request.Headers[BuyerTokenHeader].ToString().Trim(); + return value.Length is > 0 and <= 64 ? value : null; + } + + private ObjectResult MissingToken() => Problem( + statusCode: StatusCodes.Status400BadRequest, + title: "Buyer token required", + detail: $"Send a visitor token of 1 to 64 characters in the {BuyerTokenHeader} header.", + extensions: new Dictionary { ["code"] = "buyer_token_required" }); +} diff --git a/NainOrder.Api/Infrastructure/GlobalExceptionHandler.cs b/NainOrder.Api/Infrastructure/GlobalExceptionHandler.cs index 1ec5196..7d2b708 100644 --- a/NainOrder.Api/Infrastructure/GlobalExceptionHandler.cs +++ b/NainOrder.Api/Infrastructure/GlobalExceptionHandler.cs @@ -70,6 +70,12 @@ public async ValueTask TryHandleAsync( { NotFoundException e => (StatusCodes.Status404NotFound, e.Code, "Resource not found"), OrderItemNotFoundException e => (StatusCodes.Status404NotFound, e.Code, "Order line not found"), + HoldNotFoundException e => (StatusCodes.Status404NotFound, e.Code, "Hold not found"), + + DropNotLiveException e => (StatusCodes.Status409Conflict, e.Code, "Drop is not live"), + BuyerLimitReachedException e => (StatusCodes.Status409Conflict, e.Code, "Buyer limit reached"), + HoldExpiredException e => (StatusCodes.Status409Conflict, e.Code, "Hold expired"), + HoldNotActiveException e => (StatusCodes.Status409Conflict, e.Code, "Hold not active"), ConflictException e => (StatusCodes.Status409Conflict, e.Code, "Conflict"), InsufficientStockException e => (StatusCodes.Status409Conflict, e.Code, "Insufficient stock"), diff --git a/NainOrder.Api/Infrastructure/HoldExpirySweeper.cs b/NainOrder.Api/Infrastructure/HoldExpirySweeper.cs new file mode 100644 index 0000000..a1732dc --- /dev/null +++ b/NainOrder.Api/Infrastructure/HoldExpirySweeper.cs @@ -0,0 +1,51 @@ +using NainOrder.Application.Exceptions; +using NainOrder.Application.Interfaces; + +namespace NainOrder.Api.Infrastructure; + +/// +/// Marks expired drop holds once a second. A failed pass is logged and retried on the next tick: +/// the sweeper is an optimisation over lazy expiry, never the source of correctness (ADR-0008). +/// +public sealed class HoldExpirySweeper : BackgroundService +{ + private static readonly TimeSpan Interval = TimeSpan.FromSeconds(1); + + private readonly IServiceScopeFactory _scopeFactory; + private readonly ILogger _logger; + + public HoldExpirySweeper(IServiceScopeFactory scopeFactory, ILogger logger) + { + _scopeFactory = scopeFactory; + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + using var timer = new PeriodicTimer(Interval); + + while (await timer.WaitForNextTickAsync(stoppingToken)) + { + try + { + using var scope = _scopeFactory.CreateScope(); + var drops = scope.ServiceProvider.GetRequiredService(); + var expired = await drops.ExpireDueHoldsAsync(stoppingToken); + + if (expired > 0) _logger.LogInformation("Expired {Count} drop holds", expired); + } + catch (ConflictException) + { + // A buyer wrote to the same drop first; the next tick sweeps again. + } + catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + { + return; + } + catch (Exception ex) + { + _logger.LogError(ex, "Hold expiry sweep failed"); + } + } + } +} diff --git a/NainOrder.Api/Program.cs b/NainOrder.Api/Program.cs index 99fb514..24cfb9b 100644 --- a/NainOrder.Api/Program.cs +++ b/NainOrder.Api/Program.cs @@ -18,6 +18,10 @@ builder.Services.AddApplication(); builder.Services.AddInfrastructure(connectionString); +// Returns the units of unconfirmed drop holds shortly after their window ends. Correctness does +// not depend on it (reads apply the clock themselves); it keeps stored state and streams fresh. +builder.Services.AddHostedService(); + builder.Services.AddControllers(); builder.Services.AddMemoryCache(); diff --git a/NainOrder.Api/wwwroot/assets/js/api.js b/NainOrder.Api/wwwroot/assets/js/api.js index 01a168d..e7fb60e 100644 --- a/NainOrder.Api/wwwroot/assets/js/api.js +++ b/NainOrder.Api/wwwroot/assets/js/api.js @@ -84,12 +84,30 @@ const buildUrl = (path, query) => { return url; }; -async function request(method, path, { body, query, signal } = {}) { +/** + * Anonymous visitor identity for drops (Q-005): a random token kept in this browser, sent as + * `X-Buyer-Token`. It identifies a visitor, never a person. + */ +export const buyerToken = () => { + try { + let token = localStorage.getItem("nainorder.buyer"); + if (!token) { + token = crypto.randomUUID(); + localStorage.setItem("nainorder.buyer", token); + } + return token; + } catch { + // Storage blocked: a per-page token still lets this visit work. + return (buyerToken.fallback ??= crypto.randomUUID()); + } +}; + +async function request(method, path, { body, query, signal, headers } = {}) { const startedAt = performance.now(); if (isStaticHost) { try { - const result = await mockDispatch(method, path, { body, query }); + const result = await mockDispatch(method, path, { body, query, headers }); const elapsedMs = performance.now() - startedAt; const queryStr = query && Object.keys(query).length > 0 ? `?${new URLSearchParams(query).toString()}` : ""; publishTrace({ @@ -122,18 +140,20 @@ async function request(method, path, { body, query, signal } = {}) { response = await fetch(url, { method, signal, - headers: body ? { "Content-Type": "application/json" } : undefined, + headers: body || headers ? { ...(body ? { "Content-Type": "application/json" } : {}), ...headers } : undefined, body: body ? JSON.stringify(body) : undefined }); } catch (networkError) { // Backend offline: conmuta con gracia al motor de dominio en memoria isStaticHost = true; - return request(method, path, { body, query, signal }); + return request(method, path, { body, query, signal, headers }); } - if (response.status === 404) { + // A 404 with a problem+json body is the API answering about a missing resource; only a 404 + // without it means there is no API behind this host (static hosting), so fall back then. + if (response.status === 404 && !response.headers.get("content-type")?.includes("problem+json")) { isStaticHost = true; - return request(method, path, { body, query, signal }); + return request(method, path, { body, query, signal, headers }); } const elapsedMs = performance.now() - startedAt; @@ -191,6 +211,19 @@ export const api = { stateMachine: () => request("GET", "/meta/order-state-machine") }, + drops: { + list: () => request("GET", "/drops"), + get: (id) => request("GET", `/drops/${id}`, { headers: { "X-Buyer-Token": buyerToken() } }), + create: (body) => request("POST", "/drops", { body }), + take: (id, quantity) => + request("POST", `/drops/${id}/holds`, { body: { quantity }, headers: { "X-Buyer-Token": buyerToken() } }), + confirm: (id, holdId) => + request("POST", `/drops/${id}/holds/${holdId}/confirm`, { headers: { "X-Buyer-Token": buyerToken() } }), + /** Takes as another visitor; used by the crowd simulator. */ + takeAs: (id, token, quantity) => + request("POST", `/drops/${id}/holds`, { body: { quantity }, headers: { "X-Buyer-Token": token } }) + }, + demo: { simulate: () => request("POST", "/demo/simulate-purchase"), stockRace: (buyers, units) => request("POST", "/demo/stock-race", { body: { buyers, units } }) diff --git a/NainOrder.Api/wwwroot/assets/js/mock-backend.js b/NainOrder.Api/wwwroot/assets/js/mock-backend.js index b0184fb..947f8b6 100644 --- a/NainOrder.Api/wwwroot/assets/js/mock-backend.js +++ b/NainOrder.Api/wwwroot/assets/js/mock-backend.js @@ -225,8 +225,174 @@ class MockDatabase { export const mockDb = new MockDatabase(); +/* -------------------------------------------------------------------------- + Drops en memoria. Mismas reglas y misma forma que la API .NET, pero en un solo hilo: + no demuestran concurrencia. Viven solo en la sesión de la pestaña. + -------------------------------------------------------------------------- */ +const mockDrops = new Map(); + +const dropError = (status, code, title, detail) => ({ status, code, title, detail }); + +const dropNow = () => Date.now(); + +const dropCounts = (drop, now) => { + const sold = drop.holds.filter((h) => h.state === "Confirmed").reduce((s, h) => s + h.quantity, 0); + const held = drop.holds + .filter((h) => h.state === "Active" && Date.parse(h.expiresAt) > now) + .reduce((s, h) => s + h.quantity, 0); + return { sold, held, available: drop.totalUnits - sold - held }; +}; + +const mapDrop = (drop, token) => { + const now = dropNow(); + const { sold, held, available } = dropCounts(drop, now); + const status = now < Date.parse(drop.opensAt) ? "Scheduled" : available === 0 ? "SoldOut" : "Live"; + + return { + id: drop.id, + productId: drop.productId, + productName: drop.productName, + productSku: drop.productSku, + unitPrice: drop.unitPrice, + totalUnits: drop.totalUnits, + available, + held, + sold, + status, + opensAt: drop.opensAt, + perBuyerLimit: drop.perBuyerLimit, + holdSeconds: drop.holdSeconds, + serverTime: new Date(now).toISOString(), + myHolds: token + ? drop.holds.filter((h) => h.buyerToken === token).map(({ buyerToken, ...hold }) => ({ + ...hold, + state: hold.state === "Active" && Date.parse(hold.expiresAt) <= now ? "Expired" : hold.state + })) + : [] + }; +}; + +const dispatchDrops = (method, pathname, { body, headers }) => { + const token = headers?.["X-Buyer-Token"] || null; + + if (method === "GET" && pathname === "/drops") { + return [...mockDrops.values()].reverse().slice(0, 20).map((d) => mapDrop(d, null)); + } + + if (method === "POST" && pathname === "/drops") { + const product = mockDb.products.find((p) => p.id === body?.productId); + if (!product) throw dropError(404, "not_found", "Resource not found", "Producto no encontrado."); + + const { totalUnits, perBuyerLimit, holdSeconds } = body; + if (!(totalUnits >= 1 && totalUnits <= 1000 && perBuyerLimit >= 1 && perBuyerLimit <= totalUnits && + holdSeconds >= 5 && holdSeconds <= 3600)) { + throw dropError(400, "invalid_data", "Invalid request data", "Configuración de drop no válida."); + } + + const drop = { + id: mockDb.generateId(), + productId: product.id, + productName: product.name, + productSku: product.sku, + unitPrice: product.price, + totalUnits, + perBuyerLimit, + holdSeconds, + opensAt: new Date(dropNow() + (body.opensInSeconds || 0) * 1000).toISOString(), + holds: [] + }; + mockDrops.set(drop.id, drop); + return mapDrop(drop, null); + } + + const match = pathname.match(/^\/drops\/([^/]+)(?:\/holds(?:\/([^/]+)\/confirm)?)?$/); + if (!match) return undefined; + + const drop = mockDrops.get(match[1]); + if (!drop) throw dropError(404, "not_found", "Resource not found", `Drop ${match[1]} no existe.`); + + if (method === "GET" && pathname === `/drops/${drop.id}`) return mapDrop(drop, token); + + if (!token) throw dropError(400, "buyer_token_required", "Buyer token required", "Falta el identificador de visitante."); + const now = dropNow(); + + if (method === "POST" && pathname === `/drops/${drop.id}/holds`) { + const quantity = Number(body?.quantity); + if (!(quantity >= 1)) throw dropError(400, "invalid_data", "Invalid request data", "Cantidad no válida."); + if (now < Date.parse(drop.opensAt)) { + throw dropError(409, "drop_not_live", "Drop is not live", "El drop aún no ha abierto."); + } + + const owned = drop.holds + .filter((h) => h.buyerToken === token && + (h.state === "Confirmed" || (h.state === "Active" && Date.parse(h.expiresAt) > now))) + .reduce((s, h) => s + h.quantity, 0); + if (owned + quantity > drop.perBuyerLimit) { + throw dropError(409, "buyer_limit_reached", "Buyer limit reached", `Límite de ${drop.perBuyerLimit} por comprador.`); + } + + const { available } = dropCounts(drop, now); + if (quantity > available) { + throw dropError(409, "insufficient_stock", "Insufficient stock", `Solo quedan ${available} unidades.`); + } + + const hold = { + id: mockDb.generateId(), + buyerToken: token, + quantity, + createdAt: new Date(now).toISOString(), + expiresAt: new Date(now + drop.holdSeconds * 1000).toISOString(), + state: "Active", + orderId: null + }; + drop.holds.push(hold); + const { buyerToken, ...dto } = hold; + return dto; + } + + const holdId = match[2]; + if (method === "POST" && holdId) { + const hold = drop.holds.find((h) => h.id === holdId && h.buyerToken === token); + if (!hold) throw dropError(404, "hold_not_found", "Hold not found", "Reserva no encontrada."); + if (hold.state === "Confirmed") throw dropError(409, "hold_not_active", "Hold not active", "La reserva ya está confirmada."); + if (hold.state === "Expired" || Date.parse(hold.expiresAt) <= now) { + throw dropError(409, "hold_expired", "Hold expired", "La reserva ha caducado."); + } + + const customer = mockDb.customers[0]; + const order = { + id: mockDb.generateId(), + reference: mockDb.generateReference(), + customerId: customer.id, + customerName: customer.name, + customerEmail: customer.email, + status: "Paid", + createdAt: new Date(now).toISOString(), + paidAt: new Date(now).toISOString(), + shippedAt: null, + cancelledAt: null, + items: [{ + productId: drop.productId, + productName: drop.productName, + productSku: drop.productSku, + unitPrice: drop.unitPrice, + quantity: hold.quantity, + totalPrice: drop.unitPrice * hold.quantity + }] + }; + mockDb.orders.unshift(order); + mockDb.save(); + + hold.state = "Confirmed"; + hold.orderId = order.id; + return mockDb.mapOrderDto(order); + } + + return undefined; +}; + /** Despachador de peticiones simuladas en memoria. */ -export async function mockDispatch(method, path, { body, query } = {}) { +export async function mockDispatch(method, path, { body, query, headers } = {}) { // Simulación de latencia realista en cliente (8-24 ms) await new Promise((resolve) => setTimeout(resolve, 8 + Math.random() * 16)); @@ -234,6 +400,11 @@ export async function mockDispatch(method, path, { body, query } = {}) { const pathname = url.pathname.replace(/^\/api/, ""); const searchParams = query ? new URLSearchParams(query) : url.searchParams; + if (pathname === "/drops" || pathname.startsWith("/drops/")) { + const result = dispatchDrops(method, pathname, { body, headers }); + if (result !== undefined) return result; + } + // -------------------------------------------------------------------------- // PRODUCTS // -------------------------------------------------------------------------- diff --git a/NainOrder.Api/wwwroot/assets/js/views/drop.js b/NainOrder.Api/wwwroot/assets/js/views/drop.js new file mode 100644 index 0000000..72c8fd0 --- /dev/null +++ b/NainOrder.Api/wwwroot/assets/js/views/drop.js @@ -0,0 +1,353 @@ +/** + * Drop: venta de unidades limitadas a una multitud. La vista pinta lo que devuelve la API + * (disponibles, reservadas, vendidas, estado) y no calcula ninguna regla: quién puede comprar, + * cuándo caduca una reserva y si el drop está agotado lo decide el servidor. + */ + +import { html, icon, raw, render, $, delegate } from "../dom.js"; +import { api, ApiError, isDemoMode } from "../api.js"; +import { toast, toastError } from "../toast.js"; +import { withBusy } from "../overlay.js"; +import { fmtMoney, fmtNumber } from "../format.js"; + +const LAST_DROP_KEY = "nainorder.drop"; +const POLL_MS = 1000; +const CROWD = 40; + +const STATUS_LABEL = { Scheduled: "Programado", Live: "En vivo", SoldOut: "Agotado" }; + +const MESSAGES = { + drop_not_live: "El drop aún no ha abierto", + buyer_limit_reached: "Ya tienes el máximo permitido", + insufficient_stock: "Agotado: otra persona fue más rápida", + concurrency_conflict: "Mucha demanda, inténtalo otra vez", + hold_expired: "Tu reserva caducó" +}; + +const remember = (id) => { + try { + id ? localStorage.setItem(LAST_DROP_KEY, id) : localStorage.removeItem(LAST_DROP_KEY); + } catch { + /* El almacenamiento puede estar bloqueado: se pierde solo el atajo. */ + } +}; + +const lastDropId = () => { + try { + return localStorage.getItem(LAST_DROP_KEY); + } catch { + return null; + } +}; + +const clock = (milliseconds) => { + const total = Math.max(0, Math.ceil(milliseconds / 1000)); + return `${Math.floor(total / 60)}:${String(total % 60).padStart(2, "0")}`; +}; + +const slider = (name, label, min, max, value, unit = "") => html` + +`; + +const launcher = (products, recent) => html` +
+
+ + ${raw(slider("units", "Unidades", 1, 200, 24))} + ${raw(slider("perBuyer", "Máximo por persona", 1, 10, 2))} + ${raw(slider("hold", "Reserva", 10, 120, 30, " s"))} + +
+ ${raw( + recent.length + ? html`
${raw( + recent + .map( + (d) => html`` + ) + .join("") + )}
` + : "" + )} +
+`; + +const stage = () => html` +
+
+
+

+

+
+
+ + +
+
+ +
+ +
+ +
+ + + +
+ + + +
    +
  • disponible
  • +
  • reservada
  • +
  • vendida
  • +
+
+`; + +const cellsFor = (drop, mine) => { + const states = [ + ...Array(drop.sold).fill("sold"), + ...Array(drop.held).fill("held"), + ...Array(drop.available).fill("available") + ]; + let owned = mine; + return states + .map((state, index) => { + const own = state === "held" && owned-- > 0; + return ``; + }) + .join(""); +}; + +export const dropView = { + title: "Drop", + subtitle: "Unidades limitadas, una multitud, cero sobreventa", + + destroy() { + clearInterval(this._poll); + clearInterval(this._tick); + this._poll = this._tick = null; + }, + + async render(outlet) { + this.destroy(); + + const header = html` +
+
+

Drop

+

Lanza una venta limitada y suelta una multitud sobre ella.

+
+
+ ${raw(isDemoMode() + ? html`
+ ${raw(icon("info", { size: 15 }))} +

Aquí corre en el navegador. Las colisiones reales + entre compradores simultáneos se ven con la API .NET en marcha.

+
` + : "")} + `; + + const root = render(outlet, html`${raw(header)}
`); + const body = $("[data-body]", root); + + const showLauncher = async () => { + remember(null); + this.destroy(); + + let products = []; + let recent = []; + try { + [products, recent] = await Promise.all([api.products.list(), api.drops.list()]); + } catch (error) { + toastError(error, "No se pudo cargar el catálogo"); + return; + } + + body.innerHTML = launcher(products, recent); + }; + + const openDrop = async (id) => { + let drop; + try { + drop = await api.drops.get(id); + } catch { + await showLauncher(); + return; + } + + remember(id); + body.innerHTML = stage(); + const stageNode = $("[data-stage]", body); + let current = drop; + let skew = Date.parse(drop.serverTime) - Date.now(); + let busy = false; + + const cell = drop.totalUnits <= 48 ? 44 : drop.totalUnits <= 200 ? 26 : 14; + $("[data-grid]", stageNode).style.setProperty("--cell", `${cell}px`); + $("[data-name]", stageNode).textContent = drop.productName; + $("[data-price]", stageNode).textContent = fmtMoney(drop.unitPrice); + + const paint = () => { + const mine = current.myHolds.find((h) => h.state === "Active"); + const now = Date.now() + skew; + + $("[data-grid]", stageNode).innerHTML = cellsFor(current, mine?.quantity ?? 0); + + const badge = $("[data-badge]", stageNode); + badge.textContent = STATUS_LABEL[current.status] ?? current.status; + badge.dataset.status = { Scheduled: "PendingPayment", Live: "Paid", SoldOut: "Cancelled" }[current.status]; + + $("[data-stats]", stageNode).innerHTML = html` +
${fmtNumber(current.available)}disponibles
+
${fmtNumber(current.held)}reservadas
+
${fmtNumber(current.sold)}vendidas
+ `; + + $('[data-action="take"]', stageNode).disabled = busy || current.status !== "Live"; + + const holdNode = $("[data-hold]", stageNode); + holdNode.hidden = !mine; + if (mine) { + const left = Date.parse(mine.expiresAt) - now; + $("[data-hold-clock]", stageNode).textContent = clock(left); + $("[data-hold-bar]", stageNode).style.width = `${Math.max(0, Math.min(100, (left / (current.holdSeconds * 1000)) * 100))}%`; + } + + const clockNode = $("[data-clock]", stageNode); + clockNode.textContent = current.status === "Scheduled" ? `Abre en ${clock(Date.parse(current.opensAt) - now)}` : ""; + }; + + const refresh = async () => { + try { + current = await api.drops.get(id); + skew = Date.parse(current.serverTime) - Date.now(); + paint(); + } catch { + /* Un fallo puntual de red se corrige en el siguiente ciclo. */ + } + }; + + const say = (error, fallback) => { + const code = error instanceof ApiError ? error.code : null; + if (MESSAGES[code]) toast({ title: MESSAGES[code], variant: "error" }); + else toastError(error, fallback); + }; + + paint(); + this._poll = setInterval(refresh, POLL_MS); + this._tick = setInterval(paint, 250); + + delegate(stageNode, "click", '[data-action="take"]', async (event, button) => { + try { + busy = true; + await withBusy(button, () => api.drops.take(id, 1)); + } catch (error) { + say(error, "No se pudo reservar"); + } finally { + busy = false; + await refresh(); + } + }); + + delegate(stageNode, "click", '[data-action="confirm"]', async (event, button) => { + const mine = current.myHolds.find((h) => h.state === "Active"); + if (!mine) return; + try { + const order = await withBusy(button, () => api.drops.confirm(id, mine.id)); + toast({ title: "Compra confirmada", text: `Pedido ${order.reference} · ${fmtMoney(order.totalAmount)}`, variant: "success" }); + } catch (error) { + say(error, "No se pudo confirmar"); + } finally { + await refresh(); + } + }); + + delegate(stageNode, "click", '[data-action="crowd"]', async (event, button) => { + // Cada comprador es un visitante distinto; las colisiones de escritura se reintentan + // como haría cualquier cliente, y lo que sobra recibe "agotado". + const burst = setInterval(refresh, 150); + try { + await withBusy(button, () => + Promise.all( + Array.from({ length: CROWD }, async () => { + const visitor = crypto.randomUUID(); + for (let attempt = 0; attempt < 40; attempt++) { + try { + await api.drops.takeAs(id, visitor, 1); + return; + } catch (error) { + if (!(error instanceof ApiError) || error.code !== "concurrency_conflict") return; + } + } + }) + ) + ); + } finally { + clearInterval(burst); + await refresh(); + } + }); + + delegate(stageNode, "click", '[data-action="reset"]', showLauncher); + }; + + delegate(root, "input", "[data-input]", (event, input) => { + const out = $(`[data-out="${input.dataset.input}"]`, root); + if (out) out.textContent = input.value; + if (input.name === "units") { + const per = $('[data-input="perBuyer"]', root); + per.max = Math.min(10, Number(input.value)); + if (Number(per.value) > Number(per.max)) { + per.value = per.max; + $('[data-out="perBuyer"]', root).textContent = per.max; + } + } + }); + + delegate(root, "click", '[data-action="launch"]', async (event, button) => { + const value = (name) => $(`[data-input="${name}"]`, root).value; + try { + const drop = await withBusy(button, () => + api.drops.create({ + productId: value("product"), + totalUnits: Number(value("units")), + perBuyerLimit: Number(value("perBuyer")), + holdSeconds: Number(value("hold")), + opensInSeconds: 0 + }) + ); + await openDrop(drop.id); + } catch (error) { + toastError(error, "No se pudo lanzar el drop"); + } + }); + + delegate(root, "click", "[data-open]", (event, node) => openDrop(node.dataset.open)); + + const last = lastDropId(); + if (last) await openDrop(last); + else await showLauncher(); + } +}; diff --git a/NainOrder.Application/Common/DropDefaults.cs b/NainOrder.Application/Common/DropDefaults.cs new file mode 100644 index 0000000..75b60a0 --- /dev/null +++ b/NainOrder.Application/Common/DropDefaults.cs @@ -0,0 +1,10 @@ +namespace NainOrder.Application.Common; + +public static class DropDefaults +{ + /// + /// The one customer every drop order belongs to: buyers are anonymous visitors identified + /// only by a token (Q-005). Fixed so the seeder and the use case agree on it. + /// + public static readonly Guid AnonymousBuyerId = Guid.Parse("5d0c6f0e-7b0a-4f3e-9a3e-0d0e5a1b2c3d"); +} diff --git a/NainOrder.Application/DTOs/DropDtos.cs b/NainOrder.Application/DTOs/DropDtos.cs new file mode 100644 index 0000000..97856fd --- /dev/null +++ b/NainOrder.Application/DTOs/DropDtos.cs @@ -0,0 +1,39 @@ +using System.ComponentModel.DataAnnotations; + +namespace NainOrder.Application.DTOs; + +/// +/// Creates a drop from a catalogue product. OpensInSeconds is relative so the client's +/// clock never decides when a drop opens. +/// +public record CreateDropRequest( + [Required] Guid ProductId, + [Range(1, 1_000)] int TotalUnits, + [Range(1, 1_000)] int PerBuyerLimit, + [Range(5, 3_600)] int HoldSeconds, + [Range(0, 604_800)] int OpensInSeconds = 0); + +public record TakeUnitsRequest([Range(1, 1_000)] int Quantity); + +public record HoldDto(Guid Id, int Quantity, DateTime ExpiresAt, string State, Guid? OrderId); + +/// +/// Live state of a drop. Every figure is computed by the server at ServerTime; the panel +/// draws it and derives nothing. +/// +public record DropDto( + Guid Id, + Guid ProductId, + string ProductName, + string ProductSku, + decimal UnitPrice, + int TotalUnits, + int Available, + int Held, + int Sold, + string Status, + DateTime OpensAt, + int PerBuyerLimit, + int HoldSeconds, + DateTime ServerTime, + IReadOnlyList MyHolds); diff --git a/NainOrder.Application/DependencyInjection.cs b/NainOrder.Application/DependencyInjection.cs index 87e8621..541f0d9 100644 --- a/NainOrder.Application/DependencyInjection.cs +++ b/NainOrder.Application/DependencyInjection.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using NainOrder.Application.Interfaces; using NainOrder.Application.Services; @@ -13,6 +14,10 @@ public static IServiceCollection AddApplication(this IServiceCollection services services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); + + // Time is injected so drop expiry can be tested with a clock the test moves by hand. + services.TryAddSingleton(TimeProvider.System); return services; } diff --git a/NainOrder.Application/Interfaces/IRepositories.cs b/NainOrder.Application/Interfaces/IRepositories.cs index db1cabf..bc5fae1 100644 --- a/NainOrder.Application/Interfaces/IRepositories.cs +++ b/NainOrder.Application/Interfaces/IRepositories.cs @@ -38,6 +38,19 @@ Task> GetAllAsync( Task AddAsync(Product product, CancellationToken cancellationToken = default); } +public interface IDropRepository +{ + /// Loads the drop with its holds, tracked: it is about to be mutated. + Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default); + + Task> GetRecentAsync(int count, CancellationToken cancellationToken = default); + + /// Drops that still carry an active hold whose window has ended at . + Task> GetWithDueHoldsAsync(DateTime now, CancellationToken cancellationToken = default); + + Task AddAsync(Drop drop, CancellationToken cancellationToken = default); +} + public interface ICustomerRepository { Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default); diff --git a/NainOrder.Application/Interfaces/IServices.cs b/NainOrder.Application/Interfaces/IServices.cs index 5b1ac35..c476cd1 100644 --- a/NainOrder.Application/Interfaces/IServices.cs +++ b/NainOrder.Application/Interfaces/IServices.cs @@ -35,6 +35,18 @@ public interface ICustomerService Task> GetAllCustomersAsync(CancellationToken cancellationToken = default); } +public interface IDropService +{ + Task CreateAsync(CreateDropRequest request, CancellationToken cancellationToken = default); + Task GetAsync(Guid dropId, string? buyerToken, CancellationToken cancellationToken = default); + Task> ListAsync(CancellationToken cancellationToken = default); + Task TakeAsync(Guid dropId, string buyerToken, TakeUnitsRequest request, CancellationToken cancellationToken = default); + Task ConfirmAsync(Guid dropId, Guid holdId, string buyerToken, CancellationToken cancellationToken = default); + + /// Expires every hold whose window has ended, across all drops. Returns how many. + Task ExpireDueHoldsAsync(CancellationToken cancellationToken = default); +} + public interface IDashboardService { Task GetStatsAsync(CancellationToken cancellationToken = default); diff --git a/NainOrder.Application/Services/DropService.cs b/NainOrder.Application/Services/DropService.cs new file mode 100644 index 0000000..f8e3f8f --- /dev/null +++ b/NainOrder.Application/Services/DropService.cs @@ -0,0 +1,127 @@ +using NainOrder.Application.Common; +using NainOrder.Application.DTOs; +using NainOrder.Application.Exceptions; +using NainOrder.Application.Interfaces; +using NainOrder.Domain.Entities; + +namespace NainOrder.Application.Services; + +/// +/// Orchestrates drops. Every rule lives in ; this class loads the aggregate, +/// supplies the clock, owns the transaction and projects to DTOs. +/// +public sealed class DropService : IDropService +{ + private readonly IDropRepository _drops; + private readonly IProductRepository _products; + private readonly IOrderRepository _orders; + private readonly IUnitOfWork _unitOfWork; + private readonly TimeProvider _clock; + + public DropService( + IDropRepository drops, IProductRepository products, IOrderRepository orders, + IUnitOfWork unitOfWork, TimeProvider clock) + { + _drops = drops; + _products = products; + _orders = orders; + _unitOfWork = unitOfWork; + _clock = clock; + } + + private DateTime Now => _clock.GetUtcNow().UtcDateTime; + + public async Task CreateAsync(CreateDropRequest request, CancellationToken cancellationToken = default) + { + var product = await _products.GetByIdAsync(request.ProductId, cancellationToken) + ?? throw new NotFoundException("Product", request.ProductId); + + var drop = new Drop( + product.Id, product.Name, product.Sku, product.Price, + request.TotalUnits, Now.AddSeconds(request.OpensInSeconds), request.PerBuyerLimit, request.HoldSeconds); + + await _drops.AddAsync(drop, cancellationToken); + await _unitOfWork.SaveChangesAsync(cancellationToken); + + return MapToDto(drop, null); + } + + public async Task GetAsync(Guid dropId, string? buyerToken, CancellationToken cancellationToken = default) => + MapToDto(await LoadAsync(dropId, cancellationToken), buyerToken); + + public async Task> ListAsync(CancellationToken cancellationToken = default) => + (await _drops.GetRecentAsync(20, cancellationToken)).Select(d => MapToDto(d, null)).ToList(); + + public async Task TakeAsync( + Guid dropId, string buyerToken, TakeUnitsRequest request, CancellationToken cancellationToken = default) + { + var drop = await LoadAsync(dropId, cancellationToken); + + return await _unitOfWork.ExecuteInTransactionAsync(async ct => + { + var hold = drop.Take(buyerToken, request.Quantity, Now); + await _unitOfWork.SaveChangesAsync(ct); + return MapHold(hold); + }, cancellationToken); + } + + public async Task ConfirmAsync( + Guid dropId, Guid holdId, string buyerToken, CancellationToken cancellationToken = default) + { + var drop = await LoadAsync(dropId, cancellationToken); + + return await _unitOfWork.ExecuteInTransactionAsync(async ct => + { + var hold = drop.Holds.FirstOrDefault(h => h.Id == holdId && h.BuyerToken == buyerToken); + + // The order is built first so the hold can record it; nothing is persisted unless + // Confirm accepts, because the whole transaction rolls back on a rejection. + var order = new Order(DropDefaults.AnonymousBuyerId); + order.AddItem(drop.ProductId, drop.ProductName, drop.ProductSku, drop.UnitPrice, hold?.Quantity ?? 1); + order.MarkAsPaid(); + + drop.Confirm(holdId, buyerToken, Now, order.Id); + + await _orders.AddAsync(order, ct); + await _unitOfWork.SaveChangesAsync(ct); + return MapOrder(order); + }, cancellationToken); + } + + public async Task ExpireDueHoldsAsync(CancellationToken cancellationToken = default) + { + var now = Now; + var due = await _drops.GetWithDueHoldsAsync(now, cancellationToken); + if (due.Count == 0) return 0; + + var expired = due.Sum(d => d.ExpireHolds(now)); + await _unitOfWork.SaveChangesAsync(cancellationToken); + return expired; + } + + private async Task LoadAsync(Guid dropId, CancellationToken cancellationToken) => + await _drops.GetByIdAsync(dropId, cancellationToken) ?? throw new NotFoundException("Drop", dropId); + + private DropDto MapToDto(Drop drop, string? buyerToken) + { + var now = Now; + var mine = buyerToken is null + ? [] + : drop.Holds.Where(h => h.BuyerToken == buyerToken).OrderBy(h => h.CreatedAt).Select(MapHold).ToList(); + + return new DropDto( + drop.Id, drop.ProductId, drop.ProductName, drop.ProductSku, drop.UnitPrice, + drop.TotalUnits, drop.AvailableAt(now), drop.HeldAt(now), drop.SoldUnits, + drop.StatusAt(now).ToString(), drop.OpensAt, drop.PerBuyerLimit, drop.HoldSeconds, now, mine); + } + + private static HoldDto MapHold(Hold hold) => + new(hold.Id, hold.Quantity, hold.ExpiresAt, hold.State.ToString(), hold.OrderId); + + private static OrderDto MapOrder(Order order) => new( + order.Id, order.Reference, order.CustomerId, null, null, order.Status.ToString(), + order.TotalAmount, order.TotalUnits, order.IsEditable, + order.NextStates.Select(s => s.ToString()).ToList(), + order.CreatedAt, order.PaidAt, order.ShippedAt, order.CancelledAt, + order.Items.Select(i => new OrderItemDto(i.ProductId, i.ProductName, i.ProductSku, i.UnitPrice, i.Quantity, i.TotalPrice)).ToList()); +} diff --git a/NainOrder.Domain/Entities/Drop.cs b/NainOrder.Domain/Entities/Drop.cs new file mode 100644 index 0000000..a23a79d --- /dev/null +++ b/NainOrder.Domain/Entities/Drop.cs @@ -0,0 +1,131 @@ +using NainOrder.Domain.Enums; +using NainOrder.Domain.Exceptions; +using NainOrder.Domain.Primitives; + +namespace NainOrder.Domain.Entities; + +/// +/// A limited sale of a fixed number of units. The drop owns its units for as long as it is live +/// ([ADR-0008]): it never borrows , so "exactly N units" cannot +/// be disturbed by the catalogue. Time always comes from the caller, which keeps the aggregate +/// deterministic and expiry testable without sleeping. +/// +public class Drop : AggregateRoot +{ + public const int MaxUnits = 1_000; + public const int MinHoldSeconds = 5; + public const int MaxHoldSeconds = 3_600; + + public Guid ProductId { get; private set; } + public string ProductName { get; private set; } = null!; + public string ProductSku { get; private set; } = null!; + public decimal UnitPrice { get; private set; } + public int TotalUnits { get; private set; } + public DateTime OpensAt { get; private set; } + public int PerBuyerLimit { get; private set; } + public int HoldSeconds { get; private set; } + public DateTime CreatedAt { get; private set; } + + /// Optimistic concurrency token, bumped on every mutation (same pattern as ADR-0007). + public int Version { get; private set; } + + private readonly List _holds = new(); + public IReadOnlyCollection Holds => _holds.AsReadOnly(); + + private Drop() { } + + public Drop(Guid productId, string productName, string productSku, decimal unitPrice, + int totalUnits, DateTime opensAt, int perBuyerLimit, int holdSeconds) + : base(Guid.NewGuid()) + { + if (string.IsNullOrWhiteSpace(productName)) + throw new InvalidDomainDataException(nameof(productName), "Product name is required."); + if (unitPrice < 0) + throw new InvalidDomainDataException(nameof(unitPrice), "Price cannot be negative."); + if (totalUnits is < 1 or > MaxUnits) + throw new InvalidDomainDataException(nameof(totalUnits), $"A drop holds 1 to {MaxUnits} units."); + if (perBuyerLimit < 1 || perBuyerLimit > totalUnits) + throw new InvalidDomainDataException(nameof(perBuyerLimit), "The per-buyer limit must be between 1 and the drop's units."); + if (holdSeconds is < MinHoldSeconds or > MaxHoldSeconds) + throw new InvalidDomainDataException(nameof(holdSeconds), $"A hold lasts {MinHoldSeconds} to {MaxHoldSeconds} seconds."); + + ProductId = productId; + ProductName = productName.Trim(); + ProductSku = productSku.Trim().ToUpperInvariant(); + UnitPrice = decimal.Round(unitPrice, 2, MidpointRounding.AwayFromZero); + TotalUnits = totalUnits; + OpensAt = opensAt; + PerBuyerLimit = perBuyerLimit; + HoldSeconds = holdSeconds; + CreatedAt = DateTime.UtcNow; + Version = 1; + } + + public int SoldUnits => _holds.Where(h => h.State == HoldState.Confirmed).Sum(h => h.Quantity); + + public int HeldAt(DateTime now) => _holds.Where(h => h.IsLiveAt(now)).Sum(h => h.Quantity); + + /// + /// Units still on offer. An unswept hold whose window has passed does not count, so + /// correctness never depends on a background job having run (REQ-083). + /// + public int AvailableAt(DateTime now) => TotalUnits - SoldUnits - HeldAt(now); + + public DropStatus StatusAt(DateTime now) => + now < OpensAt ? DropStatus.Scheduled + : AvailableAt(now) == 0 ? DropStatus.SoldOut + : DropStatus.Live; + + /// Reserves units for a buyer (REQ-081, REQ-082, REQ-088). + public Hold Take(string buyerToken, int quantity, DateTime now) + { + if (string.IsNullOrWhiteSpace(buyerToken)) + throw new InvalidDomainDataException(nameof(buyerToken), "A buyer token is required."); + if (quantity < 1) + throw new InvalidDomainDataException(nameof(quantity), "Must take a positive quantity."); + if (now < OpensAt) + throw new DropNotLiveException(OpensAt); + + var owned = _holds + .Where(h => h.BuyerToken == buyerToken && (h.IsLiveAt(now) || h.State == HoldState.Confirmed)) + .Sum(h => h.Quantity); + if (owned + quantity > PerBuyerLimit) + throw new BuyerLimitReachedException(PerBuyerLimit, owned); + + var available = AvailableAt(now); + if (quantity > available) + throw new InsufficientStockException(quantity, available); + + var hold = new Hold(Id, buyerToken, quantity, now, HoldSeconds); + _holds.Add(hold); + Version++; + return hold; + } + + /// Turns an unexpired hold into a sale (REQ-084). + public Hold Confirm(Guid holdId, string buyerToken, DateTime now, Guid orderId) + { + // A hold that belongs to someone else is indistinguishable from one that does not exist. + var hold = _holds.FirstOrDefault(h => h.Id == holdId && h.BuyerToken == buyerToken) + ?? throw new HoldNotFoundException(holdId); + + if (hold.State == HoldState.Confirmed) + throw new HoldNotActiveException(holdId); + if (hold.State == HoldState.Expired || hold.ExpiresAt <= now) + throw new HoldExpiredException(holdId); + + hold.Confirm(orderId); + Version++; + return hold; + } + + /// Marks holds whose window has ended as expired and reports how many (REQ-083). + public int ExpireHolds(DateTime now) + { + var due = _holds.Where(h => h.State == HoldState.Active && h.ExpiresAt <= now).ToList(); + foreach (var hold in due) hold.Expire(); + + if (due.Count > 0) Version++; + return due.Count; + } +} diff --git a/NainOrder.Domain/Entities/Hold.cs b/NainOrder.Domain/Entities/Hold.cs new file mode 100644 index 0000000..fbc5f39 --- /dev/null +++ b/NainOrder.Domain/Entities/Hold.cs @@ -0,0 +1,45 @@ +using NainOrder.Domain.Enums; +using NainOrder.Domain.Primitives; + +namespace NainOrder.Domain.Entities; + +/// +/// A short reservation of drop units for one buyer. It only changes through its +/// , which is the authority on the drop's unit count. +/// +public class Hold : Entity +{ + public Guid DropId { get; private set; } + public string BuyerToken { get; private set; } = null!; + public int Quantity { get; private set; } + public DateTime CreatedAt { get; private set; } + public DateTime ExpiresAt { get; private set; } + public HoldState State { get; private set; } + + /// The paid order a confirmed hold became. + public Guid? OrderId { get; private set; } + + private Hold() { } + + internal Hold(Guid dropId, string buyerToken, int quantity, DateTime now, int holdSeconds) + : base(Guid.NewGuid()) + { + DropId = dropId; + BuyerToken = buyerToken; + Quantity = quantity; + CreatedAt = now; + ExpiresAt = now.AddSeconds(holdSeconds); + State = HoldState.Active; + } + + /// True while the hold still reserves units at . + internal bool IsLiveAt(DateTime now) => State == HoldState.Active && ExpiresAt > now; + + internal void Confirm(Guid orderId) + { + State = HoldState.Confirmed; + OrderId = orderId; + } + + internal void Expire() => State = HoldState.Expired; +} diff --git a/NainOrder.Domain/Enums/DropEnums.cs b/NainOrder.Domain/Enums/DropEnums.cs new file mode 100644 index 0000000..fb36840 --- /dev/null +++ b/NainOrder.Domain/Enums/DropEnums.cs @@ -0,0 +1,16 @@ +namespace NainOrder.Domain.Enums; + +/// Where a drop stands on the clock and its counters. Derived, never stored. +public enum DropStatus +{ + Scheduled = 1, + Live = 2, + SoldOut = 3 +} + +public enum HoldState +{ + Active = 1, + Confirmed = 2, + Expired = 3 +} diff --git a/NainOrder.Domain/Exceptions/DomainException.cs b/NainOrder.Domain/Exceptions/DomainException.cs index 9fddb3d..e3be25c 100644 --- a/NainOrder.Domain/Exceptions/DomainException.cs +++ b/NainOrder.Domain/Exceptions/DomainException.cs @@ -68,6 +68,58 @@ public DuplicateOrderItemException(Guid productId) => ProductId = productId; } +/// The drop has not opened yet. +public sealed class DropNotLiveException : DomainException +{ + public override string Code => "drop_not_live"; + + public DateTime OpensAt { get; } + + public DropNotLiveException(DateTime opensAt) + : base($"The drop opens at {opensAt:O}.") + => OpensAt = opensAt; +} + +/// The buyer already holds or bought as many units as one buyer may. +public sealed class BuyerLimitReachedException : DomainException +{ + public override string Code => "buyer_limit_reached"; + + public int Limit { get; } + public int Owned { get; } + + public BuyerLimitReachedException(int limit, int owned) + : base($"Limit of {limit} per buyer reached ({owned} already held or bought).") + { + Limit = limit; + Owned = owned; + } +} + +/// The hold's window ended before it was confirmed. +public sealed class HoldExpiredException : DomainException +{ + public override string Code => "hold_expired"; + + public HoldExpiredException(Guid holdId) : base($"Hold {holdId} has expired.") { } +} + +/// The hold exists but can no longer be confirmed (already confirmed). +public sealed class HoldNotActiveException : DomainException +{ + public override string Code => "hold_not_active"; + + public HoldNotActiveException(Guid holdId) : base($"Hold {holdId} is no longer active.") { } +} + +/// No hold with that id belongs to this buyer in this drop. +public sealed class HoldNotFoundException : DomainException +{ + public override string Code => "hold_not_found"; + + public HoldNotFoundException(Guid holdId) : base($"Hold {holdId} was not found.") { } +} + /// La línea de pedido referenciada no pertenece al pedido. public sealed class OrderItemNotFoundException : DomainException { diff --git a/NainOrder.Infrastructure/DependencyInjection.cs b/NainOrder.Infrastructure/DependencyInjection.cs index daf75a6..a986bc7 100644 --- a/NainOrder.Infrastructure/DependencyInjection.cs +++ b/NainOrder.Infrastructure/DependencyInjection.cs @@ -20,6 +20,7 @@ public static IServiceCollection AddInfrastructure(this IServiceCollection servi services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); return services; diff --git a/NainOrder.Infrastructure/Persistence/Configurations/DropConfigurations.cs b/NainOrder.Infrastructure/Persistence/Configurations/DropConfigurations.cs new file mode 100644 index 0000000..f79e7b8 --- /dev/null +++ b/NainOrder.Infrastructure/Persistence/Configurations/DropConfigurations.cs @@ -0,0 +1,52 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using NainOrder.Domain.Entities; +using NainOrder.Infrastructure.Persistence.Converters; + +namespace NainOrder.Infrastructure.Persistence.Configurations; + +public class DropConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(d => d.Id); + builder.Property(d => d.Id).ValueGeneratedNever(); + + builder.Property(d => d.ProductName).IsRequired().HasMaxLength(Product.MaxNameLength); + builder.Property(d => d.ProductSku).IsRequired().HasMaxLength(Product.MaxSkuLength); + builder.Property(d => d.UnitPrice).HasConversion(); + + // Same pattern as ADR-0007: a losing writer fails the UPDATE instead of overwriting. + builder.Property(d => d.Version).IsConcurrencyToken(); + + builder.HasMany(d => d.Holds) + .WithOne() + .HasForeignKey(h => h.DropId) + .OnDelete(DeleteBehavior.Cascade); + + // Holds change only through the aggregate, so EF reads and writes the backing field. + builder.Navigation(d => d.Holds).UsePropertyAccessMode(PropertyAccessMode.Field); + + builder.HasOne() + .WithMany() + .HasForeignKey(d => d.ProductId) + .OnDelete(DeleteBehavior.Restrict); + + builder.HasIndex(d => d.CreatedAt); + } +} + +public class HoldConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(h => h.Id); + builder.Property(h => h.Id).ValueGeneratedNever(); + + builder.Property(h => h.BuyerToken).IsRequired().HasMaxLength(64); + builder.Property(h => h.State).HasConversion(); + + builder.HasIndex(h => new { h.DropId, h.BuyerToken }); + builder.HasIndex(h => new { h.State, h.ExpiresAt }); + } +} diff --git a/NainOrder.Infrastructure/Persistence/Migrations/20261020152656_AddDrops.Designer.cs b/NainOrder.Infrastructure/Persistence/Migrations/20261020152656_AddDrops.Designer.cs new file mode 100644 index 0000000..2625103 --- /dev/null +++ b/NainOrder.Infrastructure/Persistence/Migrations/20261020152656_AddDrops.Designer.cs @@ -0,0 +1,323 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NainOrder.Infrastructure.Persistence; + +#nullable disable + +namespace NainOrder.Infrastructure.Persistence.Migrations +{ + [DbContext(typeof(NainOrderDbContext))] + [Migration("20261020152656_AddDrops")] + partial class AddDrops + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "10.0.10"); + + modelBuilder.Entity("NainOrder.Domain.Entities.Customer", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email") + .IsUnique(); + + b.ToTable("Customers"); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Drop", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("HoldSeconds") + .HasColumnType("INTEGER"); + + b.Property("OpensAt") + .HasColumnType("TEXT"); + + b.Property("PerBuyerLimit") + .HasColumnType("INTEGER"); + + b.Property("ProductId") + .HasColumnType("TEXT"); + + b.Property("ProductName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("ProductSku") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TotalUnits") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("INTEGER"); + + b.Property("Version") + .IsConcurrencyToken() + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CreatedAt"); + + b.HasIndex("ProductId"); + + b.ToTable("Drops"); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Hold", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BuyerToken") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("DropId") + .HasColumnType("TEXT"); + + b.Property("ExpiresAt") + .HasColumnType("TEXT"); + + b.Property("OrderId") + .HasColumnType("TEXT"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DropId", "BuyerToken"); + + b.HasIndex("State", "ExpiresAt"); + + b.ToTable("Holds"); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Order", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CancelledAt") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CustomerId") + .HasColumnType("TEXT"); + + b.Property("PaidAt") + .HasColumnType("TEXT"); + + b.Property("Reference") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("TEXT"); + + b.Property("ShippedAt") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TotalAmount") + .HasColumnType("INTEGER"); + + b.Property("TotalUnits") + .HasColumnType("INTEGER"); + + b.Property("Version") + .IsConcurrencyToken() + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CreatedAt"); + + b.HasIndex("CustomerId"); + + b.HasIndex("Reference") + .IsUnique(); + + b.HasIndex("Status"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.OrderItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("OrderId") + .HasColumnType("TEXT"); + + b.Property("ProductId") + .HasColumnType("TEXT"); + + b.Property("ProductName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("ProductSku") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("OrderId", "ProductId") + .IsUnique(); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Product", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("INTEGER"); + + b.Property("Sku") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("StockQuantity") + .HasColumnType("INTEGER"); + + b.Property("Version") + .IsConcurrencyToken() + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("Sku") + .IsUnique(); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Drop", b => + { + b.HasOne("NainOrder.Domain.Entities.Product", null) + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Hold", b => + { + b.HasOne("NainOrder.Domain.Entities.Drop", null) + .WithMany("Holds") + .HasForeignKey("DropId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Order", b => + { + b.HasOne("NainOrder.Domain.Entities.Customer", null) + .WithMany() + .HasForeignKey("CustomerId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.OrderItem", b => + { + b.HasOne("NainOrder.Domain.Entities.Order", null) + .WithMany("Items") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("NainOrder.Domain.Entities.Product", null) + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Drop", b => + { + b.Navigation("Holds"); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Order", b => + { + b.Navigation("Items"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/NainOrder.Infrastructure/Persistence/Migrations/20261020152656_AddDrops.cs b/NainOrder.Infrastructure/Persistence/Migrations/20261020152656_AddDrops.cs new file mode 100644 index 0000000..227b3c1 --- /dev/null +++ b/NainOrder.Infrastructure/Persistence/Migrations/20261020152656_AddDrops.cs @@ -0,0 +1,96 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace NainOrder.Infrastructure.Persistence.Migrations +{ + /// + public partial class AddDrops : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Drops", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + ProductId = table.Column(type: "TEXT", nullable: false), + ProductName = table.Column(type: "TEXT", maxLength: 200, nullable: false), + ProductSku = table.Column(type: "TEXT", maxLength: 50, nullable: false), + UnitPrice = table.Column(type: "INTEGER", nullable: false), + TotalUnits = table.Column(type: "INTEGER", nullable: false), + OpensAt = table.Column(type: "TEXT", nullable: false), + PerBuyerLimit = table.Column(type: "INTEGER", nullable: false), + HoldSeconds = table.Column(type: "INTEGER", nullable: false), + CreatedAt = table.Column(type: "TEXT", nullable: false), + Version = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Drops", x => x.Id); + table.ForeignKey( + name: "FK_Drops_Products_ProductId", + column: x => x.ProductId, + principalTable: "Products", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Holds", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + DropId = table.Column(type: "TEXT", nullable: false), + BuyerToken = table.Column(type: "TEXT", maxLength: 64, nullable: false), + Quantity = table.Column(type: "INTEGER", nullable: false), + CreatedAt = table.Column(type: "TEXT", nullable: false), + ExpiresAt = table.Column(type: "TEXT", nullable: false), + State = table.Column(type: "INTEGER", nullable: false), + OrderId = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Holds", x => x.Id); + table.ForeignKey( + name: "FK_Holds_Drops_DropId", + column: x => x.DropId, + principalTable: "Drops", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Drops_CreatedAt", + table: "Drops", + column: "CreatedAt"); + + migrationBuilder.CreateIndex( + name: "IX_Drops_ProductId", + table: "Drops", + column: "ProductId"); + + migrationBuilder.CreateIndex( + name: "IX_Holds_DropId_BuyerToken", + table: "Holds", + columns: new[] { "DropId", "BuyerToken" }); + + migrationBuilder.CreateIndex( + name: "IX_Holds_State_ExpiresAt", + table: "Holds", + columns: new[] { "State", "ExpiresAt" }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Holds"); + + migrationBuilder.DropTable( + name: "Drops"); + } + } +} diff --git a/NainOrder.Infrastructure/Persistence/Migrations/NainOrderDbContextModelSnapshot.cs b/NainOrder.Infrastructure/Persistence/Migrations/NainOrderDbContextModelSnapshot.cs index f66ee59..0f1c693 100644 --- a/NainOrder.Infrastructure/Persistence/Migrations/NainOrderDbContextModelSnapshot.cs +++ b/NainOrder.Infrastructure/Persistence/Migrations/NainOrderDbContextModelSnapshot.cs @@ -43,6 +43,92 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Customers"); }); + modelBuilder.Entity("NainOrder.Domain.Entities.Drop", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("HoldSeconds") + .HasColumnType("INTEGER"); + + b.Property("OpensAt") + .HasColumnType("TEXT"); + + b.Property("PerBuyerLimit") + .HasColumnType("INTEGER"); + + b.Property("ProductId") + .HasColumnType("TEXT"); + + b.Property("ProductName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("ProductSku") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TotalUnits") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("INTEGER"); + + b.Property("Version") + .IsConcurrencyToken() + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CreatedAt"); + + b.HasIndex("ProductId"); + + b.ToTable("Drops"); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Hold", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BuyerToken") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("DropId") + .HasColumnType("TEXT"); + + b.Property("ExpiresAt") + .HasColumnType("TEXT"); + + b.Property("OrderId") + .HasColumnType("TEXT"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DropId", "BuyerToken"); + + b.HasIndex("State", "ExpiresAt"); + + b.ToTable("Holds"); + }); + modelBuilder.Entity("NainOrder.Domain.Entities.Order", b => { b.Property("Id") @@ -177,6 +263,24 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Products"); }); + modelBuilder.Entity("NainOrder.Domain.Entities.Drop", b => + { + b.HasOne("NainOrder.Domain.Entities.Product", null) + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("NainOrder.Domain.Entities.Hold", b => + { + b.HasOne("NainOrder.Domain.Entities.Drop", null) + .WithMany("Holds") + .HasForeignKey("DropId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("NainOrder.Domain.Entities.Order", b => { b.HasOne("NainOrder.Domain.Entities.Customer", null) @@ -201,6 +305,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); + modelBuilder.Entity("NainOrder.Domain.Entities.Drop", b => + { + b.Navigation("Holds"); + }); + modelBuilder.Entity("NainOrder.Domain.Entities.Order", b => { b.Navigation("Items"); diff --git a/NainOrder.Infrastructure/Persistence/NainOrderDbContext.cs b/NainOrder.Infrastructure/Persistence/NainOrderDbContext.cs index 69524da..00fc2c1 100644 --- a/NainOrder.Infrastructure/Persistence/NainOrderDbContext.cs +++ b/NainOrder.Infrastructure/Persistence/NainOrderDbContext.cs @@ -9,6 +9,8 @@ public class NainOrderDbContext : DbContext public DbSet OrderItems => Set(); public DbSet Products => Set(); public DbSet Customers => Set(); + public DbSet Drops => Set(); + public DbSet Holds => Set(); public NainOrderDbContext(DbContextOptions options) : base(options) { diff --git a/NainOrder.Infrastructure/Persistence/Repositories/DropRepository.cs b/NainOrder.Infrastructure/Persistence/Repositories/DropRepository.cs new file mode 100644 index 0000000..785e780 --- /dev/null +++ b/NainOrder.Infrastructure/Persistence/Repositories/DropRepository.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore; +using NainOrder.Application.Interfaces; +using NainOrder.Domain.Entities; +using NainOrder.Domain.Enums; + +namespace NainOrder.Infrastructure.Persistence.Repositories; + +public class DropRepository : IDropRepository +{ + private readonly NainOrderDbContext _context; + + public DropRepository(NainOrderDbContext context) => _context = context; + + public Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default) => + _context.Drops + .Include(d => d.Holds) + .FirstOrDefaultAsync(d => d.Id == id, cancellationToken); + + public async Task> GetRecentAsync(int count, CancellationToken cancellationToken = default) => + await _context.Drops + .AsNoTracking() + .Include(d => d.Holds) + .OrderByDescending(d => d.CreatedAt) + .Take(count) + .ToListAsync(cancellationToken); + + public async Task> GetWithDueHoldsAsync(DateTime now, CancellationToken cancellationToken = default) => + await _context.Drops + .Include(d => d.Holds) + .Where(d => d.Holds.Any(h => h.State == HoldState.Active && h.ExpiresAt <= now)) + .ToListAsync(cancellationToken); + + public async Task AddAsync(Drop drop, CancellationToken cancellationToken = default) => + await _context.Drops.AddAsync(drop, cancellationToken); +} diff --git a/NainOrder.Infrastructure/Persistence/Seeding/DatabaseSeeder.cs b/NainOrder.Infrastructure/Persistence/Seeding/DatabaseSeeder.cs index 79f2ed8..c2d76db 100644 --- a/NainOrder.Infrastructure/Persistence/Seeding/DatabaseSeeder.cs +++ b/NainOrder.Infrastructure/Persistence/Seeding/DatabaseSeeder.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore; +using NainOrder.Application.Common; using NainOrder.Domain.Entities; namespace NainOrder.Infrastructure.Persistence.Seeding; @@ -41,6 +42,7 @@ private static readonly (string Name, string Email)[] CustomerSeed = public static async Task SeedAsync(NainOrderDbContext context, CancellationToken cancellationToken = default) { var changed = await SeedDemoCustomerAsync(context, cancellationToken); + changed |= await SeedAnonymousBuyerAsync(context, cancellationToken); changed |= await SeedCustomersAsync(context, cancellationToken); changed |= await SeedCatalogAsync(context, cancellationToken); @@ -63,6 +65,18 @@ private static async Task SeedDemoCustomerAsync(NainOrderDbContext context return true; } + /// The single customer all drop orders belong to: buyers are anonymous (Q-005). + private static async Task SeedAnonymousBuyerAsync(NainOrderDbContext context, CancellationToken cancellationToken) + { + if (await context.Customers.AnyAsync(c => c.Id == DropDefaults.AnonymousBuyerId, cancellationToken)) + return false; + + var entry = context.Customers.Add(new Customer("Anonymous drop buyer", "drop-buyers@naindev.com")); + entry.Property(nameof(Customer.Id)).CurrentValue = DropDefaults.AnonymousBuyerId; + + return true; + } + private static async Task SeedCustomersAsync(NainOrderDbContext context, CancellationToken cancellationToken) { var existing = await context.Customers diff --git a/NainOrder.Tests/Api/DropFlowTests.cs b/NainOrder.Tests/Api/DropFlowTests.cs new file mode 100644 index 0000000..9b15fe4 --- /dev/null +++ b/NainOrder.Tests/Api/DropFlowTests.cs @@ -0,0 +1,244 @@ +using System.Net; +using System.Net.Http.Json; +using System.Text.Json; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using NainOrder.Application.DTOs; + +namespace NainOrder.Tests.Api; + +/// A clock the test moves by hand, so hold expiry is exercised without sleeping. +public sealed class TestClock : TimeProvider +{ + private DateTimeOffset _now = DateTimeOffset.UtcNow; + + public override DateTimeOffset GetUtcNow() => _now; + + public void Advance(TimeSpan by) => _now += by; +} + +/// REQ-080 to REQ-086 and REQ-088 over HTTP, on the real application. +public class DropFlowTests : IClassFixture +{ + private static readonly JsonSerializerOptions Json = new(JsonSerializerDefaults.Web); + + private readonly TestClock _clock = new(); + private readonly WebApplicationFactory _factory; + private readonly HttpClient _client; + + public DropFlowTests(NainOrderApiFactory factory) + { + _factory = factory.WithWebHostBuilder(builder => builder.ConfigureServices(services => + { + services.RemoveAll(); + services.AddSingleton(_clock); + })); + _client = _factory.CreateClient(); + } + + private async Task CreateProductAsync() => + (await (await _client.PostAsJsonAsync("/api/products", + new CreateProductRequest($"NO-DROP-{Guid.NewGuid():N}"[..20], "Limited sneaker", 129.90m, 1), Json)) + .Content.ReadFromJsonAsync(Json))!.Id; + + private async Task CreateDropAsync(int units, int perBuyer = 1, int holdSeconds = 60, int opensInSeconds = 0) + { + var response = await _client.PostAsJsonAsync("/api/drops", new + { + productId = await CreateProductAsync(), + totalUnits = units, + perBuyerLimit = perBuyer, + holdSeconds, + opensInSeconds + }, Json); + + response.EnsureSuccessStatusCode(); + return (await response.Content.ReadFromJsonAsync(Json))!; + } + + private static HttpRequestMessage Post(string url, string buyer, object? body = null) + { + var request = new HttpRequestMessage(HttpMethod.Post, url) { Content = JsonContent.Create(body ?? new { }, options: Json) }; + request.Headers.Add("X-Buyer-Token", buyer); + return request; + } + + private async Task TakeAsync(Guid dropId, string buyer, int quantity = 1) => + await _client.SendAsync(Post($"/api/drops/{dropId}/holds", buyer, new { quantity })); + + private async Task GetAsync(Guid dropId, string? buyer = null) + { + var request = new HttpRequestMessage(HttpMethod.Get, $"/api/drops/{dropId}"); + if (buyer is not null) request.Headers.Add("X-Buyer-Token", buyer); + return (await (await _client.SendAsync(request)).Content.ReadFromJsonAsync(Json))!; + } + + private static async Task CodeOf(HttpResponseMessage response) => + (await response.Content.ReadFromJsonAsync(Json)).GetProperty("code").GetString(); + + [Fact] + public async Task A_new_drop_reports_its_units_and_goes_live() + { + var drop = await CreateDropAsync(units: 8, perBuyer: 2); + + Assert.Equal("Live", drop.Status); + Assert.Equal(8, drop.TotalUnits); + Assert.Equal(8, drop.Available); + Assert.Equal(0, drop.Held + drop.Sold); + } + + [Fact] + public async Task A_scheduled_drop_rejects_takes_until_it_opens() + { + var drop = await CreateDropAsync(units: 5, opensInSeconds: 120); + + var early = await TakeAsync(drop.Id, "buyer-a"); + Assert.Equal(HttpStatusCode.Conflict, early.StatusCode); + Assert.Equal("drop_not_live", await CodeOf(early)); + + _clock.Advance(TimeSpan.FromSeconds(121)); + Assert.Equal(HttpStatusCode.OK, (await TakeAsync(drop.Id, "buyer-a")).StatusCode); + } + + [Fact] + public async Task Taking_and_confirming_turns_a_hold_into_a_paid_order() + { + var drop = await CreateDropAsync(units: 5, perBuyer: 2); + + var take = await TakeAsync(drop.Id, "buyer-a", 2); + var hold = (await take.Content.ReadFromJsonAsync(Json))!; + + var confirm = await _client.SendAsync(Post($"/api/drops/{drop.Id}/holds/{hold.Id}/confirm", "buyer-a")); + confirm.EnsureSuccessStatusCode(); + var order = (await confirm.Content.ReadFromJsonAsync(Json))!; + + Assert.Equal("Paid", order.Status); + Assert.Equal(2, order.TotalUnits); + Assert.Equal(259.80m, order.TotalAmount); + + var after = await GetAsync(drop.Id, "buyer-a"); + Assert.Equal(2, after.Sold); + Assert.Equal(3, after.Available); + } + + [Fact] + public async Task A_buyer_over_the_limit_is_rejected_with_409() + { + var drop = await CreateDropAsync(units: 5, perBuyer: 1); + await TakeAsync(drop.Id, "buyer-a"); + + var second = await TakeAsync(drop.Id, "buyer-a"); + + Assert.Equal(HttpStatusCode.Conflict, second.StatusCode); + Assert.Equal("buyer_limit_reached", await CodeOf(second)); + } + + [Fact] + public async Task An_unconfirmed_hold_expires_and_returns_its_units() + { + var drop = await CreateDropAsync(units: 2, perBuyer: 2, holdSeconds: 30); + var hold = (await (await TakeAsync(drop.Id, "buyer-a", 2)).Content.ReadFromJsonAsync(Json))!; + Assert.Equal("SoldOut", (await GetAsync(drop.Id)).Status); + + _clock.Advance(TimeSpan.FromSeconds(31)); + + var after = await GetAsync(drop.Id); + Assert.Equal("Live", after.Status); + Assert.Equal(2, after.Available); + + var late = await _client.SendAsync(Post($"/api/drops/{drop.Id}/holds/{hold.Id}/confirm", "buyer-a")); + Assert.Equal(HttpStatusCode.Conflict, late.StatusCode); + Assert.Equal("hold_expired", await CodeOf(late)); + } + + [Fact] + public async Task Sweeping_persists_the_expiry_of_due_holds() + { + var drop = await CreateDropAsync(units: 3, perBuyer: 3, holdSeconds: 30); + await TakeAsync(drop.Id, "buyer-a", 2); + _clock.Advance(TimeSpan.FromSeconds(31)); + + // The background sweeper may get there first; either way the hold must end up Expired. + using (var scope = _factory.Services.CreateScope()) + await scope.ServiceProvider.GetRequiredService().ExpireDueHoldsAsync(); + + var after = await GetAsync(drop.Id, "buyer-a"); + Assert.Equal("Expired", Assert.Single(after.MyHolds).State); + Assert.Equal(3, after.Available); + } + + [Fact] + public async Task A_hold_of_another_buyer_cannot_be_confirmed() + { + var drop = await CreateDropAsync(units: 3); + var hold = (await (await TakeAsync(drop.Id, "buyer-a")).Content.ReadFromJsonAsync(Json))!; + + var stolen = await _client.SendAsync(Post($"/api/drops/{drop.Id}/holds/{hold.Id}/confirm", "buyer-b")); + + Assert.Equal(HttpStatusCode.NotFound, stolen.StatusCode); + Assert.Equal("hold_not_found", await CodeOf(stolen)); + } + + [Fact] + public async Task Taking_without_a_buyer_token_is_a_400() + { + var drop = await CreateDropAsync(units: 3); + + var response = await _client.PostAsJsonAsync($"/api/drops/{drop.Id}/holds", new { quantity = 1 }, Json); + + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + } + + /// REQ-085 under a real crowd: 40 buyers, 10 units, conflicts retried like a client would. + [Fact] + public async Task A_crowd_never_holds_or_sells_more_units_than_the_drop_contains() + { + const int units = 10; + const int buyers = 40; + var drop = await CreateDropAsync(units, perBuyer: 1); + var startGun = new TaskCompletionSource(); + + var attempts = Enumerable.Range(0, buyers).Select(index => Task.Run(async () => + { + await startGun.Task; + for (var attempt = 0; attempt < 60; attempt++) + { + var response = await TakeAsync(drop.Id, $"crowd-{index}"); + if (response.IsSuccessStatusCode) return "won"; + + var code = await CodeOf(response); + if (code != "concurrency_conflict") return code!; + } + + return "gave_up"; + })).ToList(); + + startGun.SetResult(); + var outcomes = await Task.WhenAll(attempts); + + var after = await GetAsync(drop.Id); + Assert.Equal(units, outcomes.Count(o => o == "won")); + Assert.All(outcomes.Where(o => o != "won"), o => Assert.Equal("insufficient_stock", o)); + Assert.Equal(units, after.Held + after.Sold); + Assert.Equal(0, after.Available); + Assert.Equal("SoldOut", after.Status); + } + + [Theory] + [InlineData(0, 1, 60)] + [InlineData(5, 6, 60)] + [InlineData(5, 1, 1)] + public async Task An_invalid_drop_configuration_is_rejected_with_400(int units, int perBuyer, int holdSeconds) + { + var response = await _client.PostAsJsonAsync("/api/drops", new + { + productId = await CreateProductAsync(), + totalUnits = units, + perBuyerLimit = perBuyer, + holdSeconds + }, Json); + + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + } +} diff --git a/NainOrder.Tests/Domain/DropTests.cs b/NainOrder.Tests/Domain/DropTests.cs new file mode 100644 index 0000000..c1f2ca7 --- /dev/null +++ b/NainOrder.Tests/Domain/DropTests.cs @@ -0,0 +1,228 @@ +using FsCheck.Xunit; +using NainOrder.Domain.Entities; +using NainOrder.Domain.Enums; +using NainOrder.Domain.Exceptions; + +namespace NainOrder.Tests.Domain; + +/// +/// REQ-080 to REQ-086 and REQ-088 on the aggregate alone, with an explicit clock so expiry +/// is tested without sleeping. +/// +public class DropTests +{ + private static readonly DateTime Opens = new(2026, 10, 20, 12, 0, 0, DateTimeKind.Utc); + private static DateTime At(int seconds) => Opens.AddSeconds(seconds); + + private static Drop NewDrop(int units = 10, int perBuyer = 2, int holdSeconds = 60, DateTime? opensAt = null) => + new(Guid.NewGuid(), "Last-unit sneaker", "NO-DROP-001", 129.90m, units, opensAt ?? Opens, perBuyer, holdSeconds); + + [Fact] + public void A_drop_is_scheduled_until_it_opens_and_live_afterwards() + { + var drop = NewDrop(); + + Assert.Equal(DropStatus.Scheduled, drop.StatusAt(Opens.AddSeconds(-1))); + Assert.Equal(DropStatus.Live, drop.StatusAt(Opens)); + } + + [Fact] + public void Taking_from_a_drop_that_is_not_live_is_rejected() + { + var drop = NewDrop(); + + var error = Assert.Throws(() => drop.Take("buyer-a", 1, At(-5))); + + Assert.Equal("drop_not_live", error.Code); + Assert.Equal(10, drop.AvailableAt(At(-5))); + } + + [Fact] + public void Taking_units_creates_a_hold_that_reduces_availability() + { + var drop = NewDrop(); + + var hold = drop.Take("buyer-a", 2, At(1)); + + Assert.Equal(HoldState.Active, hold.State); + Assert.Equal(2, hold.Quantity); + Assert.Equal(At(1).AddSeconds(60), hold.ExpiresAt); + Assert.Equal(8, drop.AvailableAt(At(2))); + Assert.Equal(2, drop.HeldAt(At(2))); + } + + [Fact] + public void A_buyer_cannot_exceed_the_per_buyer_limit_across_holds() + { + var drop = NewDrop(perBuyer: 2); + drop.Take("buyer-a", 1, At(1)); + + var error = Assert.Throws(() => drop.Take("buyer-a", 2, At(2))); + + Assert.Equal("buyer_limit_reached", error.Code); + Assert.Equal(9, drop.AvailableAt(At(2))); + } + + [Fact] + public void Asking_for_more_than_is_available_is_rejected_and_leaves_the_drop_untouched() + { + var drop = NewDrop(units: 3, perBuyer: 3); + drop.Take("buyer-a", 2, At(1)); + + var error = Assert.Throws(() => drop.Take("buyer-b", 2, At(2))); + + Assert.Equal(1, error.Available); + Assert.Equal(1, drop.AvailableAt(At(2))); + } + + [Fact] + public void An_unconfirmed_hold_returns_its_units_when_its_window_ends() + { + var drop = NewDrop(units: 3, perBuyer: 3, holdSeconds: 60); + drop.Take("buyer-a", 3, At(0)); + Assert.Equal(DropStatus.SoldOut, drop.StatusAt(At(30))); + + // Lazy correctness: the units are free by the clock even before anything sweeps the hold. + Assert.Equal(3, drop.AvailableAt(At(61))); + Assert.Equal(DropStatus.Live, drop.StatusAt(At(61))); + } + + [Fact] + public void Sweeping_marks_expired_holds_and_reports_how_many() + { + var drop = NewDrop(units: 5, perBuyer: 5, holdSeconds: 60); + var hold = drop.Take("buyer-a", 2, At(0)); + drop.Take("buyer-b", 1, At(50)); + + var swept = drop.ExpireHolds(At(70)); + + Assert.Equal(1, swept); + Assert.Equal(HoldState.Expired, hold.State); + Assert.Equal(4, drop.AvailableAt(At(70))); + } + + [Fact] + public void Confirming_a_hold_in_time_sells_the_units_for_good() + { + var drop = NewDrop(units: 5, perBuyer: 5); + var hold = drop.Take("buyer-a", 2, At(0)); + var orderId = Guid.NewGuid(); + + drop.Confirm(hold.Id, "buyer-a", At(10), orderId); + + Assert.Equal(HoldState.Confirmed, hold.State); + Assert.Equal(orderId, hold.OrderId); + Assert.Equal(2, drop.SoldUnits); + // A confirmed hold never expires. + Assert.Equal(3, drop.AvailableAt(At(10_000))); + } + + [Fact] + public void Confirming_after_the_window_is_rejected() + { + var drop = NewDrop(); + var hold = drop.Take("buyer-a", 1, At(0)); + + var error = Assert.Throws(() => drop.Confirm(hold.Id, "buyer-a", At(61), Guid.NewGuid())); + + Assert.Equal("hold_expired", error.Code); + Assert.Equal(0, drop.SoldUnits); + } + + [Fact] + public void Only_the_owner_can_confirm_a_hold() + { + var drop = NewDrop(); + var hold = drop.Take("buyer-a", 1, At(0)); + + Assert.Throws(() => drop.Confirm(hold.Id, "buyer-b", At(5), Guid.NewGuid())); + } + + [Fact] + public void A_hold_cannot_be_confirmed_twice() + { + var drop = NewDrop(); + var hold = drop.Take("buyer-a", 1, At(0)); + drop.Confirm(hold.Id, "buyer-a", At(5), Guid.NewGuid()); + + var error = Assert.Throws(() => drop.Confirm(hold.Id, "buyer-a", At(6), Guid.NewGuid())); + + Assert.Equal("hold_not_active", error.Code); + Assert.Equal(1, drop.SoldUnits); + } + + [Fact] + public void Expired_units_do_not_count_against_the_buyer_limit() + { + var drop = NewDrop(perBuyer: 1, holdSeconds: 60); + drop.Take("buyer-a", 1, At(0)); + + var second = drop.Take("buyer-a", 1, At(61)); + + Assert.Equal(HoldState.Active, second.State); + } + + [Fact] + public void A_drop_rejects_invalid_configuration() + { + Assert.Throws(() => NewDrop(units: 0)); + Assert.Throws(() => NewDrop(units: 5, perBuyer: 6)); + Assert.Throws(() => NewDrop(perBuyer: 0)); + Assert.Throws(() => NewDrop(holdSeconds: 1)); + } + + [Fact] + public void Every_mutation_moves_the_concurrency_token_forward() + { + var drop = NewDrop(); + var version = drop.Version; + + var hold = drop.Take("buyer-a", 1, At(0)); + Assert.True(drop.Version > version); + + version = drop.Version; + drop.Confirm(hold.Id, "buyer-a", At(1), Guid.NewGuid()); + Assert.True(drop.Version > version); + } + + /// REQ-085: whatever the sequence, held plus sold never exceeds the units of the drop. + [Property] + public void Held_plus_sold_never_exceeds_the_units_of_the_drop(int[] seeds) + { + var drop = NewDrop(units: 20, perBuyer: 4, holdSeconds: 30); + var holds = new List<(Hold Hold, string Buyer)>(); + var clock = 0; + + foreach (var seed in seeds.Take(60)) + { + var step = Math.Abs(seed % 1000); + clock += step % 15; + var now = At(clock); + var buyer = $"buyer-{step % 7}"; + + try + { + switch (step % 3) + { + case 0: + holds.Add((drop.Take(buyer, step % 4 + 1, now), buyer)); + break; + case 1 when holds.Count > 0: + var pick = holds[step % holds.Count]; + drop.Confirm(pick.Hold.Id, pick.Buyer, now, Guid.NewGuid()); + break; + default: + drop.ExpireHolds(now); + break; + } + } + catch (DomainException) + { + // A rejected operation is correct behaviour; only the invariant is under test. + } + + Assert.True(drop.HeldAt(now) + drop.SoldUnits <= drop.TotalUnits); + Assert.True(drop.AvailableAt(now) >= 0); + } + } +} diff --git a/docs/11-open-questions.md b/docs/11-open-questions.md index 56e9df7..99fcffb 100644 --- a/docs/11-open-questions.md +++ b/docs/11-open-questions.md @@ -1,20 +1,25 @@ # Open questions -**Status:** Open (Q-005 to Q-007); earlier questions resolved +**Status:** Resolved -## Open +Historical log of design questions and their resolved decisions. -These block the requirements of [specs/002-drops](../specs/002-drops/spec.md). +## Resolved -- **Q-005 — Buyer identity without accounts.** The charter excludes authentication. Options: - (a) an anonymous per-visitor token in a cookie, limits enforced per token and per IP; - (b) an email address entered at checkout. Blocks REQ-088 and the webhooks. -- **Q-006 — Payment.** Keep `confirm` as the existing `MarkAsPaid` transition (no gateway), or add a - payment provider in test mode. Blocks any claim of real commerce. -- **Q-007 — Hold persistence.** Holds survive a restart (persisted, recommended) or are in-memory only. - Blocks the migration design. +### Q-005 — Buyer identity without accounts -## Resolved +**Resolution:** Option (a) approved by owner. An anonymous per-visitor token, sent as `X-Buyer-Token` +and generated by the client; limits are enforced per token, and the existing per-IP rate limiter +covers the rest. All drop orders belong to one seeded anonymous customer. + +### Q-006 — Payment + +**Resolution:** Approved by owner. `confirm` is the existing `MarkAsPaid` transition; no payment +gateway. The product makes no claim of real payment capture. + +### Q-007 — Hold persistence + +**Resolution:** Approved by owner. Holds are persisted with their drop, so a restart loses nothing. ### Q-001 — Test coverage gaps recorded in traceability diff --git a/docs/30-decisions/ADR-0008-drops-with-expiring-holds.md b/docs/30-decisions/ADR-0008-drops-with-expiring-holds.md index dc011e3..894644e 100644 --- a/docs/30-decisions/ADR-0008-drops-with-expiring-holds.md +++ b/docs/30-decisions/ADR-0008-drops-with-expiring-holds.md @@ -1,6 +1,6 @@ # ADR-0008 — Drops with expiring holds -**Status:** Proposed +**Status:** Approved ## Context diff --git a/docs/30-decisions/README.md b/docs/30-decisions/README.md index 16f9f1c..01117bb 100644 --- a/docs/30-decisions/README.md +++ b/docs/30-decisions/README.md @@ -11,4 +11,4 @@ Records of significant architectural and design decisions for NainOrder. | [ADR-0005](ADR-0005-problem-details-error-contract.md) | RFC 7807 Problem Details error contract | Proposed | | [ADR-0006](ADR-0006-dependency-free-client-panel.md) | Dependency-free client panel | Proposed | | [ADR-0007](ADR-0007-optimistic-concurrency-on-order-aggregate.md) | Optimistic concurrency on the order aggregate | Proposed | -| [ADR-0008](ADR-0008-drops-with-expiring-holds.md) | Drops with expiring holds | Proposed | +| [ADR-0008](ADR-0008-drops-with-expiring-holds.md) | Drops with expiring holds | Approved | diff --git a/docs/openapi.json b/docs/openapi.json index 8a1f2b6..c765405 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -165,6 +165,237 @@ } } }, + "/api/Drops": { + "get": { + "tags": [ + "Drops" + ], + "summary": "Most recent drops.", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DropDto" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "Drops" + ], + "summary": "Creates a drop for a catalogue product. It opens after \u0060opensInSeconds\u0060.", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateDropRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateDropRequest" + } + }, + "application/*\u002Bjson": { + "schema": { + "$ref": "#/components/schemas/CreateDropRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DropDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/Drops/{id}": { + "get": { + "tags": [ + "Drops" + ], + "summary": "Live state of a drop. With \u0060X-Buyer-Token\u0060, also the caller\u0027s own holds.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DropDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/Drops/{id}/holds": { + "post": { + "tags": [ + "Drops" + ], + "summary": "Takes units from a live drop: an expiring hold for the caller\u0027s buyer token.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TakeUnitsRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/TakeUnitsRequest" + } + }, + "application/*\u002Bjson": { + "schema": { + "$ref": "#/components/schemas/TakeUnitsRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HoldDto" + } + } + } + }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, + "/api/Drops/{id}/holds/{holdId}/confirm": { + "post": { + "tags": [ + "Drops" + ], + "summary": "Confirms an unexpired hold; it becomes a paid order.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "holdId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OrderDto" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + } + }, "/api/Meta/order-state-machine": { "get": { "tags": [ @@ -1043,6 +1274,32 @@ }, "additionalProperties": false }, + "CreateDropRequest": { + "type": "object", + "properties": { + "productId": { + "type": "string", + "format": "uuid" + }, + "totalUnits": { + "type": "integer", + "format": "int32" + }, + "perBuyerLimit": { + "type": "integer", + "format": "int32" + }, + "holdSeconds": { + "type": "integer", + "format": "int32" + }, + "opensInSeconds": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, "CreateOrderRequest": { "type": "object", "properties": { @@ -1164,6 +1421,102 @@ }, "additionalProperties": false }, + "DropDto": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "productId": { + "type": "string", + "format": "uuid" + }, + "productName": { + "type": "string", + "nullable": true + }, + "productSku": { + "type": "string", + "nullable": true + }, + "unitPrice": { + "type": "number", + "format": "double" + }, + "totalUnits": { + "type": "integer", + "format": "int32" + }, + "available": { + "type": "integer", + "format": "int32" + }, + "held": { + "type": "integer", + "format": "int32" + }, + "sold": { + "type": "integer", + "format": "int32" + }, + "status": { + "type": "string", + "nullable": true + }, + "opensAt": { + "type": "string", + "format": "date-time" + }, + "perBuyerLimit": { + "type": "integer", + "format": "int32" + }, + "holdSeconds": { + "type": "integer", + "format": "int32" + }, + "serverTime": { + "type": "string", + "format": "date-time" + }, + "myHolds": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HoldDto" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "HoldDto": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "quantity": { + "type": "integer", + "format": "int32" + }, + "expiresAt": { + "type": "string", + "format": "date-time" + }, + "state": { + "type": "string", + "nullable": true + }, + "orderId": { + "type": "string", + "format": "uuid", + "nullable": true + } + }, + "additionalProperties": false + }, "OrderDto": { "type": "object", "properties": { @@ -1626,6 +1979,16 @@ "additionalProperties": false, "description": "Verdict of a stock race. \u0060Balanced\u0060 is computed from the persisted product." }, + "TakeUnitsRequest": { + "type": "object", + "properties": { + "quantity": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, "TopProductDto": { "type": "object", "properties": { @@ -1686,6 +2049,9 @@ { "name": "Demo" }, + { + "name": "Drops" + }, { "name": "Meta" }, diff --git a/specs/002-drops/spec.md b/specs/002-drops/spec.md index e9bda41..3c5acd1 100644 --- a/specs/002-drops/spec.md +++ b/specs/002-drops/spec.md @@ -1,6 +1,6 @@ # 002 — Drops -**Status:** Draft — pending owner approval. Changes the product scope: see [ADR-0008](../../docs/30-decisions/ADR-0008-drops-with-expiring-holds.md) and the open questions Q-005 to Q-007. +**Status:** Approved by the owner. Changes the product scope: see [ADR-0008](../../docs/30-decisions/ADR-0008-drops-with-expiring-holds.md); Q-005 to Q-007 are resolved in `docs/11-open-questions.md`. ## Problem diff --git a/specs/002-drops/tasks.md b/specs/002-drops/tasks.md index ff744d1..9b12321 100644 --- a/specs/002-drops/tasks.md +++ b/specs/002-drops/tasks.md @@ -1,11 +1,11 @@ # 002 — Tasks -Blocked until the owner approves the spec, [ADR-0008](../../docs/30-decisions/ADR-0008-drops-with-expiring-holds.md) -and answers Q-005 to Q-007. Labels: `[A]` agent alone, `[M]` mixed, `[H]` owner only. +Spec and [ADR-0008](../../docs/30-decisions/ADR-0008-drops-with-expiring-holds.md) approved; Q-005 to Q-007 +resolved. Phase 1 is T-040 to T-045. Labels: `[A]` agent alone, `[M]` mixed, `[H]` owner only. | ID | Task | Label | Done when | | :--- | :--- | :--- | :--- | -| T-040 | Approve scope change, ADR-0008 and Q-005 to Q-007 | `[H]` | Statuses updated in `docs/` | +| T-040 | Approve scope change, ADR-0008 and Q-005 to Q-007 | `[H]` | ✅ Statuses updated in `docs/` | | T-041 | `Drop` and `Hold` domain with `TimeProvider`, property tests first | `[A]` | Invariant REQ-085 holds for generated sequences | | T-042 | `DropService` and persistence, migration `AddDrops` | `[A]` | Concurrency test: never more than `TotalUnits` held plus sold | | T-043 | Hold expiry, lazy plus background sweeper | `[A]` | Clock-controlled test returns units after the window | From 70aa25ee6195b957df6619b12ece280806c9daa1 Mon Sep 17 00:00:00 2001 From: naindev Date: Tue, 20 Oct 2026 17:47:36 +0200 Subject: [PATCH 3/4] feat(drops): add the Drop panel view and harden drops under a crowd Drop view with a unit grid, hold countdown and a crowd simulator, plus fixes found by running it against the real API: timestamps now leave as UTC (countdowns were off by the timezone offset), SQLite runs in WAL mode (a crowd surfaced "database is locked" as a 500), and drops get a larger rate-limit window so the simulator is not throttled. Also stops the client falling back to the in-browser engine on a real API 404 that carries problem+json. --- NainOrder.Api/Program.cs | 21 +++- NainOrder.Api/wwwroot/assets/css/views.css | 104 ++++++++++++++++++ NainOrder.Api/wwwroot/assets/js/app.js | 2 + NainOrder.Api/wwwroot/assets/js/dom.js | 3 +- NainOrder.Api/wwwroot/assets/js/views/drop.js | 2 +- .../Configurations/DropConfigurations.cs | 11 ++ NainOrder.Tests/Api/DropFlowTests.cs | 16 +++ docs/client.ts | 38 +++++++ 8 files changed, 191 insertions(+), 6 deletions(-) diff --git a/NainOrder.Api/Program.cs b/NainOrder.Api/Program.cs index 24cfb9b..bcb2a50 100644 --- a/NainOrder.Api/Program.cs +++ b/NainOrder.Api/Program.cs @@ -50,14 +50,21 @@ { options.RejectionStatusCode = StatusCodes.Status429TooManyRequests; options.AddPolicy(RateLimitPolicies.Api, httpContext => - RateLimitPartition.GetFixedWindowLimiter( - partitionKey: httpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown", + { + // A drop is polled every second and its crowd simulator fires dozens of requests at + // once, so drops get their own, larger window; everything else keeps 120 per minute. + var isDrop = httpContext.Request.Path.StartsWithSegments("/api/drops"); + var address = httpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown"; + + return RateLimitPartition.GetFixedWindowLimiter( + partitionKey: isDrop ? $"drops:{address}" : address, factory: _ => new FixedWindowRateLimiterOptions { - PermitLimit = 120, + PermitLimit = isDrop ? 1_200 : 120, Window = TimeSpan.FromMinutes(1), QueueLimit = 0 - })); + }); + }); }); // Render y cualquier PaaS terminan TLS por delante: sin esto la app vería http y una IP interna. @@ -178,6 +185,12 @@ static async Task InitializeDatabaseAsync(WebApplication app) try { await context.Database.MigrateAsync(); + + // WAL lets readers proceed while a writer commits. With the default rollback journal, a + // crowd of simultaneous buyers (plus the hold sweeper) surfaces "database is locked" as + // a 500. The mode is stored in the database file, so this is a no-op after the first run. + await context.Database.ExecuteSqlRawAsync("PRAGMA journal_mode=WAL;"); + await DatabaseSeeder.SeedAsync(context); logger.LogInformation("Database ready at {ConnectionString}", context.Database.GetConnectionString()); } diff --git a/NainOrder.Api/wwwroot/assets/css/views.css b/NainOrder.Api/wwwroot/assets/css/views.css index 28413f4..2cfad46 100644 --- a/NainOrder.Api/wwwroot/assets/css/views.css +++ b/NainOrder.Api/wwwroot/assets/css/views.css @@ -894,8 +894,112 @@ background: var(--danger); } +/* -------------------------------------------------------------------------- + Drop + -------------------------------------------------------------------------- */ +.drop { + display: grid; + gap: var(--space-5); +} + +.drop__head { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + justify-content: space-between; + gap: var(--space-4); +} + +.drop__name { + font-size: var(--text-xl); + font-weight: 700; +} + +.drop__price { + font-size: var(--text-lg); + color: var(--text-secondary); +} + +.drop__state { + display: flex; + align-items: center; + gap: var(--space-3); +} + +.drop__clock { + font-size: var(--text-lg); + font-weight: 650; +} + +.drop__grid { + --cell: 44px; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(var(--cell), 1fr)); + gap: var(--space-2); +} + +.drop__cell, +.race__legend i[data-cell] { + border-radius: var(--radius-xs); + border: 1px solid var(--border-default); + background: var(--surface-2); +} + +.drop__cell { + aspect-ratio: 1; + transition: background var(--duration-base) var(--ease), border-color var(--duration-base) var(--ease); +} + +.drop__cell[data-cell="available"], .race__legend i[data-cell="available"] { background: color-mix(in srgb, var(--success) 18%, transparent); border-color: var(--success); } +.drop__cell[data-cell="held"], .race__legend i[data-cell="held"] { background: color-mix(in srgb, var(--warning) 38%, transparent); border-color: var(--warning); } +.drop__cell[data-cell="sold"], .race__legend i[data-cell="sold"] { background: var(--brand-2); border-color: transparent; } +.drop__cell[data-mine] { outline: 2px solid var(--brand-3); outline-offset: 1px; } + +.drop__actions { + display: flex; + flex-wrap: wrap; + gap: var(--space-3); +} + +.drop__hold { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: var(--space-4); + padding: var(--space-3) var(--space-4); + border-radius: var(--radius-md); + border: 1px solid var(--warning); + background: color-mix(in srgb, var(--warning) 10%, transparent); +} + +.drop__hold[hidden] { display: none; } + +.drop__hold-bar { + flex: 1 1 140px; + height: 6px; + border-radius: var(--radius-pill); + background: var(--surface-3); + overflow: hidden; +} + +.drop__hold-bar i { + display: block; + height: 100%; + background: var(--warning); + transition: width 250ms linear; +} + +.drop-recent { + display: flex; + flex-wrap: wrap; + gap: var(--space-2); +} + +.drop-recent__item { cursor: pointer; } + @media (prefers-reduced-motion: reduce) { .race__tile { animation: none; } + .drop__cell, .drop__hold-bar i { transition: none; } } @media (max-width: 620px) { diff --git a/NainOrder.Api/wwwroot/assets/js/app.js b/NainOrder.Api/wwwroot/assets/js/app.js index 83a46c1..3a0ba68 100644 --- a/NainOrder.Api/wwwroot/assets/js/app.js +++ b/NainOrder.Api/wwwroot/assets/js/app.js @@ -13,9 +13,11 @@ import { catalogView } from "./views/catalog.js"; import { ordersView } from "./views/orders.js"; import { architectureView } from "./views/architecture.js"; import { raceView } from "./views/race.js"; +import { dropView } from "./views/drop.js"; const NAV = [ { path: "/panel", label: "Panel", icon: "dashboard", view: dashboardView }, + { path: "/drop", label: "Drop", icon: "ticket", view: dropView }, { path: "/catalogo", label: "Catálogo", icon: "catalog", view: catalogView }, { path: "/pedidos", label: "Pedidos", icon: "orders", view: ordersView }, { path: "/carrera", label: "Carrera de stock", icon: "race", view: raceView }, diff --git a/NainOrder.Api/wwwroot/assets/js/dom.js b/NainOrder.Api/wwwroot/assets/js/dom.js index ff87d2e..b77f962 100644 --- a/NainOrder.Api/wwwroot/assets/js/dom.js +++ b/NainOrder.Api/wwwroot/assets/js/dom.js @@ -111,7 +111,8 @@ const ICON_PATHS = { spark: '', layers: '', filter: '', - race: '' + race: '', + ticket: '' }; /** diff --git a/NainOrder.Api/wwwroot/assets/js/views/drop.js b/NainOrder.Api/wwwroot/assets/js/views/drop.js index 72c8fd0..4b79978 100644 --- a/NainOrder.Api/wwwroot/assets/js/views/drop.js +++ b/NainOrder.Api/wwwroot/assets/js/views/drop.js @@ -222,7 +222,7 @@ export const dropView = { $("[data-stats]", stageNode).innerHTML = html`
${fmtNumber(current.available)}disponibles
${fmtNumber(current.held)}reservadas
-
${fmtNumber(current.sold)}vendidas
+
${fmtNumber(current.sold)}vendidas
`; $('[data-action="take"]', stageNode).disabled = busy || current.status !== "Live"; diff --git a/NainOrder.Infrastructure/Persistence/Configurations/DropConfigurations.cs b/NainOrder.Infrastructure/Persistence/Configurations/DropConfigurations.cs index f79e7b8..bc08937 100644 --- a/NainOrder.Infrastructure/Persistence/Configurations/DropConfigurations.cs +++ b/NainOrder.Infrastructure/Persistence/Configurations/DropConfigurations.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using NainOrder.Domain.Entities; using NainOrder.Infrastructure.Persistence.Converters; @@ -7,6 +8,9 @@ namespace NainOrder.Infrastructure.Persistence.Configurations; public class DropConfiguration : IEntityTypeConfiguration { + internal static readonly ValueConverter AsUtc = + new(v => v, v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); + public void Configure(EntityTypeBuilder builder) { builder.HasKey(d => d.Id); @@ -16,6 +20,11 @@ public void Configure(EntityTypeBuilder builder) builder.Property(d => d.ProductSku).IsRequired().HasMaxLength(Product.MaxSkuLength); builder.Property(d => d.UnitPrice).HasConversion(); + // SQLite returns DateTime as Unspecified; without UTC the API would serialise a bare + // timestamp that browsers read as local time and every countdown would be off by the offset. + builder.Property(d => d.OpensAt).HasConversion(AsUtc); + builder.Property(d => d.CreatedAt).HasConversion(AsUtc); + // Same pattern as ADR-0007: a losing writer fails the UPDATE instead of overwriting. builder.Property(d => d.Version).IsConcurrencyToken(); @@ -45,6 +54,8 @@ public void Configure(EntityTypeBuilder builder) builder.Property(h => h.BuyerToken).IsRequired().HasMaxLength(64); builder.Property(h => h.State).HasConversion(); + builder.Property(h => h.CreatedAt).HasConversion(DropConfiguration.AsUtc); + builder.Property(h => h.ExpiresAt).HasConversion(DropConfiguration.AsUtc); builder.HasIndex(h => new { h.DropId, h.BuyerToken }); builder.HasIndex(h => new { h.State, h.ExpiresAt }); diff --git a/NainOrder.Tests/Api/DropFlowTests.cs b/NainOrder.Tests/Api/DropFlowTests.cs index 9b15fe4..e96e270 100644 --- a/NainOrder.Tests/Api/DropFlowTests.cs +++ b/NainOrder.Tests/Api/DropFlowTests.cs @@ -88,6 +88,22 @@ public async Task A_new_drop_reports_its_units_and_goes_live() Assert.Equal(0, drop.Held + drop.Sold); } + [Fact] + public async Task Timestamps_are_serialised_as_utc_so_browsers_do_not_read_them_as_local_time() + { + var drop = await CreateDropAsync(units: 3); + await TakeAsync(drop.Id, "buyer-utc"); + + var json = await (await _client.SendAsync( + new HttpRequestMessage(HttpMethod.Get, $"/api/drops/{drop.Id}") { Headers = { { "X-Buyer-Token", "buyer-utc" } } })) + .Content.ReadAsStringAsync(); + using var doc = JsonDocument.Parse(json); + + Assert.EndsWith("Z", doc.RootElement.GetProperty("opensAt").GetString()); + Assert.EndsWith("Z", doc.RootElement.GetProperty("serverTime").GetString()); + Assert.EndsWith("Z", doc.RootElement.GetProperty("myHolds")[0].GetProperty("expiresAt").GetString()); + } + [Fact] public async Task A_scheduled_drop_rejects_takes_until_it_opens() { diff --git a/docs/client.ts b/docs/client.ts index 8d3508c..c5b650f 100644 --- a/docs/client.ts +++ b/docs/client.ts @@ -27,6 +27,14 @@ export interface CreateCustomerRequest { email?: string; } +export interface CreateDropRequest { + productId?: string; + totalUnits?: number; + perBuyerLimit?: number; + holdSeconds?: number; + opensInSeconds?: number; +} + export interface CreateOrderRequest { customerId?: string; } @@ -61,6 +69,32 @@ export interface DashboardStatsDto { topProducts?: TopProductDto[]; } +export interface DropDto { + id?: string; + productId?: string; + productName?: string; + productSku?: string; + unitPrice?: number; + totalUnits?: number; + available?: number; + held?: number; + sold?: number; + status?: string; + opensAt?: string; + perBuyerLimit?: number; + holdSeconds?: number; + serverTime?: string; + myHolds?: HoldDto[]; +} + +export interface HoldDto { + id?: string; + quantity?: number; + expiresAt?: string; + state?: string; + orderId?: string; +} + export interface OrderDto { id?: string; reference?: string; @@ -192,6 +226,10 @@ export interface StockRaceResultDto { results?: StockRaceBuyerDto[]; } +export interface TakeUnitsRequest { + quantity?: number; +} + export interface TopProductDto { productId?: string; name?: string; From a8a25084a6ea359b8e6932ff53d02436093339f1 Mon Sep 17 00:00:00 2001 From: naindev Date: Tue, 20 Oct 2026 17:47:41 +0200 Subject: [PATCH 4/4] docs: rebuild the README around the drop engine and trace drops README now leads with a live drop capture, the hold lifecycle and one guarantees table. Requirements REQ-080 to REQ-086 and REQ-088 are traced to their tests; ADR-0009 (SQLite WAL) is proposed; runbook, changelog and spec 002 tasks record phase 1. --- README.md | 67 +++++++++--------- docs/10-requirements.md | 16 +++++ docs/30-decisions/ADR-0009-sqlite-wal-mode.md | 30 ++++++++ docs/30-decisions/README.md | 1 + docs/50-traceability.md | 17 ++++- docs/60-runbook.md | 6 ++ docs/90-changelog.md | 5 ++ docs/assets/drop-live.png | Bin 0 -> 266384 bytes specs/002-drops/tasks.md | 24 ++++--- 9 files changed, 124 insertions(+), 42 deletions(-) create mode 100644 docs/30-decisions/ADR-0009-sqlite-wal-mode.md create mode 100644 docs/assets/drop-live.png diff --git a/README.md b/README.md index 96074e8..dac0c14 100644 --- a/README.md +++ b/README.md @@ -6,46 +6,45 @@ # NainOrder -**An order engine where a unit of stock can never be sold twice — and you can watch it prove it.** +**Sell a limited drop to a crowd — exactly N units, never oversold, no stock stuck in abandoned carts.** [![ci](https://github.com/Nain9Dev/NainOrder/actions/workflows/ci.yml/badge.svg)](https://github.com/Nain9Dev/NainOrder/actions/workflows/ci.yml) [![CodeQL](https://github.com/Nain9Dev/NainOrder/actions/workflows/codeql.yml/badge.svg)](https://github.com/Nain9Dev/NainOrder/actions/workflows/codeql.yml) ![.NET 10](https://img.shields.io/badge/.NET-10-512BD4) -![Tests](https://img.shields.io/badge/tests-82%20passing-2ea44f) +![Tests](https://img.shields.io/badge/tests-110%20passing-2ea44f) ![Client dependencies](https://img.shields.io/badge/client%20dependencies-0-22d3ee) [![Live demo](https://img.shields.io/badge/live%20demo-order.naindev.com-8b5cf6)](https://order.naindev.com/)

- Stock race: 24 buyers compete for 5 units; 5 win, 19 are rejected, stock balances to the unit + A live drop: 56 units, 2 sold, 42 held by a crowd of 40 buyers, 12 still available

-> **Stock race** — 24 buyers hit 5 units at the same instant. Exactly 5 win, 19 get a `409`, and -> *sold + remaining = in stock* holds. Press the button in the panel and see it yourself. +> **56 units. 40 buyers released at once.** Each unit is *available*, *held* for 60 seconds, or *sold*. +> Hold it and don't confirm: it goes back to the crowd. Press **Soltar 40 compradores** and watch. --- -## What it does +## The problem it solves -| 🛒 Orders | 📦 Inventory | 🔒 Guarantees | -| :--- | :--- | :--- | -| Basket → paid → processing → shipped, or cancelled | Adding a line **reserves** stock in the same transaction | No oversell under concurrency | -| Only legal transitions; the API publishes them | Cancelling **returns** every unit | Money in integer cents, never floats | -| Totals always equal the sum of the lines | Quantity changes adjust stock by the exact difference | Business failure `4xx`, technical failure `500` | +Sneaker releases, merch drops and ticket sales fail the same way: a crowd arrives in one second, and +the shop either **oversells** or **locks stock behind abandoned carts**. NainOrder is the engine that +prevents both. ```mermaid -stateDiagram-v2 - direction LR - [*] --> PendingPayment - PendingPayment --> Paid - Paid --> Processing - Processing --> Shipped - Shipped --> [*] - PendingPayment --> Cancelled - Paid --> Cancelled - Processing --> Cancelled - Cancelled --> [*] +flowchart LR + A([Take a unit]) --> B[Hold
30–3600 s] + B -->|Confirm in time| C([Paid order]) + B -->|Window ends| D([Unit back to the drop]) + D -.-> A ``` +| Guarantee | How it is enforced | +| :--- | :--- | +| Never more units held + sold than the drop has | One aggregate, one concurrency token | +| A holder can't hog the drop | Per-buyer limit across holds and orders | +| Abandoned holds free themselves | Expiry applied on every read, swept every second | +| Money is exact | Integer cents, never floats | + --- ## Architecture @@ -58,11 +57,12 @@ The rule is **enforced, not declared**: `NetArchTest` fails the build if `Domain `Application` learns about EF Core.

+ Stock race: 24 buyers compete for 5 units; 5 win, 19 are rejected Dashboard with revenue, order states and top products - Architecture view with live request trace and state machine

-The client panel is plain ES modules served by the API itself: no npm, no build step, no CORS. +The panel is plain ES modules served by the API itself: no npm, no build step, no CORS. It also ships a +**stock race** (many buyers, few units, one verdict) and the full order back office. --- @@ -70,10 +70,10 @@ The client panel is plain ES modules served by the API itself: no npm, no build | Claim | Proof | | :--- | :--- | +| A crowd never holds or sells more than the drop contains | `DropFlowTests` (40 concurrent buyers), `DropTests` (property-based) | +| Holds expire without a sleeping test | `DropTests`, `DropFlowTests` with a hand-moved clock | | Stock is never oversold, even in a race | `StockRaceTests`, `ConcurrencyTests` | -| Stock never goes negative, for any sequence | `DomainInvariantProperties` (FsCheck) | | Two writers on one order never lose an update | `OrderAggregateConcurrencyProbe` | -| Cancelling returns every unit | `OrderFlowTests` | | Domain has zero dependencies | `CleanArchitectureTests` | | The shipped container works | CI builds the image and probes it | @@ -88,26 +88,27 @@ git clone https://github.com/Nain9Dev/NainOrder.git cd NainOrder/NainOrder.Api && dotnet run ``` -Open — panel, [`/swagger`](http://localhost:8170/swagger) and `/health` are all there. -No database to install: SQLite creates itself. +Open → **Drop** → *Lanzar drop*. Also there: [`/swagger`](http://localhost:8170/swagger) +and `/health`. No database to install: SQLite creates itself. ```bash -dotnet test NainOrder.slnx -c Release # 82 tests +dotnet test NainOrder.slnx -c Release # 110 tests docker build -t nainorder . && docker run -p 8080:8080 nainorder ``` > **About the live demo.** [order.naindev.com](https://order.naindev.com/) is a static page, so the panel runs -> on an in-browser engine and says so. The concurrency guarantees above run against the .NET API — locally. +> on an in-browser engine and says so: one thread can't collide with itself. The concurrency guarantees +> run against the .NET API — locally. --- ## Go deeper [Charter](docs/00-charter.md) · [Requirements](docs/10-requirements.md) · [Architecture](docs/20-architecture.md) · -[Data model](docs/21-data-model.md) · [7 ADRs](docs/30-decisions/) · [Threat model](docs/22-threat-model.md) · -[Traceability](docs/50-traceability.md) · [OpenAPI](docs/openapi.json) +[Data model](docs/21-data-model.md) · [9 ADRs](docs/30-decisions/) · [Threat model](docs/22-threat-model.md) · +[Traceability](docs/50-traceability.md) · [OpenAPI](docs/openapi.json) · [Drops spec](specs/002-drops/spec.md) -**Stack** — C# 13 · .NET 10 · ASP.NET Core · EF Core · SQLite · xUnit · FsCheck · ES modules +**Stack** — C# 13 · .NET 10 · ASP.NET Core · EF Core · SQLite (WAL) · xUnit · FsCheck · ES modules --- diff --git a/docs/10-requirements.md b/docs/10-requirements.md index 658575e..455ca22 100644 --- a/docs/10-requirements.md +++ b/docs/10-requirements.md @@ -64,6 +64,22 @@ says. | REQ-072 | The system shall report `sold + remaining = units`, `sold <= units` and `remaining >= 0` as a `balanced` verdict computed from the persisted product, not from the buyers' answers. | | REQ-073 | If `buyers` is outside 2..64 or `units` is outside 1..32, then the system shall reject the request with `400` before any data is created. | +## Drops + +Phase 1 of [specs/002-drops](../specs/002-drops/spec.md). REQ-087 (live stream) is specified there and +enters this table when it is implemented and tested. + +| ID | Requirement | +| :--- | :--- | +| REQ-080 | When a shop owner creates a drop with a product, a number of units, an opening time and a per-buyer limit, the system shall publish it as `Scheduled` until it opens. | +| REQ-081 | While a drop is not `Live`, the system shall reject any attempt to take a unit with `409 drop_not_live`. | +| REQ-082 | When a buyer takes units from a live drop, the system shall create a hold of at most the per-buyer limit, reserving those units atomically. | +| REQ-083 | When a hold is not confirmed within its time window, the system shall expire it and return its units to the drop. | +| REQ-084 | When a buyer confirms an unexpired hold, the system shall turn it into a paid order for that buyer. | +| REQ-085 | The system shall never hold or sell more units than the drop contains, whatever the concurrency. | +| REQ-086 | When a drop's units are all sold or held, the system shall report it `SoldOut`; when expired holds free units again, it shall report it `Live`. | +| REQ-088 | If a buyer exceeds the per-buyer limit across holds and orders of one drop, then the system shall reject the request with `409 buyer_limit_reached`. | + ## HTTP contract | ID | Requirement | diff --git a/docs/30-decisions/ADR-0009-sqlite-wal-mode.md b/docs/30-decisions/ADR-0009-sqlite-wal-mode.md new file mode 100644 index 0000000..24ffca7 --- /dev/null +++ b/docs/30-decisions/ADR-0009-sqlite-wal-mode.md @@ -0,0 +1,30 @@ +# ADR-0009 — SQLite in WAL mode + +**Status:** Proposed + +## Context + +Drops bring many buyers writing to one database at once, plus a background sweeper. With SQLite's +default rollback journal a committing writer blocks readers, and under a 40-buyer crowd the +application answered `500` with `SQLite Error 5: database is locked`. That breaks the rule that a +business outcome is `4xx` and only a technical failure is `500`: a busy database is not the +buyer's fault and should not reach them at all. + +## Decision + +Run `PRAGMA journal_mode=WAL` at start-up, after migrations. Readers then proceed while a writer +commits; writers still serialise, and optimistic concurrency keeps resolving conflicts as `409`. +The mode is stored in the database file, so repeating the statement on later starts changes nothing. + +## Alternatives considered + +- **Raise the busy timeout.** Rejected as the only fix: it hides contention behind latency and does + not remove the reader/writer block. +- **Move to PostgreSQL.** Right for sustained production load, rejected here: it breaks the charter's + single-process, zero-cost deployment. The runbook already records this as the known limit. + +## Consequences + +- Two extra files, `-wal` and `-shm`, appear beside the database. Back up and move all three together. +- WAL needs a local filesystem; it is not supported on network shares. +- Sustained write traffic still needs a different engine (see the runbook). diff --git a/docs/30-decisions/README.md b/docs/30-decisions/README.md index 01117bb..49e5823 100644 --- a/docs/30-decisions/README.md +++ b/docs/30-decisions/README.md @@ -12,3 +12,4 @@ Records of significant architectural and design decisions for NainOrder. | [ADR-0006](ADR-0006-dependency-free-client-panel.md) | Dependency-free client panel | Proposed | | [ADR-0007](ADR-0007-optimistic-concurrency-on-order-aggregate.md) | Optimistic concurrency on the order aggregate | Proposed | | [ADR-0008](ADR-0008-drops-with-expiring-holds.md) | Drops with expiring holds | Approved | +| [ADR-0009](ADR-0009-sqlite-wal-mode.md) | SQLite in WAL mode | Proposed | diff --git a/docs/50-traceability.md b/docs/50-traceability.md index 9d3180d..0c059c4 100644 --- a/docs/50-traceability.md +++ b/docs/50-traceability.md @@ -1,6 +1,6 @@ # Traceability -**Status:** Active · verified against a green run of `dotnet test NainOrder.slnx -c Release` (82/82 tests) +**Status:** Active · verified against a green run of `dotnet test NainOrder.slnx -c Release` (110/110 tests) Every requirement in [10-requirements.md](10-requirements.md) and the test that demonstrates it. A requirement with no test is not done, whatever the code says. @@ -15,6 +15,8 @@ Test suites: | `Api.OrderFlowTests` | Integration over HTTP | The real application with its migrations and middleware | | `Api.ConcurrencyTests` | Integration, concurrent | Simultaneous requests competing for the same units | | `Api.OrderAggregateConcurrencyProbe` | Concurrency, aggregate | Multi-context concurrent aggregate mutations and optimistic concurrency conflict enforcement | +| `Domain.DropTests` | Example-based + property-based | The drop aggregate with an explicit clock: holds, expiry, limits, the held-plus-sold invariant | +| `Api.DropFlowTests` | Integration, concurrent | Drops over HTTP with a hand-moved clock, a 40-buyer crowd and UTC serialisation | | `Api.StockRaceTests` | Integration, concurrent | The on-demand race: many buyers, few units, verdict from persisted stock | | `Api.GlobalExceptionHandlerTests` | Contract/Unit | RFC 7807 error translation and production 500 detail sanitization | @@ -76,6 +78,19 @@ Test suites: | REQ-072 | `StockRaceTests.A_race_never_sells_more_units_than_exist_and_balances_to_the_unit` | | REQ-073 | `StockRaceTests.A_race_outside_the_allowed_range_is_rejected_with_400` (four boundary cases) | +## Drops + +| Requirement | Test | +| :--- | :--- | +| REQ-080 | `DropTests.A_drop_is_scheduled_until_it_opens_and_live_afterwards`, `A_drop_rejects_invalid_configuration`; `DropFlowTests.A_new_drop_reports_its_units_and_goes_live`, `An_invalid_drop_configuration_is_rejected_with_400` | +| REQ-081 | `DropTests.Taking_from_a_drop_that_is_not_live_is_rejected`; `DropFlowTests.A_scheduled_drop_rejects_takes_until_it_opens` | +| REQ-082 | `DropTests.Taking_units_creates_a_hold_that_reduces_availability`, `Asking_for_more_than_is_available_is_rejected_and_leaves_the_drop_untouched`; `DropFlowTests.Taking_and_confirming_turns_a_hold_into_a_paid_order` | +| REQ-083 | `DropTests.An_unconfirmed_hold_returns_its_units_when_its_window_ends`, `Sweeping_marks_expired_holds_and_reports_how_many`; `DropFlowTests.An_unconfirmed_hold_expires_and_returns_its_units`, `Sweeping_persists_the_expiry_of_due_holds` | +| REQ-084 | `DropTests.Confirming_a_hold_in_time_sells_the_units_for_good`, `Confirming_after_the_window_is_rejected`, `Only_the_owner_can_confirm_a_hold`, `A_hold_cannot_be_confirmed_twice`; `DropFlowTests.Taking_and_confirming_turns_a_hold_into_a_paid_order`, `A_hold_of_another_buyer_cannot_be_confirmed` | +| REQ-085 | `DropTests.Held_plus_sold_never_exceeds_the_units_of_the_drop` (property); `DropFlowTests.A_crowd_never_holds_or_sells_more_units_than_the_drop_contains` (40 concurrent buyers) | +| REQ-086 | `DropTests.An_unconfirmed_hold_returns_its_units_when_its_window_ends`; `DropFlowTests.An_unconfirmed_hold_expires_and_returns_its_units` | +| REQ-088 | `DropTests.A_buyer_cannot_exceed_the_per_buyer_limit_across_holds`, `Expired_units_do_not_count_against_the_buyer_limit`; `DropFlowTests.A_buyer_over_the_limit_is_rejected_with_409` | + ## HTTP contract | Requirement | Test | diff --git a/docs/60-runbook.md b/docs/60-runbook.md index 9c01866..b662ada 100644 --- a/docs/60-runbook.md +++ b/docs/60-runbook.md @@ -61,6 +61,12 @@ bypass it. - **Ephemeral data.** With no persistent volume the database is recreated on every deploy. The seed makes the instance usable immediately, so this is acceptable for a demonstration and not for production. +- **WAL files.** The database runs in WAL mode ([ADR-0009](30-decisions/ADR-0009-sqlite-wal-mode.md)), + so `nainorder.db-wal` and `-shm` sit beside it: copy all three together. +- **Drops have a larger rate limit** (1,200 requests per minute per address on `/api/drops`, 120 + elsewhere) because a drop page polls every second and its crowd simulator bursts. +- **Unconfirmed drop holds expire** after their window and a background service sweeps them every + second; reads also apply the clock, so a stopped sweeper never leaves units locked. - **SQLite serialises writes.** Fine at demonstration load. Sustained concurrent write traffic needs a different engine; that is a `UseSqlite` change plus a migration, not a domain change. - **No authentication.** Every endpoint is public by design — see the non-goals in diff --git a/docs/90-changelog.md b/docs/90-changelog.md index 2b618fb..615c6f8 100644 --- a/docs/90-changelog.md +++ b/docs/90-changelog.md @@ -8,6 +8,11 @@ Notable changes. Format loosely follows Keep a Changelog; dates come from git. ### Added +- Drops (phase 1 of `specs/002-drops`, ADR-0008): a fixed number of units sold to a crowd through + short expiring holds, with `/api/drops` endpoints, a `Drop` panel view with a crowd simulator, and + an in-browser engine for the static demo. REQ-080 to REQ-086 and REQ-088. +- SQLite runs in WAL mode so a crowd of buyers no longer surfaces `database is locked` as a `500` + ([ADR-0009](30-decisions/ADR-0009-sqlite-wal-mode.md)); drops get a larger rate-limit window. - Stock race: `POST /api/demo/stock-race` and a panel view that run the "never oversell" guarantee live — N buyers against M units, conflicts retried, verdict computed from persisted stock (`specs/001-stock-race`, REQ-070 to REQ-073). diff --git a/docs/assets/drop-live.png b/docs/assets/drop-live.png new file mode 100644 index 0000000000000000000000000000000000000000..8da72c71e9fdf5e99c010bf1836edb4b992f952a GIT binary patch literal 266384 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

)qPf2 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¬D<^g(b`s#zD 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 YcicIsnMB?HVS>+_U;L%u%