Skip to content

feat: Implement inventory service with stock reservation - #7

Merged
rezadrian01 merged 3 commits into
mainfrom
feature/inventory-service
May 28, 2026
Merged

feat: Implement inventory service with stock reservation#7
rezadrian01 merged 3 commits into
mainfrom
feature/inventory-service

Conversation

@rezadrian01

Copy link
Copy Markdown
Owner

Summary

  • Full inventory service implementation (port 8085) managing stock levels for products
  • Shares products_db with product-service — no separate database, no AutoMigrate (product-service owns the inventory table)
  • Consumes order.created → reserves stock via ReservedQuantity += n (optimistic atomic UPDATE)
  • Consumes order.cancelled → releases reservation via GREATEST(reserved_quantity - n, 0)
  • Publishes inventory.updated on every stock change; publishes inventory.low_stock when available stock ≤ 10
  • Admin-only HTTP endpoints; auth enforced at the gateway (requireRole("admin"))

Changes

New service — services/inventory-service/

  • Domain: Inventory entity (mirrors product-service table schema exactly), AvailableQuantity() helper, LowStockThreshold = 10, UpdateInventoryRequest, OrderCreatedEvent with json:"id" (matches order-service's Order.ID tag)
  • Repository: GetByProductID, SetTotalQuantity (PostgreSQL upsert via INSERT ... ON CONFLICT DO UPDATE), ReserveStock (atomic WHERE clause prevents overbooking, distinguishes ErrInventoryNotFound vs ErrInsufficientStock), ReleaseStock (GREATEST clamp prevents negative reservation)
  • Cache: inventory:<product_id> key, 5 min TTL (shorter because stock changes on every order)
  • Kafka publisher: writes to inventory.updated and inventory.low_stock
  • Kafka consumer: multi-topic struct with two kafka.Reader instances — one per topic (order.created, order.cancelled); Start() launches one goroutine per reader; handleMessage switches on topic
  • Service: HandleOrderCreated loops items, reserves each, logs and continues on failure (partial reservation acceptable); HandleOrderCancelled releases each item's reservation
  • Handler + route: GET /inventory/:product_id, PUT /inventory/:product_id; no auth helper needed (gateway handles it)
  • cmd: no runMigrations — product-service owns the table; Kafka consumer uses group inventory-service-orders

docker-compose.yml

  • Added REDIS_URL, KAFKA_BROKERS to inventory-service environment
  • Added kafka: condition: service_healthy to inventory-service.depends_on

Test plan

  • docker-compose up inventory-service products-db redis kafka starts without errors
  • GET /health returns {"status":"healthy","service":"inventory-service"}
  • PUT /api/inventory/:product_id (as admin) sets total stock and returns updated inventory
  • GET /api/inventory/:product_id (as admin) returns stock levels with computed available_quantity
  • Placing an order triggers order.createdreserved_quantity increments for each item
  • Cancelling an order triggers order.cancelledreserved_quantity decrements for each item
  • Setting stock below threshold publishes inventory.low_stock event (visible in Kafka UI)

🤖 Generated with Claude Code

rezadrian01 and others added 3 commits May 28, 2026 16:00
…ation design

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…a event layers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…docker-compose wiring

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 28, 2026 09:08
@rezadrian01
rezadrian01 merged commit 17d069d into main May 28, 2026
1 of 2 checks passed
@rezadrian01
rezadrian01 removed the request for review from Copilot May 28, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant