Documentation languages: English | Π ΡΡΡΠΊΠΈΠΉ
Professional psychology platform β a modern web application for psychologist Anna Vershkova, built with Next.js
16, featuring client management, survey system, and secure multi-provider authentication.
π Live: vershkov.com
π Authentication & Security
Multi-provider auth β Email/Password, Google OAuth, and WebAuthn (Passkeys) via NextAuth v5
Email verification β New users must confirm their email before accessing the platform
Welcome notifications β Automated welcome emails for Google sign-up (not on repeat login)
Rate limiting β Login attempt throttling (3 attempts per hour)
Role-based access β ADMIN, USER, and GUEST roles with granular route protection
Admin-created surveys with multiple question types (single choice, multi choice, free text, scale)
User assignment and completion tracking
Results viewer with comment discussions between admin and users
Draft auto-save for survey responses
Resend integration for transactional emails
Batch sending from admin panel (up to 100 per batch)
Real-time delivery status tracking with polling
Multilingual email templates β emails are sent in the user's preferred language
Beautiful React Email templates (verification, welcome, admin messages)
π Internationalization
Full English and Russian support via next-intl
Cookie-based locale detection (no URL prefixes)
User language preference saved to profile
Extensible β add new languages by creating a translation file
Dark/Light/System theme support via next-themes
Responsive layout with mobile-first design
Component library built on Radix UI primitives
Toast notifications via Sonner
Inter font with Latin & Cyrillic subsets
Personal dashboard with stats
Survey management (pending/completed)
Profile management (name, Google account linking)
Passkey management (create/delete)
Appearance & language settings
User management (CRUD, role assignment)
Survey builder & assignment
Email broadcast tool
Real-time online status tracking (heartbeat)
Layer
Technology
Framework
Next.js 16 (App Router, Turbopack)
Language
TypeScript (strict mode)
Database
PostgreSQL + Prisma ORM
Auth
NextAuth v5 (Google, Credentials, WebAuthn)
Email
Resend + React Email
i18n
next-intl
UI
Radix UI, Tailwind CSS, Lucide Icons
State
React Hook Form, Sonner
Charts
amCharts 5
DnD
@dnd-kit
Deploy
Vercel (standalone output)
Analytics
Vercel Analytics + Speed Insights
Node.js 18+
PostgreSQL database
Resend API key
Google OAuth credentials (optional)
# Clone the repository
git clone https://github.com/evn88/psy.git
cd psy
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env.local
# Generate Prisma client
npx prisma generate
# Run database migrations
npx prisma migrate deploy
# Start development server
npm run dev
Authentication & Database
Variable
Description
AUTH_SECRET
NextAuth secret key for session signing (generate: openssl rand -base64 32)
AUTH_GOOGLE_ID
Google OAuth client ID (formerly GOOGLE_CLIENT_ID)
AUTH_GOOGLE_SECRET
Google OAuth client secret (formerly GOOGLE_CLIENT_SECRET)
DATABASE_URL
PostgreSQL connection string (full URL with credentials)
POSTGRES_URL
Alternative Postgres connection string (used by Vercel Postgres)
PRISMA_DATABASE_URL
Explicit Prisma database URL (overrides DATABASE_URL if set)
ADMIN_EMAIL
Email address to grant admin access on first login (e.g., your@email.com )
Variable
Description
RESEND_API_KEY
Resend API key for transactional emails
VAPID_PRIVATE_KEY
VAPID private key for push notifications (keep secret)
NEXT_PUBLIC_VAPID_PUBLIC_KEY
VAPID public key for push notifications (safe to expose)
VAPID_SUBJECT
VAPID subject URI (e.g., mailto:your@email.com) for push notification identification
CRON_SECRET
Secret token for securing daily Vercel Cron endpoint /api/cron/session-reminders
WORKFLOW_MONTHLY_STEP_LIMIT
Optional monthly workflow steps budget for admin alerts (default: 50000)
WORKFLOW_ALERT_THRESHOLD_PERCENT
Optional warning threshold in percent (default: 80)
WORKFLOW_ESTIMATED_STEPS_PER_REMINDER
Optional estimated steps per one reminder workflow run (default: 3)
Variable
Description
AI_GATEWAY_API_KEY
Vercel AI Gateway API key (optional if using OIDC)
BLOB_READ_WRITE_TOKEN
Vercel Blob storage token for file uploads
VERCEL_OIDC_TOKEN
Auto-provisioned OIDC token for Vercel services (set by Vercel on deploy)
Variable
Description
NEXT_PUBLIC_APP_URL
Public base URL of the application (e.g., http://localhost:3000)
PROD_DOMAIN
Production domain with protocol (e.g., https://example.com) - required for production emails
Register β Sign up with your email or Google OAuth
Set ADMIN_EMAIL β Add your email to .env.local:
ADMIN_EMAIL=your@email.com
Login Again β Sign in again and your account will automatically be elevated to ADMIN role
Access Admin Panel β Navigate to /admin (accessible only to ADMIN users)
src/
βββ app/
β βββ (main)/ # Main layout group
β β βββ admin/ # Admin panel pages
β β βββ auth/ # Authentication page
β β βββ my/ # User dashboard pages
β βββ api/ # API routes
β βββ auth/ # Register, verify-email
β βββ profile/ # Profile updates, passkeys
β βββ send/ # Email sending
β βββ settings/ # User preferences
βββ components/
β βββ admin/ # Admin-specific components
β βββ email-templates/ # React Email templates
β βββ my/ # User dashboard components
β βββ ui/ # Radix UI primitives
βββ i18n/ # Internationalization config
βββ shared/lib/ # Shared utilities (Prisma, email)
βββ middleware.ts # Auth & locale middleware
messages/
βββ en.json # English UI translations
βββ ru.json # Russian UI translations
βββ email-en.json # English email translations
βββ email-ru.json # Russian email translations
Command
Description
npm run dev
Start dev server with Turbopack
npm run build
Production build (Prisma generate + Next.js)
npm start
Start production server
npm run lint
Run ESLint
npm run type-check
TypeScript type checking
The application works offline thanks to the Service Worker (public/sw.js).
Page
Path
Home
/
User Dashboard
/my
Sessions Schedule
/my/sessions
Surveys
/my/surveys
Adding a New Page to Offline Cache
Open public/sw.js
Find the PRE_CACHED_URLS array
Add the required path:
const PRE_CACHED_URLS = [
'/' ,
'/my' ,
'/my/sessions' ,
'/my/surveys' ,
'/my/your-page' , // β add here
] ;
Deploy. After updating the Service Worker, new pages will appear in the cache automatically.
To clear the old cache for all users (for example after a major update) β change the constant:
const CACHE_VERSION = 'v2' ; // was v1
Request Type
Strategy
/api/**
Network Only β never cache
/_next/static/**
Cache First β immutable JS/CSS bundles
PNG/SVG/ICO
Cache First β static icons
HTML pages
Network First β fallback to cache
Generate VAPID keys:
npx web-push generate-vapid-keys
Add to .env.local and on the server:
NEXT_PUBLIC_VAPID_PUBLIC_KEY = <public_key>
VAPID_PRIVATE_KEY = <private_key>
VAPID_SUBJECT = mailto:admin@vershkov.com
On the first visit, users are shown a banner requesting permission
Subscriptions are stored in the PushSubscription table in the database
Management: /my/settings β "Push Notifications"
If blocked by user β instructions for unblocking are displayed
Platform
Status
Android Chrome/Firefox
β
Full
iOS Safari 16.4+ (PWA installed)
β
Works
iOS Safari (browser)
β Apple does not support
Desktop Chrome/Firefox/Edge
β
Full
/admin/send-email β select recipients β write message (up to 178 characters)
Click "Send Push" β confirm
This project is licensed under the PolyForm Noncommercial License 1.0.0 . Commercial use is strictly
prohibited.