8.1 KiB
MetaCourse API — Frontend Integration Guide
Target stack: Angular + Capacitor Base URL (local):
http://localhost:8080Base URL (production):http://romaric-thibault.fr
Deployment
Requirements
- Docker + Docker Compose installed on the server
Start the stack
docker compose up -d --build
The API will be available on port 8080. SQL Server runs on port 1433 (internal). Migrations run automatically on startup.
Swagger UI
http://<host>:8080/swagger
Authentication
There is no JWT currently. Login returns user info directly. Store UserId in local storage / Capacitor Preferences to identify the current user across requests.
Data Models (TypeScript interfaces)
// Enums
type CourseStatus = 'Draft' | 'Published';
type ResourceType = 'Url' | 'Video' | 'Text' | 'File';
interface User {
id: string; // Guid
name: string;
email: string;
createdAt: string; // ISO date
}
interface LoginResponse {
userId: string;
name: string;
email: string;
}
interface Course {
id: string;
title: string;
description: string;
status: CourseStatus;
creatorId: string;
creatorName: string;
topicCount: number;
createdAt: string;
updatedAt: string;
}
interface CourseDetails extends Course {
topics: Topic[];
}
interface Topic {
id: string;
title: string;
description?: string;
position: number;
courseId: string;
resources: Resource[];
}
interface Resource {
id: string;
type: ResourceType;
title: string;
content: string; // URL, video URL, text body, or file path
createdAt: string;
}
interface Enrollment {
userId: string;
courseId: string;
courseTitle: string;
enrolledAt: string;
completedAt?: string;
}
interface CourseProgress {
courseId: string;
userId: string;
totalTopics: number;
completedTopics: number;
totalResources: number;
completedResources: number;
progressPercentage: number; // 0.0 - 100.0
}
API Endpoints
Users
Register
POST /api/users/register
Body:
{
"name": "Alice",
"email": "alice@example.com",
"password": "Password1"
}
Validation: name 2–100 chars, valid email, password ≥8 chars + 1 uppercase + 1 digit
Response: 201 → User
Errors: 400 validation | 409 email already taken
Login
POST /api/users/login
Body:
{
"email": "alice@example.com",
"password": "Password1"
}
Response: 200 → LoginResponse
Errors: 401 wrong credentials
Get User Profile
GET /api/users/{id}
Response: 200 → User | 404
Courses
List Published Courses
GET /api/courses
Optional query param: ?search=angular
Response: 200 → Course[] (only Published courses, newest first)
Get Course with Topics & Resources
GET /api/courses/{id}
Response: 200 → CourseDetails | 404
Create Course
POST /api/courses
Body:
{
"title": "Introduction to Angular",
"description": "Learn Angular from scratch",
"creatorId": "<userId>"
}
Response: 201 → Course (status = Draft)
Update Course
PUT /api/courses/{id}
Body:
{
"id": "<courseId>",
"title": "Updated Title",
"description": "Updated description"
}
Response: 200 → Course | 404
Publish Course
PATCH /api/courses/{id}/publish
Response: 200 → Course | 422 if no topics yet | 404
Delete Course
DELETE /api/courses/{id}
Response: 204 | 409 if course has enrollments | 404
Courses Created by a User
GET /api/users/{userId}/courses
Response: 200 → Course[]
Topics
Get Topic
GET /api/topics/{id}
Response: 200 → Topic (includes resources ordered by position) | 404
Create Topic
POST /api/topics
Body:
{
"courseId": "<courseId>",
"title": "Components",
"description": "Optional description",
"position": 1
}
Response: 201 → Topic
Update Topic
PUT /api/topics/{id}
Body:
{
"id": "<topicId>",
"title": "Updated Title",
"description": "Updated",
"position": 2
}
Response: 200 → Topic | 404
Delete Topic
DELETE /api/topics/{id}
Response: 204 | 404
Link Resource to Topic
POST /api/topics/{topicId}/resources/{resourceId}
Body:
{ "position": 1 }
Response: 204
Unlink Resource from Topic
DELETE /api/topics/{topicId}/resources/{resourceId}
Response: 204
Resources
List All Resources
GET /api/resources
Response: 200 → Resource[] (ordered by creation date desc)
Get Resource
GET /api/resources/{id}
Response: 200 → Resource | 404
Create Resource
POST /api/resources
Body:
{
"type": "Url",
"title": "Angular Docs",
"content": "https://angular.io"
}
Types & content:
| Type | content field |
|---|---|
Url |
Full URL (https required) |
Video |
Video URL (https required) |
Text |
Markdown or plain text body |
File |
File path or download URL |
Response: 201 → Resource
Update Resource
PUT /api/resources/{id}
Body:
{
"id": "<resourceId>",
"type": "Video",
"title": "Updated",
"content": "https://youtube.com/..."
}
Response: 200 → Resource | 404
Delete Resource
DELETE /api/resources/{id}
Response: 204 | 404
Enrollments
Enroll in a Course
POST /api/courses/{courseId}/enroll
Body:
{
"userId": "<userId>",
"courseId": "<courseId>"
}
Response: 201 → Enrollment
Errors: 409 already enrolled | 422 course not Published | 404
User's Enrollments
GET /api/users/{userId}/enrollments
Response: 200 → Enrollment[]
Progress
Mark Topic Progress
POST /api/topics/{topicId}/progress
Body:
{
"userId": "<userId>",
"topicId": "<topicId>",
"completed": true
}
Response: 204 (upsert — safe to call multiple times)
Mark Resource Progress
POST /api/resources/{resourceId}/progress
Body:
{
"userId": "<userId>",
"resourceId": "<resourceId>",
"completed": true
}
Response: 204 (upsert)
Get Course Progress
GET /api/courses/{courseId}/progress?userId={userId}
Response: 200 → CourseProgress
{
"courseId": "...",
"userId": "...",
"totalTopics": 5,
"completedTopics": 3,
"totalResources": 10,
"completedResources": 7,
"progressPercentage": 66.67
}
Error Response Format
All validation and business errors follow this shape:
{
"statusCode": 400,
"errors": {
"email": ["'Email' is not a valid email address."],
"password": ["Password must be at least 8 characters."]
}
}
CORS
All origins, methods, and headers are allowed (AllowAll policy). No special headers needed from Angular/Capacitor.
Typical User Flow (Angular/Capacitor)
1. POST /api/users/register → store userId in Capacitor Preferences
2. POST /api/users/login → verify credentials
3. GET /api/courses → show published course catalog
4. GET /api/courses/{id} → show course detail with topics
5. POST /api/courses/{id}/enroll → enroll user
6. GET /api/users/{id}/enrollments → show My Courses
7. POST /api/topics/{id}/progress → mark topic done
8. POST /api/resources/{id}/progress → mark resource done
9. GET /api/courses/{id}/progress?userId=... → show progress bar
Notes for Angular Service Layer
- All IDs are UUIDs (string) — no integer IDs.
- Dates are ISO 8601 UTC strings — use
new Date(dateString)or a pipe. progressPercentageis anumber(float 0–100), round for display.statusandtypecome back as strings, not numbers.- No auth headers needed currently — all endpoints are
AllowAnonymous.