Skip to content

๐Ÿงช Postman Testing Workflows

Quick reference for testing all Phase A-F features with Postman.


๐ŸŽฏ Workflow 1: Student Experience (5 min)

Goal: Test full student chat flow with wallet deduction

1. Auth โ†’ Signup (Student)         โ†’ Creates account, JWT auto-saved
2. Wallet โ†’ Get Balance            โ†’ Check balance (50 tokens for new users)
3. Chat โ†’ Ask Question (French)    โ†’ Get answer, tokens deducted
4. Wallet โ†’ Get Balance            โ†’ Verify deduction (balance = 50 - tokens_used)
5. Chat โ†’ Ask Question (Arabic)    โ†’ Test translation (Arabic โ†’ French corpus)
6. Wallet โ†’ Get Balance            โ†’ Verify second deduction

Expected Results: - โœ… Balance starts at 50 tokens - โœ… Each chat deducts ~10-100 tokens - โœ… Arabic questions get French corpus results - โœ… All responses include request_id


๐ŸŽฏ Workflow 2: Admin Ingestion (10 min)

Goal: Upload PDF, trigger ingestion, verify searchable

1. Auth โ†’ Signin                                โ†’ Login as admin
2. Upload โ†’ Get Presigned Upload URL            โ†’ Get S3 URL, file_id saved
   [Manual: Upload PDF to presigned URL via curl]
3. Ingestion โ†’ Create Ingestion Job             โ†’ Create job, job_id saved
4. Ingestion โ†’ Get Job Status                   โ†’ Poll until status = 'ready'
5. Chat โ†’ Ask Question                          โ†’ Verify new content searchable

Expected Results: - โœ… Presigned URL expires in 300 seconds - โœ… Job transitions: queued โ†’ parsing โ†’ ... โ†’ ready - โœ… chunks_created > 0, vectors_upserted > 0 - โœ… New content appears in search results

External Step (Upload PDF):

# After getting presigned URL from step 2:
curl -X PUT "{{upload_url}}" \
  -H "Content-Type: application/pdf" \
  --upload-file path/to/your-file.pdf


๐ŸŽฏ Workflow 3: Scraper Deduplication (5 min)

Goal: Test SimHash deduplication and quality checks

1. Auth โ†’ Signin (Admin)                        โ†’ Login
2. Scraping โ†’ Sync Koutoubi Scraper             โ†’ First sync, scrape_run_id saved
   Check Console โ†’ View stats (found, new, duplicates)
3. Scraping โ†’ List References (Koutoubi)        โ†’ View discovered references
4. Scraping โ†’ Sync Koutoubi Scraper (again)     โ†’ Second sync
   Check Console โ†’ duplicates should be > 0 (SimHash working)
5. Scraping โ†’ List References                   โ†’ View canonical vs duplicates

Expected Results: - โœ… First sync: new > 0, duplicates = 0 - โœ… Second sync: new = 0, duplicates > 0 - โœ… Duplicate references have canonical_id pointing to first discovery - โœ… Quality-failed documents not inserted (quality_failed > 0 if any)


๐ŸŽฏ Workflow 4: Quiz Generation (3 min)

Goal: Generate quiz and verify RAG context

1. Auth โ†’ Signin                                โ†’ Login
2. Wallet โ†’ Get Balance                         โ†’ Check initial balance
3. Quizzes โ†’ Generate Quiz (French)             โ†’ Get 5 questions
   Check Console โ†’ quiz_id, tokens_used
4. Wallet โ†’ Get Balance                         โ†’ Verify deduction
5. Quizzes โ†’ Generate Quiz (Arabic)             โ†’ Test Arabic quiz

Expected Results: - โœ… 5 questions with options, correct answer, explanation - โœ… Each question has source_page reference - โœ… Tokens deducted from wallet - โœ… Arabic quiz generated correctly


๐ŸŽฏ Workflow 5: Rate Limiting (2 min)

Goal: Trigger rate limit and verify 429 response

1. Auth โ†’ Signin                                โ†’ Get JWT
2. Testing โ†’ Rate Limit Test (Send 11x)         โ†’ Single request
3. Use Postman Runner:
   - Select "Rate Limit Test" request
   - Click "Run" โ†’ Iterations: 11
   - Run
4. Check Results                                โ†’ 11th should be 429

Expected Results: - โœ… Requests 1-10: 200 OK - โœ… Request 11: 429 Too Many Requests - โœ… 429 response includes: - error: "rate_limited" - retry_after: 23 (seconds until window resets) - limit: 10 - window: "1m" - request_id: "uuid"


๐ŸŽฏ Workflow 6: Request-ID Propagation (2 min)

Goal: Verify request-ID correlation across subsystems

1. Auth โ†’ Signin                                โ†’ Get JWT
2. Testing โ†’ Request-ID Test (Custom ID)        โ†’ Sends X-Request-ID: test-custom-request-id-123
3. Check Response Headers                       โ†’ X-Request-ID should match
4. Check Environment                            โ†’ last_request_id = custom ID
5. Wallet โ†’ Get Balance                         โ†’ Auto-generated UUID
6. Check Environment                            โ†’ last_request_id = new UUID

Expected Results: - โœ… Custom request-ID adopted (echoed in response) - โœ… Auto-generated UUID if no custom ID provided - โœ… All error responses include request_id - โœ… Database rows (reservations, wallet_ledger) share same request_id

Verify in Database:

-- Find all records for a request
SELECT 'reservations' as table_name, * FROM reservations WHERE request_id = 'abc123'
UNION ALL
SELECT 'wallet_ledger', * FROM wallet_ledger WHERE request_id = 'abc123';


๐ŸŽฏ Workflow 7: Idempotency Test (3 min)

Goal: Verify deterministic chunk IDs prevent duplicates

1. Auth โ†’ Signin (Admin)                        โ†’ Login
2. Ingestion โ†’ Create Ingestion Job             โ†’ reference_id = X, job_id saved
3. Wait for job to complete                     โ†’ Poll until status = 'ready'
4. Testing โ†’ Idempotency Test                   โ†’ Same reference_id again

Expected Results: - โœ… First ingestion: 202 Accepted, job created - โœ… Second ingestion (before first completes): 409 Conflict - โœ… Second ingestion (after first completes): 202, but same chunk IDs generated - โœ… No duplicate vectors in Pinecone (verify via metrics or Pinecone dashboard)

Verify in Database:

-- Check chunk_ids for same file ingested twice
SELECT chunk_id, file_id, page_number, chunk_index, created_at
FROM chunks
WHERE file_id = 'your-file-uuid'
ORDER BY page_number, chunk_index;

-- Should see same chunk_ids even after re-ingestion


๐ŸŽฏ Workflow 8: Multilingual Chat (5 min)

Goal: Test cross-lingual retrieval and translation

1. Auth โ†’ Signin                                โ†’ Login
2. Chat โ†’ Ask Question (French)                 โ†’ Baseline (no translation)
   Check Response โ†’ query_language = "fr", translated_query = null
3. Chat โ†’ Ask Question (Arabic โ†’ French Corpus) โ†’ Test translation
   Check Response โ†’ query_language = "ar", translated_query = "<French translation>"
4. Chat โ†’ Ask Question (Hassaniya)              โ†’ Test Hassaniya detection
   Check Response โ†’ query_language = "ha", translated_query = "<French>"

Expected Results: - โœ… French query: No translation, direct retrieval - โœ… Arabic query: Translated to French before retrieval - โœ… Hassaniya query: Detected and translated - โœ… All queries return relevant French corpus results


๐ŸŽฏ Workflow 9: Cache Verification (3 min)

Goal: Verify rerank cache reduces latency

1. Auth โ†’ Signin                                โ†’ Login
2. Chat โ†’ Ask Question (French)                 โ†’ First request
   Check Console โ†’ Response time (e.g., 3000 ms)
   Check Response โ†’ cache_hit = false
3. Chat โ†’ Ask Question (French) - SAME question โ†’ Second request
   Check Console โ†’ Response time (e.g., 50 ms) โ† Much faster!
   Check Response โ†’ cache_hit = true
4. Wait 16 minutes                              โ†’ TTL expires (15 min)
5. Chat โ†’ Ask Question (French) - SAME question โ†’ Third request
   Check Response โ†’ cache_hit = false (cache expired)

Expected Results: - โœ… First request: Full pipeline (2-5 seconds) - โœ… Second request: Cache hit (<100 ms) - 98% faster - โœ… After TTL: Cache miss (back to full pipeline)


๐ŸŽฏ Workflow 10: Circuit Breaker Test (Advanced)

Goal: Simulate OpenAI failure and verify fallback

Note: Requires temporarily breaking OpenAI connection (invalid API key) or mocking failures

1. [Simulate 3 OpenAI failures in 60 seconds]
2. Metrics โ†’ Get Metrics (JSON)                 โ†’ Check circuit_breaker_state
   Expected: circuit_breaker_state{service="openai_mini"} = 1 (open)
3. Chat โ†’ Ask Question                          โ†’ Should still work
   Check Response โ†’ Rerank skipped, dense retrieval order used
4. Wait 120 seconds                             โ†’ Recovery timeout
5. Metrics โ†’ Get Metrics (JSON)                 โ†’ Check circuit_breaker_state
   Expected: State = 2 (half-open) or 0 (closed after test request)

Expected Results: - โœ… Circuit opens after 3 failures - โœ… Requests still work (fallback to dense order) - โœ… Circuit recovers after 120 seconds - โœ… No complete service outage


๐Ÿ“Š Verification Checklist

Phase A - Ingestion

  • [ ] Presigned URL generated with 5-min expiry
  • [ ] Ingestion job created (status: queued)
  • [ ] Job transitions through all states
  • [ ] Chunks created with deterministic IDs
  • [ ] Vectors upserted to Pinecone
  • [ ] Same file re-ingested โ†’ same chunk IDs (idempotent)

Phase B - Security

  • [ ] JWT contains app_metadata.role
  • [ ] Admin endpoints require admin role
  • [ ] Rate limiting triggers 429 after limit
  • [ ] Request-ID in all response headers
  • [ ] Request-ID in all error responses
  • [ ] Custom X-Request-ID adopted

Phase C - Caching

  • [ ] Repeat queries have cache_hit = true
  • [ ] Cache hit latency < 100 ms
  • [ ] Cache miss latency 2-5 seconds
  • [ ] Tier limits enforced (Free: 10, Premium: 30)

Phase D - Retrieval

  • [ ] Language detection works (French, Arabic, Hassaniya)
  • [ ] Arabic queries translated to French
  • [ ] Reranking improves relevance
  • [ ] Quiz generation produces valid questions
  • [ ] Circuit breaker prevents cascade failures

Phase E - Scraper

  • [ ] Scraper sync returns statistics
  • [ ] Duplicates detected via SimHash
  • [ ] Quality-failed documents rejected
  • [ ] Canonical references created

Phase F - Observability

  • [ ] Metrics endpoint returns valid Prometheus format
  • [ ] Metrics include counters, histograms, gauges
  • [ ] Wallet reconciliation detects discrepancies
  • [ ] Background jobs run without errors

๐ŸŽฌ Ready to Test!

  1. Import collection_v2.json
  2. Import environment_local.json
  3. Follow Workflow 1 (Student Experience)
  4. Check other workflows as needed

Happy Testing! ๐Ÿš€