尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證AI application-readiness and email-intelligence platform for candidates and founders
翻譯準備中
正在載入完整 README。
檢視完整 README ↗An application-readiness tool for job seekers, with an email and attribution back office for the founder. A candidate uploads a resume (PDF or text) and a job description; Gapl scores the fit, lists the gaps, builds a learning roadmap and helps rewrite the CV. By Deepanshu Lathar.
Live app | Project status | Report an issue
| At a glance | |
|---|---|
| Status | Live beta with about 10 early users, mostly friends. Not a production launch (details) |
| Stack | Next.js (App Router), TypeScript, Firebase Auth + Firestore, Resend, Razorpay, Tailwind + Radix UI |
| AI | One gateway in src/lib/ai-gateway.ts with a primary model, a backup and optional last-resort fallbacks. The models named in the source are Anthropic Claude; which one a deployment runs depends on its keys and settings |
| Tests | 14 unit tests (credits, payments, report-ready scores); CI runs lint, typecheck, tests and a production build |
| Scope | Web app, AI gateway, email and attribution pipeline, admin tooling |
src/lib/ai-gateway.ts): one entry point for every user-facing AI task. In the current source it tries a primary Claude model, falls back to a second Claude model, and uses FreeModel or Groq only if both fail and a key is configured. Each call records tokens and cost.src/proxy.ts) turns each click into a logged redirect, and a payment or finished report is credited to the last email click in the previous 30 days./admin) with role-based access (super_admin, admin, support, readonly): email health, shortlinks, alerts, payments and refunds, audit log.Needs Node 22 (as in CI) and a Firebase project.
npm install
# create .env.local with the variables listed under "Local development setup" below
npm run dev # http://localhost:3000
npm test # node --test tests/*.test.mjs
npm run lint
npm run build
The sections below are the detailed reference: architecture, data model, API, admin tools and configuration.
graph TD
User[User / Candidate] -->|Creates Account / Pays / Scans Resume| App[Gapl React Web Application]
App -->|Authenticates| Firebase_Auth[Firebase Authentication]
App -->|Triggers Resume Analysis| API_Analyze["/api/analyze"]
API_Analyze -->|Query Routing & Prompts| Firestore[(Firestore DB: settings/routing)]
API_Analyze -->|Central AI Dispatcher| AI_Gateway[AI Gateway Fallback System]
AI_Gateway -->|Attempt 1| Preferred[Primary Claude model]
AI_Gateway -->|Attempt 2| OpenAI[Backup Claude model]
AI_Gateway -->|Attempt 3| Anthropic[Last resort: FreeModel or Groq if a key is set]
API_Analyze -->|Save Report Summary| Reports_Db[(Firestore DB: reports)]
API_Analyze -->|Trigger Notification| Email_Service[Email Service Abstraction]
Email_Service -->|Rewrite Links to Shortlinks| Link_Tracker[Shortlink Redirect Generator]
Link_Tracker -->|Point to Subdomain| Links_Domain["links.<your-domain>"]
Link_Tracker -->|Register Redirect Mapping| Trackable_Links[(Firestore DB: trackable_links)]
Email_Service -->|Dispatch Transactional/Retention Mail| Resend_API[Resend SMTP/API]
Resend_API -->|Sends Email| User
User -->|Clicks Shortlink| Links_Domain
Links_Domain -->|Next.js Proxy| Proxy_Rewrite{"src/proxy.ts"}
Proxy_Rewrite -->|Internal Redirect| Redirect_API["/api/t/id"]
Redirect_API -->|Increment Click Counts & Log Telemetry| Trackable_Links
Redirect_API -->|Set Browser Context Tracking Cookie| User
Redirect_API -->|Redirect Browser to Target Path| App
Resend_API -->|Webhooks Status: Sent, Opened, Clicked| Webhook_API["/api/webhooks/resend"]
Webhook_API -->|Verify Signature & Check Idempotency| Webhook_Events[(Firestore DB: webhook_events)]
Webhook_API -->|Log Message Status Update| Email_Messages[(Firestore DB: email_messages)]
Webhook_API -->|Log Telemetry Event| Email_Events[(Firestore DB: email_events)]
App -->|Convert: Payment / Complete Roadmap| Conversion_Engine[Conversion & Attribution Engine]
Conversion_Engine -->|Fetch Clicks 30-Day Window| Trackable_Links
Conversion_Engine -->|Stamp Marketing Campaign Attribution| Reports_Db
Conversion_Engine -->|Increment Customer Lifetime Value| Users_Db[(Firestore DB: users)]
Founder[Founder / Admin] -->|Explore Dashboards / Manage Prompts / Send Mail| Admin_Panel["/admin/*"]
Admin_Panel -->|Send Custom Email| Admin_Send_API["/api/admin/emails/send"]
Admin_Send_API -->|AI Rewrite Content| Admin_Rewrite_API["/api/admin/emails/rewrite"]
Admin_Rewrite_API -->|AI Gateway| AI_Gateway
@media print style wrappers.To protect domain reputation and maximize deliverability, the app decouples tracking redirect URLs using a dedicated subdomain set by NEXT_PUBLIC_TRACKING_DOMAIN (for example links.gapl.in). The proxy routes any links.* host to the shortlink handler.
links.gapl.in) has a CNAME pointing to cname.vercel-dns.com in your DNS registrar.src/proxy.ts (the proxy file convention, renamed from middleware in Next.js 16) intercepts requests to any host starting with links. and rewrites the request internally to /api/t/[id], preventing page reloads or client-side latency.campaignId and emailId on the document for revenue attribution./api/webhooks/resend)Processes real-time feedback from the Resend mail servers.
webhook_events Firestore collection to ignore retry events.email.sent, email.delivered, email.opened, email.clicked, email.bounced, email.complained, email.failed)./api/cron/day1-reminder for users who registered but did not complete their first resume scan./api/cron/day7-reminder to sync roadmap milestones and recover inactive users.users{
"id": "user_uid_123",
"email": "[email protected]",
"name": "Jane Doe",
"plan": "free | basic | pro",
"role": "candidate | super_admin | admin | support | readonly",
"analysisUsageCount": 2,
"analysisUsageMonth": "2026-06",
"summaryEmailCount": 1, // Max 5 rate limit
"cvEmailCount": 2, // Max 5 rate limit
"engagementScore": 75,
"suspended": false,
"createdAt": "2026-06-01T12:00:00.000Z"
}
email_campaigns{
"id": "welcome_email",
"name": "Welcome Onboarding Sequence",
"type": "transactional",
"subject": "Welcome to Gapl",
"createdAt": "2026-06-01T12:00:00.000Z"
}
email_messages{
"id": "msg_987",
"campaignId": "welcome_email",
"userId": "user_uid_123",
"email": "[email protected]",
"resendEmailId": "re_abc123xyz",
"status": "sent | delivered | opened | clicked | bounced | complained | failed",
"sentAt": "2026-06-01T12:05:00.000Z",
"deliveredAt": "2026-06-01T12:05:02.000Z",
"openedAt": "2026-06-01T12:10:00.000Z",
"clickedAt": "2026-06-01T12:12:00.000Z",
"firstVisitAt": "2026-06-01T12:12:05.000Z",
"convertedAt": null
}
email_events{
"id": "evt_456",
"emailId": "msg_987",
"userId": "user_uid_123",
"type": "email_sent | email_delivered | email_opened | email_clicked | email_bounced | email_complained | email_failed",
"timestamp": "2026-06-01T12:12:00.000Z",
"metadata": {
"ip": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"device": "desktop",
"browser": "Chrome",
"country": "IN"
}
}
trackable_links{
"id": "lnk_123",
"campaignId": "welcome_email",
"emailId": "msg_987",
"userId": "user_uid_123",
"name": "Start Analysis CTA",
"targetUrl": "/analyze",
"clickCount": 2,
"uniqueClicks": 1,
"firstClickedAt": "2026-06-01T12:12:00.000Z",
"lastClickedAt": "2026-06-01T12:15:00.000Z",
"createdAt": "2026-06-01T12:05:00.000Z"
}
POST /api/reports/[id]/email429 status code on violation.{ "success": true }
POST /api/cv-builder/email{
"cv": {
"name": "Jane Doe",
"email": "[email protected]",
"objective": "Objective text...",
"experience": [],
"skills": [],
"projects": [],
"education": []
}
}
429 status code on violation.{ "success": true }
(All /api/admin/* routes require a Bearer token mapped to a user with super_admin or admin Firestore claims)
POST /api/admin/emails/rewrite{ "message": "Draft email message here" }
{ "rewritten": "Polished and professional message rewritten by AI" }
POST /api/admin/emails/send{
"email": "[email protected]",
"subject": "Admin Notification",
"message": "Direct message contents here"
}
{
"success": true,
"messageId": "msg-xyz123"
}
/admin/*)/admin): Aggregates general statistics including candidate registrations, scans, and conversion funnel indexes./admin/emails): Tracks sent volume, open rates, CTRs, and ROI revenue details. Includes the Admin Email Dispatcher Card supporting email composition, AI message rewriting, and resend limits./admin/links): Facilitates generation of custom shortlink redirections and maps absolute traffic indexes./admin/email-health): Displays SPF, DKIM, and DMARC verification checklists, outbox bounce logs, and spam score gauges./admin/alerts): Actively sweeps metrics to raise dashboard warning logs for anomalies (e.g. bounce rates > 5%, conversion drops > 50%, or webhook signatures failures)./admin/email-insights): Analyzes email open trends, generates weekly engagement cohort optimizations, and predicts candidate churn risks./admin/payments): Lists orders, captures webhooks statuses, and supports one-click Razorpay refund triggers./admin/users / /admin/audit): Controls role assignments (super_admin, admin, support, readonly) and exposes system configuration logs.Administrative controls at /admin are gated using Firestore custom claim user roles:
super_admin: Full database access, refund configurations, prompt overriding, and user creation.admin: Full management dashboard access, excluding user role configuration edits.support: Read-only access to customer profiles, timelines, and payment histories.readonly: General read-only access to statistics and metrics charts.src/lib/ai-gateway.ts) with failover: a primary Claude model, a backup Claude model, then FreeModel or Groq if configured (model names are constants in the source). Token usage and cost are logged per call.Configure your .env.local file in the root workspace directory:
# Firebase Client Credentials
NEXT_PUBLIC_FIREBASE_API_KEY=your_firebase_api_key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_firebase_auth_domain
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your_firebase_project_id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_firebase_storage_bucket
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_firebase_messaging_sender_id
NEXT_PUBLIC_FIREBASE_APP_ID=your_firebase_app_id
# Firebase Admin SDK Configuration
FIREBASE_SERVICE_ACCOUNT_KEY='{"type": "service_account", "project_id": "...", ...}'
# AI Keys & Gateways
ANTHROPIC_API_KEY=your_anthropic_api_key
# optional last-resort fallbacks
GROQ_API_KEY=your_groq_api_key
FREEMODEL_API_KEY=your_freemodel_api_key
# Payment Configuration
NEXT_PUBLIC_RAZORPAY_KEY_ID=your_razorpay_key_id
RAZORPAY_KEY_SECRET=your_razorpay_key_secret
RAZORPAY_WEBHOOK_SECRET=your_razorpay_webhook_secret
# Email & Domain Configurations
RESEND_API_KEY=your_resend_api_key
RESEND_FROM_EMAIL="Gapl <[email protected]>"
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_TRACKING_DOMAIN=links.gapl.in
npm install
npm run dev
npm run build