VSKI v0.4.0
Bug Fixes
Section titled “Bug Fixes”Cross-Database Relations Expand
Section titled “Cross-Database Relations Expand”- Backend Expand Operation Fixed:
- The expand operation now correctly handles relations created via the frontend dashboard
- Backend previously only checked for
collectionIdin relation field options - Now falls back to
toCollectionwhich is used by the frontend when creating collections - Fixes silent failures where expand would return just the ID instead of expanded objects
Frontend Relation Field Improvements
Section titled “Frontend Relation Field Improvements”-
Relation Field Selector Display:
- Relation fields in the add/edit record modal now display as a small table
- Shows the first non-system field value (excluding
id,created,updated) - Displays last 4 characters of the record ID for easy identification
- No longer relies on
defaultSearchFieldwhich may not be set
-
Edit Record Relation Fields:
- Fixed crash when editing records with expanded relation fields
- Relation fields are now properly normalized when loading records for editing
- Expanded objects are converted to IDs
- Array relations extract IDs from each expanded item
- Resolves “Objects are not valid as a React child” error
Installation
Section titled “Installation”Binary
Section titled “Binary”Download binary for your platform:
# Linux (standalone with embedded UI)wget https://vski.sh/x/platform/releases/download/v0.4.0/vski-standalonechmod +x vski-standalone./vski-standalone
# Linux (API-only)wget https://vski.sh/x/platform/releases/download/v0.4.0/vskichmod +x vski./vskiDocker
Section titled “Docker”Pull and run official Docker image:
# Light version (API only, no embedded UI)docker pull vski.sh/x/vski:latest
# Standalone version (with embedded web UI)docker pull vski.sh/x/vski:latest-standalone
# Pull specific versiondocker pull vski.sh/x/vski:v0.4.0docker pull vski.sh/x/vski:v0.4.0-standalone
# Run light version with default configurationdocker run -p 3000:3000 -v $(pwd)/data:/app/data vski.sh/x/vski:latest
# Run standalone version with embedded web UIdocker run -p 3000:3000 -v $(pwd)/data:/app/data vski.sh/x/vski:latest-standaloneConfiguration
Section titled “Configuration”Create a .env file:
DATA_DIR=./dataSERVER_PORT=3000JWT_SECRET=your-secret-keyExpanding Cross-Database Relations
Section titled “Expanding Cross-Database Relations”// Query records with expanded relations (now works correctly)const response = await fetch('http://localhost:3000/api/collections/posts/records?expand=author,comments', { headers: { 'Authorization': 'Bearer YOUR_JWT_TOKEN' }});
const data = await response.json();console.log(data.items[0].expand.author); // Expanded object, not just IDCreating Collections with Relations (Frontend)
Section titled “Creating Collections with Relations (Frontend)”// Frontend creates collections with toCollection optionconst collection = { name: 'posts', schema: [ { name: 'author', type: 'relation', options: { toCollection: 'users', // Now correctly handled by backend maxSelect: 1 } } ]};
await fetch('http://localhost:3000/api/collections', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_JWT_TOKEN' }, body: JSON.stringify(collection)});Building from Source
Section titled “Building from Source”# Clone repositorygit clone https://vski.sh/x/platform.gitcd platform/vski
# Build production binarymake build
# Build release binary (with UPX compression)make build-release
# Run binary./bin/vskiMigration Notes
Section titled “Migration Notes”No Migration Required
Section titled “No Migration Required”All changes are backward compatible. Existing collections and records will work without any changes.
Breaking Changes
Section titled “Breaking Changes”None.
API Changes
Section titled “API Changes”Expanded Records Response
Section titled “Expanded Records Response”The expand parameter now correctly returns expanded objects for cross-database relations:
Before (buggy):
{ "id": "post1", "author": "user123", // Just the ID "expand": { "author": "user123" // Still just the ID, not expanded }}After (fixed):
{ "id": "post1", "author": "user123", "expand": { "author": { "id": "user123", "email": "user@example.com", "name": "John Doe", "created": "2026-02-21T12:00:00Z", "updated": "2026-02-21T12:00:00Z" } }}Testing
Section titled “Testing”Run E2E Tests
Section titled “Run E2E Tests”cd vskimake buildmake e2e TEST=44_crossdb_expand_test.ts # Test cross-database expandmake e2e # Run all E2E testsTest Relation Expand Manually
Section titled “Test Relation Expand Manually”# Create two collections with relationcurl -X POST http://localhost:3000/api/collections \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{ "name": "users", "schema": [ {"name": "id", "type": "text", "system": true, "primary": true}, {"name": "name", "type": "text"} ] }'
curl -X POST http://localhost:3000/api/collections \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{ "name": "posts", "schema": [ {"name": "id", "type": "text", "system": true, "primary": true}, {"name": "title", "type": "text"}, {"name": "author", "type": "relation", "options": {"toCollection": "users", "maxSelect": 1}} ] }'
# Create recordscurl -X POST http://localhost:3000/api/collections/users/records \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{"id": "user1", "name": "John"}'
curl -X POST http://localhost:3000/api/collections/posts/records \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{"id": "post1", "title": "Hello", "author": "user1"}'
# Test expand (should return expanded user object)curl 'http://localhost:3000/api/collections/posts/records?expand=author' \ -H "Authorization: Bearer YOUR_TOKEN"Documentation
Section titled “Documentation”Full documentation available at: https://vski.sh/x/platform
Changelog
Section titled “Changelog”v0.4.0 (2026-02-21)
Section titled “v0.4.0 (2026-02-21)”- Backend expand operation now correctly handles
toCollectionoption in relation fields - Fixed silent failures where expand would return just ID instead of expanded objects
- Relation field selector in frontend now displays as small table with field value and ID
- Fixed crash when editing records with expanded relation fields
- Relation fields are now properly normalized (object to ID) when loading for editing
- Resolved “Objects are not valid as a React child” error in record edit modal
Changed
Section titled “Changed”- Frontend relation picker no longer requires
defaultSearchFieldto be set - Frontend automatically detects first non-system field for display
- Last 4 characters of ID shown instead of full ID for better readability
Technical
Section titled “Technical”- Modified
internal/repositories/record_repository.go:634to check bothcollectionIdandtoCollection - Updated
web/components/ui/record-form.tsxto normalize relation fields on record load - Enhanced relation field display logic to work with any expanded object structure