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

course

package
v0.27.0 Latest Latest
Warning

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

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

Documentation

Overview

Package course — audit log implementation for academic integrity tracking.

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

View Source
var ErrBudgetExceeded = errors.New("student budget exceeded")

ErrBudgetExceeded is the sentinel error for student budget enforcement.

Functions

This section is empty.

Types

type ArchiveResult added in v0.17.0

type ArchiveResult struct {
	CourseID         string   `json:"course_id"`
	InstancesStopped []string `json:"instances_stopped"`
	SnapshotsCreated []string `json:"snapshots_created"`
	Errors           []string `json:"errors,omitempty"`
}

ArchiveResult is returned by the course archive operation.

type AuditAction added in v0.17.0

type AuditAction string

AuditAction categorises a course audit event.

const (
	AuditActionEnroll           AuditAction = "member.enroll"
	AuditActionUnenroll         AuditAction = "member.unenroll"
	AuditActionBudgetSpend      AuditAction = "budget.spend"
	AuditActionBudgetDistribute AuditAction = "budget.distribute"
	AuditActionTADebug          AuditAction = "ta.debug"
	AuditActionTAReset          AuditAction = "ta.reset"
	AuditActionInstanceLaunch   AuditAction = "instance.launch"
	AuditActionInstanceStop     AuditAction = "instance.stop"
	AuditActionCourseClose      AuditAction = "course.close"
	AuditActionCourseArchive    AuditAction = "course.archive"
	AuditActionTAAccessGrant    AuditAction = "ta.access.grant"
	AuditActionTAAccessRevoke   AuditAction = "ta.access.revoke"
	AuditActionTASSHConnect     AuditAction = "ta.ssh.connect"
	AuditActionTASSHDisconnect  AuditAction = "ta.ssh.disconnect"
	AuditActionMaterialsCreate  AuditAction = "materials.create"
	AuditActionMaterialsMount   AuditAction = "materials.mount"
	AuditActionMaterialsUpload  AuditAction = "materials.upload"
)

type AuditEntry added in v0.17.0

type AuditEntry struct {
	Timestamp time.Time              `json:"timestamp"`
	CourseID  string                 `json:"course_id"`
	Actor     string                 `json:"actor"` // who performed the action
	Action    AuditAction            `json:"action"`
	Target    string                 `json:"target,omitempty"` // student ID, instance name, etc.
	Detail    map[string]interface{} `json:"detail,omitempty"`
}

AuditEntry is one line in the course audit JSONL log.

type AuditLog added in v0.17.0

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

AuditLog manages the append-only JSONL audit log for a single course. The log lives at <stateDir>/<courseID>.jsonl.

func NewAuditLog added in v0.17.0

func NewAuditLog(courseID, stateDir string) *AuditLog

NewAuditLog returns an AuditLog for the given course. stateDir is the directory that holds all course audit files (e.g. ~/.prism/course-audits/).

func (*AuditLog) Append added in v0.17.0

func (l *AuditLog) Append(entry AuditEntry) error

Append writes one entry to the log. It opens the file, writes one JSON line, then closes it immediately — no buffering — so entries are never lost on crash. It is safe for concurrent use.

func (*AuditLog) Query added in v0.17.0

func (l *AuditLog) Query(studentID string, since time.Time, limit int) ([]AuditEntry, error)

Query returns audit entries matching the optional filters. studentID == "" matches all students. since.IsZero() returns all entries. limit <= 0 means no limit. It reads the entire log file into memory; files are bounded by course lifetime.

type BudgetExceededError added in v0.17.0

type BudgetExceededError struct {
	UserID    string
	Spent     float64
	Limit     float64
	Requested float64
}

BudgetExceededError is returned when a launch would exceed the student's allocation.

func (*BudgetExceededError) Error added in v0.17.0

func (e *BudgetExceededError) Error() string

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 CourseMaterialsCreateRequest added in v0.20.0

type CourseMaterialsCreateRequest struct {
	// SizeGB is the advisory size (EFS is elastic; default 50)
	SizeGB int `json:"size_gb,omitempty"`
	// MountPath is where to mount in student instances (default "/mnt/course-materials")
	MountPath string `json:"mount_path,omitempty"`
}

CourseMaterialsCreateRequest is the payload for POST /courses/{id}/materials

type CourseOverview added in v0.17.0

type CourseOverview struct {
	CourseID         string          `json:"course_id"`
	CourseCode       string          `json:"course_code"`
	TotalStudents    int             `json:"total_students"`
	ActiveInstances  int             `json:"active_instances"`
	TotalBudgetSpent float64         `json:"total_budget_spent"`
	Students         []StudentStatus `json:"students"`
	GeneratedAt      time.Time       `json:"generated_at"`
}

CourseOverview is the payload for GET /api/v1/courses/{id}/overview.

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"`

	// DefaultTemplate is the template slug auto-assigned to students on workspace provision.
	DefaultTemplate string `json:"default_template,omitempty"`

	// AutoProvisionOnEnroll creates a workspace for the student automatically upon
	// enrollment when true (requires DefaultTemplate to be set).
	AutoProvisionOnEnroll bool `json:"auto_provision_on_enroll,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) AppendCourseAudit added in v0.17.0

func (m *Manager) AppendCourseAudit(courseID string, entry AuditEntry) error

AppendCourseAudit is the daemon-layer entry point for writing audit events that occur outside of manager methods (e.g. instance launch/stop events).

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) CheckStudentBudget added in v0.17.0

func (m *Manager) CheckStudentBudget(courseID, userID string, estimatedCost float64) error

CheckStudentBudget returns a *BudgetExceededError if the student's accumulated spend plus estimatedCost would exceed their effective budget limit. Returns nil when the course has no budget configured, or when the member is not found (unknown users are not blocked — they will fail enrollment checks elsewhere).

func (*Manager) CheckTemplateAllowed added in v0.20.0

func (m *Manager) CheckTemplateAllowed(courseID, templateSlug string) error

CheckTemplateAllowed returns ErrNotAuthorized if the template is not in this course's whitelist. Returns nil when the course has no whitelist or the course is unknown.

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) GetCourseMaterials added in v0.20.0

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

GetCourseMaterials returns the SharedMaterialsVolume metadata for a course. Returns (nil, nil) when no materials volume has been created yet.

func (*Manager) GetCourseOverview added in v0.17.0

func (m *Manager) GetCourseOverview(ctx context.Context, courseID string, instancesByStudent map[string][]types.Instance) (*CourseOverview, error)

GetCourseOverview returns a TA-facing summary of all students. instancesByStudent maps studentUserID → list of their instances (populated by the daemon handler from state, keyed by instance.ProjectID == courseID).

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) GetProvisioningContext added in v0.17.0

func (m *Manager) GetProvisioningContext(ctx context.Context, courseID, studentID, overrideTemplate string) (*ProvisioningContext, error)

GetProvisioningContext returns the template and budget context needed to launch a workspace for a student on behalf of an instructor/TA. overrideTemplate takes precedence over the course's DefaultTemplate. Returns ErrCourseNotFound, ErrMemberNotFound, or a descriptive error if no template is available.

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) GetUsageReport added in v0.17.0

func (m *Manager) GetUsageReport(ctx context.Context, courseID string,
	instanceHoursByStudent map[string]float64,
	instanceCountByStudent map[string]int,
) (*UsageReport, error)

GetUsageReport aggregates semester-end usage for all students. instanceHoursByStudent and instanceCountByStudent are keyed by student UserID and are populated by the daemon handler from instance state history.

func (*Manager) GrantTAAccess added in v0.20.0

func (m *Manager) GrantTAAccess(ctx context.Context, courseID, taEmail, displayName string) (*types.ClassMember, error)

GrantTAAccess enrolls taEmail as a TA in the course and records a dedicated audit event. Idempotent: if the user is already enrolled as a TA, returns nil without error.

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) ListArchiveEligibleCourses added in v0.17.0

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

ListArchiveEligibleCourses returns courses in "closed" state whose SemesterEnd + GracePeriodDays has passed and that have not yet been archived.

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) ListTAAccess added in v0.20.0

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

ListTAAccess returns all members enrolled with role=ta in the course.

func (*Manager) LogTASSHConnect added in v0.20.0

func (m *Manager) LogTASSHConnect(ctx context.Context, courseID string, entry TAAccessEntry) error

LogTASSHConnect records a TA SSH access initiation in the course audit log.

func (*Manager) MarkCourseArchived added in v0.17.0

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

MarkCourseArchived transitions a course from "closed" to "archived" and saves.

func (*Manager) QueryAuditLog added in v0.17.0

func (m *Manager) QueryAuditLog(courseID, studentID string, since time.Time, limit int) ([]AuditEntry, error)

QueryAuditLog returns audit entries for a course, filtered by optional studentID, since timestamp, and entry limit. Returns nil (no error) when no log file exists yet.

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) RevokeTAAccess added in v0.20.0

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

RevokeTAAccess removes a TA from the course and records the revocation in the audit log. Returns ErrMemberNotFound if the user is not enrolled.

func (*Manager) SetCourseMaterials added in v0.20.0

func (m *Manager) SetCourseMaterials(ctx context.Context, courseID, efsID, mountPath string, sizeGB int) error

SetCourseMaterials persists the shared EFS metadata on the course record. Called by the daemon handler after the AWS EFS filesystem has been created.

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 ProvisioningContext added in v0.17.0

type ProvisioningContext struct {
	CourseID     string
	StudentID    string
	StudentEmail string
	Template     string
	BudgetLimit  float64
	BudgetSpent  float64
}

ProvisioningContext carries what the daemon needs to launch a workspace on behalf of a student.

type RosterFormat added in v0.17.0

type RosterFormat string

RosterFormat identifies the source LMS format of an uploaded CSV file.

const (
	// RosterFormatPrism is the native Prism CSV format (email,display_name,role,budget).
	RosterFormatPrism RosterFormat = "prism"
	// RosterFormatCanvas is the Canvas LMS student roster export format.
	RosterFormatCanvas RosterFormat = "canvas"
	// RosterFormatBlackboard is the Blackboard Learn user list export format.
	RosterFormatBlackboard RosterFormat = "blackboard"
)

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 ParseBlackboardCSV added in v0.17.0

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

ParseBlackboardCSV parses a Blackboard Learn user list CSV export into RosterRows. Expected header columns: Last Name, First Name, Username (user ID), Email.

func ParseCanvasCSV added in v0.17.0

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

ParseCanvasCSV parses a Canvas LMS student roster CSV export into RosterRows. Expected header columns (case-insensitive): Student (display name), SIS Login ID (user ID), Email Address (email). Rows where the Student column equals "Points Possible" are skipped.

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 SharedMaterialsVolume added in v0.20.0

type SharedMaterialsVolume struct {
	// CourseID links back to the owning course
	CourseID string `json:"course_id"`
	// EFSID is the AWS EFS filesystem ID
	EFSID string `json:"efs_id"`
	// SizeGB is the advisory provisioned size in GB (EFS is elastic)
	SizeGB int `json:"size_gb"`
	// MountPath is where the EFS is mounted inside student instances
	MountPath string `json:"mount_path"`
	// State is "creating" | "available" | "error"
	State string `json:"state"`
	// CreatedAt is when the volume was created
	CreatedAt time.Time `json:"created_at"`
	// MountedInstanceCount is how many student instances currently have it mounted
	MountedInstanceCount int `json:"mounted_instance_count"`
}

SharedMaterialsVolume describes the EFS volume used for shared course materials.

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 StudentStatus added in v0.17.0

type StudentStatus struct {
	UserID       string           `json:"user_id"`
	Email        string           `json:"email"`
	DisplayName  string           `json:"display_name,omitempty"`
	Instances    []types.Instance `json:"instances"`
	BudgetSpent  float64          `json:"budget_spent"`
	BudgetLimit  float64          `json:"budget_limit"`
	BudgetStatus string           `json:"budget_status"` // "ok" | "warning" (>80%) | "exceeded"
	LastActive   *time.Time       `json:"last_active,omitempty"`
}

StudentStatus summarises a single student's current state for the TA dashboard.

type StudentUsageRecord added in v0.17.0

type StudentUsageRecord struct {
	UserID        string  `json:"user_id"`
	Email         string  `json:"email"`
	DisplayName   string  `json:"display_name,omitempty"`
	TotalSpent    float64 `json:"total_spent"`
	BudgetLimit   float64 `json:"budget_limit"`
	InstanceHours float64 `json:"instance_hours"`
	InstanceCount int     `json:"instance_count"`
}

StudentUsageRecord is one row in the semester usage report.

type TAAccessEntry added in v0.20.0

type TAAccessEntry struct {
	// TAID is the user ID (or email) of the TA who connected
	TAID string `json:"ta_id"`
	// TAEmail is the TA's email for display purposes
	TAEmail string `json:"ta_email,omitempty"`
	// StudentID is the user ID (or email) of the student whose instance was accessed
	StudentID string `json:"student_id"`
	// StudentEmail is the student's email for display purposes
	StudentEmail string `json:"student_email,omitempty"`
	// Reason is a required explanation provided at access time
	Reason string `json:"reason"`
	// ConnectedAt is when the SSH session was initiated
	ConnectedAt time.Time `json:"connected_at"`
	// InstanceID is the AWS instance ID that was accessed
	InstanceID string `json:"instance_id,omitempty"`
	// PublicIP is the public IP address of the student's instance
	PublicIP string `json:"public_ip,omitempty"`
}

TAAccessEntry records a single TA SSH access session for the audit trail.

type TAAccessGrantRequest added in v0.20.0

type TAAccessGrantRequest struct {
	// Email is the TA's email address to grant access
	Email string `json:"email"`
	// DisplayName is the TA's display name (optional)
	DisplayName string `json:"display_name,omitempty"`
}

TAAccessGrantRequest is the payload for POST /courses/{id}/ta-access

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 TASSHConnectRequest added in v0.20.0

type TASSHConnectRequest struct {
	// StudentID is the user ID or email of the student to connect to
	StudentID string `json:"student_id"`
	// Reason is a mandatory explanation for the audit log
	Reason string `json:"reason"`
}

TASSHConnectRequest is the payload for POST /courses/{id}/ta-access/connect

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"`

	// DefaultTemplate updates the default workspace template
	DefaultTemplate *string `json:"default_template,omitempty"`

	// AutoProvisionOnEnroll updates the auto-provision setting
	AutoProvisionOnEnroll *bool `json:"auto_provision_on_enroll,omitempty"`
}

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

type UsageReport added in v0.17.0

type UsageReport struct {
	CourseID    string               `json:"course_id"`
	CourseCode  string               `json:"course_code"`
	Semester    string               `json:"semester"`
	TotalSpent  float64              `json:"total_spent"`
	TotalBudget float64              `json:"total_budget"`
	Students    []StudentUsageRecord `json:"students"`
	GeneratedAt time.Time            `json:"generated_at"`
}

UsageReport is the payload for GET /api/v1/courses/{id}/report.

type WorkspaceResetResult added in v0.20.0

type WorkspaceResetResult struct {
	// StudentID identifies whose workspace was reset
	StudentID string `json:"student_id"`
	// BackupSnapshotID is the snapshot ID created before reset (empty if --no-backup)
	BackupSnapshotID string `json:"backup_snapshot_id,omitempty"`
	// BackupDownloadURL is a pre-signed URL for the student to retrieve their backed-up work
	BackupDownloadURL string `json:"backup_download_url,omitempty"`
	// BackupExpiresAt is when the download URL expires (7 days by default)
	BackupExpiresAt *time.Time `json:"backup_expires_at,omitempty"`
	// Status is "reset_scheduled" | "reset_complete"
	Status string `json:"status"`
}

WorkspaceResetResult is returned by the reset endpoint.

Jump to

Keyboard shortcuts

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