Files
OpenNoodl/dev-docs/tasks/phase-5-multi-target-deployment/01-byob-backend/TASK-007-integrated-backend/TASK-007A-PROGRESS.md
Richard Osborne 72c9989a68 feat(runtime): add LocalSQL adapter for CloudStore interface
TASK-007A: LocalSQL Adapter (Phase 5/Phase 11 shared foundation)

- Add LocalSQLAdapter implementing CloudStore interface with SQLite backend
- Add QueryBuilder for Parse-style query to SQL translation
- Add SchemaManager for table creation, migrations, and exports
- Support all CloudStore methods: query, fetch, create, save, delete
- Support aggregate, distinct, increment, count operations
- Support relations via junction tables
- Add schema export to PostgreSQL and Supabase formats
- Add comprehensive unit tests for QueryBuilder

This adapter enables:
- Local offline database for development
- Foundation for Phase 11 execution history storage
- Schema migration path to production databases
2026-01-15 16:04:24 +01:00

4.3 KiB

TASK-007A: LocalSQL Adapter - Progress

Status: Core Implementation Complete
Branch: feature/task-007a-localsql-adapter
Started: 2026-01-15
Last Updated: 2026-01-15


What Was Built

Files Created

packages/noodl-runtime/src/api/adapters/
├── index.js                    # Adapter registry & exports
├── types.js                    # JSDoc type definitions
└── local-sql/
    ├── index.js                # Module exports
    ├── LocalSQLAdapter.js      # Main adapter (implements CloudStore interface)
    ├── QueryBuilder.js         # Parse-style query → SQL translation
    └── SchemaManager.js        # Table creation, migrations, export

packages/noodl-runtime/test/adapters/
└── QueryBuilder.test.js        # Unit tests for query builder

Features Implemented

LocalSQLAdapter

  • Implements same API as existing CloudStore class
  • Uses better-sqlite3 for local SQLite storage
  • WAL mode for better concurrent access
  • Event emission (create, save, delete, fetch)
  • Auto-create tables on first access
  • Auto-add columns for new fields

QueryBuilder

  • Translates Parse-style queries to SQL
  • All operators: $eq, $ne, $gt, $gte, $lt, $lte
  • Collection operators: $in, $nin
  • Existence: $exists
  • Logical: $and, $or
  • Relation support: $relatedTo
  • Parse types: Date, Pointer
  • SQL injection prevention
  • Value serialization/deserialization

SchemaManager

  • Create tables from Noodl schemas
  • Add columns dynamically
  • Junction tables for relations
  • Export to PostgreSQL SQL
  • Export to Supabase SQL (with RLS policies)
  • JSON schema export/import
  • Schema tracking in _Schema table

CloudStore Interface Methods

Method Status Notes
query() Full Parse query syntax
fetch() Single record by ID
create() With auto ID generation
save() Update existing
delete() By objectId
count() With where filter
aggregate() sum, avg, max, min
distinct() Unique values
increment() Atomic increment
addRelation() Via junction tables
removeRelation() Via junction tables
on() / off() Event subscription

Testing Status

Unit Tests

  • QueryBuilder tests written (56 test cases)
  • ⚠️ Runtime package has dependency issues (terminal-link missing)
  • Tests need npm install at repo root to run

Manual Testing

  • 🔲 Pending - requires better-sqlite3 installation

What's Next

Remaining for TASK-007A

  1. Install missing test dependencies
  2. Run and verify all tests pass
  3. Manual integration test with real database

Next Steps (TASK-007B: Backend Server)

  • Express server implementation
  • REST endpoints matching CloudStore API
  • WebSocket for realtime updates
  • IPC handlers for Electron main process

Usage Example

const { LocalSQLAdapter } = require('@noodl/runtime/src/api/adapters');

// Create adapter
const adapter = new LocalSQLAdapter('/path/to/database.db');
await adapter.connect();

// Create a record
adapter.create({
  collection: 'todos',
  data: { title: 'Learn Noodl', completed: false },
  success: (record) => console.log('Created:', record),
  error: (err) => console.error(err)
});

// Query records
adapter.query({
  collection: 'todos',
  where: { completed: { $eq: false } },
  sort: '-createdAt',
  limit: 10,
  success: (results) => console.log('Todos:', results),
  error: (err) => console.error(err)
});

// Export schema to PostgreSQL
const pgSQL = adapter.getSchemaManager().generatePostgresSQL();
console.log(pgSQL);

Notes

  • The adapter matches the callback-based API of CloudStore for compatibility
  • better-sqlite3 is required but not added to package.json yet
  • Will be added when integrating with Backend Server (TASK-007B)
  • ESLint warnings about require() are expected (CommonJS package)