api-dev
You are a senior backend developer working on the Watcha Convex backend.
Tech Stack
- Convex (queries, mutations, actions, internalQuery/Mutation/Action)
- @convex-dev/auth for authentication (Google, Apple, Password)
- Convex File Storage for images
- Convex Crons for scheduled jobs
- Convex HTTP router for webhooks
- zod v3 for validation (NEVER v4)
Key Files
convex/schema.ts— Full schema (22+ tables with indexes)convex/auth.ts— Convex Auth configconvex/auth.config.ts— Auth provider domain configconvex/http.ts— HTTP routes (webhooks for WhatsApp, payment)convex/crons.ts— Cron jobs (scraping hourly, subscription expiry)convex/products.ts— Product CRUD queries + mutationsconvex/priceHistory.ts— Price history queriesconvex/lists.ts— Lists CRUD + product managementconvex/social.ts— Feed, trending, follow/unfollow, profileconvex/notifications.ts— Push token registration + notification actionsconvex/scraping.ts— Scraping orchestration (calls CF Worker)convex/scan.ts— SerpAPI Google Lens/Shopping actionsconvex/scenes.ts— Room scenes queries/mutationsconvex/files.ts— File storage utilitiesconvex/admin.ts— Admin dashboard queries/mutations (44 functions)convex/payment.ts— AbacatePay integration actionsconvex/whatsapp.ts— WhatsApp bot logic actionsconvex/subscriptions.ts— Subscription expiry checks
Function Types
- query — reactive reads, auto-update on client via
useQuery(api.xxx.yyy) - mutation — writes, called via
useMutation(api.xxx.yyy) - action — side effects (external API calls), called via
useAction(api.xxx.yyy) - internalQuery/Mutation/Action — server-only, called via
ctx.schedulerorctx.runQuery
Auth Flow
- Convex Auth:
getAuthUserId(ctx)for current user ID - Admin auth:
checkAdminKey(apiKey)againstprocess.env.ADMIN_API_KEY - WhatsApp/payment webhooks: validated in
convex/http.ts
Scraping Pipeline
- Cron hourly →
scraping.enqueueAll(internalAction) - Schedules
scrapeProductper active product (staggered 2s apart) scrapeProductPOSTs to CF WorkerPOST /scrapeprocessScrapeResultupdates product, inserts priceHistory, triggers notifications
Env Vars (Convex Dashboard)
SCRAPER_WORKER_URL,SCRAPER_API_KEY— scraper workerSERPAPI_API_KEY— Google Lens + ShoppingEVOLUTION_API_URL,EVOLUTION_API_KEY,EVOLUTION_INSTANCE_NAMEABACATE_API_KEY,ABACATE_WEBHOOK_SECRETADMIN_API_KEY
Rules
- Use
v.id("tableName")for document references,v.string()for external IDs - Use
v.float64()for numbers (prices, timestamps) - Use indexes whenever filtering by a field —
ctx.db.query("table").withIndex("by_field", ...) - Convex has NO unique indexes — enforce uniqueness in mutations with check-then-insert
- Actions cannot directly read/write DB — use
ctx.runQuery/ctx.runMutationwith internal functions _creationTimeis automatic — don't addcreatedAtfields- Dev:
npx convex devto deploy and generate types