From 3c7e9d1d56109040cf3f9524b19934d6bde0e1e6 Mon Sep 17 00:00:00 2001 From: mirivlad Date: Tue, 2 Jun 2026 08:02:03 +0800 Subject: [PATCH] fix(sync): add ClientSequence and LastSeenServerSeq to Op struct and Push - Add ClientSequence and LastSeenServerSeq fields to sync.Op struct - Fix Client.Push() to copy these fields to PushOp - Add GetDeviceID() method to sync.Service --- .gitignore | 1 + internal/core/sync/client.go | 27 +++++++++++++++++++++------ internal/core/sync/sync.go | 22 ++++++++++++---------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index c8d0d30..75b9ac4 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ frontend/bindings/ /verstak-gui /verstak-cli /verstak-server +/verstak # Vault data .verstak/ diff --git a/internal/core/sync/client.go b/internal/core/sync/client.go index 4326ed0..c563389 100644 --- a/internal/core/sync/client.go +++ b/internal/core/sync/client.go @@ -130,6 +130,19 @@ func (c *Client) Login(username, password string) (token string, err error) { return resp.Token, nil } +// TestAuth checks credentials without creating a device. +func (c *Client) TestAuth(serverURL, username, password string) error { + body := map[string]string{"username": username, "password": password} + savedURL := c.ServerURL + savedKey := c.APIKey + c.ServerURL = serverURL + c.APIKey = "" + err := c.post("/api/auth/test", body, nil) + c.ServerURL = savedURL + c.APIKey = savedKey + return err +} + // PushRequest is the payload for POST /sync/push. type PushRequest struct { DeviceID string `json:"device_id"` @@ -161,12 +174,14 @@ func (c *Client) Push(ops []Op) (*PushResponse, error) { pushOps := make([]PushOp, len(ops)) for i, op := range ops { pushOps[i] = PushOp{ - OpID: op.OpID, - EntityType: op.EntityType, - EntityID: op.EntityID, - OpType: op.OpType, - PayloadJSON: op.PayloadJSON, - CreatedAt: op.CreatedAt, + OpID: op.OpID, + EntityType: op.EntityType, + EntityID: op.EntityID, + OpType: op.OpType, + PayloadJSON: op.PayloadJSON, + ClientSequence: op.ClientSequence, + LastSeenServerSeq: op.LastSeenServerSeq, + CreatedAt: op.CreatedAt, } } req := PushRequest{DeviceID: c.DeviceID, Ops: pushOps} diff --git a/internal/core/sync/sync.go b/internal/core/sync/sync.go index f22b4f7..ef6ab84 100644 --- a/internal/core/sync/sync.go +++ b/internal/core/sync/sync.go @@ -30,16 +30,18 @@ const ( // Op represents a sync operation. type Op struct { - ID string `json:"id"` - OpID string `json:"op_id"` - ServerSequence int `json:"server_sequence,omitempty"` - DeviceID string `json:"device_id,omitempty"` - EntityType string `json:"entity_type"` - EntityID string `json:"entity_id"` - OpType string `json:"op_type"` - PayloadJSON string `json:"payload_json"` - CreatedAt string `json:"created_at"` - PushedAt *string `json:"pushed_at,omitempty"` + ID string `json:"id"` + OpID string `json:"op_id"` + ServerSequence int `json:"server_sequence,omitempty"` + DeviceID string `json:"device_id,omitempty"` + EntityType string `json:"entity_type"` + EntityID string `json:"entity_id"` + OpType string `json:"op_type"` + PayloadJSON string `json:"payload_json"` + CreatedAt string `json:"created_at"` + PushedAt *string `json:"pushed_at,omitempty"` + ClientSequence int `json:"client_sequence,omitempty"` + LastSeenServerSeq int `json:"last_seen_server_seq,omitempty"` } // Service records and manages sync operations.