feat(05-01): add Paginate envelope and RegisterJoinTable

- Page/PageMeta emit {data, meta} with no links key
- RegisterJoinTable fails loud on nil db; document pivot-write contract
This commit is contained in:
Jakub Zych
2026-09-18 18:47:42 +02:00
parent 969a5f522a
commit 52638fb4e3
4 changed files with 126 additions and 0 deletions

28
lagoon/relations.go Normal file
View File

@@ -0,0 +1,28 @@
package lagoon
import (
"fmt"
"gorm.io/gorm"
)
// RegisterJoinTable wraps db.SetupJoinTable so a nil db returns an error
// instead of panicking.
//
// Pivot-write contract: pivot tables with business columns (sort_order,
// role, granted_at, granted_by) are never written through
// db.Model(&owner).Association(field).Append/Replace(...). GORM's
// Association Mode has no documented path to set those columns. Writes go
// through an explicit delete-then-bulk-insert (or ON CONFLICT DO UPDATE)
// against the join table directly, in the same transaction as the parent
// save. Reads use Preload(field) plus .Order(...) on the pivot's own
// columns once RegisterJoinTable has run.
func RegisterJoinTable(db *gorm.DB, owner any, field string, joinModel any) error {
if db == nil {
return fmt.Errorf("lagoon: register join table: db is nil")
}
if err := db.SetupJoinTable(owner, field, joinModel); err != nil {
return fmt.Errorf("lagoon: register join table: %w", err)
}
return nil
}