Files
base/migrations/1790000100_history.go
zeekay dd46954b01 A record's history, written in the record's own transaction
A base collection that turns History on gets a _history row for every
create, update and delete: the collection and record ids, the action, the
writer (an actor field stamped from the save's context) and each changed
field's from and to. The row and the record commit or roll back together.
id, autodate, actor and hidden fields are left out, a value over 4 KiB is
recorded only as changed, and one writer's updates to one record within ten
minutes fold into one entry.

GET /v1/collections/{collection}/records/{id}/history reads it, newest
first, for whoever the record's view rule admits.
2026-10-18 21:25:32 -07:00

44 lines
1.6 KiB
Go

package migrations
import (
"database/sql"
"errors"
"github.com/hanzoai/base/core"
)
// _history holds a row for every create, update and delete of a record in a
// collection that keeps its history (the base collection History option): the
// collection's id, the record's id, what was done, who did it and which fields
// changed. core/record_history.go writes it in the record's own transaction.
//
// Every rule is nil, so only a superuser reads the table directly. A person
// reads one record's history at /v1/collections/{collection}/records/{id}/history,
// which asks the record's own view rule.
func init() {
core.SystemMigrations.Register(func(txApp core.App) error {
if _, err := txApp.FindCollectionByNameOrId(core.CollectionNameHistory); err == nil {
return nil
} else if !errors.Is(err, sql.ErrNoRows) {
return err
}
c := core.NewBaseCollection(core.CollectionNameHistory)
c.System = true
c.Fields.Add(
&core.TextField{Name: "collection", Required: true, Max: 100, System: true},
&core.TextField{Name: "record", Required: true, Max: 100, System: true},
&core.SelectField{
Name: "action", Required: true, MaxSelect: 1, System: true,
Values: []string{core.HistoryCreate, core.HistoryUpdate, core.HistoryDelete},
},
&core.ActorField{Name: "actor", OnCreate: true, System: true},
&core.JSONField{Name: "changes", MaxSize: 8 << 20, System: true},
&core.AutodateField{Name: "created", OnCreate: true, System: true},
)
c.AddIndex("idx_history_record", false, "collection, record, created", "")
return txApp.Save(c)
}, nil)
}