| description | LeadPin Desktop β Tauri 2 + React + Express + Supabase. Use this when: working on frontend/backend features, debugging build issues, implementing WhatsApp automation, managing state/APIs, or handling database schema changes. Covers architecture, dev setup, conventions, common pitfalls, and directory structure. |
|---|
LeadPin is a desktop lead management + WhatsApp automation platform built with Tauri 2, React 19, Express, and Supabase.
π Full setup & feature docs: See README.md for detailed setup, deployment, and troubleshooting.
| Category | Details |
|---|---|
| Tech Stack | Frontend: React 19 + TypeScript + Tailwind 4 + Vite Β· Backend: Express + Puppeteer + whatsapp-web.js Β· Desktop: Tauri 2 Β· DB: Supabase |
| Dev Commands | Terminal 1: cd backend && npm run dev Β· Terminal 2: npm run tauri:dev |
| Build | ./build.ps1 (Windows PowerShell) β NSIS installer in src-tauri/target/release/bundle/nsis/ |
| Key Ports | Frontend: 5173 (Vite) Β· Backend: 4000 (Express) |
| Entry Points | Frontend: src/main.tsx Β· Backend: backend/src/index.ts Β· Desktop: src-tauri/src/main.rs |
| Database | Supabase cloud Β· Schema: backend/schema.sql |
| Deployment | Windows only (Tauri + MSVC) Β· Sidecar pattern: backend bundled as exe inside Tauri |
ββββββββββββββββββββββββββββββββββββ
β Tauri Desktop (Windows) β
ββββββββββββββββββββββββββββββββββββ€
β ββββββββββββββββ ββββββββββββββ β
β β React 19 ββββΊβ Express β β
β β (Vite build) β β (sidecar) β β
β β Port 5173 β β Port 4000 β β
β ββββββββββββββββ ββββββββββββββ β
ββββββββββββββββββββββββββ¬βββββββββββ
β (HTTP)
ββββββΌββββββββββ
β Supabase β
β (Cloud DB) β
ββββββββββββββββ
- Sidecar Backend: Express server (
backend-x86_64-pc-windows-msvc.exe) runs inside Tauri, started automatically - API Client:
src/lib/api-client.tsβ fetch wrapper with base URLhttp://localhost:4000 - State Management: React Query (
@tanstack/react-query) for async data, React Router for navigation - Authentication: Supabase Auth (email/password) β JWT stored in localStorage
- Database: Supabase PostgreSQL + RLS policies for row-level security
- Styling: Tailwind CSS 4 + Radix UI for components
leadpin/
βββ src/ # React frontend
β βββ components/
β β βββ business/ # Business detail page components
β β βββ dashboard/ # Main dashboard + WhatsApp panels
β β β βββ whatsapp/ # 7 WhatsApp feature tabs (bulk, greeting, etc.)
β β βββ ui/ # Reusable UI primitives (button, dialog, etc.)
β βββ hooks/ # React hooks (data fetching, custom logic)
β βββ lib/ # Utilities (api-client, supabase, utils)
β βββ pages/ # Page-level components (Auth, Dashboard, BusinessDetail)
β βββ providers/ # Context providers (QueryProvider)
β βββ types/ # TypeScript types & interfaces
β βββ App.tsx # Router setup
β βββ main.tsx # React DOM entry point
β βββ globals.css # Global Tailwind styles
β
βββ backend/ # Express + Node.js
β βββ src/
β β βββ controllers/ # Route handlers (business, list, whatsapp)
β β βββ middleware/ # Auth middleware
β β βββ routes/ # Route definitions
β β βββ services/ # Business logic (scraper, whatsapp)
β β βββ utils/ # Helpers (supabase client, etc.)
β β βββ index.ts # Express app setup
β βββ .env.example # Environment template
β βββ schema.sql # Supabase database schema
β βββ tsconfig.json
β βββ package.json
β
βββ src-tauri/ # Tauri 2 desktop config
β βββ src/
β β βββ main.rs # Tauri entry point (sidecar launcher)
β β βββ lib.rs
β βββ tauri.conf.json # Tauri config (window size, icons, sidecar)
β βββ Cargo.toml
β βββ binaries/ # Compiled backend exe (after build)
β
βββ package.json # Frontend dependencies
βββ tsconfig.json # Frontend TypeScript config
βββ vite.config.ts # Vite bundler config
βββ build.ps1 # Production build script (PowerShell)
βββ README.md # Full documentation (Turkish)
- Page components:
<Name>Page.tsx(e.g.,DashboardPage.tsx) - Feature components:
<Feature><Purpose>.tsx(e.g.,BulkSendPanel.tsx,OutreachHistory.tsx) - UI primitives: lowercase + hyphen (e.g.,
button.tsx,confirm-dialog.tsx) - Hooks:
use<Name>.ts(e.g.,useBusiness.ts,useOutreach.ts) - Services: lowercase + plural (e.g.,
scraper.ts,whatsapp.ts)
- Node.js 18+
- Rust + Cargo
- Visual Studio Build Tools (Windows, "Desktop development with C++" workload)
- Supabase account (free tier works)
# 1. Install dependencies
npm install
cd backend && npm install && cd ..
# 2. Create backend/.env
copy backend\.env.example backend\.env
# Edit .env with your Supabase credentials:
# SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_ACCESS_TOKEN
# 3. Run Supabase migrations
# In Supabase SQL Editor, run: backend/schema.sqlTerminal 1 β Backend:
cd backend
npm run dev # Runs on http://localhost:4000Terminal 2 β Frontend + Tauri:
$env:PATH = "$env:USERPROFILE\.cargo\bin;$env:PATH"
npm run tauri:dev # Opens app at http://localhost:5173| Task | Command |
|---|---|
| Build frontend only | npm run build |
| Type check | tsc (both root and backend) |
| Backend type check | cd backend && tsc |
| Build sidecar exe | cd backend && npm run build && npx @yao-pkg/pkg dist/index.js --targets node18-win-x64 ... |
| Full production build | ./build.ps1 |
-
API calls: All requests go through
src/lib/api-client.ts:const response = await apiClient.get('/api/businesses')
Base URL is
http://localhost:4000(dev) or relative (production). -
Async data: Use React Query with keys defined in
src/lib/query-keys.ts:const { data } = useQuery({ queryKey: queryKeys.business(id), queryFn: ... })
-
Authentication: Supabase client in
src/lib/supabase.ts:const { data, error } = await supabase.auth.signInWithPassword(email, password)
-
Routing: React Router with protected routes:
<Route path="/dashboard" element={<ProtectedRoute><DashboardPage /></ProtectedRoute>} />
- Database: Supabase client initialized in
backend/src/utils/supabase.ts - Express routes: Defined in
backend/src/routes/and imported inbackend/src/index.ts - Controllers: Handlers organized by domain (
business.controller.ts,list.controller.ts,whatsapp.controller.ts) - Services: Business logic (scraping, WhatsApp automation) in
backend/src/services/ - Middleware: Auth validation in
backend/src/middleware/auth.ts(validates JWT)
- Schema: See
backend/schema.sqlfor complete table definitions, indexes, RLS policies - Key tables:
auth.usersβ Supabase managed authbusinessesβ Scraped/imported leadslistsβ User-created lead groupswhatsapp_auto_rulesβ Greeting + keyword-based automationwhatsapp_scheduled_campaignsβ Queued campaignsoutreach_logsβ Message history
- Create handler in
backend/src/controllers/(or existing controller) - Add route in
backend/src/routes/(e.g.,business.routes.ts) - Import route in
backend/src/index.ts - Update TypeScript types if needed
- Test with
http://localhost:4000/api/endpointin dev mode
- Create component file in
src/components/following naming conventions - Import reusable UI from
src/components/ui/ - Use React Query hooks from
src/hooks/for data fetching - Add route in
src/App.tsxif it's a page - Test by running
npm run tauri:dev
- Define query key in
src/lib/query-keys.ts - Create custom hook in
src/hooks/using React Query:export const useBusiness = (id: string) => { return useQuery({ queryKey: queryKeys.business(id), queryFn: async () => { const response = await apiClient.get(`/api/businesses/${id}`) return response.data } }) }
- Use in component:
const { data, isLoading } = useBusiness(id)
- Add/modify table definitions in
backend/schema.sql(useIF NOT EXISTSfor safety) - Run updated SQL in Supabase SQL Editor
- Update TypeScript interfaces in
src/types/index.ts - Update API handlers to use new fields
npm run tauri:dev # Auto-builds backend sidecar when needed./build.ps1 # 4-step process:
# 1. Backend TypeScript compile
# 2. Backend pkg β exe
# 3. Frontend Vite build
# 4. Tauri bundle β NSIS installerOutput: src-tauri/target/release/bundle/nsis/LeadPin_<version>_x64-setup.exe
| Error | Solution |
|---|---|
| "cargo metadata not found" | Set Cargo in PATH: $env:PATH = "$env:USERPROFILE\.cargo\bin;$env:PATH" |
| "link.exe not found" | Install Visual Studio Build Tools with "Desktop development with C++" workload |
| "backend-*.exe doesn't exist" | Normal in dev (Tauri skips for dev mode). Build production via ./build.ps1 |
| "Connection closed" (Puppeteer) | Restart backend, check PUPPETEER_HEADLESS=true in .env |
- Wrong key: Using
SUPABASE_ANON_KEYinstead ofSUPABASE_SERVICE_ROLE_KEYβ backend auth fails - Missing credentials:
.envnot created or incomplete β backend crashes on startup - Solution: Copy
backend/.env.example, fill all required fields, restart dev server
- QR keeps refreshing: Likely auth cache corrupted
- Solution: Delete
backend/.wwebjs_auth/andbackend/.wwebjs_cache/, rescan QR
- "Cannot reach backend": Backend not running or port 4000 not accessible
- Solution: Verify Terminal 1 has
npm run devrunning, checksrc/lib/api-client.tsbase URL
- Component props type mismatch: Ensure component exports proper
React.FC<Props> - React Query hook types: Query keys must match return types of query functions
- Solution: Run
tscto catch all type errors before runtime
- "frontendDist not found": Frontend build failed before Tauri invoked
- Solution: Run
npm run buildmanually, check for errors, thennpm run tauri:build
- React 19 β UI framework
- TypeScript β Static typing
- Vite 6 β Fast bundler
- Tailwind CSS 4 β Styling
- Radix UI β Unstyled components (accessible)
- React Router 7 β Navigation
- React Query 5 β Data fetching & caching
- Supabase JS β Backend auth + database
- @tauri-apps/api β Desktop integration
- Express 5 β HTTP framework
- TypeScript 6 β Static typing
- Supabase JS β Database + auth
- Puppeteer 24 β Google Maps scraping
- whatsapp-web.js β WhatsApp Web automation
- Zod β Schema validation
- Tauri 2 β Desktop framework
- Rust β Core engine
- NSIS β Windows installer
- Always check
.envbefore debugging backend issues β missing Supabase credentials are the #1 problem - Run both dev servers β Frontend dev without backend running will cause "Cannot reach API" errors
- React Query caching β If data seems stale, check query invalidation logic in components
- Sidecar paths β Backend exe must be at
src-tauri/binaries/backend-x86_64-pc-windows-msvc.exefor Tauri to find it - Type safety: Use
queryKeysfromsrc/lib/query-keys.tsto avoid mismatches between frontend + backend - Database migrations: Always use
IF NOT EXISTSin schema.sql to prevent failures on re-runs - WhatsApp automation:
whatsapp_auto_rulestable hasreply_once_per_contact+cooldown_minutesβ check these when debugging reply logic - Short ID tracking:
businesses.short_idlinks to tΔ±klama takibi (click tracking) via Supabase RPCtrack_short_id_click
# Frontend
npm run dev # Vite dev server (port 5173)
npm run build # Build dist/
npm run tauri:dev # Launch Tauri dev (requires backend running)
npm run tauri:build # Build installer (release mode)
# Backend
cd backend
npm run dev # ts-node-dev on port 4000
npm run build # TypeScript compile to dist/
npm start # Run compiled dist/index.js
npm run build && pkg ... # Package as exe (see build.ps1)
# Full production
./build.ps1 # Complete build pipeline- Full docs: README.md
- Database schema: backend/schema.sql
- Environment template: backend/.env.example
- Tauri config: src-tauri/tauri.conf.json