bm_pin_material and bm_unpin_material on the token twins (scope write), with the pin routes documented in the README.
221 lines
10 KiB
Go
221 lines
10 KiB
Go
package bm
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/pact"
|
|
)
|
|
|
|
// MCPMaterialPrivacy is the sentence every material tool description
|
|
// carries (D-17, D-21).
|
|
const MCPMaterialPrivacy = "Returns metadata and links, never whole file contents; with q a material may carry a short plain-text snippet of the matched passage, possibly from an attached file; a material's body (possible transcript text) is left out unless include_body is true."
|
|
|
|
// The sentences every student tool description ends with (D-15).
|
|
const (
|
|
needsScopeRead = " Needs scope read."
|
|
needsScopeWrite = " Needs scope write."
|
|
)
|
|
|
|
// noInput is the input of a tool that takes no arguments.
|
|
type noInput struct{}
|
|
|
|
// idInput names one record by its id.
|
|
type idInput struct {
|
|
ID uint `json:"id" path:"id" jsonschema:"the record id, as listed by the matching list tool"`
|
|
}
|
|
|
|
// readingIDInput names one reading by its id.
|
|
type readingIDInput struct {
|
|
ID uint `json:"id" path:"id" jsonschema:"the reading id, as listed by bm_readings or bm_course"`
|
|
}
|
|
|
|
// materialIDInput names one material by its id.
|
|
type materialIDInput struct {
|
|
ID uint `json:"id" path:"id" jsonschema:"the material id, as listed by bm_materials, bm_material or bm_course"`
|
|
}
|
|
|
|
// coursesInput is the input of bm_courses.
|
|
type coursesInput struct {
|
|
Semester int `json:"semester,omitempty" query:"semester" jsonschema:"only courses of this semester, 1 to 4"`
|
|
}
|
|
|
|
// rangeInput is the input of bm_schedule and bm_deadlines.
|
|
type rangeInput struct {
|
|
From string `json:"from,omitempty" query:"from" jsonschema:"first day, YYYY-MM-DD (default: today)"`
|
|
To string `json:"to,omitempty" query:"to" jsonschema:"last day (inclusive), YYYY-MM-DD, not before from (default: no end)"`
|
|
}
|
|
|
|
// readingsInput is the input of bm_readings.
|
|
type readingsInput struct {
|
|
Course uint `json:"course,omitempty" query:"course" jsonschema:"only readings of this course id"`
|
|
}
|
|
|
|
// materialsInput is the input of bm_materials.
|
|
type materialsInput struct {
|
|
Q string `json:"q,omitempty" query:"q" jsonschema:"full-text search over the title, tags, source, course, link, body and the text of attached PDFs, 2 to 100 characters; results then come by relevance, each with a short plain-text snippet when the match is in the body or a file"`
|
|
Course uint `json:"course,omitempty" query:"course" jsonschema:"only materials of this course id"`
|
|
Meeting uint `json:"meeting,omitempty" query:"meeting" jsonschema:"only materials of this zjazd (meeting) id"`
|
|
Tag string `json:"tag,omitempty" query:"tag" jsonschema:"only materials with this tag slug, at most 100 characters"`
|
|
Type string `json:"type,omitempty" query:"type" jsonschema:"only materials of this type, one of: pdf, notatka, link, inne"`
|
|
Page int `json:"page,omitempty" query:"page" jsonschema:"page number, 1 or more (default 1)"`
|
|
PerPage int `json:"per_page,omitempty" query:"per_page" jsonschema:"materials per page, 1 to 100"`
|
|
}
|
|
|
|
// materialInput is the input of bm_material.
|
|
type materialInput struct {
|
|
ID uint `json:"id" path:"id" jsonschema:"the material id, as listed by bm_materials"`
|
|
IncludeBody bool `json:"include_body,omitempty" query:"include_body" jsonschema:"true to include the material's body (it may hold transcript text)"`
|
|
}
|
|
|
|
// boolPtr returns a pointer to b, for the tool annotations.
|
|
func boolPtr(b bool) *bool { return &b }
|
|
|
|
// studentTools are the tools over the token twins of the student API. Each
|
|
// call runs as the session's user, who reaches only their own progress and
|
|
// published data, as on the HTTP API (D-09).
|
|
func studentTools() []pact.MCPTool {
|
|
return []pact.MCPTool{
|
|
{
|
|
Name: "dashboard",
|
|
Title: "BM dashboard",
|
|
Description: "Returns the student's dashboard: the next class sessions, the deadlines not yet due, the zjazd (meeting) under way today and the next one, and the student's reading progress counts." + needsScopeRead,
|
|
Guard: "user",
|
|
Method: http.MethodGet,
|
|
Path: TokenPrefix + "/dashboard",
|
|
Input: noInput{},
|
|
},
|
|
{
|
|
Name: "courses",
|
|
Title: "BM courses",
|
|
Description: "Lists the programme's courses with code, form, lecturer, semester, ECTS, assessment, syllabus link and counters." + needsScopeRead,
|
|
Guard: "user",
|
|
Method: http.MethodGet,
|
|
Path: TokenPrefix + "/courses",
|
|
Input: coursesInput{},
|
|
},
|
|
{
|
|
Name: "course",
|
|
Title: "BM course",
|
|
Description: "Returns one course with its description, syllabus link, counters, class sessions, readings (with the student's read and owned marks) and the published materials the student may see (public ones and private ones they wrote or that are shared with them)." + needsScopeRead,
|
|
Guard: "user",
|
|
Method: http.MethodGet,
|
|
Path: TokenPrefix + "/courses/{id}",
|
|
Input: idInput{},
|
|
},
|
|
{
|
|
Name: "schedule",
|
|
Title: "BM schedule",
|
|
Description: "Lists the class sessions starting in a date range (default: from today, no end) with course, zjazd, start and end time, room, kind, lecturer, notes and whether the class is online." + needsScopeRead,
|
|
Guard: "user",
|
|
Method: http.MethodGet,
|
|
Path: TokenPrefix + "/schedule",
|
|
Input: rangeInput{},
|
|
},
|
|
{
|
|
Name: "meetings",
|
|
Title: "BM meetings",
|
|
Description: "Lists the zjazdy (weekend meetings) with number, first and last day, notes and the number of class sessions in each." + needsScopeRead,
|
|
Guard: "user",
|
|
Method: http.MethodGet,
|
|
Path: TokenPrefix + "/meetings",
|
|
Input: noInput{},
|
|
},
|
|
{
|
|
Name: "deadlines",
|
|
Title: "BM deadlines",
|
|
Description: "Lists the deadlines due in a date range (default: from today, no end) with title, due time, kind, course and description." + needsScopeRead,
|
|
Guard: "user",
|
|
Method: http.MethodGet,
|
|
Path: TokenPrefix + "/deadlines",
|
|
Input: rangeInput{},
|
|
},
|
|
{
|
|
Name: "readings",
|
|
Title: "BM readings",
|
|
Description: "Lists readings with author, source, link, course, zjazd, whether required, and the student's read and owned marks." + needsScopeRead,
|
|
Guard: "user",
|
|
Method: http.MethodGet,
|
|
Path: TokenPrefix + "/readings",
|
|
Input: readingsInput{},
|
|
},
|
|
{
|
|
Name: "mark_reading_read",
|
|
Title: "Mark a reading as read",
|
|
Description: "Marks a reading as read by the signed-in student and returns the reading id with the read time. Marking again keeps the first time." + needsScopeWrite,
|
|
Guard: "user",
|
|
Method: http.MethodPut,
|
|
Path: TokenPrefix + "/readings/{id}/progress",
|
|
Input: readingIDInput{},
|
|
},
|
|
{
|
|
Name: "unmark_reading_read",
|
|
Title: "Unmark a reading as read",
|
|
Description: "Removes the signed-in student's read mark from a reading (it can be marked again) and returns the reading id with an empty read time." + needsScopeWrite,
|
|
Guard: "user",
|
|
Method: http.MethodDelete,
|
|
Path: TokenPrefix + "/readings/{id}/progress",
|
|
Input: readingIDInput{},
|
|
Destructive: boolPtr(false),
|
|
Idempotent: boolPtr(true),
|
|
},
|
|
{
|
|
Name: "mark_reading_owned",
|
|
Title: "Mark a reading as owned",
|
|
Description: "Marks that the signed-in student has a copy of a reading and returns the reading id with the owned time." + needsScopeWrite,
|
|
Guard: "user",
|
|
Method: http.MethodPut,
|
|
Path: TokenPrefix + "/readings/{id}/owned",
|
|
Input: readingIDInput{},
|
|
},
|
|
{
|
|
Name: "unmark_reading_owned",
|
|
Title: "Unmark a reading as owned",
|
|
Description: "Removes the signed-in student's owned mark from a reading (it can be marked again) and returns the reading id with an empty owned time." + needsScopeWrite,
|
|
Guard: "user",
|
|
Method: http.MethodDelete,
|
|
Path: TokenPrefix + "/readings/{id}/owned",
|
|
Input: readingIDInput{},
|
|
Destructive: boolPtr(false),
|
|
Idempotent: boolPtr(true),
|
|
},
|
|
{
|
|
Name: "materials",
|
|
Title: "BM materials",
|
|
Description: "Lists a page of the published materials the student may see (public ones and private ones they wrote or that are shared with them): without q the student's own pinned materials first (newest pin first), then newest first; with q by relevance (pins are then only marked). Each row has title, type, course, zjazd, source, link, tags, file count and whether the student pinned it (and the snippet with q), plus the page meta. " + MCPMaterialPrivacy + needsScopeRead,
|
|
Guard: "user",
|
|
Method: http.MethodGet,
|
|
Path: TokenPrefix + "/materials",
|
|
Input: materialsInput{},
|
|
},
|
|
{
|
|
Name: "material",
|
|
Title: "BM material",
|
|
Description: "Returns one published material the student may see (public ones and private ones they wrote or that are shared with them) with its tags, its files (id, absolute link, name, size and type) and whether the student pinned it. " + MCPMaterialPrivacy + needsScopeRead,
|
|
Guard: "user",
|
|
Method: http.MethodGet,
|
|
Path: TokenPrefix + "/materials/{id}",
|
|
Input: materialInput{},
|
|
},
|
|
{
|
|
Name: "pin_material",
|
|
Title: "Pin a material",
|
|
Description: "Pins a material the signed-in student may see, for this student only (nobody else sees the pin): bm_materials without q then lists it first, newest pin first, and the material answers carry pinned true. Pinning again keeps the first pin time. Answers with no content; a material the student cannot see is not found." + needsScopeWrite,
|
|
Guard: "user",
|
|
Method: http.MethodPut,
|
|
Path: TokenPrefix + "/materials/{id}/pin",
|
|
Input: materialIDInput{},
|
|
},
|
|
{
|
|
Name: "unpin_material",
|
|
Title: "Unpin a material",
|
|
Description: "Removes the signed-in student's own pin from a material (it can be pinned again); unpinning a material that is not pinned is not an error. Answers with no content." + needsScopeWrite,
|
|
Guard: "user",
|
|
Method: http.MethodDelete,
|
|
Path: TokenPrefix + "/materials/{id}/pin",
|
|
Input: materialIDInput{},
|
|
Destructive: boolPtr(false),
|
|
Idempotent: boolPtr(true),
|
|
},
|
|
}
|
|
}
|