google-agents-cli-scaffold
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
e2e-test
Run E2E test scenarios against running services. Use for happy path testing, unhappy flows, debugging, or when user says "otestuj", "proved test", "zkus flow".
Full skill instructions
Execute end-to-end test scenarios against running microservices with automatic debugging and reporting.
/e2e-test # Interactive - asks what to test
/e2e-test happy # Happy path: create order flow
/e2e-test unhappy # Unhappy path: out of stock, invalid data
/e2e-test cancel # Cancel order flow
/e2e-test debug # Just show service status and debug info
/e2e-test trace <corr-id> # Trace request across services by CorrelationId
/e2e-test <custom scenario> # Describe what you want to test
$ARGUMENTS - Test scenario to run or empty for interactive mode| Service | Purpose | API Base | gRPC |
|---|---|---|---|
| Gateway | Reverse proxy (YARP) | /api/* | - |
| Product API | Product catalog & stock | /api/products | ProductService |
| Order API | Order management | /api/orders | - |
| Notification | Email notifications | - (consumer only) | - |
| Analytics | Order tracking | - (consumer only) | - |
| Database | Tables | Purpose |
|---|---|---|
productdb | Product, Stock, StockReservation, OutboxMessage, InboxState | Product catalog & stock |
orderdb | Order, OrderItem, OutboxMessage, OutboxState, InboxState | Orders + outbox |
notificationdb | ProcessedMessages | Inbox pattern (note: plural "Messages") |
Stock quantity is NOT decreased when orders are created. Instead:
StockReservation record is created with Status=0 (Active)Status=1 (Released)Stock.Quantity field represents total inventory, not available inventoryOrder API → [gRPC] → Product API (ReserveStock)
↓
OrderConfirmedEvent → [RabbitMQ] → Notification + Analytics
ALL API calls in E2E tests MUST go through the Gateway. This is non-negotiable.
✓ CORRECT: curl http://localhost:$GATEWAY_PORT/api/products
✗ WRONG: curl http://localhost:$PRODUCT_PORT/api/products
Why:
When direct service access is allowed:
debug scenario only - to compare Gateway vs direct responsehappy, unhappy, cancel scenariosALWAYS start here. Use AskUserQuestion to ask the user how they want to manage services:
Question: "How should I manage services for this E2E test?"
Options:
Manual (Recommended) - "I'll run the services myself or they're already running"
Automatic - "Start AppHost as a background process"
dotnet run --project src/AppHost in background using run_in_background: trueTaskStopBased on selection:
dotnet run --project src/AppHost
Use run_in_background: true parameterRun ./tools/e2e-test/discover.sh to get:
If services are not running:
Services not detected. Start with: dotnet run --project src/AppHostBased on $ARGUMENTS, plan the test scenario:
happy - Order Happy PathAll API calls via Gateway ($GATEWAY_PORT):
/api/products via Gateway → pick one with stock > 0/api/orders via Gateway → create order (see API Contract below)/api/orders/{id})ProcessedMessages table) - DB queryAPI Contract - Create Order:
{
"customerId": "guid",
"customerEmail": "[email protected]",
"items": [{
"productId": "guid",
"quantity": 2
}]
}
unhappy - Failure ScenariosAll API calls via Gateway ($GATEWAY_PORT):
/api/orders via Gateway with quantity > available/api/orders via Gateway with non-existent productId/api/orders via Gateway with missing required fieldscancel - Order CancellationAll API calls via Gateway ($GATEWAY_PORT):
/api/orders/{orderId}/cancel via Gateway (see API Contract below)/api/orders/{id})OrderCancelledConsumer) - DB queryAPI Contract - Cancel Order:
POST /api/orders/{orderId}/cancel
Content-Type: application/json
{"reason": "Customer requested cancellation"} # Body is REQUIRED!
debug - Service Debug InfoThis is the only scenario where direct service access is allowed (for comparison/troubleshooting).
trace <correlation-id> - Distributed Request Tracing./tools/e2e-test/trace-correlation.sh <correlation-id>Options:
--all-logs - Search all log files, not just latest--json - Output as JSON for further processingExample:
/e2e-test trace 228617a4-175a-4384-a8e2-ade916a78c3f
Output shows:
Execute scenario step by step. After each step:
REMEMBER: All API calls go through Gateway! (see Gateway-First Rule above)
Use these helpers:
# Service discovery - saves ports to .env file
./tools/e2e-test/discover.sh
source ./tools/e2e-test/.env
# API calls - ALWAYS use Gateway port!
curl -s "http://localhost:$GATEWAY_PORT/api/products" | jq '.'
curl -s "http://localhost:$GATEWAY_PORT/api/orders" | jq '.'
curl -s -X POST "http://localhost:$GATEWAY_PORT/api/orders" -H "Content-Type: application/json" -d '...'
# WRONG - never call services directly in E2E tests:
# curl -s "http://localhost:$PRODUCT_PORT/api/products" # ✗ DON'T DO THIS
# curl -s "http://localhost:$ORDER_PORT/api/orders" # ✗ DON'T DO THIS
# Database queries - get password first, then query
PG_PASS=$(docker exec <container> printenv POSTGRES_PASSWORD)
docker exec -e PGPASSWORD="$PG_PASS" <container> psql -U postgres -d <db> -c '<SQL>'
# Example:
PG_PASS=$(docker exec postgres-4cdf07e3 printenv POSTGRES_PASSWORD)
docker exec -e PGPASSWORD="$PG_PASS" postgres-4cdf07e3 psql -U postgres -d productdb -c 'SELECT * FROM "StockReservation";'
# Log inspection
./tools/e2e-test/logs.sh <service> [lines]
# Trace correlation ID
./tools/e2e-test/trace-correlation.sh <correlation-id>
If discover.sh fails to find services, use this:
# List all dotnet processes with ports
lsof -i -P -n | grep -E "EShop\.(Ord|Pro|Gat)" | grep LISTEN
# Typical output:
# EShop.Ord 45956 ... TCP 127.0.0.1:49814 (LISTEN) <- Order API HTTP
# EShop.Pro 45955 ... TCP 127.0.0.1:49815 (LISTEN) <- Product API HTTP
# EShop.Gat 45954 ... TCP 127.0.0.1:49818 (LISTEN) <- Gateway HTTP
Generate structured report:
═══════════════════════════════════════════════════════
E2E TEST REPORT: <scenario name>
═══════════════════════════════════════════════════════
ENVIRONMENT
Gateway: http://localhost:XXXXX ✓ ← All API calls go here
PostgreSQL: localhost:XXXXX ✓
RabbitMQ: localhost:XXXXX ✓
Backend services (for reference only):
Order API: http://localhost:XXXXX ✓
Product API: http://localhost:XXXXX ✓
SCENARIO: <description>
STEPS EXECUTED
[✓] Step 1: Get products
→ Found 10 products, selected "Cable Management Kit" (stock: 100)
[✓] Step 2: Create order
→ POST /api/orders → 201 Created
→ OrderId: abc-123-def
[✓] Step 3: Verify order status
→ DB: Order.Status = 1 (Confirmed)
[✗] Step 4: Verify stock decreased
→ Expected: 98, Actual: 100
→ FAILURE: Stock not reserved
LOGS (relevant entries)
[Order.API 21:00:10] Creating order for customer X
[Order.API 21:00:10] ERROR: gRPC call failed - No address resolver
DIAGNOSIS
Problem: gRPC service discovery not configured
Location: src/Common/EShop.ServiceClients/Extensions/ServiceCollectionExtensions.cs
Fix: Add .AddServiceDiscovery() to gRPC client registration
RESULT: FAILED (Step 4)
═══════════════════════════════════════════════════════
When an error blocks the scenario:
⚠️ Test blocked by error at Step X
Error: <description>
Service: <service name>
Log excerpt:
<relevant log lines>
Options:
1. Attempt to fix the issue (I'll suggest a fix)
2. Skip this step and continue
3. Abort test and show partial report
4. Debug mode - show all diagnostic info
Wait for user decision before proceeding.
Note: All API calls in these validation points go through Gateway.
| Check | Query/Command | Expected |
|---|---|---|
| API Response | POST $GATEWAY_PORT/api/orders | 200, status: "Confirmed" |
| Get Order | GET $GATEWAY_PORT/api/orders/{id} | status: "Confirmed" |
| Order in DB | SELECT * FROM "Order" WHERE "Id"='X' | Status = 1 (Confirmed) |
| Reservation created | SELECT * FROM "StockReservation" WHERE "OrderId"='X' | 1 row, Status=0 |
| Stock unchanged | SELECT "Quantity" FROM "Stock" | Same as before (stock is NOT decreased) |
| Outbox processed | SELECT * FROM "OutboxMessage" | 0 pending (processed) |
| Notification inbox | SELECT * FROM "ProcessedMessages" | OrderConfirmedConsumer row |
| Check | Query/Command | Expected |
|---|---|---|
| API Response | POST $GATEWAY_PORT/api/orders/{id}/cancel | 200, status: "Cancelled" |
| Get Order | GET $GATEWAY_PORT/api/orders/{id} | status: "Cancelled" |
| Order in DB | SELECT * FROM "Order" WHERE "Id"='X' | Status = 3 (Cancelled) |
| Reservation released | SELECT * FROM "StockReservation" WHERE "OrderId"='X' | Status=1 (Released) |
| Notification inbox | SELECT * FROM "ProcessedMessages" | OrderCancelledConsumer row |
| Check | Query/Command | Expected |
|---|---|---|
| Triggered when | Reservation makes available < threshold | StockLowEvent published |
| Notification inbox | SELECT * FROM "ProcessedMessages" | StockLowConsumer row |
| Service | Pattern | Meaning |
|---|---|---|
| Order.API | Creating order for customer | Command received |
| Order.API | Publishing OrderConfirmedEvent | Event dispatched |
| Product.API | ReserveStock request received | gRPC call arrived |
| Product.API | Stock reserved successfully | Reservation complete |
| Notification | Consuming OrderConfirmedEvent | Event received |
| Notification | Sending email to | Email triggered |
Use ./tools/e2e-test/rabbitmq.sh for message broker debugging:
./tools/e2e-test/rabbitmq.sh status # Overview
./tools/e2e-test/rabbitmq.sh queues # Queue status with message counts
./tools/e2e-test/rabbitmq.sh connections # Active service connections
./tools/e2e-test/rabbitmq.sh consumers # Consumer registrations
./tools/e2e-test/rabbitmq.sh messages # Pending message analysis
| Check | What to look for | Issue if... |
|---|---|---|
| Messages Ready | Should be 0 after processing | > 0 = stuck messages, consumer issue |
| Messages Unacked | Should be 0 or low | High = slow consumer or stuck processing |
| Connections | Order, Notification, Analytics | Missing = service not connected |
| Consumers | At least 2 per event type | 0 = no one listening |
| Dead Letter | Should be empty | Messages = repeated failures |
order-confirmed - OrderConfirmedEvent consumers
order-rejected - OrderRejectedEvent consumers
order-cancelled - OrderCancelledEvent consumers
stock-low - StockLowEvent consumers
Use ./tools/e2e-test/grpc.sh for inter-service communication debugging:
./tools/e2e-test/grpc.sh status # Port and connectivity check
./tools/e2e-test/grpc.sh list # List services (requires grpcurl)
./tools/e2e-test/grpc.sh test # Test gRPC calls
./tools/e2e-test/grpc.sh discovery # Service discovery configuration
| Service | Proto | Methods |
|---|---|---|
ProductService | product.proto | GetProducts, ReserveStock, ReleaseStock |
| Check | How | Expected |
|---|---|---|
| Product service reachable | grpc.sh status | HTTP 200 on health, gRPC port open |
| Service discovery | grpc.sh discovery | AddServiceDiscovery() configured |
| Proto matches | Compare proto file | Same version client/server |
After completing tests, offer cleanup options based on the mode selected in Phase 0:
Manual mode:
Test completed. Cleanup options:
1. Keep everything running (for further testing)
2. Reset test data (purge queues, clear orders)
Note: Stop services manually with Ctrl+C in your AppHost terminal.
What would you like to do?
Automatic mode (AppHost started by skill):
Test completed. Cleanup options:
1. Keep AppHost running (for further testing)
2. Stop AppHost (terminate background process)
3. Reset test data only (keep services running)
4. Full cleanup (stop AppHost + reset data)
What would you like to do?
Use TaskStop with the saved task_id to stop the background AppHost process.
Use ./tools/e2e-test/cleanup.sh for easy cleanup:
./tools/e2e-test/cleanup.sh status # See what needs cleaning
./tools/e2e-test/cleanup.sh data # Clear test orders, reservations
./tools/e2e-test/cleanup.sh queues # Purge RabbitMQ queues
./tools/e2e-test/cleanup.sh logs # Remove logs older than 7 days
./tools/e2e-test/cleanup.sh env # Remove generated .env
./tools/e2e-test/cleanup.sh services # Kill all running EShop services
./tools/e2e-test/cleanup.sh all # Full cleanup (except services)
Use ./tools/e2e-test/kill-services.sh to kill all running EShop services:
./tools/e2e-test/kill-services.sh # Show running services
./tools/e2e-test/kill-services.sh kill # Kill with confirmation
./tools/e2e-test/kill-services.sh --force # Kill without confirmation
This script finds and terminates all processes matching:
EShop.* (AppHost, common libs)Order.API, Products.API, Gateway.APINotification.API, Analytics.APIDatabaseMigrationOr manually:
# Stop Aspire (if started by this session)
# Note: AppHost runs in foreground, Ctrl+C stops it
# Reset databases (clear test orders, keep products)
./tools/reset-db.sh
# Purge RabbitMQ queues (remove stuck messages)
./tools/e2e-test/rabbitmq.sh purge <queue-name>
-- Clear orders (orderdb)
DELETE FROM "OrderItem";
DELETE FROM "Order";
DELETE FROM "OutboxMessage";
DELETE FROM "OutboxState";
DELETE FROM "InboxState";
-- Clear stock reservations (productdb)
DELETE FROM "StockReservation";
-- Note: Stock.Quantity doesn't need reset - it's not modified by orders
-- Clear processed messages (notificationdb) - note plural "Messages"
DELETE FROM "ProcessedMessages";
| Scenario | Recommended Cleanup |
|---|---|
| Single test run | Option 1 (keep running) |
| End of testing session | Option 2 (stop services) |
| Tests created bad data | Option 3 (reset data) |
| Fresh start needed | Option 4 (full cleanup) |
./tools/reset-db.sh which re-seeds productsTaskStop with the saved task_id| File | Purpose |
|---|---|
./tools/e2e-test/discover.sh | Service discovery (ports, credentials) |
./tools/e2e-test/db-query.sh | Database queries |
./tools/e2e-test/logs.sh | Log inspection |
./tools/e2e-test/api.sh | API call helper |
./tools/e2e-test/rabbitmq.sh | RabbitMQ diagnostics |
./tools/e2e-test/grpc.sh | gRPC diagnostics |
./tools/e2e-test/trace-correlation.sh | Distributed tracing by CorrelationId |
./tools/e2e-test/cleanup.sh | Test cleanup (default: all) |
./tools/e2e-test/kill-services.sh | Kill all running EShop services |
./tools/reset-db.sh | Database reset script |
src/Services/*/logs/*.log | Service log files |
http://localhost:PORT/swagger | API documentation |
ReservedAt - timestamp when reservation was madeExpiresAt - when reservation expiresStatus: 0 = Active, 1 = ReleasedAspire services use truncated names:
EShop.Ord / Order.APIEShop.Pro / Products.EShop.Gat / Gateway.AThe discover.sh script searches for both naming patterns.
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
Set up tracing, logging, and monitoring for deployed ADK agents across Cloud Trace, BigQuery, and third-party platforms.
Enterprise Azure infrastructure architect generating Bicep or Terraform from workload descriptions.
Plan and configure production-ready Azure Kubernetes Service clusters with Day-0 and Day-1 best practices.
Raw mechanical interfaces fusing Swiss typographic print with military terminal aesthetics. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects. For data-heavy dashboards, portfolios, or editorial sites that need to feel like declassified blueprints.
Web search, scraping, extraction, crawling, and monitoring via ScrapeGraph AI CLI.
Skill for working with Firebase Hosting (Classic). Use this when you want to deploy static web apps, Single Page Apps (SPAs), or simple microservices. Do NOT use for Firebase App Hosting.
Deploy and manage web apps with Firebase App Hosting. Use this skill when deploying Next.js/Angular apps with backends.
Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".
Build SEO-optimized pages at scale using templates, data, and proven playbook patterns.
Design and build isolated, reusable Convex backend components with clear boundaries and app-facing wrappers.
Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".
Opus.ai: Revolutionize Your Web Experience
Build a no-code AI app in minutes.
An IDE for code migration from legacy to modern frameworks through coding agents.
Automate CGI animation in live-action scenes
Branded artistic QR-code concepts
Launch a website in seconds with AI.
Streamline Your Coding Experience with AI Code Helper
Convert any screenshot or design to clean code.