Help us shape the future of Go! Take the 2026 Go Developer Survey

course

package
v0.14.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 24, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package course provides course and education management functionality for Prism.

This package implements course-based resource organization, template policy enforcement, and per-student budget tracking that enable instructors to manage classroom computing environments at scale.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrDuplicateCourse is returned when a course with the same code and semester already exists
	ErrDuplicateCourse = errors.New("course with this code and semester already exists")

	// ErrCourseNotFound is returned when the requested course does not exist
	ErrCourseNotFound = errors.New("course not found")

	// ErrMemberNotFound is returned when the requested member is not enrolled
	ErrMemberNotFound = errors.New("member not found")

	// ErrAlreadyEnrolled is returned when a user is already enrolled in the course
	ErrAlreadyEnrolled = errors.New("user is already enrolled in this course")

	// ErrNotAuthorized is returned when the caller lacks required permissions
	ErrNotAuthorized = errors.New("not authorized for this operation")

	// ErrCourseClosed is returned when an operation is attempted on a closed course
	ErrCourseClosed = errors.New("course is closed")
)

Error constants

Functions

This section is empty.

Types

type BulkEnrollRequest

type BulkEnrollRequest struct {
	// Members is the list of members to enroll
	Members []EnrollRequest `json:"members"`

	// DefaultRole is applied to any member with no explicit role (default: student)
	DefaultRole types.ClassRole `json:"default_role,omitempty"`

	// SendInvites sends invitation emails to each enrolled member when true
	SendInvites bool `json:"send_invites,omitempty"`
}

BulkEnrollRequest represents a request to enroll multiple members at once

type CourseBudgetSummary

type CourseBudgetSummary struct {
	// TotalBudget is the aggregate course cap in USD
	TotalBudget float64 `json:"total_budget"`

	// TotalSpent is the total spend across all students
	TotalSpent float64 `json:"total_spent"`

	// PerStudentDefault is the default allocation per student
	PerStudentDefault float64 `json:"per_student_default"`

	// Students lists per-student budget details
	Students []StudentBudgetInfo `json:"students"`
}

CourseBudgetSummary summarizes budget usage across a course

type CourseFilter

type CourseFilter struct {
	// Owner filters to courses owned by this user ID
	Owner string `json:"owner,omitempty"`

	// Status filters by course lifecycle state
	Status *types.CourseStatus `json:"status,omitempty"`

	// Semester filters by semester identifier (exact match)
	Semester string `json:"semester,omitempty"`

	// Department filters by department
	Department string `json:"department,omitempty"`

	// Tags filters to courses matching all specified tags (AND logic)
	Tags map[string]string `json:"tags,omitempty"`
}

CourseFilter defines criteria for filtering course lists

func (*CourseFilter) Matches

func (f *CourseFilter) Matches(c *types.Course) bool

Matches returns true if the course satisfies all filter criteria

type CreateCourseRequest

type CreateCourseRequest struct {
	// Code is the institutional course code (required, e.g. "CS229")
	Code string `json:"code"`

	// Title is the full course title (required)
	Title string `json:"title"`

	// Department is the offering department (optional)
	Department string `json:"department,omitempty"`

	// Semester identifies the offering period (required, e.g. "Fall 2024")
	Semester string `json:"semester"`

	// SemesterStart is when the course begins (required)
	SemesterStart time.Time `json:"semester_start"`

	// SemesterEnd is when the course ends (required)
	SemesterEnd time.Time `json:"semester_end"`

	// GracePeriodDays is days after end before auto-cleanup (default 7)
	GracePeriodDays int `json:"grace_period_days,omitempty"`

	// Owner is the primary instructor's user ID (required)
	Owner string `json:"owner"`

	// ApprovedTemplates is the initial template whitelist (empty = all allowed)
	ApprovedTemplates []string `json:"approved_templates,omitempty"`

	// PerStudentBudget is the default per-student budget in USD (0 = unlimited)
	PerStudentBudget float64 `json:"per_student_budget,omitempty"`

	// TotalBudget is the aggregate course cap in USD (0 = unlimited)
	TotalBudget float64 `json:"total_budget,omitempty"`

	// Tags are optional metadata
	Tags map[string]string `json:"tags,omitempty"`
}

CreateCourseRequest represents a request to create a new course

func (*CreateCourseRequest) Validate

func (r *CreateCourseRequest) Validate() error

Validate validates the create course request

type EnrollRequest

type EnrollRequest struct {
	// UserID is the member's user identifier (required unless Email is provided)
	UserID string `json:"user_id,omitempty"`

	// Email is the member's email address (used as identifier and for invitations)
	Email string `json:"email,omitempty"`

	// DisplayName is the member's human-readable name
	DisplayName string `json:"display_name,omitempty"`

	// Role is the member's role in the course (default: student)
	Role types.ClassRole `json:"role,omitempty"`

	// BudgetLimit overrides the course default for this member (0 = use course default)
	BudgetLimit float64 `json:"budget_limit,omitempty"`
}

EnrollRequest represents a request to enroll a single member

func (*EnrollRequest) Validate

func (r *EnrollRequest) Validate() error

Validate validates the enroll request

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager handles course lifecycle, member enrollment, template policies, and budgets

func NewManager

func NewManager() (*Manager, error)

NewManager creates a new course manager

func (*Manager) AddApprovedTemplate

func (m *Manager) AddApprovedTemplate(ctx context.Context, courseID, templateSlug string) error

AddApprovedTemplate adds a template slug to the course whitelist

func (*Manager) BulkEnroll

func (m *Manager) BulkEnroll(ctx context.Context, courseID string, req *BulkEnrollRequest) (int, []error, error)

BulkEnroll adds multiple members in one operation. Partial failures skip the bad row and continue; row errors are returned alongside the count.

func (*Manager) CheckAndCloseExpiredCourses

func (m *Manager) CheckAndCloseExpiredCourses(ctx context.Context) ([]string, error)

CheckAndCloseExpiredCourses transitions courses past their end date + grace period to "closed"

func (*Manager) CloseCourse

func (m *Manager) CloseCourse(ctx context.Context, courseID string) error

CloseCourse transitions a course to the "closed" state

func (*Manager) CreateCourse

func (m *Manager) CreateCourse(ctx context.Context, req *CreateCourseRequest) (*types.Course, error)

CreateCourse creates a new course

func (*Manager) DeleteCourse

func (m *Manager) DeleteCourse(ctx context.Context, courseID string) error

DeleteCourse permanently removes a course record

func (*Manager) DistributeBudget

func (m *Manager) DistributeBudget(ctx context.Context, courseID string, amountPerStudent float64) error

DistributeBudget sets per-student budget allocations for all currently enrolled students

func (*Manager) EnrollMember

func (m *Manager) EnrollMember(ctx context.Context, courseID string, req *EnrollRequest) (*types.ClassMember, error)

EnrollMember adds a single member to the course

func (*Manager) GetBudgetSummary

func (m *Manager) GetBudgetSummary(ctx context.Context, courseID string) (*CourseBudgetSummary, error)

GetBudgetSummary returns budget usage across the entire course

func (*Manager) GetCourse

func (m *Manager) GetCourse(ctx context.Context, courseID string) (*types.Course, error)

GetCourse retrieves a course by ID

func (*Manager) GetCourseByCode

func (m *Manager) GetCourseByCode(ctx context.Context, code, semester string) (*types.Course, error)

GetCourseByCode retrieves a course by its code and semester

func (*Manager) GetMember

func (m *Manager) GetMember(ctx context.Context, courseID, userID string) (*types.ClassMember, error)

GetMember returns a single member by user ID or email

func (*Manager) GetStudentDebugInfo

func (m *Manager) GetStudentDebugInfo(ctx context.Context, courseID, taID, studentID string) (*TADebugInfo, error)

GetStudentDebugInfo returns read-only debug information for a student in a course. The caller (taID) must be a TA or instructor in the course.

func (*Manager) ImportRosterCSV

func (m *Manager) ImportRosterCSV(ctx context.Context, courseID string, rows []RosterRow, sendInvites bool) (int, []error, error)

ImportRosterCSV parses a CSV reader and bulk-enrolls students. CSV columns: email, display_name, budget (optional), role (optional) Header row is required. Malformed rows are skipped; errors returned per row.

func (*Manager) IsTemplateApproved

func (m *Manager) IsTemplateApproved(courseID, templateSlug string) bool

IsTemplateApproved returns true if the template is allowed for this course. Returns true when the course has no whitelist (empty ApprovedTemplates = unrestricted).

func (*Manager) ListCourses

func (m *Manager) ListCourses(ctx context.Context, filter *CourseFilter) ([]*types.Course, error)

ListCourses retrieves all courses matching the optional filter

func (*Manager) ListMembers

func (m *Manager) ListMembers(ctx context.Context, courseID string, role *types.ClassRole) ([]types.ClassMember, error)

ListMembers returns enrolled members, optionally filtered by role

func (*Manager) RecordSpend

func (m *Manager) RecordSpend(ctx context.Context, courseID, userID string, amount float64) error

RecordSpend increments the spend counter for a member

func (*Manager) RemoveApprovedTemplate

func (m *Manager) RemoveApprovedTemplate(ctx context.Context, courseID, templateSlug string) error

RemoveApprovedTemplate removes a template slug from the course whitelist

func (*Manager) ResetStudentInstance

func (m *Manager) ResetStudentInstance(ctx context.Context, courseID, taID string, req *TAResetRequest) error

ResetStudentInstance records a TA reset request in the course audit trail. The actual AWS snapshot + re-provision is handled by the daemon handler (requires awsManager).

func (*Manager) UnenrollMember

func (m *Manager) UnenrollMember(ctx context.Context, courseID, userID string) error

UnenrollMember removes a member from the course

func (*Manager) UpdateCourse

func (m *Manager) UpdateCourse(ctx context.Context, courseID string, req *UpdateCourseRequest) (*types.Course, error)

UpdateCourse applies a partial update to an existing course

func (*Manager) UpdateMember

func (m *Manager) UpdateMember(ctx context.Context, courseID, userID string, role types.ClassRole, budgetLimit float64) error

UpdateMember changes a member's role or budget limit

type RosterRow

type RosterRow struct {
	// Email is the student's email address (required)
	Email string

	// DisplayName is the student's name
	DisplayName string

	// Budget is the per-student budget override in USD (0 = use course default)
	Budget float64

	// Role is the member role (optional; defaults to "student")
	Role string
}

RosterRow maps a single row from a CSV roster file

func ParseRosterCSV

func ParseRosterCSV(data []byte) ([]RosterRow, error)

ParseRosterCSV parses CSV bytes into RosterRow slice. Expected columns (with header): email, display_name, budget, role

type StudentBudgetInfo

type StudentBudgetInfo struct {
	// UserID is the student's identifier
	UserID string `json:"user_id"`

	// DisplayName is the student's name
	DisplayName string `json:"display_name,omitempty"`

	// Email is the student's email
	Email string `json:"email,omitempty"`

	// BudgetLimit is the student's spending cap
	BudgetLimit float64 `json:"budget_limit"`

	// BudgetSpent is how much has been consumed
	BudgetSpent float64 `json:"budget_spent"`

	// Remaining is BudgetLimit - BudgetSpent (negative if over budget)
	Remaining float64 `json:"remaining"`
}

StudentBudgetInfo holds per-student budget details

type TADebugInfo

type TADebugInfo struct {
	// CourseID is the course this debug info belongs to
	CourseID string `json:"course_id"`

	// StudentID is the user ID of the student
	StudentID string `json:"student_id"`

	// StudentEmail is the student's email
	StudentEmail string `json:"student_email,omitempty"`

	// Instances lists the student's current instances
	Instances []types.Instance `json:"instances"`

	// RecentEvents lists the last N instance state changes and errors
	RecentEvents []string `json:"recent_events,omitempty"`

	// BudgetSpent is how much of the student's budget has been consumed
	BudgetSpent float64 `json:"budget_spent"`

	// BudgetLimit is the student's spending cap (0 = unlimited)
	BudgetLimit float64 `json:"budget_limit"`
}

TADebugInfo is the read-only view a TA gets of a student's environment

type TAResetRequest

type TAResetRequest struct {
	// StudentID is the user ID (or email) of the student whose instance to reset
	StudentID string `json:"student_id"`

	// Reason is a required explanation for the audit log
	Reason string `json:"reason"`

	// BackupRetentionDays is how long to keep the pre-reset snapshot (default 7)
	BackupRetentionDays int `json:"backup_retention_days,omitempty"`
}

TAResetRequest represents a request to reset a student's instance

type UpdateCourseRequest

type UpdateCourseRequest struct {
	// Title updates the course title
	Title *string `json:"title,omitempty"`

	// Department updates the department
	Department *string `json:"department,omitempty"`

	// SemesterEnd extends or shortens the semester end date
	SemesterEnd *time.Time `json:"semester_end,omitempty"`

	// GracePeriodDays updates the cleanup grace period
	GracePeriodDays *int `json:"grace_period_days,omitempty"`

	// ApprovedTemplates replaces the template whitelist (nil = no change, empty slice = clear all)
	ApprovedTemplates []string `json:"approved_templates,omitempty"`

	// PerStudentBudget updates the default per-student budget
	PerStudentBudget *float64 `json:"per_student_budget,omitempty"`

	// TotalBudget updates the aggregate course budget cap
	TotalBudget *float64 `json:"total_budget,omitempty"`

	// Tags replaces the tag set
	Tags map[string]string `json:"tags,omitempty"`

	// Status manually sets the course status
	Status *types.CourseStatus `json:"status,omitempty"`
}

UpdateCourseRequest represents a request to update an existing course. All fields are optional pointers; nil means "do not change".

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL