A modern web application for managing class fund payments with Google OAuth authentication for Vimaru University students.
- Google OAuth Authentication: Secure login with @st.vimaru.edu.vn domain emails
- Student ID Extraction: Automatically extracts student ID from email username
- Role-based Access Control: Admin and User roles with Better Auth
- Payment Status Management: Track student payment status with real-time updates
- VietQR Integration: Generate payment QR codes with Vietnam QR Pay
- Admin Dashboard: Comprehensive student management interface
- CSV/Excel Import: Bulk import student data from spreadsheets
- Internationalization: Multi-language support (Vietnamese/English)
- Error Monitoring: Sentry integration for production monitoring
- Frontend: Nuxt 4, Vue 3, Nuxt UI, TailwindCSS 4
- Backend: Nuxt 4 API routes with Nitro
- Database: PostgreSQL with Drizzle ORM
- Authentication: Better Auth with Google OAuth
- Payment: Vietnam QR Pay integration
- Internationalization: Nuxt i18n
- Error Monitoring: Sentry
- Package Manager: pnpm
- Node.js 18+
- PostgreSQL database
- Google OAuth credentials
- pnpm (recommended)
- Clone the repository and install dependencies:
git clone <repository-url>
cd classfund
pnpm install- Create environment variables file:
# Create .env file with the following variables- Configure your environment variables in
.env:
# Database
NUXT_DATABASE_URL="postgresql://username:password@localhost:5432/classfund"
# Google OAuth (from Google Cloud Console)
NUXT_GOOGLE_CLIENT_ID="your_google_client_id"
NUXT_GOOGLE_CLIENT_SECRET="your_google_client_secret"
# Better Auth (generate a random secret)
NUXT_BETTER_AUTH_SECRET="your_random_secret_key_here"
# App Configuration
NUXT_APP_URL="http://localhost:3000"
NUXT_APP_NAME="ClassFund"
# Payment Configuration (optional - defaults provided)
NUXT_BANK_KEY="hdbank"
NUXT_ACCOUNT_NUMBER="099704070058389"
NUXT_ACCOUNT_HOLDER="Phạm Trung Kiên"
NUXT_PAYMENT_AMOUNT="276000"
# Sentry (optional)
SENTRY_DSN="your_sentry_dsn"
SENTRY_ORG="mightyempire"
SENTRY_PROJECT="classfund"
# Deployment
NUXT_NITRO_PRESET="node-server" # or "vercel", "netlify", etc.- Generate database migrations:
pnpm db:generate- Apply migrations to your database:
pnpm db:migrateOr push schema directly (for development):
pnpm db:push- Generate auth schema (if needed):
pnpm auth:schema- Go to Google Cloud Console
- Create a new project or select existing one
- Enable the Google+ API
- Create OAuth 2.0 credentials
- Add authorized redirect URIs:
http://localhost:3000/api/auth/callback/google(development)https://your-domain.com/api/auth/callback/google(production)
- Set domain restriction to
st.vimaru.edu.vn
Start the development server on http://localhost:3000:
pnpm devTo create an admin user, you need to manually update the database after the first login:
UPDATE "user" SET role = 'admin' WHERE email = 'your-admin-email@st.vimaru.edu.vn';Or use Drizzle Studio:
pnpm db:studio- Visit the website and click "Login with Google"
- Sign in with your @st.vimaru.edu.vn email
- View your payment status:
- If paid: See success message
- If not paid: See QR code for payment
- If not in list: See error message
- Login with admin account
- Access admin dashboard via "Quản lý" button
- Manage student records:
- Add new students manually
- Import students from CSV/Excel files
- Edit student information
- Update payment status
- Delete students
- View payment statistics
Students authenticate using their @st.vimaru.edu.vn Google accounts:
Students who have already paid see a success confirmation:
Students who haven't paid yet see a QR code for payment:
id: Primary keyname: User's display nameemail: User's email addressuserName: Username (extracted from email)firstName: User's first namelastName: User's last namerole: User role ('admin' or 'user')banned: Ban statusbanReason: Reason for banbanExpires: Ban expiration date
studentId: Primary key (5-digit student ID)order: Sequential order numberuserName: Student's usernamefullName: Student's full namehasPaid: Payment status (boolean)createdAt: Record creation timestampupdatedAt: Record update timestamp
id: Primary keykey: Setting keyvalue: Setting valuedescription: Setting descriptioncreatedAt: Record creation timestampupdatedAt: Record update timestamp
id: Primary keycacheKey: MD5 hash cache keydescription: Payment descriptionamount: Payment amountbankNumber: Bank account numberqrCodeData: Full QR response data (JSONB)createdAt: Record creation timestamp
The system integrates with Vietnam QR Pay to generate payment QR codes with:
- Fixed amount: 276,000 VND (configurable)
- Bank: HDBank (configurable)
- Account number: 099704070058389 (configurable)
- Account holder: Phạm Trung Kiên (configurable)
- Payment info:
<STT> <MSV> <NAME> Quy TTM63
- Build the application:
pnpm build- Set production environment variables
- Deploy to your preferred hosting platform:
- Vercel: Set
NUXT_NITRO_PRESET=vercel - Netlify: Set
NUXT_NITRO_PRESET=netlify - Node.js: Set
NUXT_NITRO_PRESET=node-server
- Vercel: Set
- Configure your domain in Google OAuth settings
pnpm dev: Start development serverpnpm build: Build for productionpnpm preview: Preview production buildpnpm generate: Generate static sitepnpm auth:schema: Generate auth schemapnpm db:generate: Generate database migrationspnpm db:migrate: Apply database migrationspnpm db:push: Push schema to databasepnpm db:studio: Open Drizzle Studio
classfund/
├── app/ # Nuxt 4 app directory
│ ├── components/ # Vue components
│ ├── composables/ # Composables
│ ├── layouts/ # Layout components
│ ├── middleware/ # Route middleware
│ ├── pages/ # Page components
│ └── types/ # TypeScript types
├── server/ # Server-side code
│ ├── api/ # API routes
│ ├── database/ # Database configuration
│ ├── middleware/ # Server middleware
│ ├── utils/ # Server utilities
│ └── validations/ # Validation schemas
├── shared/ # Shared utilities
├── i18n/ # Internationalization
└── public/ # Static assets
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
- GitHub Repository: https://github.com/ptkdrake/classfund
- Facebook: https://facebook.com/ptkdrake.real
This project is for educational purposes for Vimaru University TTM63 class.


