An intelligent training platform built with Next.js, featuring performance analytics, workout tracking, and training diary functionality.
- Dashboard - KPI cards, performance charts (CTL/ATL/TSB), quote of the day
- Calendar - Week view with CRUD for workouts (planned & completed)
- Diary - Track mood, energy, sleep, stress, and soreness
- Settings - Profile management and heart rate zone configuration
- Auth - Email/password authentication with NextAuth
- Framework: Next.js 15 (App Router)
- Language: TypeScript
- Database: PostgreSQL (Neon)
- ORM: Prisma
- Auth: NextAuth v5
- UI: Tailwind CSS, shadcn/ui, Lucide icons
- Charts: Recharts
- Validation: Zod
- Toasts: Sonner
- Node.js 18+ (see
enginesin package.json) - npm or yarn
# Clone and install
npm install
# Run setup (generates Prisma client, runs migrations, seeds data, starts dev server)
npm run setupThis will:
- Generate Prisma client
- Run database migrations (requires DATABASE_URL and DIRECT_URL in .env)
- Seed demo data
- Start the development server
After seeding, you can log in with:
- Email:
demo@adaptivai.app - Password:
Demo1234!
If you prefer to run steps individually:
# Install dependencies
npm install
# Generate Prisma client
npm run db:generate
# Run migrations (local: db:migrate:dev; production: db:migrate)
npm run db:migrate:dev
# Seed demo data
npm run db:seed
# Start dev server
npm run devTo show "Quote of the day" on the dashboard (Vercel/Neon), seed the quotes table. With NODE_ENV=production, the seed only upserts quotes (no demo user). Run from your machine using the production DB URL (e.g. from Neon):
DATABASE_URL="postgresql://..." DIRECT_URL="postgresql://..." NODE_ENV=production npx prisma db seedApply migrations first (npx prisma migrate deploy). Quotes are upserted by (text, author), so you can run the seed multiple times without duplicates.
Copy .env.example to .env:
cp .env.example .envSet in .env (use Neon connection strings from the Neon dashboard):
DATABASE_URL="postgresql://..." # Neon pooled/pgbouncer (runtime)
DIRECT_URL="postgresql://..." # Neon direct (migrations)
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-secret-at-least-32-characters"
NODE_ENV="development"Set in Vercel Project Settings > Environment Variables (no values in repo):
DATABASE_URL– Neon pooled/pgbouncer connection stringDIRECT_URL– Neon direct connection stringNEXTAUTH_URL– Canonical app URL (e.g. https://www.adaptivai.online)NEXTAUTH_SECRET– e.g.openssl rand -base64 32NODE_ENV=production
No additional environment variables are required for AI Coach features (empty state, send-to-calendar, swim level and total meters, post-workout feedback premium fields, quality gates).
Add these variables in Vercel (Project Settings > Environment Variables):
DATABASE_URL(pooled/pgbouncer)DIRECT_URL(direct)APP_URLNEXTAUTH_URLNEXTAUTH_SECRETINTERNAL_CRON_SECRETSTRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRETSTRIPE_PRICE_ID_PROOPENAI_API_KEY
Note: If your password includes ! or other special characters, the URL must use percent-encoding.
Pre-launch verification (AI context privacy, entitlements sanity):
HARDENING_USER_ID=<valid-user-id> npm run hardening:checksRequired env var: HARDENING_USER_ID – ID of a real user for validation. Add to CI secrets if running hardening in automation, or run manually before releases. The main CI workflow does not run hardening by default; use the optional manual workflow if needed.
The app is release-ready (100/100): Sentry monitoring, structured webhook logs, security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy), 33 unit tests covering billing, rate-limit, logger, structured error logging (coach, billing), Node.js engines pin, 0 npm audit vulnerabilities, and CI gates (lint + typecheck + test + build) are in place.
Set in Project Settings > Environment Variables:
| Variable | Required | Notes |
|---|---|---|
DATABASE_URL |
✓ | Neon pooled/pgbouncer |
DIRECT_URL |
✓ | Neon direct (migrations) |
NEXTAUTH_URL |
✓ | e.g. https://www.adaptivai.online |
NEXTAUTH_SECRET |
✓ | openssl rand -base64 32 |
STRIPE_SECRET_KEY |
✓ | Stripe secret key |
STRIPE_WEBHOOK_SECRET |
✓ | Webhook signing secret |
STRIPE_PRICE_ID_PRO or PRO_PRICE_ID_MONTHLY |
✓ | Monthly Pro price ID |
INTERNAL_CRON_SECRET |
✓ | Min 16 chars for cron auth |
OPENAI_API_KEY |
✓ | For AI Coach |
SENTRY_DSN |
✓ | Error monitoring (optional but recommended) |
npx prisma migrate deploy- Endpoint URL:
https://www.adaptivai.online/api/billing/webhook - Required events:
checkout.session.completed,customer.subscription.created,customer.subscription.updated,customer.subscription.deleted,invoice.paid,invoice.payment_failed - Signing secret: Confirm "Signing secret" is set in Stripe Dashboard and matches
STRIPE_WEBHOOK_SECRET
- Run test checkout in Stripe test mode
- Confirm DB
Subscriptionrow updates - Confirm UI switches from trial to PRO
Use /api/health for uptime checks (Vercel Health Checks, UptimeRobot, etc.). Returns 200 with { status: "healthy", database: "connected" } when DB is reachable. Response has Cache-Control: no-store so monitors get fresh status.
npm run ci(lint + typecheck + build) passesnpm run test(runs in CI)- Run
hardening:checkswithHARDENING_USER_IDset - Smoke-test auth (login/register) and locale switching
- Verify env vars in production
- Create account → onboarding: Register a new user; should see 3-step onboarding wizard; complete or skip.
- Generate plan: In onboarding step 3 or via AI Coach, generate a 7-day plan; verify sessions appear in Calendar.
- "What should I do today?": On Dashboard or Today, click the CTA; modal should show AI decision (DO_THIS_WORKOUT / LIGHT_ALTERNATIVE / REST_TODAY).
- Notifications bell: Open app header; bell icon shows notification count; dropdown lists items; click leads to correct view.
- Weekly digest: Go to Dashboard; if digest exists, "Weekly digest" section visible; click "View all" → /digest page; digest list and detail view work.
AdaptivAI is an installable PWA. Checklist:
- HTTPS – Required (Vercel provides this).
- Manifest –
public/manifest.webmanifestwith name, icons (192/512, maskable), start_url, theme_color. - Service worker – Generated by
@ducanh2912/next-pwain production; caches static assets and pages; API, auth, and billing routes are never cached. - Install on desktop – Chrome/Edge: Install icon in address bar or menu → Install app.
- Install on iOS – Safari only: Share → Add to Home Screen. See
/installfor steps. - Install on Android – Chrome: menu → Install app or Add to Home screen.
Install instructions (public, no auth): /install.
-
DevTools → Application → Manifest
Check that manifest loads (200), icons andstart_urlare correct. -
DevTools → Application → Service Worker
In production build, confirm the service worker is registered and active. No caching for/api/*. -
Lighthouse → PWA
Run PWA audit; fix any critical issues (installable, manifest, SW, icons). -
Manual
- Desktop: Chrome/Edge on Windows or macOS → open app URL → Install app.
- iOS: Safari → Share → Add to Home Screen.
- Android: Chrome → menu → Install app.
| File | Size | Purpose |
|---|---|---|
public/icons/icon-192.png |
192×192 | any |
public/icons/icon-512.png |
512×512 | any |
public/icons/icon-192-maskable.png |
192×192 | maskable |
public/icons/icon-512-maskable.png |
512×512 | maskable |
public/apple-touch-icon.png |
180×180 | iOS Add to Home Screen |
public/favicon.png or favicon.ico |
32×32 | Browser tab |
public/favicon-16.png |
16×16 | Optional |
public/favicon-32.png |
32×32 | Optional |
Manifest: public/manifest.webmanifest must reference the above icons with correct sizes, type: image/png, and purpose: any or maskable. Set theme_color and background_color (e.g. #0a0a0a for dark UI). Regenerate all with npm run pwa:icons.
Po wdrożeniu nowej wersji ikon (np. po npm run pwa:icons i deployu) ikona na urządzeniu może się nie zaktualizować z powodu cache. Żeby zobaczyć nową ikonę:
- Odinstaluj PWA (Chrome: ikona aplikacji → prawy przycisk → Usuń; Android: długie przytrzymanie ikony → Odinstaluj; iOS: długie przytrzymanie → Usuń aplikację).
- Wyczyść dane witryny (opcjonalnie): Chrome → DevTools → Application → Storage → Clear site data (lub w ustawieniach przeglądarki — dane witryny dla Twojej domeny).
- Zainstaluj ponownie (Install app / Add to Home Screen).
| Script | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Build for production |
npm run start |
Start production server |
npm run ci |
CI gates: lint + typecheck + test + build |
npm run smoke |
Lightweight smoke: typecheck + build (verifies core pages compile) |
npm run test |
Run unit tests (entitlements, subscription mapper, checkout-prices, rate-limit, logger) |
npm run lint |
Run ESLint |
npm run typecheck |
Run TypeScript check (no emit) |
npm run hardening:checks |
Pre-launch privacy/entitlement checks (requires HARDENING_USER_ID) |
npm run setup |
Full setup: generate + migrate + seed + dev |
npm run db:generate |
Generate Prisma client |
npm run db:migrate |
Deploy migrations (production) |
npm run db:migrate:dev |
Create/apply migrations (local dev) |
npm run db:seed |
Seed demo data |
npm run db:studio |
Open Prisma Studio |
npm run db:reset |
Reset database (delete all data) |
npm run pwa:icons |
Regenerate PWA icons + favicons from assets/logo.png or assets/logo-1024.png (or create assets/logo-1024.png from built-in sygnet). |
npm run cap:sync |
Sync web assets to native iOS/Android (Capacitor). |
npm run cap:open:ios |
Open iOS project in Xcode. |
npm run cap:open:android |
Open Android project in Android Studio. |
See docs/CAPACITOR_AND_STORE.md for Capacitor setup, production URL, deep links, and store submission checklists.
After deploy, run through these checks:
Web (desktop + mobile viewports)
- Landing: hero, CTAs, how it works, features, pricing teaser, screenshots, FAQ, final CTA; no horizontal scroll.
- Login / Register flow; redirect to dashboard or onboarding.
- App: Dashboard, Calendar, Coach, Settings, Progress, Simulator — all scroll smoothly; no double scrollbars; no overflow-x.
- Sticky header stays visible; main content scrolls underneath.
- Modals/drawers: open and close; body scroll lock only while open.
PWA
- Install prompt (Chrome/Edge); Add to Home Screen (iOS Safari).
- After install: icon and name correct; app opens and loads.
- Safe areas: no content cut off by notch or home bar on iOS.
Legal & consent
- Footer links: Privacy, Terms, Cookies, Support, Account deletion — all resolve.
- Cookie banner on first visit; Accept all / Reject non-essential / Customize; choice persists after reload.
Console
- No errors on landing and app shell (check DevTools Console).
See docs/smoke-test.md for a longer smoke list.
adaptivai/
├── app/
│ ├── (marketing)/ # Landing page
│ ├── (auth)/ # Login, Register
│ ├── (app)/ # Protected app routes
│ │ ├── dashboard/
│ │ ├── calendar/
│ │ ├── diary/
│ │ ├── settings/
│ │ └── onboarding/
│ └── api/ # API routes
├── components/
│ ├── ui/ # shadcn/ui components
│ └── app-shell.tsx # Main app layout
├── lib/
│ ├── auth.ts # NextAuth configuration
│ ├── db.ts # Prisma client
│ ├── env.ts # Environment validation
│ ├── utils.ts # Utility functions
│ └── services/ # Business logic
├── prisma/
│ ├── schema.prisma # Database schema
│ └── seed.ts # Seed script
└── public/
- User - Authentication and profile
- Profile - Training preferences, HR zones
- Workout - Training sessions (planned/completed)
- DiaryEntry - Daily wellness tracking
- MetricDaily - CTL, ATL, TSB, readiness scores
- Quote - Motivational quotes for dashboard
- Go to neon.tech
- Create a new project
- Copy the pooled/pgbouncer and direct connection strings from the Neon dashboard
- Push code to GitHub
- Import project in Vercel
- Add environment variables (no secrets in repo):
DATABASE_URL– Neon pooled/pgbouncer connection stringDIRECT_URL– Neon direct connection stringNEXTAUTH_URL– Canonical app URL (e.g. https://www.adaptivai.online)NEXTAUTH_SECRET– e.g.openssl rand -base64 32
From your machine (with env set) or via Vercel post-deploy:
npm run db:migrate
npm run db:seedThe following features are planned for future development:
- Decision Engine - AI-powered training recommendations
- Advanced Readiness - ML-based recovery prediction
- Guardrails - Overtraining prevention alerts
- Simulator - "What-if" scenario planning
- Coach Mode - Conversational AI coach
If you see "Server error" on startup:
- Check that
.envfile exists - Verify
DATABASE_URLis correct - Run
npm run db:generateto regenerate Prisma client
# Reset database and re-seed (PostgreSQL)
npm run db:reset
npm run db:seedTo visually browse/edit your database:
npm run db:studioMIT