package sync import ( "database/sql" "encoding/json" "net/http" "strconv" "time" mw "github.com/weltonmoura/initpage/internal/middleware" ) type Sync struct { DB *sql.DB } type syncPayload struct { Data json.RawMessage `json:"data"` Version int `json:"version"` } func (s *Sync) Get(w http.ResponseWriter, r *http.Request) { uid := mw.GetUserID(r.Context()) if uid == "" { w.WriteHeader(http.StatusUnauthorized) return } var data string var version int var updatedAt string _ = s.DB.QueryRow(`SELECT data, version, updated_at FROM user_sync WHERE user_id=?`, uid).Scan(&data, &version, &updatedAt) if data == "" { w.Header().Set("Content-Type", "application/json") w.Write([]byte(`{"data":null,"version":0}`)) return } w.Header().Set("Content-Type", "application/json") w.Write([]byte(`{"data":` + data + `,"version":` + strconv.Itoa(version) + `}`)) } func (s *Sync) Put(w http.ResponseWriter, r *http.Request) { uid := mw.GetUserID(r.Context()) if uid == "" { w.WriteHeader(http.StatusUnauthorized) return } var p syncPayload if err := json.NewDecoder(r.Body).Decode(&p); err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(`{"error":"json inválido"}`)) return } if len(p.Data) > 256*1024 { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(`{"error":"dados muito grandes"}`)) return } // valida JSON básico if !json.Valid(p.Data) { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(`{"error":"json inválido"}`)) return } _, err := s.DB.Exec(`INSERT INTO user_sync(user_id,data,version,updated_at) VALUES(?,?,?,?) ON CONFLICT(user_id) DO UPDATE SET data=excluded.data, version=excluded.version, updated_at=excluded.updated_at`, uid, string(p.Data), p.Version, time.Now()) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.Write([]byte(`{"ok":true}`)) }