dzql 0.6.5 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -2
- package/docs/feature-requests/applyPatch-bug-report.md +0 -85
- package/docs/feature-requests/connection-ready-profile.md +0 -57
- package/docs/feature-requests/hidden-bug-report.md +0 -111
- package/docs/feature-requests/hidden-fields-subscribables.md +0 -34
- package/docs/feature-requests/subscribable-param-key-bug.md +0 -38
- package/docs/feature-requests/todo.md +0 -146
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dzql",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.7",
|
|
4
4
|
"description": "Database-first real-time framework with TypeScript support",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
20
|
"src",
|
|
21
|
-
"docs",
|
|
21
|
+
"docs/README.md",
|
|
22
|
+
"docs/project-setup.md",
|
|
23
|
+
"docs/for_ai.md",
|
|
22
24
|
"README.md"
|
|
23
25
|
],
|
|
24
26
|
"scripts": {
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
# DZQL Bug Report
|
|
2
|
-
|
|
3
|
-
## Generated Store applyPatch Doesn't Match Data Structure
|
|
4
|
-
|
|
5
|
-
**Severity:** High (Breaking)
|
|
6
|
-
|
|
7
|
-
**Status:** ✅ FIXED
|
|
8
|
-
|
|
9
|
-
**Description:**
|
|
10
|
-
The generated Pinia store's `applyPatch` function assumes a flat data structure, but the subscribable SQL was returning nested wrapper objects.
|
|
11
|
-
|
|
12
|
-
**SQL was returning:**
|
|
13
|
-
```json
|
|
14
|
-
{
|
|
15
|
-
"venues": {...},
|
|
16
|
-
"sites": [
|
|
17
|
-
{ "sites": { "id": 1, "name": "..." }, "allocations": [...] },
|
|
18
|
-
{ "sites": { "id": 2, "name": "..." }, "allocations": [...] }
|
|
19
|
-
]
|
|
20
|
-
}
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
**Fix:**
|
|
24
|
-
Updated `subscribable_sql.ts` to use JSONB concatenation (`||`) to merge entity fields with nested includes into a flat structure:
|
|
25
|
-
|
|
26
|
-
```sql
|
|
27
|
-
SELECT jsonb_agg(
|
|
28
|
-
row_to_json(rel.*) || jsonb_build_object(
|
|
29
|
-
'allocations', COALESCE((
|
|
30
|
-
SELECT jsonb_agg(row_to_json(nested.*))
|
|
31
|
-
FROM allocations nested
|
|
32
|
-
WHERE nested.site_id = rel.id
|
|
33
|
-
), '[]'::jsonb))
|
|
34
|
-
)
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
**SQL now returns:**
|
|
38
|
-
```json
|
|
39
|
-
{
|
|
40
|
-
"venues": {...},
|
|
41
|
-
"sites": [
|
|
42
|
-
{ "id": 1, "name": "...", "allocations": [...] },
|
|
43
|
-
{ "id": 2, "name": "...", "allocations": [...] }
|
|
44
|
-
]
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
This flat structure matches what `applyPatch` and `handleArrayPatch` expect, so realtime updates now work correctly for nested includes.
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## Bug 2: json/jsonb Type Mismatch in Subscribable SQL
|
|
53
|
-
|
|
54
|
-
**Severity:** Critical (Blocking)
|
|
55
|
-
|
|
56
|
-
**Status:** ✅ FIXED
|
|
57
|
-
|
|
58
|
-
**Description:**
|
|
59
|
-
The generated subscribable SQL used `row_to_json()` which returns `json` type, but concatenated it with `jsonb_build_object()` which returns `jsonb`. PostgreSQL cannot concatenate these types.
|
|
60
|
-
|
|
61
|
-
**Generated SQL (before):**
|
|
62
|
-
```sql
|
|
63
|
-
row_to_json(rel.*) || jsonb_build_object(...)
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**Error:**
|
|
67
|
-
```
|
|
68
|
-
operator does not exist: json || jsonb
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
**Fix:**
|
|
72
|
-
Changed to use `to_jsonb()` instead of `row_to_json()` when concatenating with nested includes:
|
|
73
|
-
|
|
74
|
-
```sql
|
|
75
|
-
to_jsonb(rel.*) || jsonb_build_object(...)
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## Environment
|
|
81
|
-
|
|
82
|
-
- dzql version: local development (linked)
|
|
83
|
-
- Database: PostgreSQL 17 (Docker)
|
|
84
|
-
- Client: Vue 3 + Pinia + TypeScript
|
|
85
|
-
- Runtime: Bun
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# Feature Request: Send User Profile on WebSocket Connect
|
|
2
|
-
|
|
3
|
-
**Status: IMPLEMENTED**
|
|
4
|
-
|
|
5
|
-
## Summary
|
|
6
|
-
|
|
7
|
-
When a client connects to the DZQL WebSocket server, the server should immediately send a connection:ready message containing the authenticated user profile (or null if not authenticated).
|
|
8
|
-
|
|
9
|
-
## Current Behavior
|
|
10
|
-
|
|
11
|
-
1. Client connects with optional ?token=... in URL
|
|
12
|
-
2. Server opens connection but sends nothing
|
|
13
|
-
3. Client must call auth RPC to authenticate, then separately fetch profile
|
|
14
|
-
4. Client has no immediate knowledge of auth state
|
|
15
|
-
|
|
16
|
-
## Proposed Behavior
|
|
17
|
-
|
|
18
|
-
1. Client connects with optional ?token=... in URL
|
|
19
|
-
2. Server validates token (if present) and fetches user profile
|
|
20
|
-
3. Server sends first message:
|
|
21
|
-
|
|
22
|
-
{"method": "connection:ready", "params": {"user": {"id": 1, "name": "...", "email": "..."} | null}}
|
|
23
|
-
|
|
24
|
-
4. Client knows auth state immediately, can render accordingly
|
|
25
|
-
|
|
26
|
-
## Why This Matters
|
|
27
|
-
|
|
28
|
-
- Single source of truth: WebSocket connection determines auth state, not localStorage
|
|
29
|
-
- No race conditions: UI waits for connection:ready before rendering
|
|
30
|
-
- Simpler client code: No need for separate auth check after connect
|
|
31
|
-
- Better UX: App shows loading state until connection ready, then immediately correct view
|
|
32
|
-
|
|
33
|
-
## Client Usage Pattern
|
|
34
|
-
|
|
35
|
-
Template:
|
|
36
|
-
div v-if="!ready" - loading spinner
|
|
37
|
-
LoginModal v-else-if="!user"
|
|
38
|
-
RouterView v-else
|
|
39
|
-
|
|
40
|
-
## Suggested Server Changes
|
|
41
|
-
|
|
42
|
-
In src/runtime/ws.ts, modify handleOpen to:
|
|
43
|
-
1. Parse token from URL query params
|
|
44
|
-
2. If valid, verify token and fetch user profile
|
|
45
|
-
3. Send connection:ready message with user (or null)
|
|
46
|
-
|
|
47
|
-
## Suggested Client Changes
|
|
48
|
-
|
|
49
|
-
In src/client/ws.ts:
|
|
50
|
-
1. Add user and ready properties to class
|
|
51
|
-
2. Handle connection:ready message in handleMessage
|
|
52
|
-
3. Add onReady callback method
|
|
53
|
-
|
|
54
|
-
## Migration
|
|
55
|
-
|
|
56
|
-
- Existing clients that dont handle connection:ready will ignore it (no breaking change)
|
|
57
|
-
- New clients can opt-in to the pattern
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
# DZQL Bug Report
|
|
2
|
-
|
|
3
|
-
Bugs discovered while building the Venues application with DZQL.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Bug 1: Hidden Fields Exposed in Subscribables
|
|
8
|
-
|
|
9
|
-
**Severity:** High (Security)
|
|
10
|
-
|
|
11
|
-
**Status:** ✅ FIXED
|
|
12
|
-
|
|
13
|
-
**Description:**
|
|
14
|
-
Fields marked as `hidden: true` in the domain schema are still exposed when using subscribables. The generated SQL uses `row_to_json(root.*)` which includes all columns regardless of the `hidden` property.
|
|
15
|
-
|
|
16
|
-
**Fix:**
|
|
17
|
-
Added `buildVisibleRowJson` helper in `subscribable_sql.ts` that generates `jsonb_build_object()` with only visible fields instead of `row_to_json(root.*)`. Also updated all other SQL generators (`sql.ts`) to exclude hidden fields from `get_*`, `search_*`, `save_*`, and `delete_*` functions.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Bug 2: Generated Pinia Stores Don't Await Async Subscribe
|
|
22
|
-
|
|
23
|
-
**Severity:** Medium
|
|
24
|
-
|
|
25
|
-
**Status:** ✅ FIXED
|
|
26
|
-
|
|
27
|
-
**Description:**
|
|
28
|
-
The generated Pinia stores call the async `subscribe` method but don't await it. This means `store.data` is undefined immediately after calling `store.subscribe()` even though the subscription has been initiated.
|
|
29
|
-
|
|
30
|
-
**Fix:**
|
|
31
|
-
Updated `subscribable_store.ts` to make the `bind` function async. It now:
|
|
32
|
-
1. Creates a `ready` Promise that resolves when first data arrives
|
|
33
|
-
2. Awaits the `ready` Promise before returning
|
|
34
|
-
3. Stores the `ready` Promise so repeat calls can also await it
|
|
35
|
-
|
|
36
|
-
**Generated Code (after fix):**
|
|
37
|
-
```typescript
|
|
38
|
-
async function bind(params) {
|
|
39
|
-
const key = JSON.stringify(params);
|
|
40
|
-
if (documents.value[key]) {
|
|
41
|
-
const existing = documents.value[key];
|
|
42
|
-
if (existing.loading.value) {
|
|
43
|
-
await existing.ready;
|
|
44
|
-
}
|
|
45
|
-
return existing;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const docState = ref(null);
|
|
49
|
-
const loading = ref(true);
|
|
50
|
-
let resolveReady;
|
|
51
|
-
const ready = new Promise((resolve) => { resolveReady = resolve; });
|
|
52
|
-
|
|
53
|
-
ws.api.subscribe_venue_detail(params, (initialData) => {
|
|
54
|
-
docState.value = initialData;
|
|
55
|
-
loading.value = false;
|
|
56
|
-
resolveReady();
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
documents.value[key] = { data: docState, loading, ready };
|
|
60
|
-
await ready;
|
|
61
|
-
return documents.value[key];
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
**Usage:**
|
|
66
|
-
```typescript
|
|
67
|
-
const store = useMyProfileStore();
|
|
68
|
-
const { data, loading } = await store.bind({ user_id: 1 });
|
|
69
|
-
// data.value is now populated
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Bug 3: Subscribable Permission Check Uses Param Name Instead of Column Name
|
|
75
|
-
|
|
76
|
-
**Severity:** High (Breaking)
|
|
77
|
-
|
|
78
|
-
**Status:** ✅ FIXED
|
|
79
|
-
|
|
80
|
-
**Description:**
|
|
81
|
-
When generating SQL for subscribable permission checks, the compiler uses the parameter name instead of the actual database column name. This causes SQL errors when the param name differs from the column name.
|
|
82
|
-
|
|
83
|
-
**Fix:**
|
|
84
|
-
Updated `compileSubscribePermission` in `subscribable_sql.ts` to map param names to the root entity's `id` column when they match the rootKey. For example, `@org_id` now correctly resolves to `v_root.id` instead of `v_root.org_id`.
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
## Summary
|
|
89
|
-
|
|
90
|
-
| Bug | Severity | Status | Notes |
|
|
91
|
-
|-----|----------|--------|-------|
|
|
92
|
-
| Hidden fields exposed | High | ✅ Fixed | Uses `jsonb_build_object` to exclude hidden fields |
|
|
93
|
-
| Stores don't await | Medium | ✅ Fixed | `bind()` is now async and awaits first data |
|
|
94
|
-
| Permission param/column mismatch | High | ✅ Fixed | Maps param name to `id` column |
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## Environment
|
|
99
|
-
|
|
100
|
-
- dzql version: (linked local development version)
|
|
101
|
-
- Database: PostgreSQL 17 (via Docker)
|
|
102
|
-
- Client: Vue 3 + Pinia + TypeScript
|
|
103
|
-
- Runtime: Bun
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## Related Files
|
|
108
|
-
|
|
109
|
-
Detailed bug documents created in dzql docs:
|
|
110
|
-
- `/packages/tzql/docs/feature-requests/hidden-fields-in-subscribables.md`
|
|
111
|
-
- `/packages/tzql/docs/feature-requests/subscribable-param-key-bug.md`
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# Bug: Hidden fields exposed in subscribables
|
|
2
|
-
|
|
3
|
-
**Status: IMPLEMENTED**
|
|
4
|
-
|
|
5
|
-
## Issue
|
|
6
|
-
|
|
7
|
-
Entity hidden fields are not excluded from subscribable queries.
|
|
8
|
-
|
|
9
|
-
## Example
|
|
10
|
-
|
|
11
|
-
domain.js:
|
|
12
|
-
users: {
|
|
13
|
-
schema: { ... },
|
|
14
|
-
hidden: ["password_hash"], // Should be excluded from all queries
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
But get_my_profile returns:
|
|
18
|
-
{
|
|
19
|
-
"users": {
|
|
20
|
-
"password_hash": "$2a$06$..." // EXPOSED!
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
## Root Cause
|
|
25
|
-
|
|
26
|
-
The subscribable SQL generator uses row_to_json(root.*) which returns all columns.
|
|
27
|
-
|
|
28
|
-
## Fix
|
|
29
|
-
|
|
30
|
-
When generating subscribable SQL, exclude hidden fields by using explicit column list.
|
|
31
|
-
|
|
32
|
-
## Impact
|
|
33
|
-
|
|
34
|
-
Security vulnerability - sensitive data like password hashes exposed to clients.
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# Bug: Subscribable permission check uses param name instead of column name
|
|
2
|
-
|
|
3
|
-
## Issue
|
|
4
|
-
|
|
5
|
-
When generating subscribable SQL, the permission check incorrectly uses the param name instead of the actual column name on the root entity.
|
|
6
|
-
|
|
7
|
-
## Example
|
|
8
|
-
|
|
9
|
-
Domain:
|
|
10
|
-
```javascript
|
|
11
|
-
org_dashboard: {
|
|
12
|
-
params: { org_id: "int" },
|
|
13
|
-
root: { entity: "organisations", key: "org_id" },
|
|
14
|
-
canSubscribe: ["@org_id->acts_for[org_id=$]{active}.user_id"]
|
|
15
|
-
}
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Generated SQL:
|
|
19
|
-
```sql
|
|
20
|
-
-- WRONG: v_root.org_id doesn't exist on organisations table
|
|
21
|
-
WHERE acts_for.org_id = v_root.org_id
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Should be:
|
|
25
|
-
```sql
|
|
26
|
-
-- CORRECT: organisations.id is the actual column
|
|
27
|
-
WHERE acts_for.org_id = v_root.id
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Error
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
ERROR: record "v_root" has no field "org_id"
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Fix
|
|
37
|
-
|
|
38
|
-
The compiler should resolve `key: "org_id"` to mean "param org_id maps to the root entity's primary key (id)", not "access v_root.org_id".
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
# DZQL v2 Gap Analysis TODO
|
|
2
|
-
|
|
3
|
-
Gap analysis comparing v1 tests to v2 functionality. Updated 2024-12-17.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## High Priority - COMPLETED
|
|
8
|
-
|
|
9
|
-
### Soft Delete ✅
|
|
10
|
-
- [x] Add `softDelete` handling to `generateDeleteFunction()` in `src/cli/codegen/sql.ts`
|
|
11
|
-
- Sets `deleted_at = now()` instead of `DELETE FROM` when entity has `softDelete: true`
|
|
12
|
-
- [x] Add `deleted_at IS NULL` filter to `generateSearchFunction()`
|
|
13
|
-
- [x] GET still retrieves deleted records (for audit purposes)
|
|
14
|
-
- [x] Add soft delete integration tests (3 tests)
|
|
15
|
-
- Reference: `tests/integration/features.test.ts` - "Soft Delete" describe block
|
|
16
|
-
|
|
17
|
-
### Field Defaults ✅
|
|
18
|
-
- [x] Add `fieldDefaults` handling to `generateSaveFunction()` INSERT branch in `src/cli/codegen/sql.ts`
|
|
19
|
-
- `@user_id` → `p_user_id`
|
|
20
|
-
- `@now` → `now()`
|
|
21
|
-
- `@today` → `current_date`
|
|
22
|
-
- Literal values → insert as-is
|
|
23
|
-
- [x] Only apply defaults on INSERT, not UPDATE (uses COALESCE)
|
|
24
|
-
- [x] Add field defaults integration tests (4 tests)
|
|
25
|
-
- Reference: `tests/integration/features.test.ts` - "Field Defaults" describe block
|
|
26
|
-
|
|
27
|
-
### Composite Primary Key Support ✅
|
|
28
|
-
- [x] Update `generateSaveFunction()` to handle multi-column PKs
|
|
29
|
-
- Dynamic PK null check and EXISTS query
|
|
30
|
-
- WHERE clause supports all PK fields
|
|
31
|
-
- [x] Update `generateDeleteFunction()` for composite PKs
|
|
32
|
-
- [x] Update `generateGetFunction()` for composite PKs
|
|
33
|
-
- [x] Events store composite PK as JSONB object
|
|
34
|
-
- [x] Proper type casting for date, boolean, numeric columns
|
|
35
|
-
- [x] Add composite PK integration tests (4 tests)
|
|
36
|
-
- Reference: `tests/integration/features.test.ts` - "Composite Primary Keys" describe block
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## Medium Priority - V1 Features Not Ported
|
|
41
|
-
|
|
42
|
-
### Dashboard Collection (filter: TRUE)
|
|
43
|
-
- [ ] Add `filter: TRUE` handling to `generateSubscribableGetFunction()` in `src/cli/codegen/subscribable_sql.ts`
|
|
44
|
-
- Fetch ALL rows regardless of FK relationship to root
|
|
45
|
-
- [ ] Add `filter: TRUE` handling to `affected_keys` function
|
|
46
|
-
- Return `'{}'::jsonb` to notify ALL subscribers
|
|
47
|
-
- [ ] Add dashboard collection integration test
|
|
48
|
-
- Reference: `tests/integration/dashboard-collection.test.js` (v1)
|
|
49
|
-
|
|
50
|
-
### Null-Root Dashboard
|
|
51
|
-
- [ ] Support subscribables with no root entity parameter
|
|
52
|
-
- `root.key: '@user_id'` or similar built-in
|
|
53
|
-
- [ ] Add null-root dashboard test
|
|
54
|
-
- Reference: `tests/integration/null-root-dashboard.test.js` (v1)
|
|
55
|
-
|
|
56
|
-
### Delete Subscription Resolution
|
|
57
|
-
- [ ] Verify `affected_keys` function receives full record data on DELETE
|
|
58
|
-
- [ ] Add integration test for DELETE event subscription routing
|
|
59
|
-
- Reference: `tests/integration/delete-subscription-resolution.test.js` (v1)
|
|
60
|
-
|
|
61
|
-
### Atomic Subscription Updates
|
|
62
|
-
- [ ] Add integration test for Pinia store `applyPatch` with real WebSocket events
|
|
63
|
-
- [ ] Verify schema inclusion in subscribe response
|
|
64
|
-
- Reference: `tests/integration/atomic-subscription-updates.test.js` (v1)
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Low Priority - COMPLETED
|
|
69
|
-
|
|
70
|
-
### Custom Functions Pass-through ✅
|
|
71
|
-
- [x] Parse `customFunctions` from domain definition in IR generator
|
|
72
|
-
- [x] Include custom function SQL in generated migrations
|
|
73
|
-
- [x] Add custom functions to manifest allowlist for runtime security
|
|
74
|
-
- [x] Add custom functions integration tests (4 tests)
|
|
75
|
-
- Reference: `tests/integration/features.test.ts` - "Custom Functions" describe block
|
|
76
|
-
|
|
77
|
-
### JavaScript Custom Functions ✅
|
|
78
|
-
- [x] Add JS function handler registry (`src/runtime/js_functions.ts`)
|
|
79
|
-
- [x] Update `handleRequest` to check for JS handlers (takes precedence over SQL)
|
|
80
|
-
- [x] JS functions receive context with `userId`, `params`, and `db.query()` access
|
|
81
|
-
- [x] Export `registerJsFunction` API from runtime
|
|
82
|
-
- [x] Add JavaScript custom function integration tests (5 tests)
|
|
83
|
-
- Reference: `tests/integration/features.test.ts` - "JavaScript Custom Functions" describe block
|
|
84
|
-
|
|
85
|
-
### Temporal Table Support
|
|
86
|
-
- [ ] Implement `temporal.validFrom` / `temporal.validTo` filtering
|
|
87
|
-
- [ ] Auto-filter to current validity period
|
|
88
|
-
- Schema already defined in `venues.js:acts_for.temporal`
|
|
89
|
-
|
|
90
|
-
### On-Delete Graph Rules
|
|
91
|
-
- [ ] Verify `onDelete` graph rules receive correct record data
|
|
92
|
-
- [ ] Test cascading deletes
|
|
93
|
-
- Reference: `tests/integration/on-delete-graph-rules.test.js` (v1)
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## Integration Test Coverage
|
|
98
|
-
|
|
99
|
-
### Missing Integration Tests (port from v1)
|
|
100
|
-
- [ ] Security / SQL injection prevention (`security.test.js`)
|
|
101
|
-
- [ ] M2M runtime operations (`m2m-runtime.test.js`)
|
|
102
|
-
- [ ] Permissions enforcement (`permissions.test.js` - more comprehensive)
|
|
103
|
-
- [ ] Event validation (`event-validation.test.js`)
|
|
104
|
-
- [ ] Namespace/entity discovery (`namespace-cli.test.js`)
|
|
105
|
-
- [ ] Migration runner (`migrations.test.js`)
|
|
106
|
-
|
|
107
|
-
### Current V2 Integration Tests
|
|
108
|
-
- `tests/integration/db.test.ts` - CRUD, permissions, events, graph rules ✅
|
|
109
|
-
- `tests/integration/e2e.test.ts` - Compiler pipeline ✅
|
|
110
|
-
- `tests/integration/full_stack.test.ts` - Runtime + WebSocket + Pinia ✅
|
|
111
|
-
- `tests/integration/features.test.ts` - Search filters, deep paths, M2M, soft delete, field defaults, composite PK ✅
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
## Not Applicable to V2
|
|
116
|
-
|
|
117
|
-
### Interpreted Mode
|
|
118
|
-
- V1 had runtime `register_entity` + generic functions
|
|
119
|
-
- V2 is compile-only by design - no gap, intentional removal
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## Feature Comparison Summary
|
|
124
|
-
|
|
125
|
-
| Feature | V1 | V2 | Status |
|
|
126
|
-
|---------|----|----|--------|
|
|
127
|
-
| Authentication | ✅ | ✅ | Done |
|
|
128
|
-
| CRUD Operations | ✅ | ✅ | Done |
|
|
129
|
-
| Permissions | ✅ | ✅ | Done |
|
|
130
|
-
| Graph Rules | ✅ | ✅ | Done |
|
|
131
|
-
| M2M Relationships | ✅ | ✅ | Done |
|
|
132
|
-
| Events | ✅ | ✅ | Done |
|
|
133
|
-
| Subscribables | ✅ | ✅ | Done |
|
|
134
|
-
| Security (allowlist) | ✅ | ✅ | Done |
|
|
135
|
-
| Search Operators | ✅ | ✅ | Done |
|
|
136
|
-
| Deep Permission Paths | ✅ | ✅ | Done |
|
|
137
|
-
| Pinia Stores | ❌ | ✅ | New in V2 |
|
|
138
|
-
| .env Support | ❌ | ✅ | New in V2 |
|
|
139
|
-
| Soft Delete | ✅ | ✅ | Done |
|
|
140
|
-
| Field Defaults | ✅ | ✅ | Done |
|
|
141
|
-
| Composite PK | ✅ | ✅ | Done |
|
|
142
|
-
| Custom Functions (SQL) | ✅ | ✅ | Done |
|
|
143
|
-
| Custom Functions (JS) | ✅ | ✅ | Done |
|
|
144
|
-
| Dashboard Collection | ✅ | ❌ | **TODO** |
|
|
145
|
-
| Null-Root Dashboard | ✅ | ❌ | **TODO** |
|
|
146
|
-
| Interpreted Mode | ✅ | ❌ | Removed |
|