A production-grade backend for a peer-to-peer skill exchange platform — where users teach what they know and learn what they need through scheduled, real-time video sessions powered by a credit-based economy.
Built with ASP.NET Core 10, Entity Framework Core 10, and a clean Repository–Service–Controller architecture. Designed as the backend for a mobile app (iOS & Android) under the Digital Egypt Pioneers Initiative (DEPI).
🚀 Live Interactive Test Environment:
- 📄 Swagger UI (Interactive API Docs):https://skillifyapi-test.tryasp.net/swagger/index.html
- 📹 Zego Video Web UI Kit (Live Meeting Test):https://skillifyapi-test.tryasp.net/web_uikits.html
- ⚙️ Hangfire Dashboard (Timed Jobs & Automation):https://skillifyapi-test.tryasp.net/hangfire
⚠️ Note on Live Video Sessions (ZegoCloud):
Due to the ZegoCloud free trial tier, real-time video session testing is active for 25 days. After this period, video calls will require updated API keys. If you need to test the ZegoCloud integration after expiration, please contact me to refresh the test keys, or insert your ownAppIdandServerSecretintoappsettings.jsonand run the project locally.
- What It Does
- Why This Project Stands Out
- Features
- Tech Stack
- Architecture
- Project Structure
- Getting Started
- Configuration
- API Overview
- Background Jobs
- Skills Demonstrated
- Documentation
- License
Skillify connects people who want to offer a skill with people who need help in that area. The platform handles the full lifecycle:
- Users register, build a profile (skills, languages, bio, photo), and receive a starting credit wallet.
- Sessions are requested or offered between two users, scheduled at a future time with turn-based negotiation, and paid for with credits held in escrow.
- Video meetings run through ZegoCloud — the API issues secure room tokens when a session goes live.
- Attendance & Credits are automated via Zego Webhooks: escrow releases immediately when the Helper joins before the 50% mark, or refunds if the Helper fails to attend.
- Ratings & reviews can be submitted by both participants after session completion.
- Notifications (in-app + Firebase push) keep users informed about credit changes, session events, and rescheduling.
This is not a CRUD tutorial — it models real business logic:
| Capability | Implementation |
|---|---|
| Secure auth | JWT access tokens + refresh token rotation, per-session logout, global revoke, sid claim binding |
| Financial logic | Escrow holds, immutable credit ledger, automatic refund/release flows |
| Real-time video & webhooks | ZegoCloud token generation + real-time attendance webhooks (POST /api/zego/webhook) |
| Turn-based rescheduling | Participant state tracking (PendingRescheduleByUserId) preventing back-to-back proposals |
| Dual-user rating | Both participants (requester & helper) can submit ratings per completed session |
| Async automation | Hangfire jobs for session open/close and daily credit gifts |
| Push notifications | Firebase Cloud Messaging with device token management |
| Input validation | FluentValidation on all critical DTOs + SessionValidator guard pattern |
| API protection | Rate limiting (50 req/min), structured error responses |
| Media uploads | Cloudinary integration for profile pictures (PUT /api/Users/me/profile-picture) |
| Database design | 15+ entities, EF Core migrations, SQL Server 2025, seeded catalog data |
- Register / login with hashed passwords (ASP.NET Identity
PasswordHasher) - JWT access token (15 min) + refresh token (30 days) with rotation & per-session logout (
sidclaim) - Logout (single device) and global revoke (all devices)
- Profile completion with multiple needed skills, languages, bio, and dedicated profile picture endpoint (
PUT /api/Users/me/profile-picturevia Cloudinary) - Paginated and filtered user directory (
GET /api/Userswith name, main skill, minimum rating, spoken language filters; automatically excludes the authenticated caller)
- Request help or offer help (two distinct credit & escrow flows)
- Turn-based rescheduling negotiation tracked via
PendingRescheduleByUserId - Accept, decline, cancel, reschedule with complete state machine (
Pending,Accepted,Active,ReOffered,Completed,Declined,Cancelled,Expired) - ZegoCloud room creation & secure room token generation with early-join window (-2 min before start)
- Zego Webhook Attendance Automation (
POST /api/zego/webhook): Real-time join detection releases escrow to Helper if joined before 50% mark; automatically expires and refunds session if Helper fails to join
- Starting balance of 100 credits for new users
- Escrow system — credits locked until session completes or is cancelled/expired
- Full transaction ledger history (
EscrowHold,EscrowRelease,CreditEarned,Refund,GiftCredit) returning transaction history and current credit balance - Daily gift job for low-balance users (random 5–100 credits, once per 30 days)
- Dual-user rating support — both participants (Requester and Helper) can independently rate a completed session once each
- Decimal scores (1.0–5.0) with optional review text
- Public review listing per user; overall average score displayed on user profiles
- In-app notification inbox with unread count
- Mark single or all notifications as read
- FCM device registration / unregistration for mobile push delivery
- Automatic notifications generated on credit movements (earn, release, refund, gift)
- Main skills, sub-skills, and languages (seeded on startup)
- Badge system with criteria types (
SessionCount,AverageRating,ConsistentHelping)
| Category | Technologies |
|---|---|
| Framework | ASP.NET Core 10 Web API (net10.0) |
| Language | C# 13 |
| ORM | Entity Framework Core 10 |
| Database | Microsoft SQL Server 2025 |
| Auth | JWT Bearer, refresh token rotation (sid claim binding) |
| Validation | FluentValidation 11 + SessionValidator |
| Background jobs | Hangfire (SQL Server storage) |
| API docs | Swagger / Swashbuckle v10 (OpenAPI v2) |
| Media | Cloudinary SDK |
| Video & Webhooks | ZegoCloud RTC + Zego Server Webhook Callback |
| Push | Firebase Admin SDK (FCM) |
| Testing libs | Moq, FluentAssertions (project references) |
Layered architecture with dependency injection — each feature is a vertical slice:
HTTP Request
│
▼
Controller ──► Service ──► Repository ──► AppDbContext ──► SQL Server
│ │
│ └──► FluentValidation, business rules, DTO mapping
│
└──► JWT auth, rate limiting, exception → HTTP status mapping
flowchart LR
Client["Mobile / Web Client"]
API["ASP.NET Core API"]
SQL["SQL Server"]
HF["Hangfire Jobs"]
Zego["ZegoCloud"]
FCM["Firebase FCM"]
CDN["Cloudinary"]
Client -->|REST + JWT| API
API --> SQL
HF --> SQL
API --> Zego
API --> FCM
API --> CDN
Design patterns used: Repository, Service Layer, DTO mapping, Validator pipeline, Background job scheduling, Escrow/ledger pattern.
SkillifyAPI/
├── Controllers/ # API endpoints (10 controllers including ZegoWebhookController)
├── Services/ # Business logic (SessionMeetingService, UserService, etc.)
├── Repositories/ # Data access (EF Core)
├── Models/ # Domain entities (Session, EscrowHold, Rating, etc.)
├── DTOs/ # Request/response contracts
├── Validations/ # FluentValidation rules & SessionValidator
├── Data/ # AppDbContext (SQL Server 2025 configuration)
├── Migrations/ # EF Core migrations
├── Helper/ # Mappers, seeders, utilities
├── JwtService/ # Token generation, session binding & validation
├── CloudinaryService/ # Profile image uploads
├── ZegoService/ # Video room & token management
├── Firebase/ # Push notification service (FCM)
├── BackgroundService/ # Hangfire job classes (DailyGift, OpenSession, CloseSession)
├── Program.cs # DI, middleware, pipeline (.NET 10)
└── QA_BusinessModel.md # Full QA & testing guide (v1.6)
You can test and explore the live API, video rooms, and job queues directly without running locally:
- 📄 Swagger UI (Interactive API Docs):https://skillifyapi-test.tryasp.net/swagger/index.html
- 📹 Zego Video Web UI Kit (Live Meeting Test):https://skillifyapi-test.tryasp.net/web_uikits.html
- ⚙️ Hangfire Dashboard (Jobs & Automation):https://skillifyapi-test.tryasp.net/hangfire
💡 ZegoCloud Trial Limit: Live video room testing via the hosted server is available for 25 days under the free tier. To test live video meetings after expiration, reach out to update the ZegoCloud keys or supply your own
Zego:AppIdandZego:ServerSecretin localappsettings.json.
| Tool | Version |
|---|---|
| .NET SDK | 10.0+ |
| SQL Server | 2025 (or 2019+ LocalDB, Express, or full) |
| Git | Any recent version |
Optional (for full feature set):
- Cloudinary account — profile picture uploads
- ZegoCloud account — video sessions & webhooks
- Firebase project — push notifications
git clone https://github.com/YOUR_USERNAME/SkillifyAPI.git
cd SkillifyAPICopy and edit appsettings.json, or use User Secrets (recommended for local dev):
dotnet user-secrets init
dotnet user-secrets set"ConnectionStrings:DefaultConnection""Server=.;Database=SkillifyAPI;Trusted_Connection=True;TrustServerCertificate=True;"
dotnet user-secrets set"Jwt:Key""YourSuperSecretKeyThatIsAtLeast32CharactersLong!"
dotnet user-secrets set"Jwt:Issuer""SkillifyAPI"
dotnet user-secrets set"Jwt:Audience""SkillifyAPI"See Configuration for all required keys.
dotnet restore
dotnet runThe API starts at:
- HTTP:
http://localhost:5113 - HTTPS:
https://localhost:7080 - Swagger UI:
http://localhost:5113/swaggeror Live Test Swagger
On first run, EF Core applies pending migrations and seeds skills, languages, and badges automatically.
- Open Swagger locally at
/swaggeror use the Live Test Environment - Register a user via
POST /api/Users/register - Copy the
accessTokenfrom the response - Click Authorize in Swagger and enter:
Bearer {your_token} - Try endpoints like
GET /api/Users/meorPOST /api/Sessions/request
# Add a new migration
dotnet ef migrations add MigrationName
# Apply migrations
dotnet ef database updateAll settings live in appsettings.json (override with User Secrets or environment variables in production).
| Section | Keys | Purpose |
|---|---|---|
ConnectionStrings:DefaultConnection | SQL Server connection string | Database + Hangfire storage |
Jwt | Key, Issuer, Audience, AccessTokenExpirationMinutes, RememberMeRefreshTokenExpirationDays | Authentication |
Cloudinary | CloudName, ApiKey, ApiSecret, CloudFolder | Profile picture uploads |
Zego | AppId, ServerSecret | Video room tokens |
| Firebase | Service account JSON in Firebase/ folder | Push notifications (FCM) |
Example appsettings.json skeleton (replace with your values):
{
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=SkillifyAPI;Trusted_Connection=True;TrustServerCertificate=True;"
},
"Jwt": {
"Key": "<min-32-char-secret>",
"Issuer": "SkillifyAPI",
"Audience": "SkillifyAPI",
"AccessTokenExpirationMinutes": "15",
"RememberMeRefreshTokenExpirationDays": "30"
},
"Cloudinary": {
"CloudName": "<your-cloud-name>",
"ApiKey": "<your-api-key>",
"ApiSecret": "<your-api-secret>",
"CloudFolder": "SkillifyUserProfiles"
},
"Zego": {
"AppId": "<your-app-id>",
"ServerSecret": "<your-server-secret>"
}
}Security note: Never commit real secrets to source control. Use User Secrets locally and environment variables or a vault in production.
Interactive OpenAPI documentation is available locally at /swagger and online at https://skillifyapi-test.tryasp.net/swagger/index.html.
| Controller | Base Route | Auth | Description |
|---|---|---|---|
UsersController | /api/Users | Mixed | Auth (login/register/refresh), profile management, profile picture upload, filtered user directory (excludes self) |
SessionsController | /api/Sessions | ✅ Bearer | Session lifecycle (request, offer, accept, decline, cancel, turn-based reschedule) + Zego token |
RatingsController | /api/Ratings | Mixed | Submit & browse reviews (dual rating support for both participants) |
ZegoWebhookController | /api/zego/webhook | ❌ Public | ZegoCloud real-time attendance webhook & escrow release trigger |
NotificationsController | /api/Notifications | ✅ Bearer | In-app notifications + FCM device token management |
CreditTransactionsController | /api/CreditTransactions | ✅ Bearer | Credit transaction ledger history and current balance |
MainSkillsController | /api/MainSkills | ❌ Public | Main skill catalog |
SubSkillsController | /api/SubSkills | ❌ Public | Sub-skill catalog |
LanguagesController | /api/Languages | ❌ Public | Language catalog |
BadgesController | /api/Badges | ❌ Public | Badge catalog |
POST /api/Users/register → { accessToken, refreshToken }
POST /api/Users/login → { accessToken, refreshToken }
POST /api/Users/refresh → new token pair (old refresh token revoked)
POST /api/Users/logout → revoke current session
POST /api/Users/revoke → revoke all sessions
Protected routes require header: Authorization: Bearer <accessToken>
Powered by Hangfire with SQL Server storage.
- ⚙️ Live Dashboard:https://skillifyapi-test.tryasp.net/hangfire (Local:
/hangfire)
| Job | Schedule | Purpose |
|---|---|---|
OpenSession | At session ScheduledAt | Transition Accepted → Active, schedule close |
CloseSession | At session end time | Transition Active → Completed, release escrow, close Zego room (or refund if helper no-show) |
DailyGift | Daily at 03:00 UTC | Gift 5–100 credits to users with balance < 15 (once per 30 days) |
This project showcases backend engineering skills relevant to mid-level .NET developer roles:
- API design — RESTful endpoints, consistent error contracts, Swagger documentation
- Security — JWT auth, refresh rotation, session revocation, rate limiting
- Database modeling — relational schema, FK constraints, unique indexes, migrations
- Business logic — state machines, escrow/ledger patterns, validation pipelines
- Integrations — third-party SDKs (Cloudinary, Zego, Firebase)
- Async processing — scheduled background jobs with Hangfire
- Clean code — separation of concerns, DI, interface-based abstractions
- DevOps awareness — configuration management, migration-on-startup, CORS, HTTPS
| Document / Tool | Link | Description |
|---|---|---|
| QA & Business Model | QA_BusinessModel.md | Comprehensive QA guide (v1.6) — validation rules, all 10 controllers, state machines, test cases, error catalogue |
| Live Interactive Docs | Live Swagger UI | Online interactive Swagger UI testing environment |
| Live Video Session Testing | Zego Video Web UI Kit | Real-time video room UI test client |
| Live Background Jobs | Hangfire Dashboard | Live dashboard for scheduled & recurring jobs |
| Local Interactive Docs | /swagger | Local Swagger UI endpoint (when running application locally) |
This repository is provided for portfolio and evaluation purposes only.
Recruiters and hiring managers are welcome to review the source code.
No permission is granted to copy, modify, redistribute, or use this code in other projects without the author's prior written permission.
This project is licensed under the View-Only License.
Built by Ahmed Mohamed · Digital Egypt Pioneers Initiative (DEPI)