AI-powered hackathon team formation platform. Smart skill-based matching that connects the right people for the right projects.
| Layer | Technology |
|---|---|
| Runtime | Node.js v22+ |
| Framework | Express.js |
| Database | PostgreSQL via Neon |
| ORM | Prisma v7 |
| Auth | JWT |
| File Storage | Cloudinary |
| AI Model | FastAPI on HuggingFace Spaces |
| Scheduler | node-cron |
| Docs | Swagger / OpenAPI |
- Node.js v22+
- npm
- Git
- A Neon PostgreSQL database
- A Cloudinary account (free tier)
- Google OAuth Client ID
The AI matching service is deployed on HuggingFace Spaces and handles skill-based team recommendations.
| Method | Endpoint | Description |
|---|---|---|
GET |
/status |
Check AI memory pool status (rehydration trigger) |
POST |
/sync/member |
Sync user data (skills, bio, history) into AI memory |
POST |
/sync/project |
Sync project/hackathon tags into AI memory |
POST |
/recommend |
Generate 3 recommended teams from candidate pool |
Interactive API Docs:
https://teamcatalyst-ai-team-recommendation.hf.space/docs
Base URL:
https://teamcatalyst-ai-team-recommendation.hf.space
git clone https://github.com/basmala-ayman/Hackathons-Team-Formation.git
cd Hackathons-Team-Formation/backendnpm installCreate a .env file inside backend/:
NODE_ENV=development
PORT=3000
# Neon PostgreSQL
DATABASE_URL="postgresql://neondb_owner:npg_6ONhfLYs7QST@ep-dawn-wildflower-a4ifrp40-pooler.us-east-1.aws.neon.tech/neondb?sslmode=require&channel_binding=require"
# Email (Gmail app password)
EMAIL_USER=team.catalyst26@gmail.com
EMAIL_PASS=kjikpgfcsjnnlsug
# Server URLs
BASE_URL=http://localhost:3000
FRONTEND_URL=http://localhost:5173
# JWT
JWT_SECRET=omayIsTheTop_and_AllOtherIsCantalob
JWT_EXPIRES_IN=1d
# Google OAuth
GOOGLE_CLIENT_ID=653043614391-gnmnai9c6bot17euu4kfndj7pn7uegcc.apps.googleusercontent.com
# AI Model (HuggingFace Spaces)
AI_BASE_URL=https://teamcatalyst-ai-team-recommendation.hf.space
# Cloudinary
CLOUDINARY_CLOUD_NAME=doehwqejq
CLOUDINARY_API_KEY=267989441961393
CLOUDINARY_API_SECRET=rcjGwA7oqmd9CICBuE5d8iQUeI0npx prisma generatenpx prisma migrate devnpm run devYou should see:
postgreSQL connected via prisma ๐ฅ
Cron jobs initialized successfully! โฐ
server running on port 3000 ๐
Swagger docs available at http://localhost:3000/api-docs ๐ฎ
http://localhost:3000/api-docs
cd ../frontendnpm installCreate a .env file inside frontend/:
VITE_GOOGLE_CLIENT_ID=653043614391-gnmnai9c6bot17euu4kfndj7pn7uegcc.apps.googleusercontent.com
VITE_API_BASE_URL=http://localhost:3030/api/v1npm run devThe app runs at http://localhost:5173.
Open two terminal windows:
# Terminal 1 โ backend
cd backend && npm run dev
# Terminal 2 โ frontend
cd frontend && npm run devTwo matching flows exist:
Case 1 : Project-based matching When a project's interest pool hits 30 users, matching triggers immediately:
User presses "Interested" on project
โ interestsCount hits 30
โ triggerProjectMatching fires
โ AI model called with project tags + candidate pool
โ 3 recommended teams saved
โ Founder notified
Case 2 : Hackathon-based matching Runs via cron at 10pm daily (every 2 minutes in dev):
Hackathon interestCount >= 30
โ Cron fires triggerHackathonMatching
โ Each FORMING team (without a project) processed
โ AI model called per team
โ Recommendations saved + founder notified
If some invitations are rejected, the founder can request a second round:
- Accepted members are pinned (always included in new recommendations)
- Rejected members are excluded from the candidate pool
- AI called again with full team size
Founder creates team
โ AI returns 3 recommended groups
โ Founder accepts one group
โ Invitations sent to all members in that group
โ Members accept/reject individually
โ Team fills up โ status: COMPLETE
- Profile pictures โ uploaded to Cloudinary (public URL stored in DB)
- Resumes/CVs โ stored locally in
uploads/resumes/
| Variable | Description |
|---|---|
DATABASE_URL |
Neon PostgreSQL connection string |
PORT |
Server port (default: 3000) |
NODE_ENV |
development or production |
EMAIL_USER |
Gmail address for sending emails |
EMAIL_PASS |
Gmail app password (not your account password) |
BASE_URL |
Backend base URL |
FRONTEND_URL |
Frontend base URL (for CORS and redirects) |
JWT_SECRET |
Secret key for signing JWT tokens |
JWT_EXPIRES_IN |
Token expiry (e.g. 1d) |
GOOGLE_CLIENT_ID |
Google OAuth client ID |
AI_BASE_URL |
HuggingFace Spaces AI model base URL |
CLOUDINARY_CLOUD_NAME |
Cloudinary cloud name |
CLOUDINARY_API_KEY |
Cloudinary API key |
CLOUDINARY_API_SECRET |
Cloudinary API secret |
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/auth/register |
Register new user |
| POST | /api/v1/auth/login |
Login |
| GET | /api/v1/users/profile |
Get current user profile |
| PUT | /api/v1/users/profile |
Update profile + upload photo |
| GET | /api/v1/hackathons |
List all hackathons |
| POST | /api/v1/teams |
Create a team |
| GET | /api/v1/teams/my-teams |
Get all owned teams with members |
| PATCH | /api/v1/teams/:id/finalize |
Finalize team with current members |
| POST | /api/v1/interests/hackathons/:id |
Mark interest in hackathon |
| GET | /api/v1/recommendations |
Get recommended teams (all/my-teams/join) |
| PATCH | /api/v1/recommendations/:id/accept |
Founder accepts a recommendation |
| PATCH | /api/v1/recommendations/:id/reject |
Founder rejects a recommendation |
| PATCH | /api/v1/recommendations/invitations/:id/respond |
Member accepts/rejects invitation |
| POST | /api/v1/matching/round2/:teamId |
Request Round 2 recommendations |
| GET | /api/v1/notifications |
Get user notifications |
Full interactive docs at /api-docs when server is running.
To expose your local backend for frontend teammates or mobile testing:
ngrok http 3000Copy the generated HTTPS URL and update VITE_API_BASE_URL in the frontend .env.
| Job | Schedule | Description |
|---|---|---|
| Hackathon matching | 10pm daily (0 22 * * *) |
Processes all eligible hackathon teams |
| Devpost scraper | Midnight daily (0 0 * * *) |
Scrapes new hackathons from Devpost |
In development, hackathon matching runs every 2 minutes (
*/2 * * * *) for testing.
Missing required environment variable : check your .env file has all variables listed above.
Failed To Sync Member With AI : the HuggingFace Space may be sleeping. Wait 30 seconds and retry; the rehydration logic will resync automatically.
Profile picture not showing : ensure Cloudinary credentials are correct and the uploads/resumes/ folder exists locally.
Team Catalyst was developed as a graduation project at Ain Shams University, Faculty of Computer and Information Sciences.
| Name | GitHub | |
|---|---|---|
| Zeina Wady | GitHub | |
| Basmala Ayman | GitHub | |
| Hafsa Tarek | GitHub | |
| Ruba Abdelsalam | GitHub | |
| Habiba Adel | GitHub | |
| Esraa Ahmed | GitHub |
If you find this project useful, feel free to โญ the repository.