handlers
import "github.com/Ask-Atlas/AskAtlas/api/internal/handlers"
Package handlers contains the HTTP handlers and routes for the API endpoints.
Index
- type ClerkHandler
- type ClerkService
- type CompositeHandler
- type CourseService
- type CoursesHandler
- func NewCoursesHandler(service CourseService) *CoursesHandler
- func (h *CoursesHandler) CheckMembership(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID, sectionId openapi_types.UUID)
- func (h *CoursesHandler) GetCourse(w http.ResponseWriter, r *http.Request, courseID openapi_types.UUID)
- func (h *CoursesHandler) JoinSection(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID, sectionId openapi_types.UUID)
- func (h *CoursesHandler) LeaveSection(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID, sectionId openapi_types.UUID)
- func (h *CoursesHandler) ListCourses(w http.ResponseWriter, r *http.Request, params api.ListCoursesParams)
- func (h *CoursesHandler) ListMyEnrollments(w http.ResponseWriter, r *http.Request, params api.ListMyEnrollmentsParams)
- func (h *CoursesHandler) ListSectionMembers(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID, sectionId openapi_types.UUID, params api.ListSectionMembersParams)
- type FileHandler
- func NewFileHandler(service FileService, publisher files.QStashPublisher) *FileHandler
- func (h *FileHandler) CreateFile(w http.ResponseWriter, r *http.Request)
- func (h *FileHandler) DeleteFile(w http.ResponseWriter, r *http.Request, fileId openapi_types.UUID)
- func (h *FileHandler) GetFile(w http.ResponseWriter, r *http.Request, fileId openapi_types.UUID)
- func (h *FileHandler) ListFiles(w http.ResponseWriter, r *http.Request, params api.ListFilesParams)
- func (h *FileHandler) UpdateFile(w http.ResponseWriter, r *http.Request, fileId openapi_types.UUID)
- type FileService
- type GrantHandler
- type GrantService
- type JobHandler
- type QuizService
- type QuizzesHandler
- func NewQuizzesHandler(service QuizService) *QuizzesHandler
- func (h *QuizzesHandler) CreateQuiz(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
- func (h *QuizzesHandler) DeleteQuiz(w http.ResponseWriter, r *http.Request, quizId openapi_types.UUID)
- func (h *QuizzesHandler) ListQuizzes(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
- func (h *QuizzesHandler) UpdateQuiz(w http.ResponseWriter, r *http.Request, quizId openapi_types.UUID)
- type SchoolService
- type SchoolsHandler
- type StudyGuideHandler
- func NewStudyGuideHandler(service StudyGuideService) *StudyGuideHandler
- func (h *StudyGuideHandler) AttachFile(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID, fileId openapi_types.UUID)
- func (h *StudyGuideHandler) AttachResource(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
- func (h *StudyGuideHandler) CastStudyGuideVote(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
- func (h *StudyGuideHandler) CreateStudyGuide(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID)
- func (h *StudyGuideHandler) DeleteStudyGuide(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
- func (h *StudyGuideHandler) DetachFile(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID, fileId openapi_types.UUID)
- func (h *StudyGuideHandler) DetachResource(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID, resourceId openapi_types.UUID)
- func (h *StudyGuideHandler) GetStudyGuide(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
- func (h *StudyGuideHandler) ListStudyGuides(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID, params api.ListStudyGuidesParams)
- func (h *StudyGuideHandler) RecommendStudyGuide(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
- func (h *StudyGuideHandler) RemoveStudyGuideRecommendation(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
- func (h *StudyGuideHandler) RemoveStudyGuideVote(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
- func (h *StudyGuideHandler) UpdateStudyGuide(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
- type StudyGuideService
type ClerkHandler
ClerkHandler manages incoming HTTP webhook requests from Clerk.
type ClerkHandler struct {
// contains filtered or unexported fields
}
func NewClerkWebhookHandler
func NewClerkWebhookHandler(clerkService ClerkService) *ClerkHandler
NewClerkWebhookHandler creates a new ClerkHandler with the given service.
func (*ClerkHandler) Webhook
func (ch *ClerkHandler) Webhook(w http.ResponseWriter, r *http.Request)
Webhook processes the incoming Clerk webhook request, parsing and dispatching the event.
type ClerkService
ClerkService defines the interface for processing Clerk webhook payloads.
type ClerkService interface {
HandleWebhookEvent(ctx context.Context, payload clerk.Event) error
}
type CompositeHandler
CompositeHandler combines multiple handler structs into a single value that satisfies the generated api.ServerInterface.
type CompositeHandler struct {
*FileHandler
*GrantHandler
*SchoolsHandler
*CoursesHandler
*StudyGuideHandler
*QuizzesHandler
}
func NewCompositeHandler
func NewCompositeHandler(fh *FileHandler, gh *GrantHandler, sh *SchoolsHandler, ch *CoursesHandler, sgh *StudyGuideHandler, qh *QuizzesHandler) *CompositeHandler
NewCompositeHandler creates a handler that delegates to FileHandler, GrantHandler, SchoolsHandler, CoursesHandler, StudyGuideHandler, and QuizzesHandler.
type CourseService
CourseService defines the application logic required by the CoursesHandler.
type CourseService interface {
ListCourses(ctx context.Context, params courses.ListCoursesParams) (courses.ListCoursesResult, error)
GetCourse(ctx context.Context, params courses.GetCourseParams) (courses.CourseDetail, error)
JoinSection(ctx context.Context, params courses.JoinSectionParams) (courses.Membership, error)
LeaveSection(ctx context.Context, params courses.LeaveSectionParams) error
ListMyEnrollments(ctx context.Context, params courses.ListMyEnrollmentsParams) ([]courses.Enrollment, error)
CheckMembership(ctx context.Context, params courses.CheckMembershipParams) (courses.MembershipCheck, error)
ListSectionMembers(ctx context.Context, params courses.ListSectionMembersParams) (courses.ListSectionMembersResult, error)
}
type CoursesHandler
CoursesHandler manages incoming HTTP requests relating to course operations.
type CoursesHandler struct {
// contains filtered or unexported fields
}
func NewCoursesHandler
func NewCoursesHandler(service CourseService) *CoursesHandler
NewCoursesHandler creates a new CoursesHandler backed by the given CourseService.
func (*CoursesHandler) CheckMembership
func (h *CoursesHandler) CheckMembership(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID, sectionId openapi_types.UUID)
CheckMembership handles GET /courses/{course_id}/sections/{section_id}/members/me. Always returns 200 -- non-membership is enrolled=false with null role/joined_at, NOT 404. 404 is reserved for missing course/section (so the frontend can distinguish "not enrolled" from "section deleted").
func (*CoursesHandler) GetCourse
func (h *CoursesHandler) GetCourse(w http.ResponseWriter, r *http.Request, courseID openapi_types.UUID)
GetCourse handles GET /courses/{course_id}, returning a single course with its embedded school summary and inline sections array.
func (*CoursesHandler) JoinSection
func (h *CoursesHandler) JoinSection(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID, sectionId openapi_types.UUID)
JoinSection handles POST /courses/{course_id}/sections/{section_id}/members. The viewer joins the section as a 'student'. Any *fields* in the request body are intentionally ignored -- the role is enforced by the service + SQL layer to prevent privilege escalation via {"role": "instructor"} -- but malformed JSON is still rejected with 400 per the spec, so we shallow-parse the body when one is provided.
func (*CoursesHandler) LeaveSection
func (h *CoursesHandler) LeaveSection(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID, sectionId openapi_types.UUID)
LeaveSection handles DELETE /courses/{course_id}/sections/{section_id}/members/me. The viewer leaves the section. The /me path segment makes self-only scope explicit; there is no path parameter for the user being removed.
func (*CoursesHandler) ListCourses
func (h *CoursesHandler) ListCourses(w http.ResponseWriter, r *http.Request, params api.ListCoursesParams)
ListCourses handles GET /courses, returning a paginated list of courses (with embedded school summaries) optionally filtered by school_id, department, or a q search term.
func (*CoursesHandler) ListMyEnrollments
func (h *CoursesHandler) ListMyEnrollments(w http.ResponseWriter, r *http.Request, params api.ListMyEnrollmentsParams)
ListMyEnrollments handles GET /me/courses, returning every section the authenticated viewer is enrolled in. Filters on term + role come from the query string; the openapi layer enforces role enum membership and term maxLength so the service path-validation is defense in depth.
func (*CoursesHandler) ListSectionMembers
func (h *CoursesHandler) ListSectionMembers(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID, sectionId openapi_types.UUID, params api.ListSectionMembersParams)
ListSectionMembers handles GET /courses/{course_id}/sections/{section_id}/members. Any authenticated user can list -- no membership check on the caller (course pages are public within the app). The response payload is the privacy floor: 5 fields, no email, no clerk_id.
type FileHandler
FileHandler manages incoming HTTP requests relating to File operations.
type FileHandler struct {
// contains filtered or unexported fields
}
func NewFileHandler
func NewFileHandler(service FileService, publisher files.QStashPublisher) *FileHandler
NewFileHandler creates a new FileHandler backed by the given FileService.
func (*FileHandler) CreateFile
func (h *FileHandler) CreateFile(w http.ResponseWriter, r *http.Request)
CreateFile handles requests to create a new file reference and get a presigned upload URL.
func (*FileHandler) DeleteFile
func (h *FileHandler) DeleteFile(w http.ResponseWriter, r *http.Request, fileId openapi_types.UUID)
DeleteFile handles requests to delete a single file by its unique identifier.
func (*FileHandler) GetFile
func (h *FileHandler) GetFile(w http.ResponseWriter, r *http.Request, fileId openapi_types.UUID)
GetFile handles requests to retrieve a single file by its unique identifier.
func (*FileHandler) ListFiles
func (h *FileHandler) ListFiles(w http.ResponseWriter, r *http.Request, params api.ListFilesParams)
ListFiles handles requests to retrieve a paginated list of files accessible to the viewer.
func (*FileHandler) UpdateFile
func (h *FileHandler) UpdateFile(w http.ResponseWriter, r *http.Request, fileId openapi_types.UUID)
UpdateFile handles requests to rename a file.
type FileService
FileService defines the application logic required by the FileHandler.
type FileService interface {
CreateFile(ctx context.Context, params files.CreateFileParams) (files.CreateFileResult, error)
GetFile(ctx context.Context, params files.GetFileParams) (files.File, error)
ListFiles(ctx context.Context, params files.ListFilesParams) ([]files.File, *string, error)
DeleteFile(ctx context.Context, params files.DeleteFileParams, publisher files.QStashPublisher) error
UpdateFile(ctx context.Context, params files.UpdateFileParams) (files.File, error)
}
type GrantHandler
GrantHandler manages incoming HTTP requests relating to file grant operations.
type GrantHandler struct {
// contains filtered or unexported fields
}
func NewGrantHandler
func NewGrantHandler(service GrantService) *GrantHandler
NewGrantHandler creates a new GrantHandler backed by the given GrantService.
func (*GrantHandler) CreateGrant
func (h *GrantHandler) CreateGrant(w http.ResponseWriter, r *http.Request, fileId openapi_types.UUID)
CreateGrant handles requests to create a permission grant on a file.
func (*GrantHandler) RevokeGrant
func (h *GrantHandler) RevokeGrant(w http.ResponseWriter, r *http.Request, fileId openapi_types.UUID)
RevokeGrant handles requests to revoke a permission grant on a file.
type GrantService
GrantService defines the application logic required by the GrantHandler.
type GrantService interface {
CreateGrant(ctx context.Context, params files.CreateGrantParams) (files.Grant, error)
RevokeGrant(ctx context.Context, params files.RevokeGrantParams) error
}
type JobHandler
JobHandler handles async job requests from QStash.
type JobHandler struct {
// contains filtered or unexported fields
}
func NewJobHandler
func NewJobHandler(s3 *s3client.Client, queries *db.Queries) *JobHandler
NewJobHandler creates a JobHandler with S3 and DB clients.
func (*JobHandler) DeleteFileFailedJob
func (h *JobHandler) DeleteFileFailedJob(w http.ResponseWriter, r *http.Request)
DeleteFileFailedJob handles POST /jobs/delete-file-failed. Called by QStash when the delete-file job fails after all retries.
func (*JobHandler) DeleteFileJob
func (h *JobHandler) DeleteFileJob(w http.ResponseWriter, r *http.Request)
DeleteFileJob handles POST /jobs/delete-file. It deletes the S3 object and marks the file as deleted in the DB.
type QuizService
QuizService defines the application logic required by the QuizzesHandler. Mirrors StudyGuideService: small, defined at the consumer, and mocked via mockery for handler tests.
type QuizService interface {
CreateQuiz(ctx context.Context, params quizzes.CreateQuizParams) (quizzes.QuizDetail, error)
ListQuizzes(ctx context.Context, params quizzes.ListQuizzesParams) ([]quizzes.QuizListItem, error)
DeleteQuiz(ctx context.Context, params quizzes.DeleteQuizParams) error
UpdateQuiz(ctx context.Context, params quizzes.UpdateQuizParams) (quizzes.QuizDetail, error)
}
type QuizzesHandler
QuizzesHandler manages incoming HTTP requests for the quizzes surface. Embedded in CompositeHandler so a single instance satisfies the generated api.ServerInterface.
type QuizzesHandler struct {
// contains filtered or unexported fields
}
func NewQuizzesHandler
func NewQuizzesHandler(service QuizService) *QuizzesHandler
NewQuizzesHandler creates a new QuizzesHandler backed by the given QuizService.
func (*QuizzesHandler) CreateQuiz
func (h *QuizzesHandler) CreateQuiz(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
CreateQuiz handles POST /study-guides/{study_guide_id}/quizzes. The body is decoded into the openapi-generated request type; the service layer applies the cross-field validation (per-type correct_answer typing, MCQ correct-count invariant) and runs the quiz + questions + options inserts inside one transaction. The creator id is always taken from the JWT -- the openapi schema explicitly forbids accepting one in the request body.
func (*QuizzesHandler) DeleteQuiz
func (h *QuizzesHandler) DeleteQuiz(w http.ResponseWriter, r *http.Request, quizId openapi_types.UUID)
DeleteQuiz handles DELETE /quizzes/{quiz_id} (ASK-102). Creator-only -- the service runs the locked SELECT + creator check + soft-delete in a single transaction. 404 covers both 'never existed' and 'already deleted' (idempotent semantics); 403 covers viewer-is-not-creator. Returns 204 with no body on success.
func (*QuizzesHandler) ListQuizzes
func (h *QuizzesHandler) ListQuizzes(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
ListQuizzes handles GET /study-guides/{study_guide_id}/quizzes (ASK-136). Auth-only -- any authenticated user can list. The service runs the live-guide preflight + the list query; a missing or soft-deleted guide surfaces as 404. The response always emits a non-nil quizzes slice so the JSON shape is `[]` (not null) when the guide has no quizzes.
func (*QuizzesHandler) UpdateQuiz
func (h *QuizzesHandler) UpdateQuiz(w http.ResponseWriter, r *http.Request, quizId openapi_types.UUID)
UpdateQuiz handles PATCH /quizzes/{quiz_id} (ASK-153). Decodes the raw body twice: once into a key-presence map so the service can distinguish 'description absent' from 'description explicitly null' (the openapi-generated CreateQuizRequest type uses *string with omitempty, which loses that distinction at the Go-struct level), once into the typed request body for title + description values. Builds UpdateQuizParams from both passes and delegates to service.UpdateQuiz.
Creator-only authz + 404/403 dispatch lives in the service. 200 on success carries the freshly re-hydrated QuizDetail (same wire shape as CreateQuiz) so the frontend can patch its local state without a follow-up GET.
type SchoolService
SchoolService defines the application logic required by the SchoolsHandler.
type SchoolService interface {
ListSchools(ctx context.Context, params schools.ListSchoolsParams) (schools.ListSchoolsResult, error)
GetSchool(ctx context.Context, params schools.GetSchoolParams) (schools.School, error)
}
type SchoolsHandler
SchoolsHandler manages incoming HTTP requests relating to school operations.
type SchoolsHandler struct {
// contains filtered or unexported fields
}
func NewSchoolsHandler
func NewSchoolsHandler(service SchoolService) *SchoolsHandler
NewSchoolsHandler creates a new SchoolsHandler backed by the given SchoolService.
func (*SchoolsHandler) GetSchool
func (h *SchoolsHandler) GetSchool(w http.ResponseWriter, r *http.Request, schoolID openapi_types.UUID)
GetSchool handles GET /schools/{school_id}, returning the school's full metadata or a 404 envelope if the ID does not match any row.
func (*SchoolsHandler) ListSchools
func (h *SchoolsHandler) ListSchools(w http.ResponseWriter, r *http.Request, params api.ListSchoolsParams)
ListSchools handles GET /schools, returning a paginated list of schools optionally filtered by the q search term.
type StudyGuideHandler
StudyGuideHandler manages incoming HTTP requests for the study-guide surface. Embedded in CompositeHandler so a single instance satisfies the generated api.ServerInterface.
type StudyGuideHandler struct {
// contains filtered or unexported fields
}
func NewStudyGuideHandler
func NewStudyGuideHandler(service StudyGuideService) *StudyGuideHandler
NewStudyGuideHandler creates a new StudyGuideHandler backed by the given StudyGuideService.
func (*StudyGuideHandler) AttachFile
func (h *StudyGuideHandler) AttachFile(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID, fileId openapi_types.UUID)
AttachFile handles POST /study-guides/{id}/files/{file_id}. No body. AttacherID comes from JWT. Service runs ownership + status checks; 201 on success with FileAttachmentResponse, 403/404/409/500 flow through ToHTTPError.
func (*StudyGuideHandler) AttachResource
func (h *StudyGuideHandler) AttachResource(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
AttachResource handles POST /study-guides/{id}/resources. Decodes the body, takes attached_by from JWT, delegates to service. 201 on success with ResourceSummary; 409 on duplicate URL on guide; 404 on missing guide; 400 on validation; 500 on db errors.
func (*StudyGuideHandler) CastStudyGuideVote
func (h *StudyGuideHandler) CastStudyGuideVote(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
CastStudyGuideVote handles POST /study-guides/{id}/votes. Decodes the body, validates that `vote` is one of "up" | "down" at the openapi-validator wrapper, then delegates to the service which upserts and returns the post-mutation vote_score so the UI can patch its local state without a follow-up GET.
func (*StudyGuideHandler) CreateStudyGuide
func (h *StudyGuideHandler) CreateStudyGuide(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID)
CreateStudyGuide handles POST /courses/{course_id}/study-guides. The body is decoded into the openapi-generated request type; the service layer applies tag normalization (trim + lowercase + dedupe) and runs the AssertCourseExists preflight so a missing course surfaces as 404 instead of an FK-violation 500. The creator id is always taken from the JWT -- the openapi schema explicitly forbids accepting one in the request body to avoid privilege-attribution forging.
func (*StudyGuideHandler) DeleteStudyGuide
func (h *StudyGuideHandler) DeleteStudyGuide(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
DeleteStudyGuide handles DELETE /study-guides/{study_guide_id}. Creator-only -- the service runs the locked SELECT + creator check + soft-delete + child-quiz cascade in a single transaction. 404 covers both 'never existed' and 'already deleted' (idempotent semantics); 403 covers viewer-is-not-creator.
func (*StudyGuideHandler) DetachFile
func (h *StudyGuideHandler) DetachFile(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID, fileId openapi_types.UUID)
DetachFile handles DELETE /study-guides/{id}/files/{file_id}. 204 on success. Dual-authz (file owner OR guide creator) lives in the service; 403/404 from the service flow through ToHTTPError.
func (*StudyGuideHandler) DetachResource
func (h *StudyGuideHandler) DetachResource(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID, resourceId openapi_types.UUID)
DetachResource handles DELETE /study-guides/{id}/resources/{resource_id}. 204 on success; 403 when viewer is neither guide creator nor attacher; 404 when guide is missing/deleted or resource isn't attached to this guide.
func (*StudyGuideHandler) GetStudyGuide
func (h *StudyGuideHandler) GetStudyGuide(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
GetStudyGuide handles GET /study-guides/{study_guide_id}. Pure read per the design decision to keep GET idempotent + safe (HTTP semantics); view tracking is intentionally absent and will ship as a separate POST endpoint in a future ticket.
func (*StudyGuideHandler) ListStudyGuides
func (h *StudyGuideHandler) ListStudyGuides(w http.ResponseWriter, r *http.Request, courseId openapi_types.UUID, params api.ListStudyGuidesParams)
ListStudyGuides handles GET /courses/{course_id}/study-guides. Runs the AssertCourseExists preflight first so a missing course surfaces as a tailored 404 'Course not found' (rather than an empty 200 that would be indistinguishable from 'course exists but has no guides'). Malformed cursors are rejected at the handler with a 400 before the service is reached.
func (*StudyGuideHandler) RecommendStudyGuide
func (h *StudyGuideHandler) RecommendStudyGuide(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
RecommendStudyGuide handles POST /study-guides/{id}/recommendations. No request body. Service returns 403 / 404 / 409 directly via typed AppErrors; handler just maps + emits 201 with the recommendation payload on success.
func (*StudyGuideHandler) RemoveStudyGuideRecommendation
func (h *StudyGuideHandler) RemoveStudyGuideRecommendation(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
RemoveStudyGuideRecommendation handles DELETE /study-guides/{id}/recommendations. Same role gate as POST. 204 on success; 403/404 from the service flow through ToHTTPError.
func (*StudyGuideHandler) RemoveStudyGuideVote
func (h *StudyGuideHandler) RemoveStudyGuideVote(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
RemoveStudyGuideVote handles DELETE /study-guides/{id}/votes. 404 covers both "guide missing/deleted" and "no existing vote" -- the service already collapses both cases to apperrors.ErrNotFound.
func (*StudyGuideHandler) UpdateStudyGuide
func (h *StudyGuideHandler) UpdateStudyGuide(w http.ResponseWriter, r *http.Request, studyGuideId openapi_types.UUID)
UpdateStudyGuide handles PATCH /study-guides/{study_guide_id}. Decodes the partial-update body into pointer-typed params (so 'absent' is distinct from 'empty'), pulls viewer id from JWT, delegates to service.UpdateStudyGuide which gates on creator-only + returns the freshly re-hydrated detail. 200 on success; 400/403/404 flow through ToHTTPError unchanged.
type StudyGuideService
StudyGuideService defines the application logic required by the StudyGuideHandler. Mirrors CourseService: small, defined at the consumer, and mocked via mockery for handler tests.
type StudyGuideService interface {
ListStudyGuides(ctx context.Context, params studyguides.ListStudyGuidesParams) (studyguides.ListStudyGuidesResult, error)
AssertCourseExists(ctx context.Context, courseID uuid.UUID) error
GetStudyGuide(ctx context.Context, params studyguides.GetStudyGuideParams) (studyguides.StudyGuideDetail, error)
CreateStudyGuide(ctx context.Context, params studyguides.CreateStudyGuideParams) (studyguides.StudyGuideDetail, error)
UpdateStudyGuide(ctx context.Context, params studyguides.UpdateStudyGuideParams) (studyguides.StudyGuideDetail, error)
DeleteStudyGuide(ctx context.Context, params studyguides.DeleteStudyGuideParams) error
CastVote(ctx context.Context, params studyguides.CastVoteParams) (studyguides.CastVoteResult, error)
RemoveVote(ctx context.Context, params studyguides.RemoveVoteParams) error
RecommendStudyGuide(ctx context.Context, params studyguides.RecommendStudyGuideParams) (studyguides.Recommendation, error)
RemoveRecommendation(ctx context.Context, params studyguides.RemoveRecommendationParams) error
AttachResource(ctx context.Context, params studyguides.AttachResourceParams) (studyguides.Resource, error)
DetachResource(ctx context.Context, params studyguides.DetachResourceParams) error
AttachFile(ctx context.Context, params studyguides.AttachFileParams) (studyguides.FileAttachment, error)
DetachFile(ctx context.Context, params studyguides.DetachFileParams) error
}
Generated by gomarkdoc