Revision history: change sets + revisions + revert — the undo substrate (#48) (#61)
Build image / build-and-push (push) Successful in 5s
Build image / build-and-push (push) Successful in 5s
Co-authored-by: Steve Dudenhoeffer <[email protected]>
This commit was merged in pull request #61.
This commit is contained in:
@@ -93,6 +93,97 @@ const (
|
||||
CategoryFruit = "fruit"
|
||||
CategoryTreeShrub = "tree_shrub"
|
||||
CategoryCover = "cover"
|
||||
|
||||
// Where a change set came from. SourceAgent is what the history UI badges
|
||||
// differently, so an autonomous edit is never mistaken for a hand edit.
|
||||
SourceUI = "ui"
|
||||
SourceAgent = "agent"
|
||||
SourceAPI = "api"
|
||||
|
||||
// The entity types a revision can snapshot. Garden covers metadata edits
|
||||
// only — garden creation and deletion are deliberately not revertible.
|
||||
EntityGarden = "garden"
|
||||
EntityObject = "object"
|
||||
EntityPlanting = "planting"
|
||||
|
||||
OpCreate = "create"
|
||||
OpUpdate = "update"
|
||||
OpDelete = "delete"
|
||||
)
|
||||
|
||||
// ChangeSet groups the revisions produced by one logical operation — the unit of
|
||||
// undo. A revert is itself a change set (RevertsID names its target), so history
|
||||
// is append-only and an undo can be undone.
|
||||
type ChangeSet struct {
|
||||
ID int64 `json:"id"`
|
||||
GardenID int64 `json:"gardenId"`
|
||||
ActorID int64 `json:"actorId"`
|
||||
Source string `json:"source"`
|
||||
Summary string `json:"summary"`
|
||||
AgentRunID *string `json:"agentRunId,omitempty"`
|
||||
RevertsID *int64 `json:"revertsId,omitempty"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
|
||||
// Computed by the service for the history list, never persisted.
|
||||
ActorName string `json:"actorName,omitempty"`
|
||||
// RevertedByID is the change set that reverted this one, if any — what lets
|
||||
// the list mark an entry as already undone.
|
||||
RevertedByID *int64 `json:"revertedById,omitempty"`
|
||||
// Counts tallies the revisions by (entity type, op) so the list can say
|
||||
// "3 plops added, 1 bed moved" without loading every revision.
|
||||
Counts []ChangeCount `json:"counts,omitempty"`
|
||||
// Revisions is populated only when a single change set is loaded in full.
|
||||
Revisions []Revision `json:"revisions,omitempty"`
|
||||
}
|
||||
|
||||
// ChangeCount is one (entity type, op) tally within a change set.
|
||||
type ChangeCount struct {
|
||||
EntityType string `json:"entityType"`
|
||||
Op string `json:"op"`
|
||||
N int `json:"n"`
|
||||
}
|
||||
|
||||
// Revision is one row-level change within a change set. Before/After are JSON
|
||||
// row snapshots (nil for create/delete respectively) and include the row's
|
||||
// version, which the revert guard compares against.
|
||||
type Revision struct {
|
||||
ID int64 `json:"id"`
|
||||
ChangeSetID int64 `json:"changeSetId"`
|
||||
Seq int64 `json:"seq"`
|
||||
EntityType string `json:"entityType"`
|
||||
EntityID int64 `json:"entityId"`
|
||||
Op string `json:"op"`
|
||||
Before *string `json:"before,omitempty"`
|
||||
After *string `json:"after,omitempty"`
|
||||
}
|
||||
|
||||
// RevertConflict reports one entity a revert deliberately left alone, because
|
||||
// reverting it would have discarded a change made after the change set being
|
||||
// reverted. The rest of the change set still reverts.
|
||||
type RevertConflict struct {
|
||||
EntityType string `json:"entityType"`
|
||||
EntityID int64 `json:"entityId"`
|
||||
// Reason is one of the ConflictReason* values below.
|
||||
Reason string `json:"reason"`
|
||||
// Name is a human label for the entity where one exists (an object's name),
|
||||
// so the UI can say "the north bed" rather than "object 41".
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// Why a revert skipped an entity.
|
||||
const (
|
||||
// ConflictChanged: the row was edited after the change set being reverted, so
|
||||
// restoring the old snapshot would silently discard that edit.
|
||||
ConflictChanged = "changed"
|
||||
// ConflictMissing: the row is gone, so there is nothing to revert to.
|
||||
ConflictMissing = "missing"
|
||||
// ConflictExists: a row with that id exists again, so restoring the deleted
|
||||
// snapshot would overwrite it.
|
||||
ConflictExists = "exists"
|
||||
// ConflictUnsupported: this kind of change has no inverse the revert knows how
|
||||
// to apply. Reported rather than silently skipped, so a change recorded by a
|
||||
// later feature that revert wasn't taught about is visible instead of quiet.
|
||||
ConflictUnsupported = "unsupported"
|
||||
)
|
||||
|
||||
// User is a pansy account. It may have a local password, OIDC identity, or both.
|
||||
|
||||
Reference in New Issue
Block a user