feat(workspace): implement Yjs CRDT real-time collaborative editing (resolves FLAW-01)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 29s

This commit is contained in:
sandrodach committed 2026-10-26 15:18:48 +01:00
1 parent 0bdeb5f320
commit ef8cf8f022
13 files changed
+1028 -85

No files matched your search

+70
View File
@@ -838,3 +838,73 @@ func TestWebhookTriageBadgeAndIngestion(t *testing.T) {
t.Fatalf("expected thought content to contain 'Waschmaschine', got '%s'", ingestResp.Thought.Content)
}
}
func TestDocumentCRDTEndpoints(t *testing.T) {
tmpDir := t.TempDir()
dbPath := filepath.Join(tmpDir, "crdt_api_test.db")
store, err := storage.NewStore(dbPath)
if err != nil {
t.Fatalf("NewStore failed: %v", err)
}
defer store.Close()
cfg := &config.Config{
JWTSecret: "test-jwt-secret-key",
AllowRegistration: true,
}
hub := ws.NewHub()
srv := NewServer(cfg, store, hub, nil)
router := srv.Router()
user, err := store.CreateUser("crdt_api@example.com", "hash", "CRDT API User", "member")
if err != nil {
t.Fatalf("CreateUser failed: %v", err)
}
token, _ := auth.GenerateToken(cfg.JWTSecret, user.ID, user.Email, user.Role)
doc, err := store.CreateDocument(user.ID, "", "API CRDT Doc", "📄", "", nil, nil, false)
if err != nil {
t.Fatalf("CreateDocument failed: %v", err)
}
// 1. Initial GET /api/v1/documents/{id}/crdt
req := httptest.NewRequest(http.MethodGet, "/api/v1/documents/"+doc.ID+"/crdt", nil)
req.Header.Set("Authorization", "Bearer "+token)
rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected 200 OK from GET crdt, got %d: %s", rec.Code, rec.Body.String())
}
// 2. PUT /api/v1/documents/{id}/crdt with base64 state
savePayload := []byte(`{"state":"AQIDBA=="}`)
req = httptest.NewRequest(http.MethodPut, "/api/v1/documents/"+doc.ID+"/crdt", bytes.NewReader(savePayload))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
rec = httptest.NewRecorder()
router.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected 200 OK from PUT crdt, got %d: %s", rec.Code, rec.Body.String())
}
// 3. Verify state persisted
req = httptest.NewRequest(http.MethodGet, "/api/v1/documents/"+doc.ID+"/crdt", nil)
req.Header.Set("Authorization", "Bearer "+token)
rec = httptest.NewRecorder()
router.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected 200 OK from GET crdt, got %d", rec.Code)
}
var crdtResp struct {
DocID string `json:"docId"`
State string `json:"state"`
}
_ = json.Unmarshal(rec.Body.Bytes(), &crdtResp)
if crdtResp.State != "AQIDBA==" {
t.Fatalf("expected state 'AQIDBA==', got '%s'", crdtResp.State)
}
}