# HalaVoice AI for Salla — Testing Checklist

## Installation & OAuth
- [ ] Salla Partner test store created with required scopes
- [ ] App installs via OAuth Easy Mode (redirect)
- [ ] OAuth callback receives access_token and refresh_token
- [ ] `salla_tokens` table populated correctly
- [ ] `salla_stores` record created with merchant_id
- [ ] Token refresh works when access_token expires
- [ ] Re-install same store → update existing records (no duplicates)
- [ ] Uninstall → store marked inactive, subscription cancelled
- [ ] Install from different store → separate records

## Webhooks
- [ ] HMAC-SHA256 signature verification (valid and invalid)
- [ ] Token-based webhook verification
- [ ] `app.store.authorize` creates token and store
- [ ] `app.installed` / `app.uninstalled` handled
- [ ] `app.subscription.*` events handled (started, expired, cancelled, renewed)
- [ ] `app.trial.started` handled
- [ ] `app.settings.updated` handled
- [ ] `order.created` triggers COD confirmation workflow
- [ ] `order.status.updated` triggers appropriate action
- [ ] `order.cancelled` handled gracefully
- [ ] `abandoned.cart` triggers recovery workflow
- [ ] `customer.created` / `customer.updated` syncs customer
- [ ] `shipment.created` triggers WhatsApp notification
- [ ] Duplicate webhook events rejected (idempotency)
- [ ] Unknown event types logged but not errored
- [ ] Raw payload stored in `webhook_events` table

## Voice Calls
- [ ] `MakeOutboundCall` job dispatched for COD orders
- [ ] Job respects `call_delay_minutes` setting
- [ ] HalaVoice API called with correct script and variables
- [ ] Call initiated → `CallJob` status updated to `initiated`
- [ ] Call answered → status `completed`, duration recorded
- [ ] Call failed → status `failed`, retry logic works (up to max_retry_attempts)
- [ ] Customer confirms order → `cod_confirmation_status = confirmed`
- [ ] Customer cancels → `cod_confirmation_status = cancelled`, order cancelled via Salla API
- [ ] No phone number → job marked failed with 'no_phone' outcome
- [ ] `ConversationLog` created for each call
- [ ] `CallTranscript` stored when available
- [ ] `AiSummary` generated from transcript
- [ ] Mock mode works without real HalaVoice API

## Abandoned Cart Recovery
- [ ] `RecoverAbandonedCart` job dispatched on `abandoned.cart` event
- [ ] Strategy selection works: WhatsApp → Call → Both → Skip
- [ ] `min_cart_value_for_call` respected
- [ ] `abandoned_cart_delay_minutes` respected
- [ ] Reminder count increments correctly
- [ ] `converted_to_order` flag updated when customer orders
- [ ] `recovered_revenue` tracked
- [ ] Already-converted carts skipped
- [ ] Call and WhatsApp jobs created with correct metadata

## WhatsApp
- [ ] `SendWhatsAppMessage` job dispatched for events
- [ ] Template selection matches event type
- [ ] Variable interpolation correct (Arabic text)
- [ ] WhatsApp sent → status `sent`, `sent_at` timestamp
- [ ] Send failed → retry logic works (3 attempts)
- [ ] No phone → failed with 'no_phone' error
- [ ] All 5 templates functional: order_confirmation, shipping_update, delivery_confirmation, abandoned_cart, review_request
- [ ] Media attachments handled (if applicable)

## Dashboard
- [ ] Overview page loads with correct KPIs
- [ ] Period selector (7d, 30d, 90d, 1y) works
- [ ] Setup wizard steps flow correctly
- [ ] Automation rules page displays rules
- [ ] Call logs pagination and filtering
- [ ] WhatsApp logs pagination and filtering
- [ ] Recovered revenue page with totals
- [ ] Settings page: all fields save and persist
- [ ] Settings page: fields load saved values correctly
- [ ] Voice scripts page displays all scripts
- [ ] WhatsApp templates page displays all templates
- [ ] Billing page shows subscription and usage
- [ ] All Arabic UI text renders correctly (RTL)
- [ ] Responsive layout works on mobile
- [ ] Salla Embedded SDK initializes within iframe

## API
- [ ] `GET /api/calls` returns paginated list
- [ ] `GET /api/calls/{id}` returns call details with relations
- [ ] `GET /api/calls/{id}/transcript` returns transcript
- [ ] `GET /api/calls/{id}/summary` returns AI summary
- [ ] `GET /api/whatsapp` returns paginated messages
- [ ] `GET /api/whatsapp/conversations` returns conversation logs
- [ ] `GET /api/settings` returns all settings
- [ ] `POST /api/settings` updates settings
- [ ] `GET /api/settings/{key}` returns single setting
- [ ] Rate limiting works (60 req/min)
- [ ] Authentication required (bearer token)
- [ ] Invalid store_id returns 400

## Security
- [ ] Tokens encrypted at rest (Laravel `encrypted` cast)
- [ ] Webhook signature verified for every request
- [ ] API endpoints require authentication
- [ ] Rate limiting active on API routes
- [ ] No sensitive data in logs
- [ ] SQL injection prevention (parameterized queries)
- [ ] XSS prevention in Blade views
- [ ] CSRF protection on forms
- [ ] CORS configured for Salla iframe domain

## Performance
- [ ] Webhook processing < 30 seconds (includes job dispatch)
- [ ] Dashboard loads < 2 seconds
- [ ] API pagination works with large datasets
- [ ] Database queries optimized (indexes, eager loading)
- [ ] Queue worker processes jobs without backlog
- [ ] Concurrent webhook requests handled correctly

## Edge Cases
- [ ] Empty phone number → appropriate error
- [ ] Invalid phone format → handled
- [ ] Store uninstalled while jobs pending → jobs cancelled
- [ ] Token expired → auto-refresh on next Salla API call
- [ ] Network failure to HalaVoice → retry with backoff
- [ ] Very large payload webhooks → processed without timeout
- [ ] Arabic + English mixed characters in templates
- [ ] Special characters in customer names
- [ ] Decimal amounts (e.g., 199.99 SAR)
