Files
sparkantiplagiat-frontend/docs/swagger.json

4272 lines
142 KiB
JSON

{
"schemes": [
"http"
],
"swagger": "2.0",
"info": {
"description": "REST API for SparkGuard backend services: identity, academic entities, work uploads, asynchronous analysis runs, plagiarism findings, and dashboard summaries.",
"title": "SparkGuard Backend API",
"contact": {},
"version": "1.0"
},
"basePath": "/",
"paths": {
"/adoptions/{id}/segment": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Downloads the work archive, extracts the specific file, and returns the segment identified by the adoption record.",
"produces": [
"application/octet-stream"
],
"tags": [
"adoptions"
],
"summary": "Get adoption file segment",
"parameters": [
{
"type": "integer",
"description": "Adoption ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "The requested file segment",
"schema": {
"type": "string"
}
},
"400": {
"description": "Invalid adoption ID or missing segment info in adoption",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Adoption, Work, S3 file, or file within archive not found, or segment out of bounds",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal server error (S3 download, zip extraction, file reading)",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/analysis-runs/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns a single asynchronous analysis run",
"produces": [
"application/json"
],
"tags": [
"AnalysisRuns"
],
"summary": "Get analysis run by ID",
"parameters": [
{
"type": "string",
"description": "Analysis Run ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.AnalysisRun"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/analysis-runs/{id}/adoptions": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns materialized adoptions created from a specific analysis run",
"produces": [
"application/json"
],
"tags": [
"AnalysisRuns"
],
"summary": "Get analysis run adoptions",
"parameters": [
{
"type": "string",
"description": "Analysis Run ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.Adoption"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/analysis-runs/{id}/chunks": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns raw chunk metadata stored for a specific analysis run",
"produces": [
"application/json"
],
"tags": [
"AnalysisRuns"
],
"summary": "Get analysis run chunks",
"parameters": [
{
"type": "string",
"description": "Analysis Run ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.AnalysisRunChunk"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/analysis-runs/{id}/report.html": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns the enriched teacher-facing HTML report for a completed analysis run",
"produces": [
"text/html"
],
"tags": [
"AnalysisRuns"
],
"summary": "Download analysis report HTML",
"parameters": [
{
"type": "string",
"description": "Analysis Run ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "file"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/analysis-runs/{id}/report.json": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns the enriched teacher-facing JSON report for a completed analysis run",
"produces": [
"application/json"
],
"tags": [
"AnalysisRuns"
],
"summary": "Download analysis report JSON",
"parameters": [
{
"type": "string",
"description": "Analysis Run ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "file"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/analysis-runs/{id}/report.pdf": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns the enriched teacher-facing PDF report for a completed analysis run",
"produces": [
"application/pdf"
],
"tags": [
"AnalysisRuns"
],
"summary": "Download analysis report PDF",
"parameters": [
{
"type": "string",
"description": "Analysis Run ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "file"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/analysis-runs/{id}/report.raw.json": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns the raw JSON report produced by SparkGuardAntiplagiarism",
"produces": [
"application/json"
],
"tags": [
"AnalysisRuns"
],
"summary": "Download raw analyzer report JSON",
"parameters": [
{
"type": "string",
"description": "Analysis Run ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "file"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/analysis-runs/{id}/retry": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Creates a new analysis run for the same uploaded archive without re-uploading the work file",
"produces": [
"application/json"
],
"tags": [
"AnalysisRuns"
],
"summary": "Retry analysis run",
"parameters": [
{
"type": "string",
"description": "Analysis Run ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"202": {
"description": "Accepted",
"schema": {
"$ref": "#/definitions/work.UploadWorkResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/audit-logs": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns backend audit trail entries for administrative and teacher actions",
"produces": [
"application/json"
],
"tags": [
"Audit"
],
"summary": "List audit logs",
"parameters": [
{
"type": "integer",
"description": "Actor user ID",
"name": "actor_user_id",
"in": "query"
},
{
"type": "string",
"description": "Action filter",
"name": "action",
"in": "query"
},
{
"type": "string",
"description": "Resource type filter",
"name": "resource_type",
"in": "query"
},
{
"type": "string",
"description": "Resource ID filter",
"name": "resource_id",
"in": "query"
},
{
"type": "string",
"description": "Source filter: http or system",
"name": "source",
"in": "query"
},
{
"type": "integer",
"description": "Result limit, default 100, max 500",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.AuditLog"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/auth/login": {
"post": {
"description": "Authenticates a user and returns a JWT token",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Login",
"parameters": [
{
"description": "Login",
"name": "login",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/users.LoginRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/users.LoginResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/auth/me": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns claims from the current JWT token",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Get current user claims",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/auth.Claims"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/events": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get a list of all events",
"produces": [
"application/json"
],
"tags": [
"Events"
],
"summary": "Retrieve all events",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.Event"
}
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Create a new event with the provided information",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Events"
],
"summary": "Create a new event",
"parameters": [
{
"description": "Event to create",
"name": "event",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/events.CreateEventRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/db.Event"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/events/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get details of an event by its ID",
"produces": [
"application/json"
],
"tags": [
"Events"
],
"summary": "Retrieve a specific event",
"parameters": [
{
"type": "string",
"description": "Event ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.Event"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Delete an event by its ID",
"produces": [
"application/json"
],
"tags": [
"Events"
],
"summary": "Delete a specific event",
"parameters": [
{
"type": "string",
"description": "Event ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.DefaultSuccessResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"patch": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Update an event's data by its ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Events"
],
"summary": "Update a specific event",
"parameters": [
{
"type": "string",
"description": "Event ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Event data to update",
"name": "event",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/events.EditEventRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.Event"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/events/{id}/summary": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns event-level dashboard metrics, work cards, and a plagiarism graph for frontend dashboards",
"produces": [
"application/json"
],
"tags": [
"Events"
],
"summary": "Retrieve event dashboard summary",
"parameters": [
{
"type": "string",
"description": "Event ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.ScopeDashboard"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/events/{id}/works": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get all works linked to an event by its ID",
"produces": [
"application/json"
],
"tags": [
"Events"
],
"summary": "Retrieve works for a specific event",
"parameters": [
{
"type": "string",
"description": "Event ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.Work"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/groups": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns all groups",
"produces": [
"application/json"
],
"tags": [
"groups"
],
"summary": "List groups",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.Group"
}
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Create a new group in the system",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"groups"
],
"summary": "Create a group",
"parameters": [
{
"description": "Group data",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/groups.CreateGroupRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/db.Group"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/groups/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns a group by ID",
"produces": [
"application/json"
],
"tags": [
"groups"
],
"summary": "Get group",
"parameters": [
{
"type": "integer",
"description": "Group ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.Group"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Delete a group by its ID",
"produces": [
"application/json"
],
"tags": [
"groups"
],
"summary": "Delete group",
"parameters": [
{
"type": "integer",
"description": "Group ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.DefaultSuccessResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"patch": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Updates an existing group",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"groups"
],
"summary": "Update group",
"parameters": [
{
"type": "integer",
"description": "Group ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Group data",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/groups.EditGroupRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.Group"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/groups/{id}/stats": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns group-level dashboard metrics, work cards, and the plagiarism graph for the group",
"produces": [
"application/json"
],
"tags": [
"groups"
],
"summary": "Get group statistics",
"parameters": [
{
"type": "integer",
"description": "Group ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.ScopeDashboard"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/groups/{id}/students/{student_id}": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Creates a membership link between a group and a student",
"produces": [
"application/json"
],
"tags": [
"groups"
],
"summary": "Add student to group",
"parameters": [
{
"type": "integer",
"description": "Group ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Student ID",
"name": "student_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.DefaultSuccessResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"409": {
"description": "Conflict",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Deletes a membership link between a group and a student",
"produces": [
"application/json"
],
"tags": [
"groups"
],
"summary": "Remove student from group",
"parameters": [
{
"type": "integer",
"description": "Group ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Student ID",
"name": "student_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.DefaultSuccessResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/groups/{id}/users/{user_id}": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Creates a membership link between a group and a user",
"produces": [
"application/json"
],
"tags": [
"groups"
],
"summary": "Add user to group",
"parameters": [
{
"type": "integer",
"description": "Group ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "User ID",
"name": "user_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.DefaultSuccessResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"409": {
"description": "Conflict",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Deletes a membership link between a group and a user",
"produces": [
"application/json"
],
"tags": [
"groups"
],
"summary": "Remove user from group",
"parameters": [
{
"type": "integer",
"description": "Group ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "User ID",
"name": "user_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.DefaultSuccessResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/healthz": {
"get": {
"description": "Returns service liveness information for the backend API",
"produces": [
"application/json"
],
"tags": [
"System"
],
"summary": "Health check",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.HealthResponse"
}
}
}
}
},
"/readyz": {
"get": {
"description": "Returns backend readiness after checking the database connection required by the API",
"produces": [
"application/json"
],
"tags": [
"System"
],
"summary": "Readiness check",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.HealthResponse"
}
},
"503": {
"description": "Service Unavailable",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/reference-sets": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns all teacher-managed reference and template sets",
"produces": [
"application/json"
],
"tags": [
"ReferenceSets"
],
"summary": "List reference sets",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.ReferenceSet"
}
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Creates a teacher-managed reference or template set",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"ReferenceSets"
],
"summary": "Create reference set",
"parameters": [
{
"description": "Reference set payload",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/references.CreateReferenceSetRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/db.ReferenceSet"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/reference-sets/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns one reference or template set by ID",
"produces": [
"application/json"
],
"tags": [
"ReferenceSets"
],
"summary": "Get reference set",
"parameters": [
{
"type": "integer",
"description": "Reference Set ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.ReferenceSet"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Deletes a reference/template set with all linked ingestion records",
"produces": [
"application/json"
],
"tags": [
"ReferenceSets"
],
"summary": "Delete reference set",
"parameters": [
{
"type": "integer",
"description": "Reference Set ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.DefaultSuccessResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"patch": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Updates the name, description, or kind of a reference/template set",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"ReferenceSets"
],
"summary": "Update reference set",
"parameters": [
{
"type": "integer",
"description": "Reference Set ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Reference set payload",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/references.EditReferenceSetRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.ReferenceSet"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/reference-sets/{id}/ingestions": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns ingestion attempts for a reference/template set",
"produces": [
"application/json"
],
"tags": [
"ReferenceSets"
],
"summary": "List reference ingestions",
"parameters": [
{
"type": "integer",
"description": "Reference Set ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.ReferenceIngestion"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Uploads an archive for a reference/template set and schedules analyzer ingestion through Kafka",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"ReferenceSets"
],
"summary": "Upload reference ingestion archive",
"parameters": [
{
"type": "integer",
"description": "Reference Set ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "file",
"description": "Archive file",
"name": "file",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "Logical archive title",
"name": "title",
"in": "formData"
}
],
"responses": {
"202": {
"description": "Accepted",
"schema": {
"$ref": "#/definitions/references.CreateReferenceIngestionResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/students": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns all students",
"produces": [
"application/json"
],
"tags": [
"Students"
],
"summary": "List students",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.Student"
}
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Creates a new student",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Students"
],
"summary": "Create student",
"parameters": [
{
"description": "Student",
"name": "student",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/students.CreateStudentRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/students.GetStudentResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/students/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns a student by ID",
"produces": [
"application/json"
],
"tags": [
"Students"
],
"summary": "Get student",
"parameters": [
{
"type": "integer",
"description": "Student ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/students.GetStudentResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Deletes a student by ID",
"produces": [
"application/json"
],
"tags": [
"Students"
],
"summary": "Delete student",
"parameters": [
{
"type": "integer",
"description": "Student ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.DefaultSuccessResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"patch": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Updates an existing student",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Students"
],
"summary": "Update student",
"parameters": [
{
"type": "integer",
"description": "Student ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Student",
"name": "student",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/students.EditStudentRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/students.GetStudentResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/students/{id}/stats": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns student-level dashboard metrics, related works, and the local plagiarism graph",
"produces": [
"application/json"
],
"tags": [
"Students"
],
"summary": "Get student statistics",
"parameters": [
{
"type": "integer",
"description": "Student ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.ScopeDashboard"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/users": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns all users",
"produces": [
"application/json"
],
"tags": [
"Users"
],
"summary": "List users",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.User"
}
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Creates a new user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Users"
],
"summary": "Create user",
"parameters": [
{
"description": "User",
"name": "user",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/users.CreateUserRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/users.GetUserResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"409": {
"description": "Conflict",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/users/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns a user by ID",
"produces": [
"application/json"
],
"tags": [
"Users"
],
"summary": "Get user",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/users.GetUserResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/works": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns all works",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Works"
],
"summary": "List works",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.Work"
}
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Creates a new work",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Works"
],
"summary": "Create work",
"parameters": [
{
"description": "Work data",
"name": "work",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/work.CreateWorkRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/db.Work"
}
},
"400": {
"description": "Invalid request body",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Referenced student or event not found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/works/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns a work by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Works"
],
"summary": "Get work",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.Work"
}
},
"400": {
"description": "Invalid request URI parameters",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Work not found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"put": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Updates an existing work",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Works"
],
"summary": "Update work",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Work data",
"name": "work",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/work.EditWorkRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.Work"
}
},
"400": {
"description": "Invalid request body or URI",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Work not found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Removes a work item from the database by its ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Works"
],
"summary": "Deletes a specific work",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/basic.DefaultSuccessResponse"
}
},
"400": {
"description": "Invalid request URI parameters",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Work not found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/works/{id}/adoptions": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get the list of all adoptions related to a specific work",
"produces": [
"application/json"
],
"tags": [
"adoptions"
],
"summary": "Get adoptions by work",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.Adoption"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/works/{id}/adoptions/archive": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Retrieves all adoptions related to the specified work (including recursive relations) and packages their file segments into a downloadable zip archive. Each file in the archive contains metadata followed by the segment content.",
"produces": [
"application/zip"
],
"tags": [
"Works"
],
"summary": "Download all related adoption segments",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "A zip archive containing adoption segments",
"schema": {
"type": "string"
}
},
"400": {
"description": "Invalid work ID",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Work or related adoptions not found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal server error during processing or S3 interaction",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/works/{id}/adoptions/related": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get all related adoptions recursively for a given work",
"produces": [
"application/json"
],
"tags": [
"adoptions"
],
"summary": "Get related adoptions",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.Adoption"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/works/{id}/analysis-runs": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Fetches the asynchronous analysis runs created after work uploads",
"produces": [
"application/json"
],
"tags": [
"Works"
],
"summary": "Retrieves analysis runs for a specific work",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/db.AnalysisRun"
}
}
},
"400": {
"description": "Invalid request URI parameters",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Work not found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/works/{id}/archive": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns a presigned URL or redirect to the uploaded archive",
"produces": [
"application/json"
],
"tags": [
"Works"
],
"summary": "Get work archive",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "boolean",
"description": "Redirect flag",
"name": "redirect",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/work.DownloadWorkResponse"
}
},
"307": {
"description": "Temporary redirected URL for file download",
"schema": {
"type": "string"
}
},
"400": {
"description": "Invalid request URI parameters",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Work doesn't exist",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Failed to download the file",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
},
"put": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Uploads or replaces the current archive for a work without starting analysis. Accepts both raw zip body and multipart upload.",
"consumes": [
"application/octet-stream"
],
"produces": [
"application/json"
],
"tags": [
"Works"
],
"summary": "Upload work archive",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "file",
"description": "File to upload",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "Archive uploaded successfully",
"schema": {
"$ref": "#/definitions/work.UploadWorkResponse"
}
},
"400": {
"description": "Invalid request URI parameters",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Work not found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/works/{id}/check": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Starts a new analysis run for the archive already stored for this work",
"produces": [
"application/json"
],
"tags": [
"Works"
],
"summary": "Queue analysis for an already uploaded work archive",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"202": {
"description": "Accepted",
"schema": {
"$ref": "#/definitions/work.UploadWorkResponse"
}
},
"400": {
"description": "Invalid request URI parameters",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Work or archive not found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
},
"/works/{id}/summary": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Returns work-level dashboard data aggregated from bilateral adoptions and the latest analysis run",
"produces": [
"application/json"
],
"tags": [
"Works"
],
"summary": "Get work dashboard summary",
"parameters": [
{
"type": "integer",
"description": "Work ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/db.WorkDashboard"
}
},
"400": {
"description": "Invalid request URI parameters",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"404": {
"description": "Work not found",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/basic.DefaultErrorResponse"
}
}
}
}
}
},
"definitions": {
"auth.Claims": {
"type": "object",
"properties": {
"access_level": {
"type": "string"
},
"aud": {
"description": "the `aud` (Audience) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3",
"type": "array",
"items": {
"type": "string"
}
},
"email": {
"type": "string"
},
"exp": {
"description": "the `exp` (Expiration Time) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4",
"allOf": [
{
"$ref": "#/definitions/jwt.NumericDate"
}
]
},
"iat": {
"description": "the `iat` (Issued At) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6",
"allOf": [
{
"$ref": "#/definitions/jwt.NumericDate"
}
]
},
"iss": {
"description": "the `iss` (Issuer) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1",
"type": "string"
},
"jti": {
"description": "the `jti` (JWT ID) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7",
"type": "string"
},
"nbf": {
"description": "the `nbf` (Not Before) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5",
"allOf": [
{
"$ref": "#/definitions/jwt.NumericDate"
}
]
},
"sub": {
"description": "the `sub` (Subject) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2",
"type": "string"
},
"user_id": {
"type": "integer"
}
}
},
"basic.DefaultErrorResponse": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
},
"basic.DefaultSuccessResponse": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
},
"basic.HealthResponse": {
"type": "object",
"properties": {
"status": {
"type": "string"
}
}
},
"db.Adoption": {
"type": "object",
"properties": {
"analysis_run_id": {
"type": "string"
},
"chunk_index": {
"type": "integer"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"is_ai_generated": {
"type": "boolean"
},
"part_offset": {
"type": "integer"
},
"part_size": {
"type": "integer"
},
"path": {
"type": "string"
},
"refers_to": {
"type": "integer"
},
"segment_excerpt": {
"type": "string"
},
"similarity_score": {
"type": "number"
},
"verdict": {
"$ref": "#/definitions/db.AdoptionVerdict"
},
"work_id": {
"type": "integer"
}
}
},
"db.AdoptionVerdict": {
"type": "string",
"enum": [
"Not Issued"
],
"x-enum-varnames": [
"AdoptionNotIssued"
]
},
"db.AnalysisRun": {
"type": "object",
"properties": {
"algorithm_id": {
"type": "string"
},
"analyzer_name": {
"type": "string"
},
"analyzer_report_html_key": {
"type": "string"
},
"analyzer_report_json_key": {
"type": "string"
},
"analyzer_report_pdf_key": {
"type": "string"
},
"archive_checksum": {
"type": "string"
},
"archive_size": {
"type": "integer"
},
"archive_uploaded_at": {
"type": "string"
},
"completed_at": {
"type": "string"
},
"error_message": {
"type": "string"
},
"event_id": {
"type": "integer"
},
"generated_at": {
"type": "string"
},
"id": {
"type": "string"
},
"object_key": {
"type": "string"
},
"report_html_key": {
"type": "string"
},
"report_json_key": {
"type": "string"
},
"report_pdf_key": {
"type": "string"
},
"started_at": {
"type": "string"
},
"status": {
"$ref": "#/definitions/db.AnalysisRunStatus"
},
"submitted_at": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"work_id": {
"type": "integer"
}
}
},
"db.AnalysisRunChunk": {
"type": "object",
"properties": {
"checksum": {
"type": "string"
},
"chunk_index": {
"type": "integer"
},
"findings_count": {
"type": "integer"
},
"is_final": {
"type": "boolean"
},
"payload": {
"type": "array",
"items": {
"type": "integer"
}
},
"received_at": {
"type": "string"
},
"run_id": {
"type": "string"
}
}
},
"db.AnalysisRunStatus": {
"type": "string",
"enum": [
"Queued"
],
"x-enum-varnames": [
"AnalysisRunQueued"
]
},
"db.AuditLog": {
"type": "object",
"properties": {
"action": {
"type": "string"
},
"actor_access_level": {
"type": "string"
},
"actor_email": {
"type": "string"
},
"actor_user_id": {
"type": "integer"
},
"created_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"metadata": {
"type": "object",
"additionalProperties": {}
},
"method": {
"type": "string"
},
"path": {
"type": "string"
},
"request_id": {
"type": "string"
},
"resource_id": {
"type": "string"
},
"resource_type": {
"type": "string"
},
"source": {
"type": "string"
}
}
},
"db.DashboardCounterpart": {
"type": "object",
"properties": {
"average_similarity": {
"type": "number"
},
"blatant_matches": {
"type": "integer"
},
"event_id": {
"type": "integer"
},
"event_name": {
"type": "string"
},
"group_id": {
"type": "integer"
},
"group_name": {
"type": "string"
},
"label": {
"type": "string"
},
"match_count": {
"type": "integer"
},
"max_similarity": {
"type": "number"
},
"risk_level": {
"type": "string"
},
"score": {
"type": "number"
},
"significant_matches": {
"type": "integer"
},
"student_id": {
"type": "integer"
},
"student_name": {
"type": "string"
},
"work_id": {
"type": "integer"
}
}
},
"db.DashboardGraph": {
"type": "object",
"properties": {
"edges": {
"type": "array",
"items": {
"$ref": "#/definitions/db.DashboardGraphEdge"
}
},
"nodes": {
"type": "array",
"items": {
"$ref": "#/definitions/db.DashboardGraphNode"
}
}
}
},
"db.DashboardGraphEdge": {
"type": "object",
"properties": {
"average_similarity": {
"type": "number"
},
"blatant_matches": {
"type": "integer"
},
"from_work_id": {
"type": "integer"
},
"match_count": {
"type": "integer"
},
"max_similarity": {
"type": "number"
},
"risk_level": {
"type": "string"
},
"score": {
"type": "number"
},
"significant_matches": {
"type": "integer"
},
"to_work_id": {
"type": "integer"
}
}
},
"db.DashboardGraphNode": {
"type": "object",
"properties": {
"event_id": {
"type": "integer"
},
"event_name": {
"type": "string"
},
"group_id": {
"type": "integer"
},
"group_name": {
"type": "string"
},
"in_scope": {
"type": "boolean"
},
"label": {
"type": "string"
},
"needs_review": {
"type": "boolean"
},
"plagiarism_rate": {
"type": "number"
},
"risk_level": {
"type": "string"
},
"student_id": {
"type": "integer"
},
"student_name": {
"type": "string"
},
"trust_score": {
"type": "number"
},
"work_id": {
"type": "integer"
}
}
},
"db.DashboardMetrics": {
"type": "object",
"properties": {
"ai_findings_count": {
"type": "integer"
},
"average_plagiarism_rate": {
"type": "number"
},
"blatant_matches": {
"type": "integer"
},
"connections_count": {
"type": "integer"
},
"counterparts_count": {
"type": "integer"
},
"headline": {
"type": "string"
},
"max_plagiarism_rate": {
"type": "number"
},
"plagiarism_rate": {
"type": "number"
},
"risk_level": {
"type": "string"
},
"significant_matches": {
"type": "integer"
},
"trust_score": {
"type": "number"
},
"works_checked": {
"type": "integer"
},
"works_completed": {
"type": "integer"
},
"works_failed": {
"type": "integer"
},
"works_flagged": {
"type": "integer"
},
"works_processing": {
"type": "integer"
},
"works_queued": {
"type": "integer"
},
"works_total": {
"type": "integer"
}
}
},
"db.DashboardWorkItem": {
"type": "object",
"properties": {
"ai_findings_count": {
"type": "integer"
},
"blatant_matches": {
"type": "integer"
},
"checked": {
"type": "boolean"
},
"connections_count": {
"type": "integer"
},
"counterparts_count": {
"type": "integer"
},
"event_id": {
"type": "integer"
},
"event_name": {
"type": "string"
},
"group_id": {
"type": "integer"
},
"group_name": {
"type": "string"
},
"has_teacher_report": {
"type": "boolean"
},
"label": {
"type": "string"
},
"latest_run_id": {
"type": "string"
},
"latest_run_status": {
"$ref": "#/definitions/db.AnalysisRunStatus"
},
"needs_review": {
"type": "boolean"
},
"plagiarism_rate": {
"type": "number"
},
"risk_level": {
"type": "string"
},
"significant_matches": {
"type": "integer"
},
"strongest_connection_score": {
"type": "number"
},
"strongest_counterpart": {
"type": "string"
},
"strongest_counterpart_work_id": {
"type": "integer"
},
"student_id": {
"type": "integer"
},
"student_name": {
"type": "string"
},
"trust_score": {
"type": "number"
},
"work_id": {
"type": "integer"
}
}
},
"db.Event": {
"type": "object",
"properties": {
"date": {
"type": "string"
},
"description": {
"type": "string"
},
"group_id": {
"type": "integer"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"db.Group": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"students": {
"type": "array",
"items": {
"type": "integer"
}
},
"users": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"db.ReferenceIngestion": {
"type": "object",
"properties": {
"analyzer_name": {
"type": "string"
},
"completed_at": {
"type": "string"
},
"created_at": {
"type": "string"
},
"error_message": {
"type": "string"
},
"id": {
"type": "string"
},
"object_key": {
"type": "string"
},
"reference_set_id": {
"type": "integer"
},
"status": {
"$ref": "#/definitions/db.ReferenceIngestionStatus"
},
"title": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"db.ReferenceIngestionStatus": {
"type": "string",
"enum": [
"Queued",
"Processing",
"Completed",
"Failed"
],
"x-enum-varnames": [
"ReferenceIngestionQueued",
"ReferenceIngestionProcessing",
"ReferenceIngestionCompleted",
"ReferenceIngestionFailed"
]
},
"db.ReferenceSet": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"kind": {
"$ref": "#/definitions/db.ReferenceSetKind"
},
"name": {
"type": "string"
}
}
},
"db.ReferenceSetKind": {
"type": "string",
"enum": [
"reference",
"template"
],
"x-enum-varnames": [
"ReferenceSetKindReference",
"ReferenceSetKindTemplate"
]
},
"db.ScopeDashboard": {
"type": "object",
"properties": {
"graph": {
"$ref": "#/definitions/db.DashboardGraph"
},
"name": {
"type": "string"
},
"presentation_summary": {
"$ref": "#/definitions/db.DashboardMetrics"
},
"scope": {
"type": "string"
},
"scope_id": {
"type": "integer"
},
"works": {
"type": "array",
"items": {
"$ref": "#/definitions/db.DashboardWorkItem"
}
}
}
},
"db.Student": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"user_id": {
"type": "integer"
}
}
},
"db.User": {
"type": "object",
"properties": {
"access_level": {
"type": "string"
},
"email": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"db.Work": {
"type": "object",
"properties": {
"archive_checksum": {
"type": "string"
},
"archive_object_key": {
"type": "string"
},
"archive_size": {
"type": "integer"
},
"archive_uploaded_at": {
"type": "string"
},
"event_id": {
"type": "integer"
},
"id": {
"type": "integer"
},
"student_id": {
"type": "integer"
},
"time": {
"type": "string"
}
}
},
"db.WorkDashboard": {
"type": "object",
"properties": {
"counterparts": {
"type": "array",
"items": {
"$ref": "#/definitions/db.DashboardCounterpart"
}
},
"graph": {
"$ref": "#/definitions/db.DashboardGraph"
},
"latest_run": {
"$ref": "#/definitions/db.AnalysisRun"
},
"presentation_summary": {
"$ref": "#/definitions/db.DashboardMetrics"
},
"work": {
"$ref": "#/definitions/db.DashboardWorkItem"
}
}
},
"events.CreateEventRequest": {
"type": "object",
"required": [
"date",
"group_id",
"name"
],
"properties": {
"date": {
"type": "string"
},
"description": {
"type": "string"
},
"group_id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"events.EditEventRequest": {
"type": "object",
"required": [
"date",
"group_id",
"id",
"name"
],
"properties": {
"date": {
"type": "string"
},
"description": {
"type": "string"
},
"group_id": {
"type": "integer"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"groups.CreateGroupRequest": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
}
}
},
"groups.EditGroupRequest": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"jwt.NumericDate": {
"type": "object",
"properties": {
"time.Time": {
"type": "string"
}
}
},
"references.CreateReferenceIngestionResponse": {
"type": "object",
"properties": {
"ingestion_id": {
"type": "string"
},
"message": {
"type": "string"
},
"object_key": {
"type": "string"
},
"status": {
"$ref": "#/definitions/db.ReferenceIngestionStatus"
}
}
},
"references.CreateReferenceSetRequest": {
"type": "object",
"required": [
"kind",
"name"
],
"properties": {
"description": {
"type": "string"
},
"kind": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"references.EditReferenceSetRequest": {
"type": "object",
"required": [
"kind",
"name"
],
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"kind": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"students.CreateStudentRequest": {
"type": "object",
"required": [
"email",
"name"
],
"properties": {
"email": {
"type": "string"
},
"name": {
"type": "string"
},
"user_id": {
"type": "integer"
}
}
},
"students.EditStudentRequest": {
"type": "object",
"required": [
"email",
"id",
"name"
],
"properties": {
"email": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"user_id": {
"type": "integer"
}
}
},
"students.GetStudentResponse": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"user_id": {
"type": "integer"
}
}
},
"users.CreateUserRequest": {
"type": "object",
"required": [
"access_level",
"email",
"name",
"password"
],
"properties": {
"access_level": {
"type": "string",
"enum": [
"Admin",
"Teacher",
"Student",
"Guest"
]
},
"email": {
"type": "string"
},
"name": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
"users.GetUserResponse": {
"type": "object",
"properties": {
"access_level": {
"type": "string"
},
"email": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"users.LoginRequest": {
"type": "object",
"required": [
"email",
"password"
],
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
"users.LoginResponse": {
"type": "object",
"properties": {
"token": {
"type": "string"
},
"user": {
"$ref": "#/definitions/db.User"
}
}
},
"work.CreateWorkRequest": {
"type": "object",
"required": [
"event_id",
"student_id",
"time"
],
"properties": {
"event_id": {
"type": "integer"
},
"student_id": {
"type": "integer"
},
"time": {
"type": "string"
}
}
},
"work.DownloadWorkResponse": {
"type": "object",
"properties": {
"url": {
"type": "string"
}
}
},
"work.EditWorkRequest": {
"type": "object",
"required": [
"event_id",
"id",
"student_id",
"time"
],
"properties": {
"event_id": {
"type": "integer"
},
"id": {
"type": "integer"
},
"student_id": {
"type": "integer"
},
"time": {
"type": "string"
}
}
},
"work.UploadWorkResponse": {
"type": "object",
"properties": {
"analysis_run_id": {
"type": "string"
},
"archive_checksum": {
"type": "string"
},
"archive_object_key": {
"type": "string"
},
"archive_size": {
"type": "integer"
},
"message": {
"type": "string"
},
"status": {
"type": "string"
}
}
}
},
"securityDefinitions": {
"ApiKeyAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
}
}