feat: personal pins on materials
A per-user jz_bm_material_pins table and PUT/DELETE /materials/{id}/pin
on the student API and its token twins: 204 for a material the caller
may see, idempotent, 404 otherwise. List rows, course rows and the
detail carry pinned. The plain list lists the caller's pins first
(newest pin first); with q the relevance order stays. A pin writes only
the pins table and never changes the material's revision.
This commit is contained in:
30
updates/20261109130000_create_jz_bm_material_pins.go
Normal file
30
updates/20261109130000_create_jz_bm_material_pins.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package updates
|
||||
|
||||
import (
|
||||
"github.com/go-gormigrate/gormigrate/v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// CreateMaterialPins returns the
|
||||
// 20261109130000_create_jz_bm_material_pins gormigrate entry: a student's
|
||||
// own pins on materials. A pinned material lists first on that student's
|
||||
// Materiały list, and nobody else sees the pin. The rows go with the
|
||||
// material or the golem15.user user.
|
||||
func CreateMaterialPins() *gormigrate.Migration {
|
||||
return &gormigrate.Migration{
|
||||
ID: "20261109130000_create_jz_bm_material_pins",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return execAll(tx, `CREATE TABLE jz_bm_material_pins (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
material_id BIGINT NOT NULL REFERENCES jz_bm_materials (id) ON DELETE CASCADE,
|
||||
user_id INTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
pinned_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (material_id, user_id)
|
||||
);
|
||||
CREATE INDEX jz_bm_material_pins_user_id_index ON jz_bm_material_pins (user_id)`)
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
return tx.Exec("DROP TABLE IF EXISTS jz_bm_material_pins").Error
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user