Documentation Index
Fetch the complete documentation index at: https://cernio.gadulabs.com/llms.txt
Use this file to discover all available pages before exploring further.
05 — Pre-Operation Confirmation System
Ring: 1 (Launch Blocker)
Dependency: R1-2 (Cost Control — cost info needed), R1-4 (Billing — plan/limit info needed)
Handbook: Ch. 76 (credit costs), Ch. 6 (WOW moment — minimize friction but keep costs transparent)
Problem
- AI operations cost money but the user is unaware.
- Limit overages happen silently (currently there are no limits at all).
- User clicks “Discovery” but doesn’t know it costs 1 credit / 1 quota.
- A misclick could burn through 50 discovery quotas in 2 minutes.
Decisions
D1: Confirmation Dialog on Every Costly Operation
User clicks "Discover" / "Headhunt" / "Enrich"
→ Frontend: calls /api/usage/check
→ Backend: checks plan limit + credit balance
→ Frontend: shows UsageConfirmDialog
→ User clicks "Confirm" → operation starts
→ User clicks "Cancel" → operation aborted
D2: Dialog Content by Plan Type
Free Plan:
┌─────────────────────────────────────────┐
│ Discover Companies │
│ │
│ This operation will use 1 quota from │
│ your monthly search limit. │
│ │
│ Remaining: 2 / 3 │
│ ████████░░░░ 67% used │
│ │
│ [ ] Don't ask again this session │
│ │
│ [Cancel] [Confirm] │
└─────────────────────────────────────────┘
Pro Plan (within limit):
┌─────────────────────────────────────────┐
│ Discover Companies │
│ │
│ This operation will use 1 quota from │
│ your monthly search limit. │
│ │
│ Remaining: 38 / 50 │
│ ██████░░░░░░ 24% used │
│ │
│ [ ] Don't ask again this session │
│ │
│ [Cancel] [Confirm] │
└─────────────────────────────────────────┘
Pro Plan (over limit — credit usage):
┌─────────────────────────────────────────┐
│ Discover Companies │
│ │
│ ⚠ Your monthly limit is reached. │
│ This operation will cost 1 credit. │
│ │
│ Credit balance: 23 │
│ After operation: 22 │
│ │
│ [ ] Don't ask again this session │
│ │
│ [Buy Credits] [Cancel] [Confirm] │
└─────────────────────────────────────────┘
Limit + credits exhausted:
┌─────────────────────────────────────────┐
│ Discover Companies │
│ │
│ ❌ Monthly limit and credits are │
│ exhausted. │
│ │
│ [Buy Credits] [Upgrade Plan] │
└─────────────────────────────────────────┘
Enterprise (informational mode — can be turned off in settings):
┌─────────────────────────────────────────┐
│ Discover Companies │
│ │
│ This month: 142 searches performed │
│ ℹ Unlimited plan — no limits │
│ │
│ [ ] Don't ask again this session │
│ │
│ [Confirm] │
└─────────────────────────────────────────┘
D3: Bypass Rules
| Rule | Description |
|---|
| Default | Dialog is shown on EVERY costly operation |
| ”Don’t ask again this session” | Session-based (sessionStorage). Resets when the browser is closed. Per operation type — disabling for discovery does not affect headhunt. |
| Enterprise disable | usage_confirmation: false in org settings. Only visible in the Enterprise plan. Dialog is completely disabled, operations start immediately. |
| Limit approaching | When remaining quota is <= 20%, the dialog is shown EVEN IF “don’t ask” is selected (warning purpose). |
D4: Which Operations Trigger the Dialog
| Operation | Dialog | Reason |
|---|
| Discovery | ✅ | 1 quota / 1 credit |
| Headhunt | ✅ | 1 quota / 1 credit |
| Deep enrichment | ✅ | 2 credits |
| Batch operation | ✅ | N * 0.5 credits (total shown) |
| Score recalculate | ❌ | Deterministic, no AI cost |
| Lead CRUD | ❌ | DB operation, no cost |
| Company list/filter | ❌ | DB query, no cost |
| Scraper file upload | ✅ | AI classify cost applies |
Architecture
Component
components/UsageConfirmDialog.tsx
Props:
action: 'discovery' | 'headhunt' | 'enrichment' | 'batch' | 'scraper'
onConfirm: () => void
onCancel: () => void
Internal flow:
1. On mount, call /api/usage/check?action=X
2. Build dialog content based on response
3. "Don't ask again" → write to sessionStorage
4. Confirm → call onConfirm()
5. Cancel → call onCancel()
sessionStorage key: `usage_confirm_skip_$\{action\}`
API
GET /api/usage/check?action=discovery
Response:
{
"allowed": true,
"source": "plan_limit", // 'plan_limit' | 'credit' | 'unlimited'
"remaining": 38,
"limit": 50,
"usedPercent": 24,
"creditCost": null, // null = within plan
"creditBalance": 23,
"plan": "pro",
"canBypassDialog": false // Enterprise + settings off
}
Current Code Impact
New Files
| File | Content |
|---|
components/UsageConfirmDialog.tsx | Confirmation dialog component |
lib/hooks/useUsageCheck.ts | Hook: call /api/usage/check + sessionStorage check |
Files to Change
| File | Change |
|---|
app/discovery/page.tsx | ”Discover” button → wrap with UsageConfirmDialog |
app/companies/hooks/useCompanyData.ts | Headhunt → wrap with UsageConfirmDialog |
app/companies/components/CompanyDetailModal.tsx | Headhunt button → UsageConfirmDialog |
app/scraper/page.tsx | Push/classify → UsageConfirmDialog |
Atomic Tasks
| # | Task | Ring | Size |
|---|
| CONFIRM-1 | GET /api/usage/check endpoint (together with 04-billing check-usage) | R1 | Medium |
| CONFIRM-2 | components/UsageConfirmDialog.tsx — 4 variants (plan/credit/exhausted/enterprise) | R1 | Medium |
| CONFIRM-3 | lib/hooks/useUsageCheck.ts — hook + sessionStorage bypass | R1 | Small |
| CONFIRM-4 | Discovery page integration | R1 | Small |
| CONFIRM-5 | Headhunt integration (companies page + modal) | R1 | Small |
| CONFIRM-6 | Scraper integration | R1 | Small |
| CONFIRM-7 | Batch operations integration (with 06) | R2 | Small |
| CONFIRM-8 | Enterprise org settings → “usage_confirmation: false” | R1 | Small |