Skip to content

feat(agents): Phase 4 — ProductWatch Agent - #4

Merged
NavneetHegde merged 1 commit into
mainfrom
feat/phase-4-product-watch-agent
Mar 9, 2026
Merged

NavneetHegde merged 1 commit into
mainfrom
feat/phase-4-product-watch-agent

Conversation

@NavneetHegde

Copy link
Copy Markdown
Owner

Summary

  • Implements the ProductWatchWorker BackgroundService that polls every 15s for active watches and finds matching products
  • Adds MockProductSource (10-item catalog with ±15% price jitter and 70% availability simulation) registered as IProductSource
  • Adds MatchingService — pure static helper filtering listings by price and optional preferred sellers
  • Adds 31 unit tests across a new AgentPayWatch.Agents.ProductWatch.Tests project

Test plan

  • All 31 new unit tests pass
  • All existing unit tests continue to pass
  • Start system via Aspire, create a watch for "iPhone" with maxPrice 999, wait 15-30s, confirm status transitions to Matched
  • Check Aspire traces for Cosmos write and Service Bus publish on product-match-found

🤖 Generated with Claude Code

Add autonomous product monitoring: MockProductSource (10-item catalog
with price jitter), MatchingService (price + seller filter), and
ProductWatchWorker (BackgroundService polling every 15s). On match,
persists ProductMatch to Cosmos, transitions WatchRequest to Matched,
and publishes ProductMatchFound to the product-match-found Service Bus
topic for the Phase 5 Approval Agent to consume.

Also adds 31 unit tests (MatchingService, MockProductSource, Worker)
with hand-written fakes and a new AgentPayWatch.Agents.ProductWatch.Tests
project wired into the solution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@NavneetHegde NavneetHegde left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

🔍 Phase 4 Code Review — ProductWatch Agent

Commits

  • 7735ce4 feat(agents): implement Phase 4 — ProductWatch agent

Files Changed

File Description
src/.../Mocks/MockProductSource.cs New — 10-product hardcoded catalog; deterministic per-minute seed with ±15% price jitter and 70% availability filter
src/.../MatchingService.cs New — pure static match evaluator (price ≤ maxPrice + optional seller filter, case-insensitive)
src/.../ProductWatchWorker.cs New — BackgroundService polling every 15s; scan → match → persist ProductMatch → update WatchRequest → publish ProductMatchFound
src/.../Program.cs Wired up AddInfrastructureServices() and AddHostedService<ProductWatchWorker>()
src/.../appsettings.json New — PollIntervalSeconds: 15, Debug log level for agent namespace
src/AgentPayWatch.Infrastructure/DependencyInjection.cs Registers MockProductSource as IProductSource singleton
AgentPayWatch.slnx New test project added to solution
tests/.../Fakes.cs Hand-written fakes for all 4 interfaces (no mocking library)
tests/.../MatchingServiceTests.cs 8 unit tests — price boundaries, seller filtering, case sensitivity
tests/.../MockProductSourceTests.cs 7 unit tests — known/unknown search terms, listing shape, URL format, price jitter bounds, 3-result cap
tests/.../ProductWatchWorkerTests.cs 10 unit tests — no watches, no listings, price filtering, match creation, status transition, event publishing, lowest-price selection, preferred sellers, multi-watch, expiry
tests/.../*.csproj New test project targeting net10.0, xUnit 2.9.3, coverlet

Test Results

  • ✅ Unit tests: 70 passed, 0 failed (8 skipped — integration tests requiring live emulators)
  • ✅ Integration tests: 2 skipped (emulator not running — expected in CI without infrastructure)
  • ✅ Build: 0 errors, 0 warnings
  • ✅ New tests added: 31 new unit tests
  • ✅ Branch up to date with main

Code Quality

  • ✅ No Console.Write / debug statements
  • ✅ No hardcoded secrets or API keys
  • ✅ No TODO / FIXME comments
  • ✅ No unused imports detected
  • ✅ Error handling in ProductWatchWorker: per-watch exceptions are caught and logged, scan continues; scan-level exception is caught and retried next interval; graceful shutdown via OperationCanceledException

Potential Issues

  • ⚠️ MockProductSource registered globallyIProductSource is registered in DependencyInjection.cs (shared Infrastructure DI), meaning all three agent projects will get the mock. This is fine for the current phase but should be swapped for a real implementation later. Consider a comment noting this is temporary.
  • ⚠️ ProductWatchWorker timing testProductWatchWorkerTests uses Task.Delay(300ms) to let one scan cycle complete before StopAsync. This is reliable with synchronous fakes but could be flaky in heavily loaded CI environments. An internal-exposed scan method + InternalsVisibleTo would make these tests fully deterministic if that becomes a concern.
  • ℹ️ No end-to-end test — Phase 5 will consume ProductMatchFound; integration coverage spans across phases. This is expected and acceptable at this stage.

Recommendation

Ready to merge — implementation matches the Phase 4 spec exactly, all unit tests pass, no blocking issues. The two notes above are low-priority and can be addressed in later phases.

@NavneetHegde
NavneetHegde merged commit 1b81dab into main Mar 9, 2026
1 check failed
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