{ "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" } } }