Files
sm-bm-plugin/models/material.go
Jakub Zych 418f8240a4 feat: private materials with per-user shares
A material may be private: only its author and the users it is shared
with see it. Every student read (list, detail, course detail and
counters, the checklist linked material, the token twins) goes through
one visibility fragment. Existing materials stay public with no author.

GET/PUT /_bm/api/v1/materials/{id}/access let the author, a material
manager, toggle the flag and pick the users; the first change of an
author-less material makes the caller its author.
2026-11-08 11:52:47 +01:00

75 lines
2.7 KiB
Go

// Code generated by summer make. DO NOT EDIT.
package models
import (
"time"
"git.golem15.com/golem15/summercms/modules/lagoon/attach"
"gorm.io/gorm"
)
// MaterialTypes lists the allowed Material.Type values.
var MaterialTypes = []string{"pdf", "notatka", "link", "inne"}
// MaterialFilesField is the system_files field of a material's attachments
// (attachMany "files").
const MaterialFilesField = "files"
// Material is a study material: a note, a link or uploaded files, optionally
// tied to a course. A material without published_at is a draft and is not
// served by the API. A private material is visible only to its author and to
// the users it is shared with (MaterialShare); a public one to every student.
type Material struct {
ID uint `gorm:"column:id;primaryKey"`
CourseID *uint `gorm:"column:course_id"`
Course *Course `gorm:"foreignKey:CourseID"`
MeetingID *uint `gorm:"column:meeting_id"`
Meeting *Meeting `gorm:"foreignKey:MeetingID"`
Title string `gorm:"column:title"`
Type string `gorm:"column:type"`
Body *string `gorm:"column:body"`
Source *string `gorm:"column:source"`
URL *string `gorm:"column:url"`
PublishedAt *time.Time `gorm:"column:published_at"`
IsPrivate bool `gorm:"column:is_private"`
AuthorUserID *uint `gorm:"column:author_user_id"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
Tags []Tag `gorm:"many2many:jz_bm_material_tag;joinForeignKey:material_id;joinReferences:tag_id"`
}
// TableName is the plugin table.
func (Material) TableName() string { return "jz_bm_materials" }
// MorphName is the attachment_type of the material's system_files rows.
func (Material) MorphName() string { return `Jz\Bm\Models\Material` }
// Fillable lists the columns mass assignment may set.
func (Material) Fillable() []string {
return []string{"course_id", "meeting_id", "title", "type", "body", "source", "url", "published_at", "is_private", "author_user_id"}
}
// Rules are checked by the admin API on every save.
func (Material) Rules() map[string]string {
return map[string]string{
"title": "required|max:255",
"type": "required|in:pdf,notatka,link,inne",
"source": "nullable|max:500",
"url": "nullable|max:2048",
}
}
// AttachRelations declares the attachMany "files". The files are public:
// the student app links them by their storage URL.
func (Material) AttachRelations() []attach.Relation {
return []attach.Relation{{Name: MaterialFilesField, Many: true, Public: true}}
}
// BeforeSave stores NULL for empty optional text.
func (m *Material) BeforeSave(*gorm.DB) error {
blank(&m.Body, &m.Source, &m.URL)
return nil
}