feat: ship loose-offline dbsync (validate, agent push, LWW audit)

Add UUID/FK channel checks, agent whitelist/push APIs, bindings, super-admin LWW audit with rollback, reconcile rate limits, and sync docs. Default customers stay opt-in; company conflict UI is removed.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
whm
2026-07-31 17:54:14 +08:00
parent 632057c857
commit 76cdcd760e
39 changed files with 3302 additions and 199 deletions

View File

@@ -0,0 +1,54 @@
package dbsync
import (
"context"
"path/filepath"
"testing"
"time"
)
func TestRollbackRejectsNonApplied(t *testing.T) {
dir := t.TempDir()
st, err := NewFileStore(filepath.Join(dir, "dbsync"))
if err != nil {
t.Fatal(err)
}
o := LwwOverride{
ID: "ov1",
TenantID: 1,
ChannelID: "ch1",
Table: "orders",
RowPK: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
Outcome: OutcomeKept,
CreatedAt: time.Now().UTC(),
}
if err := st.AddLwwOverride(o); err != nil {
t.Fatal(err)
}
_, err = RollbackLwwOverride(context.Background(), st, "ov1")
if err == nil {
t.Fatal("expected reject kept_target")
}
}
func TestGetLwwOverride(t *testing.T) {
dir := t.TempDir()
st, err := NewFileStore(filepath.Join(dir, "dbsync"))
if err != nil {
t.Fatal(err)
}
o := LwwOverride{
ID: "ov2",
TenantID: 1,
Table: "t",
RowPK: "pk",
Outcome: OutcomeApplied,
}
if err := st.AddLwwOverride(o); err != nil {
t.Fatal(err)
}
got, err := st.GetLwwOverride("ov2")
if err != nil || got.Table != "t" {
t.Fatalf("got=%+v err=%v", got, err)
}
}