material_manage_system/internal/repository/organization_audit.go

74 lines
2.4 KiB
Go

package repository
import (
"database/sql"
"fmt"
"github.com/wmms/wmms/internal/model"
"github.com/wmms/wmms/pkg/database"
)
type OrganizationAuditRepository struct{}
func NewOrganizationAuditRepository() *OrganizationAuditRepository {
return &OrganizationAuditRepository{}
}
type auditExecutor interface {
Exec(string, ...interface{}) (sql.Result, error)
}
func writeOrganizationAudit(q auditExecutor, entry *model.OrganizationAuditLog) error {
if entry == nil {
return fmt.Errorf("audit entry is required")
}
result, err := q.Exec(`INSERT INTO organization_audit_logs(actor_user_id,organization_id,action,old_value,new_value) VALUES(?,?,?,?,?)`, entry.ActorUserID, entry.OrganizationID, entry.Action, nullableAuditJSON(entry.OldValue), nullableAuditJSON(entry.NewValue))
if err != nil {
return err
}
entry.ID, err = result.LastInsertId()
return err
}
func nullableAuditJSON(value []byte) interface{} {
if len(value) == 0 {
return nil
}
return string(value)
}
func (r *OrganizationAuditRepository) Create(entry *model.OrganizationAuditLog) error {
return writeOrganizationAudit(database.DB, entry)
}
// The caller owns commit/rollback; audit errors must roll back its mutation.
func (r *OrganizationAuditRepository) CreateTx(tx *sql.Tx, entry *model.OrganizationAuditLog) error {
if tx == nil {
return fmt.Errorf("audit transaction is required")
}
return writeOrganizationAudit(tx, entry)
}
func (r *OrganizationAuditRepository) ListByOrganization(organizationID int64, limit, offset int) ([]model.OrganizationAuditLog, error) {
if organizationID <= 0 || limit <= 0 || limit > 500 || offset < 0 {
return nil, fmt.Errorf("valid organization and pagination are required")
}
rows, err := database.DB.Query(`SELECT id,actor_user_id,organization_id,action,old_value,new_value,created_at FROM organization_audit_logs WHERE organization_id=? ORDER BY id DESC LIMIT ? OFFSET ?`, organizationID, limit, offset)
if err != nil {
return nil, err
}
defer rows.Close()
entries := make([]model.OrganizationAuditLog, 0)
for rows.Next() {
var item model.OrganizationAuditLog
var org sql.NullInt64
var oldValue, newValue []byte
if err := rows.Scan(&item.ID, &item.ActorUserID, &org, &item.Action, &oldValue, &newValue, &item.CreatedAt); err != nil {
return nil, err
}
if org.Valid {
item.OrganizationID = &org.Int64
}
item.OldValue = oldValue
item.NewValue = newValue
entries = append(entries, item)
}
return entries, rows.Err()
}