Skip to content

kggurram/tailor

Repository files navigation

Tailor AI

Land more interviews. Upload your resume and a job description; get an ATS-style score, missing keywords, improved bullet suggestions, and a concise cover‑letter draft.

ScreenshotScreenshot

Features

  • AI tailoring (OpenAI, JSON mode): improved bullets + cover‑letter draft
  • ATS insights: match score and missing keywords (lightweight local analysis)
  • Auth & history: email/password login and per-user run history (Firestore)
  • Free vs Pro: daily free limit vs. unlimited (Stripe subscriptions)
  • Billing UX: Upgrade, Manage Billing, and Resume Subscription flows
  • Production-ready Next.js app: App Router, TypeScript, Tailwind v4

Stack

  • Frontend/Server: Next.js (App Router), TypeScript, Tailwind CSS v4
  • Auth & Data: Firebase Auth + Firestore
  • Billing: Stripe (Checkout + Customer Portal + Webhooks, test mode initially)
  • AI: OpenAI Chat Completions (JSON output)
  • Hosting: Vercel (Node runtime for API routes)

Project structure

src/
  app/
    api/
      tailor/route.ts            # main generation route
      history/route.ts           # user runs
      me/route.ts                # plan state for billing buttons
      billing/
        checkout/route.ts        # Stripe Checkout
        portal/route.ts          # Stripe Customer Portal
      stripe/
        webhook/route.ts         # Stripe webhook (raw body, Node runtime)
    (pages + layout)
  components/
    AIForm.tsx                   # editor + results
    billing/BillingButtons.tsx   # plan-aware billing UI
    Section.tsx                  # simple panel
    (auth/status, footer, etc.)
  lib/
    validators.ts                # zod schemas & TailorResponse type
    ats.ts                       # lightweight ATS keyword coverage
    firebase/                    # client & admin init
    stripe.ts                    # stripe client/server helpers

API contracts

POST /api/tailor (auth required)

Body:

{ "resumeText": "string (>=50)", "jobDescription": "string (>=50)" }

Response:

{
  "atsScore": 0,
  "missingKeywords": ["string"],
  "improvedBullets": ["string"],
  "coverLetterDraft": "string"
}

GET /api/history (auth required)

Returns the user’s recent runs from users/{uid}/runs.

GET /api/me (auth required)

Plan state used by the header:

{
  "isPro": true,
  "hasCustomer": true,
  "subscriptionStatus": "active",
  "cancelAtPeriodEnd": false,
  "scheduledCancel": false,
  "currentPeriodEnd": "2025-10-31T...Z",
  "cancelAt": null
}

POST /api/billing/checkout (auth required)

Starts a Stripe subscription Checkout session.

POST /api/billing/portal (auth required)

Opens the Customer Portal. If the user has no Stripe customer yet, returns 400 { "error": "NO_CUSTOMER" } and the client falls back to Checkout.

POST /api/stripe/webhook (Stripe only)

Raw-body verified webhook (Node runtime). Updates Firestore plan fields on subscription create/update/delete. Supports flexible billing (may fall back to item period end / cancel_at).


Data Model (Firestore)

  • users/{uid}:
    isPro, stripeCustomerId, stripeSubscriptionId, subscriptionStatus, cancelAtPeriodEnd, scheduledCancel, currentPeriodEnd, cancelAt, canceledAt, stripeUpdatedAt

  • users/{uid}/runs/{runId}:
    resumePreview, jdPreview, tailoredResume, coverLetter, bullets, resumeLen, jdLen, atsScore, missingKeywordsCount, improvedBulletsCount, coverLetterLen, model, plan, createdAt

  • usage_daily/{uid_YYYY-MM-DD}:
    userId, date, count, createdAt, updatedAt (used for free daily limit; avoids composite index).


Billing UI behavior

  • Signed out → “Sign in to upgrade”
  • Free or Pro with no Stripe customer → “Upgrade to Pro”
  • Pro + customer
    • If scheduledCancel or cancelAtPeriodEnd → show Resume subscription + Manage Billing + “Access until {date}” (currentPeriodEnd ?? cancelAt)
    • Else just Manage Billing (+ “Access until” when available)

Roadmap

  • Richer ATS metrics (skills taxonomy, seniority verbs, readability)
  • Shareable public links for runs
  • Observability: latency, token usage, failure analytics

About

Resources

Stars

Watchers

Forks

Languages