CLAUDE.md 11 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

ShopCall.ai is an AI-powered calling system integrated with e-commerce platforms. The project consists of:

  • shopcall.ai-main: React/Vite frontend application with TypeScript
  • supabase: Supabase Edge Functions for backend API

Repository Structure

/data/shopcall/
├── shopcall.ai-main/          # Frontend application
│   ├── src/
│   │   ├── components/        # React components
│   │   │   ├── context/       # React context providers (AuthContext)
│   │   │   └── ui/            # shadcn-ui component library
│   │   ├── pages/             # Route pages (Dashboard, Login, CallLogs, etc.)
│   │   ├── hooks/             # Custom React hooks
│   │   ├── lib/               # Utility functions
│   │   └── App.tsx            # Main application with routing
│   └── package.json
└── supabase/                   # Supabase Edge Functions
    └── functions/              # Backend API functions

Development Commands

Frontend (shopcall.ai-main)

cd shopcall.ai-main
npm install              # Install dependencies
npm run dev              # Start dev server on port 8080
npm run build            # Production build
npm run build:dev        # Development build
npm run lint             # Run ESLint
npm run preview          # Preview production build

Supabase Edge Functions

# Deploy Edge Functions
supabase functions deploy <function-name>

# Test locally
supabase functions serve

Technology Stack

Frontend

  • Framework: React 18 with Vite
  • Language: TypeScript
  • UI Library: shadcn-ui with Radix UI primitives
  • Styling: Tailwind CSS
  • Routing: React Router v6
  • State Management: React Query (@tanstack/react-query)
  • Form Handling: React Hook Form with Zod validation
  • Theme: next-themes for dark mode support

Backend

  • Platform: Supabase Edge Functions (Deno)
  • Database: Supabase (PostgreSQL with auth)
  • Authentication: Supabase Auth

Architecture

Frontend Architecture

Authentication Flow:

  • AuthContext provider (src/components/context/AuthContext.tsx) manages global auth state
  • Token stored in localStorage as session_data
  • PrivateRoute component protects authenticated routes
  • Auth validation via Supabase client

Routing Structure:

/ (Index)               → Landing page
/signup                 → User registration
/login                  → User login
/otp                    → OTP verification
/dashboard (protected)  → Main dashboard
/call-logs (protected)  → Call history
/analytics (protected)  → Analytics dashboard
/webshops (protected)   → E-commerce integrations
/phone-numbers (protected) → Phone number management
/ai-config (protected)  → AI configuration
/onboarding (protected) → User onboarding flow
/about, /privacy, /terms → Public pages

Component Organization:

  • Page components in src/pages/ handle routing
  • Content components (e.g., DashboardContent.tsx) contain page logic
  • UI components in src/components/ui/ are reusable shadcn components
  • Context providers wrap the app in App.tsx

Backend Architecture

Supabase Edge Functions: Backend logic implemented as serverless Edge Functions

Authentication:

  • Handled by Supabase Auth
  • User management and session handling via Supabase client

E-commerce Integrations:

  • Shopify OAuth flow (not yet implemented)
  • WooCommerce integration (fully implemented)
    • OAuth flow: oauth-woocommerce (OAuth 1.0a authentication)
    • API client: _shared/woocommerce-client.ts
    • Read-only access to products, orders, and customers
    • Secure OAuth 1.0a with HMAC-SHA256 signatures
  • ShopRenter integration (fully implemented)
    • OAuth flow: oauth-shoprenter-init, oauth-shoprenter-callback
    • Uninstall webhook: webhook-shoprenter-uninstall
    • Data sync endpoints: shoprenter-products, shoprenter-orders, shoprenter-customers
    • Manual sync: shoprenter-sync
    • Scheduled background sync: shoprenter-scheduled-sync (automated via pg_cron)
    • API client: _shared/shoprenter-client.ts
  • Store credentials in Supabase stores table

Database Schema (Supabase)

stores table:

- user_id: UUID (FK to auth.users)
- platform_name: text (e.g., 'shopify', 'woocommerce', 'shoprenter')
- store_name: text
- store_url: text
- api_key: text (access token for ShopRenter)
- api_secret: text (refresh token for ShopRenter)
- scopes: text[]
- alt_data: jsonb (platform-specific data, e.g., expires_at, last_sync_at)
- phone_number: text
- package: text

oauth_states table (for OAuth flow state management):

- state: text (UUID for CSRF protection)
- user_id: UUID (FK to auth.users)
- platform: text (e.g., 'shoprenter')
- shopname: text
- expires_at: timestamp

pending_shoprenter_installs table (temporary storage during OAuth):

- installation_id: text (UUID)
- shopname: text
- access_token: text
- refresh_token: text
- token_type: text
- expires_in: integer
- scopes: text[]
- expires_at: timestamp

shoprenter_products_cache table (cached product data):

- store_id: UUID (FK to stores)
- shoprenter_product_id: text
- name: text
- sku: text
- price: decimal
- currency: text
- description: text
- stock: integer
- active: boolean
- raw_data: jsonb
- last_synced_at: timestamp

shoprenter_webhooks table (webhook registrations):

- store_id: UUID (FK to stores)
- shoprenter_webhook_id: text
- event: text (e.g., 'order/create')
- callback_url: text
- is_active: boolean
- last_received_at: timestamp
- total_received: integer

sync_logs table (scheduled sync execution logs):

- id: UUID (primary key)
- sync_type: text ('manual', 'scheduled', 'webhook')
- platform: text ('shopify', 'woocommerce', 'shoprenter')
- stores_processed: integer
- results: jsonb (detailed results per store)
- started_at: timestamptz
- completed_at: timestamptz
- created_at: timestamptz

store_sync_config table (per-store sync configuration):

- id: UUID (primary key)
- store_id: UUID (FK to stores, unique)
- enabled: boolean (default: true)
- sync_frequency: text ('15min', '30min', 'hourly', '6hours', 'daily')
- last_sync_at: timestamptz
- next_sync_at: timestamptz (auto-calculated)
- sync_products: boolean (default: true)
- sync_orders: boolean (default: true)
- sync_customers: boolean (default: true)
- created_at: timestamptz
- updated_at: timestamptz

Environment Configuration

Frontend .env (shopcall.ai-main)

# Supabase Configuration
VITE_SUPABASE_URL=https://ztklqodcdjeqpsvhlpud.supabase.co
VITE_SUPABASE_ANON_KEY=<anon_key>

# Backend API Base URL (Supabase Edge Functions)
VITE_API_URL=https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1

# Frontend URL (for OAuth callbacks)
VITE_FRONTEND_URL=https://shopcall.ai

Supabase Edge Functions .env

# OAuth Configuration
SHOPIFY_API_KEY=<shopify_api_key>
SHOPIFY_API_SECRET=<shopify_api_secret>
SHOPRENTER_CLIENT_ID=<shoprenter_client_id>
SHOPRENTER_CLIENT_SECRET=<shoprenter_client_secret>

# Scheduled Sync Security
INTERNAL_SYNC_SECRET=<random_secure_secret_for_scheduled_sync>

# Email Configuration
RESEND_API_KEY=<resend_api_key>

# Frontend URL
FRONTEND_URL=https://shopcall.ai

# Supabase Configuration
SUPABASE_URL=<supabase_project_url>
SUPABASE_ANON_KEY=<supabase_anon_key>
SUPABASE_SERVICE_ROLE_KEY=<supabase_service_role_key>

Supabase Database Settings (for pg_cron)

Configure in Supabase Dashboard → Project Settings → Database → Custom Postgres Configuration:

app.internal_sync_secret = '<same_as_INTERNAL_SYNC_SECRET_above>'
app.supabase_url = 'https://ztklqodcdjeqpsvhlpud.supabase.co'

Deployment

Frontend

  • Build: npm run build generates static files in dist/
  • Deployment: Can be deployed to any static hosting service (Netlify, Vercel, GitHub Pages, etc.)
  • SPA routing handled by React Router

Supabase Edge Functions

  • Deployment: Use supabase functions deploy command
  • Edge Functions are deployed to Supabase infrastructure
  • Automatically scaled and managed by Supabase

Development Workflow

When making changes:

  1. Frontend Changes: Work in shopcall.ai-main/src/
  2. Backend Changes: Modify Supabase Edge Functions in supabase/functions/
  3. Auth Flow Changes: Update AuthContext and Supabase Auth configuration
  4. New Protected Routes: Add to App.tsx inside <PrivateRoute> wrapper
  5. New API Endpoints: Create new Edge Functions in supabase/functions/

Important Notes

  • Backend is implemented as Supabase Edge Functions (serverless)
  • Supabase handles user authentication, data storage, and API endpoints
  • Frontend is a static React application that can be hosted anywhere
  • All API calls go through Supabase Edge Functions
  • OAuth flows store credentials in Supabase stores table

Path Aliases

Frontend uses TypeScript path alias:

  • @/./src/

Example: import { Button } from "@/components/ui/button"

Background Sync & Scheduling

ShopRenter Automated Synchronization

The ShopRenter integration includes automated background sync capabilities using PostgreSQL's pg_cron extension.

How it works:

  1. pg_cron schedules database jobs at specified intervals
  2. pg_net makes HTTP requests from the database to Edge Functions
  3. shoprenter-scheduled-sync Edge Function processes all active stores
  4. Sync results are logged to sync_logs table

Sync Frequencies:

  • 15min - Every 15 minutes (high-frequency updates)
  • 30min - Every 30 minutes
  • hourly - Every hour (default, recommended)
  • 6hours - Every 6 hours
  • daily - Once per day

Configuration:

  • Per-store sync frequency via store_sync_config table
  • Enable/disable sync per store
  • Choose what to sync (products, orders, customers)
  • Automatic next sync calculation

Monitoring:

  • sync_logs table tracks all sync executions
  • sync_statistics view provides aggregated metrics
  • Logs include per-store success/failure status
  • Sync duration and item counts tracked

Setup Requirements:

  1. Run migration: supabase/migrations/20250129_shoprenter_scheduled_sync.sql
  2. Deploy Edge Function: supabase functions deploy shoprenter-scheduled-sync
  3. Configure INTERNAL_SYNC_SECRET in Edge Functions environment
  4. Configure database settings in Supabase Dashboard
  5. Monitor sync_logs table for execution results

Manual Control:

-- Enable/disable sync for a store
SELECT set_store_sync_enabled('store-uuid', true);

-- Change sync frequency
SELECT set_store_sync_frequency('store-uuid', 'hourly');

-- View recent sync logs
SELECT * FROM sync_logs ORDER BY created_at DESC LIMIT 10;

-- View sync statistics
SELECT * FROM sync_statistics;

Security:

  • INTERNAL_SYNC_SECRET prevents unauthorized sync triggers
  • Only internal pg_cron jobs can trigger scheduled sync
  • Row-level security ensures users only see their own sync logs