feat(v3): restructure project + add complete frontend

- Restructure: move backend from new_project/ to backend/
- Add full React/TypeScript frontend (37 pages, 17 services, 16 type defs, 11 query hooks)
- Add docs/ with SRS specs, user stories, and workflow documentation
- Update .gitignore for new directory layout

Workflows implemented:
  WF1 User Signup, WF2 Placement Test, WF3 Exam Configuration,
  WF4 General English Exam, WF5 Course Generation,
  WF6 Entity Student Onboarding, AI Course Generation,
  Adaptive Learning Engine UI, White-Label Branding, Score Release

Made-with: Cursor
This commit is contained in:
Yamen Ahmad
2026-04-10 17:26:42 +04:00
parent a3e12f62fa
commit f1c4953a63
731 changed files with 67205 additions and 139 deletions

View File

@@ -0,0 +1,41 @@
import { api } from "@/lib/api-client";
import type {
AICourseConfig,
QualityGateResult,
IELTSValidationResult,
ExaminerReview,
AICourseTrack,
} from "@/types";
import type { ApiSuccessResponse } from "@/types";
export const aiCourseService = {
createEnglish: (data: { current_level: string; target_level: string; learning_style: string[] }) =>
api.post<{ course_id: number }>("/ai-course/english/create", data),
createIelts: (data: { exam_type: string; target_band: number; skills: string[] }) =>
api.post<{ course_id: number }>("/ai-course/ielts/create", data),
getCourse: (courseId: number) =>
api.get<AICourseConfig>(`/ai-course/${courseId}`),
getTracks: (courseId: number) =>
api.get<AICourseTrack[]>(`/ai-course/${courseId}/tracks`),
getQualityGate: (courseId: number) =>
api.get<QualityGateResult>(`/ai-course/${courseId}/quality`),
approveQuality: (courseId: number) =>
api.post<ApiSuccessResponse>(`/ai-course/${courseId}/quality/approve`),
rejectQuality: (courseId: number, notes: string) =>
api.post<ApiSuccessResponse>(`/ai-course/${courseId}/quality/reject`, { notes }),
getIeltsValidation: (courseId: number) =>
api.get<IELTSValidationResult>(`/ai-course/${courseId}/validation`),
submitExaminerReview: (data: ExaminerReview) =>
api.post<ApiSuccessResponse>(`/ai-course/examiner-review`, data),
getEnglishTaxonomy: () =>
api.get<Record<string, unknown>>("/ai-course/english/taxonomy"),
};