From 62677f853875fc6128fa622b855e4c751eab50f7 Mon Sep 17 00:00:00 2001 From: FabrizioCostaMedich Date: Wed, 4 Mar 2026 13:33:08 +0100 Subject: [PATCH] feat: add faculty profile models and endpoints --- src/common.tsp | 10 +++ src/examples/faculty/profile.tsp | 110 +++++++++++++++++++++++ src/routes/faculty/profile.tsp | 144 +++++++++++++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 src/examples/faculty/profile.tsp create mode 100644 src/routes/faculty/profile.tsp diff --git a/src/common.tsp b/src/common.tsp index 0b7dec4..3aec90a 100644 --- a/src/common.tsp +++ b/src/common.tsp @@ -85,6 +85,11 @@ alias NoContentResponse = { @statusCode statusCode: 204; }; +alias AcceptedResponse = { + @statusCode statusCode: 202; + @body body: T; +}; + alias RedirectResponse = { @statusCode statusCode: 302; }; @@ -99,6 +104,11 @@ alias NotFound = { @body body: ErrorResponse; }; +alias NotAuthorized = { + @statusCode statusCode: 401; + @body body: ErrorResponse; +}; + alias ServerError = { @statusCode statusCode: 500; @body body: ErrorResponse; diff --git a/src/examples/faculty/profile.tsp b/src/examples/faculty/profile.tsp new file mode 100644 index 0000000..b2c5bc6 --- /dev/null +++ b/src/examples/faculty/profile.tsp @@ -0,0 +1,110 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +// Get faculty profile example +const _ex_getFacultyProfile_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #{ + id: "2154", + name: "Marco Torchiano", + personal_email: "marco.torchiano@gmail.com", + academic_email: "marco.torchiano@polito.it", + phone: "+39 011 090 7654", + residence: "Torino, Via Roma 1", + fiscalResidence: "Torino, Via Roma 1", + iban: "XK238804602955671016", + department: "Dipartimento di Automatica e Informatica", + publications: #[ + #{ + id: "pub-001", + name: "Dispensa di Informatica", + mimeType: "application/pdf", + sizeInKiloBytes: 2456, + createdAt: utcDateTime.fromISO("2026-03-04T12:27:38.153Z"), + downloadUrl: "https://example.com/download/pub-001", + }, + ], + assignedCourses: #[ + #{ + courseId: "02JSKOV", + name: "Human Computer Interaction", + period: "2025/2026 - Secondo semestre", + enrolledCount: 120, + }, + ], + }, + }, + }, +}; + +// Update faculty profile example +const _ex_updateFacultyProfile_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #{ + id: "2154", + name: "Marco Torchiano", + personal_email: "marco.torchiano@gmail.com", + academic_email: "marco.torchiano@polito.it", + phone: "+39 011 090 1234", + residence: "Torino, Via Garibaldi 10", + fiscalResidence: "Torino, Via Garibaldi 10", + iban: "IT60X0542811101000000123456", + department: "Dipartimento di Automatica e Informatica", + publications: #[ + #{ + id: "pub-001", + name: "Dispensa di Informatica", + mimeType: "application/pdf", + sizeInKiloBytes: 2456, + createdAt: utcDateTime.fromISO("2026-03-04T12:27:38.153Z"), + downloadUrl: "https://example.com/download/pub-001", + }, + ], + assignedCourses: #[ + #{ + courseId: "02JSKOV", + name: "Human Computer Interaction", + period: "2025/2026 - Secondo semestre", + enrolledCount: 120, + }, + ], + }, + }, + }, +}; + +// List faculty publications example +const _ex_listFacultyPublications_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + id: "pub-001", + name: "Dispensa di Informatica", + mimeType: "application/pdf", + sizeInKiloBytes: 2456, + createdAt: utcDateTime.fromISO("2026-03-04T12:29:26.681Z"), + downloadUrl: "https://example.com/download/pub-001", + }, + ], + page: 1, + pageSize: 20, + total: 1, + }, + }, +}; + +// Download faculty publication example +const _ex_downloadFacultyPublication_resp = #{ + returnType: #{ + statusCode: 302, + }, +}; diff --git a/src/routes/faculty/profile.tsp b/src/routes/faculty/profile.tsp new file mode 100644 index 0000000..fd2c660 --- /dev/null +++ b/src/routes/faculty/profile.tsp @@ -0,0 +1,144 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../../common.tsp"; +import "../../examples/faculty/profile.tsp"; + +using Http; + +namespace PolitoAPI; + +model FacultyPublication { + @example("pub-001") + id: string; + + @example("Dispensa di Informatica") + name: string; + + @example("application/pdf") + mimeType: string; + + @example(2456) + sizeInKiloBytes: integer; + + @example(utcDateTime.fromISO("2026-03-04T12:27:38.153Z")) + createdAt: utcDateTime; + + @example("https://example.com/download/pub-001") + downloadUrl: string; +} + +model AssignedCourse { + @example("02JSKOV") + courseId: string; + + @example("Human Computer Interaction") + name: string; + + @example("2025/2026 - Secondo semestre") + period: string; + + @example(120) + enrolledCount: integer; +} + +model FacultyProfile { + @example("2154") + id: string; + + @example("Marco Torchiano") + name: string; + + @example("marco.torchiano@gmail.com") + personal_email: string; + + @example("marco.torchiano@polito.it") + academic_email: string; + + @example("+39 011 090 7654") + phone: string; + + @example("Torino, Via Roma 1") + residence: string; + + @example("Torino, Via Roma 1") + fiscalResidence: string; + + @example("XK238804602955671016") + iban: string; + + @example("Dipartimento di Automatica e Informatica") + department: string; + + publications: FacultyPublication[]; + assignedCourses: AssignedCourse[]; +} + +model PaginatedFacultyPublicationList { + data: FacultyPublication[]; + + @example(1) + page: integer; + + @example(20) + pageSize: integer; + + @example(42) + total: integer; +} + +model FacultyProfileUpdateRequest { + @example("Torino, Via Garibaldi 10") + residence?: string; + + @example("Torino, Via Garibaldi 10") + fiscalResidence?: string; + + @example("+39 011 090 1234") + phone?: string; + + @example("marco.torchiano@gmail.com") + personal_email?: string; + + @example("marco.torchiano@polito.it") + academic_email?: string; +} + +@tag("Faculty - Profile") +@route("/faculty/me") +interface FacultyProfile_Routes { + @get + @summary("Get faculty profile | Profilo docente") + @doc("Restituisce i dati anagrafici e informativi del docente autenticato (pubblicazioni, corsi assegnati – se disponibili).") + @opExample(_ex_getFacultyProfile_resp) + getFacultyProfile(): OkDataResponse | NotAuthorized | ServerError; + + @patch(#{implicitOptionality: true}) + @summary("Update faculty profile | Aggiorna dati anagrafici del docente") + @opExample(_ex_updateFacultyProfile_resp) + updateFacultyProfile( + @body body: FacultyProfileUpdateRequest, + ): OkDataResponse | NotAuthorized | BaseErrors; + + @route("/publications") + @get + @summary("List faculty publications | Elenca pubblicazioni del docente") + @doc("Restituisce l'elenco paginato delle pubblicazioni associate al docente autenticato.") + @opExample(_ex_listFacultyPublications_resp) + listFacultyPublications( + @query page?: integer = 1, + @query pageSize?: integer = 20, + ): OkResponse | NotAuthorized | ServerError; + + @route("/publications/{publicationId}") + @get + @summary("Download faculty publication | Scarica pubblicazione") + @doc("Restituisce un redirect o lo stream del file associato alla pubblicazione indicata.") + @opExample(_ex_downloadFacultyPublication_resp) + downloadFacultyPublication(@path publicationId: string): + | OkResponse + | RedirectResponse + | NotAuthorized + | NotFound + | ServerError; +}