Created
January 23, 2026 13:24
-
-
Save sunmeat/6aae4cb4f0d72add09593d5bf189b0ed to your computer and use it in GitHub Desktop.
TypeSpec example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import "@typespec/http"; | |
| import "@typespec/openapi"; | |
| using Http; | |
| using OpenAPI; | |
| @service({ | |
| title: "ITStep MyStat Journal API", | |
| version: "1.0.0" | |
| }) | |
| namespace ITStep.MyStat; | |
| scalar CrystalAmount extends int32; | |
| scalar CoinAmount extends int32; | |
| enum AttendanceStatus { | |
| Present, | |
| Absent, | |
| Late, | |
| SickLeave, | |
| OtherExcuse | |
| } | |
| enum GradeType { | |
| Theory, | |
| Practice, | |
| Homework, | |
| Exam, | |
| Test, | |
| Project | |
| } | |
| enum HomeworkStatus { | |
| NotSubmitted, | |
| Submitted, | |
| Checked, | |
| LateSubmitted, | |
| NotAccepted | |
| } | |
| model UserBase { | |
| id: string; | |
| fullName: string; | |
| email: string; | |
| avatarUrl?: string; | |
| } | |
| model Student extends UserBase { | |
| groupId: string; | |
| enrollmentDate: utcDateTime; | |
| crystals: CrystalAmount; | |
| coins: CoinAmount; | |
| ratingPosition?: int32; // місце в груповому/глобальному рейтингу | |
| } | |
| model Teacher extends UserBase { | |
| subjects: string[]; // кодів предметів, які викладає | |
| } | |
| model Group { | |
| id: string; | |
| name: string; // наприклад "FE-23-1" або "Python Pro" | |
| startDate: utcDateTime; | |
| endDate?: utcDateTime; | |
| studentsCount: int32; | |
| } | |
| model Subject { | |
| id: string; | |
| code: string; // "CS101", "WEB-DEV" | |
| title: string; | |
| credits?: int32; | |
| hoursTotal: int32; | |
| } | |
| model Lesson { | |
| id: string; | |
| subjectId: string; | |
| groupId: string; | |
| teacherId: string; | |
| date: utcDateTime; | |
| topic?: string; | |
| isOnline: boolean; | |
| room?: string; | |
| } | |
| model Attendance { | |
| lessonId: string; | |
| studentId: string; | |
| status: AttendanceStatus; | |
| comment?: string; | |
| } | |
| model Grade { | |
| id: string; | |
| studentId: string; | |
| lessonId?: string; // оцінка за конкретне заняття | |
| subjectId: string; | |
| type: GradeType; | |
| value: int32; // наприклад 0-12 або 0-100 | |
| maxValue: int32; // максимум, наприклад 12 або 100 | |
| weight?: float; // вага для середнього | |
| date: utcDateTime; | |
| teacherId: string; | |
| comment?: string; | |
| } | |
| model Homework { | |
| id: string; | |
| lessonId: string; // прив'язане до заняття | |
| title: string; | |
| description: string; | |
| deadline: utcDateTime; | |
| maxPoints: int32; | |
| } | |
| model HomeworkSubmission { | |
| homeworkId: string; | |
| studentId: string; | |
| submittedAt: utcDateTime; | |
| status: HomeworkStatus; | |
| points?: int32; | |
| teacherComment?: string; | |
| attachmentUrls?: string[]; | |
| } | |
| // Операції — основні ендпоінти | |
| @route("/students") | |
| interface Students { | |
| @get list(@query groupId?: string, @query search?: string): Student[]; | |
| @get @route("/{studentId}") get(@path studentId: string): Student; | |
| @get @route("/{studentId}/stats") getStats(@path studentId: string): { | |
| averageGrade: float; | |
| attendancePercent: float; | |
| totalCrystals: CrystalAmount; | |
| positionInGroup: int32?; | |
| }; | |
| } | |
| @route("/groups") | |
| interface Groups { | |
| @get list(): Group[]; | |
| @get @route("/{groupId}/students") getStudents(@path groupId: string): Student[]; | |
| } | |
| @route("/subjects") | |
| interface Subjects { | |
| @get list(): Subject[]; | |
| } | |
| @route("/schedule") | |
| interface Schedule { | |
| @get @route("/group/{groupId}") | |
| getForGroup(@path groupId: string, @query from: utcDateTime, @query to: utcDateTime): Lesson[]; | |
| } | |
| @route("/attendance") | |
| interface AttendanceApi { | |
| @get @route("/lesson/{lessonId}") | |
| listForLesson(@path lessonId: string): Attendance[]; | |
| @put @route("/lesson/{lessonId}/student/{studentId}") | |
| mark(@path lessonId: string, @path studentId: string, @body data: {status: AttendanceStatus, comment?: string}): Attendance; | |
| } | |
| @route("/grades") | |
| interface GradesApi { | |
| @get @route("/student/{studentId}") | |
| listForStudent(@path studentId: string, @query subjectId?: string): Grade[]; | |
| @post create(@body grade: Grade): Grade; | |
| } | |
| @route("/homeworks") | |
| interface Homeworks { | |
| @get @route("/lesson/{lessonId}") | |
| listForLesson(@path lessonId: string): Homework[]; | |
| @get @route("/student/{studentId}/pending") | |
| getPendingForStudent(@path studentId: string): Homework[]; | |
| } | |
| @route("/submissions") | |
| interface Submissions { | |
| @post @route("/homework/{homeworkId}") | |
| submit(@path homeworkId: string, @body submission: {attachmentUrls?: string[]}): HomeworkSubmission; | |
| @put @route("/{submissionId}/grade") | |
| grade(@path submissionId: string, @body {points: int32, comment?: string, status: HomeworkStatus}): HomeworkSubmission; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment