A Node.js/Express backend application for Foodly - a food booking platform - cut queues, enjoy your food!
- 🔐 Google OAuth 2.0 Authentication
- 👥 Role-based access control (Admin, Customer, Eatery)
- 📧 Email notifications using Resend
- 🗄️ PostgreSQL database with Prisma ORM
- 🔒 JWT-based authentication with refresh tokens
- 🚀 TypeScript for type safety
- ⚡ Hot reload development with Nodemon
- Runtime: Node.js
- Framework: Express.js
- Language: TypeScript
- Database: PostgreSQL
- ORM: Prisma
- Authentication: Google OAuth 2.0 + JWT
- Email Service: Resend
- Development: Nodemon, ts-node
Before setting up the application, ensure you have the following installed:
- Node.js (v16 or higher)
- npm or yarn
- PostgreSQL (v12 or higher)
- Git
git clone <repository-url>
cd foodly/server
npm install
Create a .env
file in the root directory with the following variables:
# Database
DATABASE_URL="postgresql://username:password@localhost:5432/database_name"
# Google OAuth
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
# JWT Secrets
ACCESS_TOKEN_SECRET=your_access_token_secret
ACCESS_TOKEN_EXPIRY=15m
REFRESH_TOKEN_SECRET=your_refresh_token_secret
REFRESH_TOKEN_EXPIRY=14d
# Email Service
RESEND_API_KEY=your_resend_api_key
Variable | Description | Example |
---|---|---|
DATABASE_URL |
PostgreSQL connection string | postgresql://user:pass@localhost:5432/foodly |
GOOGLE_CLIENT_ID |
Google OAuth client ID | Get from Google Cloud Console |
GOOGLE_CLIENT_SECRET |
Google OAuth client secret | Get from Google Cloud Console |
ACCESS_TOKEN_SECRET |
JWT access token secret | Generate a secure random string |
REFRESH_TOKEN_SECRET |
JWT refresh token secret | Generate a secure random string |
RESEND_API_KEY |
Resend email service API key | Get from Resend dashboard |
brew install postgresql
brew services start postgresql
sudo apt update
sudo apt install postgresql postgresql-contrib
sudo systemctl start postgresql
sudo systemctl enable postgresql
Download and install from PostgreSQL official website
# Access PostgreSQL
sudo -u postgres psql
# Create database
CREATE DATABASE foodly;
# Create user (optional)
CREATE USER foodly_user WITH PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE foodly TO foodly_user;
# Exit
\q
# Generate Prisma client
npx prisma generate
# Run migrations
npm run migrate
docker pull postgres:latest
docker run --name<CONTAINER_NAME> -e POSTGRES_PASSWORD=your_secret -p 5432:5432 -d postgres
postgresql://postgres:<password>@localhost:5432/postgres
# Generate Prisma client
npx prisma generate
# Run migrations
npm run migrate
- Go to Google Cloud Console
- Create a new project or select existing one
- Enable Google+ API
- Go to "Credentials" → "Create Credentials" → "OAuth 2.0 Client IDs"
- Set application type to "Web application"
- Add authorized redirect URIs:
http://localhost:3001/api/v1/auth/google/callback
- Copy Client ID and Client Secret to your
.env
file
- Sign up at Resend
- Go to API Keys section
- Create a new API key
- Copy the API key to your
.env
file
# Development mode with hot reload
npm run dev
The server will start on http://localhost:3001
Script | Description |
---|---|
npm run dev |
Start development server with hot reload |
npm run migrate |
Run Prisma database migrations |
src/
├── app.ts # Express app configuration
├── index.ts # Server entry point
├── constants/ # Application constants
│ └── index.ts
├── controllers/ # Route controllers
│ └── auth/
│ └── google-oauth.controller.ts
├── db/ # Database configuration
│ └── index.ts
├── generated/ # Generated Prisma client
│ └── prisma/
├── resend/ # Email service configuration
│ └── index.ts
├── routes/ # API routes
│ └── auth/
│ └── oauth.route.ts
└── utils/ # Utility functions
├── JWTTokens.ts
└── email-templates/
└── welcome-email.ts
Method | Endpoint | Description | Body | Protected |
---|---|---|---|---|
POST |
/register |
Register new user with email | { firstname, lastname?, email, password, role } |
No |
POST |
/login |
Login with email and password | { email, password } |
No |
POST |
/verify-token |
Verify JWT/email token | { token, setPassword } |
No |
POST |
/logout |
Logout user (clear tokens) | - | Yes |
POST |
/send-welcome-mail |
Send welcome mail to users | { firstname, email } |
No |
POST |
/refresh-token |
Refresh Access token | - | Yes |
Method | Endpoint | Description |
---|---|---|
GET |
/api/v1/oauth/google/url |
Get Google OAuth URL |
GET |
/api/v1/oauth/google/callback |
Google OAuth callback |
Method | Endpoint | Description |
---|---|---|
GET |
/test |
Health check endpoint |
model User {
id String @id @default(uuid())
firstname String
lastname String?
isVerified Boolean @default(false)
provider String?
providerId String?
role Role @default(CUSTOMER)
profilePicture String?
mobileNumber String? @unique
username String @unique @default(nanoid())
email String @unique
password String?
refreshToken String?
loginCount Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
}
ADMIN
- Administrative accessCUSTOMER
- Regular customerEATERY
- Restaurant/food provider
- JWT Authentication: Access and refresh token system
- Secure Cookies: HTTP-only, secure cookies for token storage
- Environment Variables: Sensitive data stored in environment variables
- OAuth 2.0: Secure Google authentication
- Password Hashing: User passwords are securely hashed (when applicable)
Error: Can't reach database server
Solution:
- Ensure PostgreSQL is running
- Check DATABASE_URL in
.env
- Verify database exists
Error: Cannot find module '@prisma/client'
Solution:
npx prisma generate
Error: invalid_client
Solution:
- Verify GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET
- Check redirect URI in Google Cloud Console
Error: Invalid API key
Solution:
- Verify RESEND_API_KEY in
.env
- Check Resend dashboard for API key status
-
Database Reset: If you need to reset the database:
npx prisma migrate reset
-
View Database: Use Prisma Studio to view your data:
npx prisma studio
-
Environment Variables: Always restart the server after changing
.env
file -
TypeScript Errors: If you encounter TypeScript errors after database changes:
npx prisma generate npm run dev
- Set
NODE_ENV=production
- Use production database URL
- Set secure JWT secrets
- Configure proper CORS settings
- Use HTTPS for OAuth redirects
- Database: AWS RDS, Google Cloud SQL, or Heroku Postgres
- Hosting: Heroku, Railway, or DigitalOcean
- Domain: Configure custom domain for OAuth redirects
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
This project is licensed under the ISC License.
For issues and questions:
- Check the troubleshooting section
- Review the project documentation
- Create an issue in the repository
Note: Remember to keep your environment variables secure and never commit them to version control. The .env
file is already included in .gitignore
for security.