undo.go
package assist
import (
"log"
"github.com/readysite/readysite/website/models"
)
// UndoMutation reverts a mutation to its before state.
func UndoMutation(m *models.Mutation) error {
log.Printf("[ASSIST] UndoMutation: id=%s type=%s action=%s", m.ID, m.EntityType, m.Action)
handler, ok := GetEntityHandler(m.EntityType)
if !ok {
return nil // Unknown entity type, skip
}
switch m.Action {
case ActionCreate:
// Delete the created entity
return handler.Delete(m.EntityID)
case ActionUpdate:
// Restore previous state
if m.BeforeState == "" {
return nil
}
return handler.Restore(m.EntityID, m.BeforeState)
}
return nil
}
// RedoMutation re-applies a mutation using its after state.
func RedoMutation(m *models.Mutation) error {
log.Printf("[ASSIST] RedoMutation: id=%s type=%s action=%s", m.ID, m.EntityType, m.Action)
if m.AfterState == "" {
return nil
}
handler, ok := GetEntityHandler(m.EntityType)
if !ok {
return nil // Unknown entity type, skip
}
switch m.Action {
case ActionCreate:
// Re-create the entity
return handler.Insert(m.AfterState)
case ActionUpdate:
// Re-apply the update
return handler.Restore(m.EntityID, m.AfterState)
}
return nil
}
// UndoConversation undoes the last AI action in a conversation.
func UndoConversation(conv *models.Conversation) error {
if conv == nil {
return nil
}
messages, _ := conv.Messages()
for i := len(messages) - 1; i >= 0; i-- {
if messages[i].Role == RoleAssistant {
mutations, _ := messages[i].Mutations()
for j := len(mutations) - 1; j >= 0; j-- {
m := mutations[j]
if CanUndo(m) {
if err := UndoMutation(m); err == nil {
m.Undone = true
models.Mutations.Update(m)
log.Printf("[ASSIST] UndoConversation: undid mutation=%s", m.ID)
}
}
}
break
}
}
return nil
}
// RedoConversation redoes undone actions in a conversation.
func RedoConversation(conv *models.Conversation) error {
if conv == nil {
return nil
}
messages, _ := conv.Messages()
for i := len(messages) - 1; i >= 0; i-- {
if messages[i].Role == RoleAssistant {
mutations, _ := messages[i].Mutations()
for _, m := range mutations {
if CanRedo(m) {
if err := RedoMutation(m); err == nil {
m.Undone = false
models.Mutations.Update(m)
log.Printf("[ASSIST] RedoConversation: redid mutation=%s", m.ID)
}
}
}
break
}
}
return nil
}