Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/common.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ alias NoContentResponse = {
@statusCode statusCode: 204;
};

alias AcceptedResponse<T = null> = {
@statusCode statusCode: 202;
@body body: T;
};

alias RedirectResponse = {
@statusCode statusCode: 302;
};
Expand All @@ -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;
Expand Down
110 changes: 110 additions & 0 deletions src/examples/faculty/profile.tsp
Original file line number Diff line number Diff line change
@@ -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,
},
};
144 changes: 144 additions & 0 deletions src/routes/faculty/profile.tsp
Original file line number Diff line number Diff line change
@@ -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<FacultyProfile> | NotAuthorized | ServerError;

@patch(#{implicitOptionality: true})
@summary("Update faculty profile | Aggiorna dati anagrafici del docente")
@opExample(_ex_updateFacultyProfile_resp)
updateFacultyProfile(
@body body: FacultyProfileUpdateRequest,
): OkDataResponse<FacultyProfile> | 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<PaginatedFacultyPublicationList> | 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<void>
| RedirectResponse
| NotAuthorized
| NotFound
| ServerError;
}
Loading