canvas-website/test-r2-conversion.md

185 lines
5.3 KiB
Markdown

# Testing R2 Data Conversion
This guide helps you test the data conversion from old tldraw sync format to new automerge sync format using actual data from your R2 bucket.
## Overview
The conversion system handles three data formats:
1. **Automerge Array Format**: `[{ state: {...} }, ...]`
2. **Store Format**: `{ store: { "recordId": {...}, ... }, schema: {...} }` (already converted)
3. **Old Documents Format**: `{ documents: [{ state: {...} }, ...] }` (legacy tldraw sync)
## Testing Steps
### 1. Identify Test Rooms
First, identify rooms in your R2 bucket that use the old format:
```bash
# List all rooms in R2
# You can use wrangler CLI or Cloudflare dashboard
wrangler r2 object list TLDRAW_BUCKET --prefix "rooms/"
```
### 2. Check Data Format
For each room, check its format:
```typescript
// Example: Check a room's format
const roomId = "your-room-id"
const doc = await r2.get(`rooms/${roomId}`)
const data = await doc.json()
// Check format
if (Array.isArray(data)) {
console.log("Format: Automerge Array")
} else if (data.store) {
console.log("Format: Store Format (already converted)")
} else if (data.documents) {
console.log("Format: Old Documents Format (needs conversion)")
} else {
console.log("Format: Unknown")
}
```
### 3. Test Conversion
The conversion happens automatically when a room is loaded. To test:
1. **Load the room in your app** - The `AutomergeDurableObject.getDocument()` method will automatically detect and convert the format
2. **Check the logs** - Look for conversion statistics in the worker logs:
- `📊 Automerge to Store conversion statistics`
- `📊 Documents to Store migration statistics`
- `📊 Shape migration statistics`
### 4. Verify Data Integrity
After conversion, verify:
1. **All shapes are present**: Check that shape count matches
2. **Custom shapes preserved**: Verify ObsNote, Holon, etc. have all their properties
3. **Custom records preserved**: Check that obsidian_vault records are present
4. **No validation errors**: Shapes should render without errors
## Expected Log Output
When a room is converted, you should see logs like:
```
Converting Automerge document format to store format for room abc123
📊 Automerge to Store conversion statistics: {
total: 150,
converted: 148,
skipped: 2,
errors: 0,
storeKeys: 148,
customRecordCount: 1,
customRecordIds: ['obsidian_vault:test'],
errorCount: 0
}
✅ Verified 1 custom records preserved during conversion
🔄 Server-side: Starting shape migration for room abc123
📊 Shape migration statistics: {
total: 120,
migrated: 45,
skipped: 75,
errors: 0,
shapeTypes: { geo: 50, arrow: 20, ObsNote: 10, ... },
customShapesCount: 10,
customShapeIds: ['shape:obs1', 'shape:holon1', ...],
errorCount: 0
}
✅ Verified 10 custom shapes preserved during migration
```
## Manual Testing Script
You can create a test script to verify conversion:
```typescript
// test-r2-room.ts
import { AutomergeDurableObject } from './worker/AutomergeDurableObject'
async function testRoomConversion(roomId: string) {
// This would need to be run in a Cloudflare Worker context
// or use wrangler dev to test locally
const env = {
TLDRAW_BUCKET: yourR2Bucket
}
// Create a mock Durable Object state
const ctx = {
storage: {
get: async (key: string) => roomId,
put: async (key: string, value: any) => {}
},
blockConcurrencyWhile: async (fn: () => Promise<void>) => await fn()
}
const do = new AutomergeDurableObject(ctx as any, env as any)
// Load and convert
const doc = await do.getDocument()
// Verify
console.log('Conversion complete:', {
storeKeys: Object.keys(doc.store).length,
shapes: Object.values(doc.store).filter((r: any) => r.typeName === 'shape').length,
customRecords: Object.values(doc.store).filter((r: any) =>
r.id && typeof r.id === 'string' && r.id.startsWith('obsidian_vault:')
).length
})
}
```
## Common Issues and Solutions
### Issue: Records are skipped during conversion
**Cause**: Missing required fields (id, typeName, state)
**Solution**: Check the error details in logs. The conversion will skip invalid records but log warnings.
### Issue: Custom shapes missing properties
**Cause**: Shape migration may have failed
**Solution**: Check shape migration logs. Custom shape props should be preserved automatically.
### Issue: Custom records (obsidian_vault) missing
**Cause**: They were filtered out during conversion
**Solution**: This shouldn't happen - custom records are preserved. Check logs for `customRecordCount`.
## Validation Checklist
After conversion, verify:
- [ ] All shapes are present (count matches)
- [ ] Custom shapes (ObsNote, Holon, etc.) have all properties
- [ ] Custom records (obsidian_vault) are preserved
- [ ] No validation errors when loading the room
- [ ] Shapes render correctly in the UI
- [ ] All text content is preserved
- [ ] All metadata is preserved
## Rollback Plan
If conversion fails:
1. The original data in R2 is **not modified** until the first save
2. You can restore from backup if needed
3. Check worker logs for specific errors
4. The conversion creates a new document if it fails, so original data is safe
## Next Steps
1. Test with a few sample rooms first
2. Monitor logs for any warnings or errors
3. Verify data integrity after conversion
4. Once confident, the conversion will happen automatically for all rooms