Compare commits
6 Commits
7e28eb2645
...
1.0.158
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f1c0d7ee9 | |||
| 25bbf2b564 | |||
| c8cc4cbde8 | |||
| 5af2399e3b | |||
| 1d56bae9a5 | |||
| 813e9ff3c2 |
@ -16,7 +16,7 @@ url = "2.5.8"
|
||||
fluent-uri = "0.3.2"
|
||||
idna = "1.1.0"
|
||||
percent-encoding = "2.3.2"
|
||||
uuid = { version = "1.20.0", features = ["v4", "serde"] }
|
||||
uuid = { version = "1.20.0", features = ["v7", "serde"] }
|
||||
chrono = { version = "0.4.43", features = ["serde"] }
|
||||
json-pointer = "0.3.4"
|
||||
indexmap = { version = "2.13.0", features = ["serde"] }
|
||||
|
||||
@ -175,6 +175,7 @@ In the Punc architecture, filters are automatically synthesized, strongly-typed
|
||||
|
||||
* **Conditions**: A condition schema is the contract defining the mathematical operations allowed on a primitive field. For example, a `string.condition` allows `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$of` (IN), and `$nof` (NOT IN).
|
||||
* **Enum Conditions**: When JSPG synthesizes an enum, it dynamically generates an `<enum>.condition` (e.g., `address_kind.condition`). This strongly-typed condition perfectly mirrors the operations of a `string.condition`, but strictly limits the arrays and inputs of `$eq`, `$ne`, `$of`, and `$nof` to the exact variations defined by that Enum. This context ensures that UI generators know exactly when to render `<Select>` dropdowns instead of generic `<Text>` boxes.
|
||||
* **Pre-compiled Condition and Filter Mapping**: To prevent redundant double-wrapping of search structures, any schema property whose type is already a `.condition` or `.filter` type (such as `"string.condition"` or `"$kind.filter"`) maps directly to itself during filter synthesis rather than receiving a redundant `.filter` suffix.
|
||||
* **Filters**: A filter schema (e.g., `person.filter`) is an object containing condition properties used to filter entities. It natively supports structural composition:
|
||||
* **Inherited Properties**: Filters automatically inherit all valid database columns from their base type schema, immediately converting them to their respective `.condition` schemas.
|
||||
* **Relational Proxies**: If a table has a foreign key to another table, the filter automatically generates a proxy property pointing to the related entity's filter (e.g., the `person` filter automatically gains an `organization` property that points to `organization.filter`), allowing infinitely deep nested queries natively.
|
||||
|
||||
@ -466,7 +466,7 @@
|
||||
},
|
||||
"filter": {
|
||||
"type": [
|
||||
"$kind.filter.filter",
|
||||
"$kind.filter",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
|
||||
@ -1242,8 +1242,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -1256,12 +1255,12 @@
|
||||
" '{{uuid:generated_1}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'person'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"first_name\": \"IncompleteFirst\",",
|
||||
" \"last_name\": \"IncompleteLast\",",
|
||||
@ -1276,8 +1275,7 @@
|
||||
" \"first_name\": \"IncompleteFirst\",",
|
||||
" \"last_name\": \"IncompleteLast\",",
|
||||
" \"type\": \"person\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
]
|
||||
]
|
||||
@ -1342,8 +1340,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" '{",
|
||||
@ -1357,12 +1354,12 @@
|
||||
" '{{uuid:generated_0}}',",
|
||||
" 'update',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'person'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"update\",",
|
||||
" \"complete\": {",
|
||||
" \"id\": \"{{uuid:mocks.0.id}}\",",
|
||||
" \"type\": \"person\",",
|
||||
@ -1378,7 +1375,6 @@
|
||||
" \"contact_id\": \"abc-contact\",",
|
||||
" \"type\": \"person\"",
|
||||
" },",
|
||||
" \"kind\": \"update\",",
|
||||
" \"old\": {",
|
||||
" \"contact_id\": \"old-contact\"",
|
||||
" }",
|
||||
@ -1448,8 +1444,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" '{",
|
||||
@ -1463,12 +1458,12 @@
|
||||
" '{{uuid:generated_0}}',",
|
||||
" 'update',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'person'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"update\",",
|
||||
" \"complete\": {",
|
||||
" \"id\": \"{{uuid:mocks.0.id}}\",",
|
||||
" \"type\": \"person\",",
|
||||
@ -1484,7 +1479,6 @@
|
||||
" \"contact_id\": \"abc-contact\",",
|
||||
" \"type\": \"person\"",
|
||||
" },",
|
||||
" \"kind\": \"update\",",
|
||||
" \"old\": {",
|
||||
" \"contact_id\": \"old-contact\"",
|
||||
" },",
|
||||
@ -1535,6 +1529,7 @@
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"replace\",",
|
||||
" \"complete\": {",
|
||||
" \"id\": \"{{uuid:mocks.0.id}}\",",
|
||||
" \"type\": \"person\",",
|
||||
@ -1549,7 +1544,6 @@
|
||||
" \"new\": {",
|
||||
" \"type\": \"person\"",
|
||||
" },",
|
||||
" \"kind\": \"replace\",",
|
||||
" \"replaces\": \"{{uuid:data.id}}\"",
|
||||
"}'))"
|
||||
]
|
||||
@ -1608,8 +1602,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" '{",
|
||||
@ -1625,12 +1618,12 @@
|
||||
" '{{uuid:generated_0}}',",
|
||||
" 'update',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'person'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"update\",",
|
||||
" \"complete\": {",
|
||||
" \"id\": \"{{uuid:mocks.0.id}}\",",
|
||||
" \"type\": \"person\",",
|
||||
@ -1644,7 +1637,6 @@
|
||||
" \"last_name\": \"NewLast\",",
|
||||
" \"type\": \"person\"",
|
||||
" },",
|
||||
" \"kind\": \"update\",",
|
||||
" \"old\": {",
|
||||
" \"first_name\": \"OldFirst\",",
|
||||
" \"last_name\": \"OldLast\"",
|
||||
@ -1742,8 +1734,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -1758,12 +1749,12 @@
|
||||
" '{{uuid:generated_0}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'person'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"first_name\": \"John\",",
|
||||
" \"last_name\": \"Doe\",",
|
||||
@ -1782,8 +1773,7 @@
|
||||
" \"date_of_birth\": \"{{timestamp}}\",",
|
||||
" \"pronouns\": \"\",",
|
||||
" \"type\": \"person\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
]
|
||||
]
|
||||
@ -1870,8 +1860,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -1886,8 +1875,7 @@
|
||||
" '{{uuid:generated_2}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'person'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -1930,8 +1918,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -1944,12 +1931,12 @@
|
||||
" '{{uuid:generated_4}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'order'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"total\": 100.0,",
|
||||
" \"id\": \"{{uuid:generated_3}}\",",
|
||||
@ -1964,12 +1951,12 @@
|
||||
" \"total\": 100.0,",
|
||||
" \"type\": \"order\",",
|
||||
" \"customer_id\": \"{{uuid:generated_0}}\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"first_name\": \"Bob\",",
|
||||
" \"last_name\": \"Smith\",",
|
||||
@ -1988,8 +1975,7 @@
|
||||
" \"date_of_birth\": \"2000-01-01\",",
|
||||
" \"type\": \"person\",",
|
||||
" \"organization_id\": \"{{uuid:generated_1}}\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
]
|
||||
]
|
||||
@ -2094,8 +2080,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -2109,8 +2094,7 @@
|
||||
" '{{uuid:generated_1}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'order_line'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -2121,8 +2105,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -2134,12 +2117,12 @@
|
||||
" '{{uuid:generated_2}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'order'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"total\": 99.0,",
|
||||
" \"id\": \"abc\",",
|
||||
@ -2152,12 +2135,12 @@
|
||||
" \"new\": {",
|
||||
" \"total\": 99.0,",
|
||||
" \"type\": \"order\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"product\": \"Widget\",",
|
||||
" \"price\": 99.0,",
|
||||
@ -2174,8 +2157,7 @@
|
||||
" \"price\": 99.0,",
|
||||
" \"order_id\": \"abc\",",
|
||||
" \"type\": \"order_line\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
]
|
||||
]
|
||||
@ -2307,8 +2289,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -2320,8 +2301,7 @@
|
||||
" '{{uuid:generated_2}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'phone_number'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -2372,8 +2352,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -2389,8 +2368,7 @@
|
||||
" '{{uuid:generated_4}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'contact'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -2427,8 +2405,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -2440,8 +2417,7 @@
|
||||
" '{{uuid:generated_6}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'email_address'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -2492,8 +2468,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -2509,8 +2484,7 @@
|
||||
" '{{uuid:generated_8}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'contact'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -2547,8 +2521,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -2560,8 +2533,7 @@
|
||||
" '{{uuid:generated_10}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'email_address'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -2612,8 +2584,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -2629,8 +2600,7 @@
|
||||
" '{{uuid:generated_12}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'contact'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -2641,8 +2611,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -2655,12 +2624,12 @@
|
||||
" '{{uuid:generated_13}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'person'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"first_name\": \"Relation\",",
|
||||
" \"last_name\": \"Test\",",
|
||||
@ -2675,12 +2644,12 @@
|
||||
" \"first_name\": \"Relation\",",
|
||||
" \"last_name\": \"Test\",",
|
||||
" \"type\": \"person\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"is_primary\": true,",
|
||||
" \"source_id\": \"{{uuid:generated_0}}\",",
|
||||
@ -2701,12 +2670,12 @@
|
||||
" \"target_id\": \"{{uuid:generated_1}}\",",
|
||||
" \"target_type\": \"phone_number\",",
|
||||
" \"type\": \"contact\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"number\": \"555-0001\",",
|
||||
" \"id\": \"{{uuid:generated_1}}\",",
|
||||
@ -2719,12 +2688,12 @@
|
||||
" \"new\": {",
|
||||
" \"number\": \"555-0001\",",
|
||||
" \"type\": \"phone_number\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"is_primary\": false,",
|
||||
" \"source_id\": \"{{uuid:generated_0}}\",",
|
||||
@ -2745,12 +2714,12 @@
|
||||
" \"target_id\": \"{{uuid:generated_5}}\",",
|
||||
" \"target_type\": \"email_address\",",
|
||||
" \"type\": \"contact\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"address\": \"test@example.com\",",
|
||||
" \"id\": \"{{uuid:generated_5}}\",",
|
||||
@ -2763,12 +2732,12 @@
|
||||
" \"new\": {",
|
||||
" \"address\": \"test@example.com\",",
|
||||
" \"type\": \"email_address\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"is_primary\": false,",
|
||||
" \"source_id\": \"{{uuid:generated_0}}\",",
|
||||
@ -2789,12 +2758,12 @@
|
||||
" \"target_id\": \"{{uuid:generated_9}}\",",
|
||||
" \"target_type\": \"email_address\",",
|
||||
" \"type\": \"contact\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"address\": \"test2@example.com\",",
|
||||
" \"id\": \"{{uuid:generated_9}}\",",
|
||||
@ -2807,8 +2776,7 @@
|
||||
" \"new\": {",
|
||||
" \"address\": \"test2@example.com\",",
|
||||
" \"type\": \"email_address\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
]
|
||||
]
|
||||
@ -2860,8 +2828,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" '{",
|
||||
@ -2875,12 +2842,12 @@
|
||||
" '{{uuid:generated_0}}',",
|
||||
" 'delete',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'person'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"delete\",",
|
||||
" \"complete\": {",
|
||||
" \"id\": \"abc-archived\",",
|
||||
" \"type\": \"person\",",
|
||||
@ -2894,7 +2861,6 @@
|
||||
" \"archived\": true,",
|
||||
" \"type\": \"person\"",
|
||||
" },",
|
||||
" \"kind\": \"delete\",",
|
||||
" \"old\": {",
|
||||
" \"archived\": false",
|
||||
" }",
|
||||
@ -2969,8 +2935,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -2991,12 +2956,12 @@
|
||||
" '{{uuid:generated_1}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'attachment'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"flags\": [",
|
||||
" \"urgent\",",
|
||||
@ -3027,8 +2992,7 @@
|
||||
" \"type\": \"type_metadata\"",
|
||||
" },",
|
||||
" \"type\": \"attachment\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
]
|
||||
]
|
||||
@ -3094,8 +3058,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -3109,12 +3072,12 @@
|
||||
" '{{uuid:generated_1}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'order_line'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"product\": \"Widget\",",
|
||||
" \"price\": 99.0,",
|
||||
@ -3131,8 +3094,7 @@
|
||||
" \"price\": 99.0,",
|
||||
" \"order_id\": \"abc\",",
|
||||
" \"type\": \"order_line\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
]
|
||||
]
|
||||
@ -3206,8 +3168,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -3221,12 +3182,12 @@
|
||||
" '{{uuid:generated_0}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'order_line'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"product\": \"Widget\",",
|
||||
" \"price\": 99.0,",
|
||||
@ -3243,8 +3204,7 @@
|
||||
" \"price\": 99.0,",
|
||||
" \"order_id\": \"abc\",",
|
||||
" \"type\": \"order_line\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
]
|
||||
]
|
||||
@ -3349,8 +3309,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -3382,8 +3341,7 @@
|
||||
" '{{uuid:generated_0}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'invoice'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
]
|
||||
]
|
||||
@ -3449,8 +3407,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -3463,12 +3420,12 @@
|
||||
" '{{uuid:generated_0}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'account'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"kind\": \"checking\",",
|
||||
" \"routing_number\": \"123456789\",",
|
||||
@ -3483,8 +3440,7 @@
|
||||
" \"kind\": \"checking\",",
|
||||
" \"routing_number\": \"123456789\",",
|
||||
" \"type\": \"account\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
]
|
||||
]
|
||||
@ -3577,8 +3533,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -3592,8 +3547,7 @@
|
||||
" '{{uuid:generated_2}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'person'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -3668,8 +3622,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -3682,8 +3635,7 @@
|
||||
" '{{uuid:generated_5}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'order_line'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -3726,8 +3678,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -3740,8 +3691,7 @@
|
||||
" '{{uuid:generated_7}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'order_line'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
@ -3752,8 +3702,7 @@
|
||||
" \"id\",",
|
||||
" \"kind\",",
|
||||
" \"modified_at\",",
|
||||
" \"modified_by\",",
|
||||
" \"entity_type\"",
|
||||
" \"modified_by\"",
|
||||
")",
|
||||
"VALUES (",
|
||||
" NULL,",
|
||||
@ -3766,12 +3715,12 @@
|
||||
" '{{uuid:generated_8}}',",
|
||||
" 'create',",
|
||||
" '{{timestamp}}',",
|
||||
" '00000000-0000-0000-0000-000000000000',",
|
||||
" 'order'",
|
||||
" '00000000-0000-0000-0000-000000000000'",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"organization_id\": \"parent-org-id\",",
|
||||
" \"id\": \"{{uuid:generated_3}}\",",
|
||||
@ -3786,12 +3735,12 @@
|
||||
" \"organization_id\": \"parent-org-id\",",
|
||||
" \"type\": \"order\",",
|
||||
" \"customer_id\": \"{{uuid:generated_0}}\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"first_name\": \"Const\",",
|
||||
" \"last_name\": \"Person\",",
|
||||
@ -3808,12 +3757,12 @@
|
||||
" \"last_name\": \"Person\",",
|
||||
" \"type\": \"person\",",
|
||||
" \"organization_id\": \"{{uuid:generated_1}}\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"order_id\": \"{{uuid:generated_3}}\",",
|
||||
" \"id\": \"{{uuid:generated_4}}\",",
|
||||
@ -3828,12 +3777,12 @@
|
||||
" \"order_id\": \"{{uuid:generated_3}}\",",
|
||||
" \"type\": \"order_line\",",
|
||||
" \"organization_id\": \"parent-org-id\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
],
|
||||
[
|
||||
"(SELECT pg_notify('entity', '{",
|
||||
" \"kind\": \"create\",",
|
||||
" \"complete\": {",
|
||||
" \"organization_id\": \"explicit-org-id\",",
|
||||
" \"order_id\": \"{{uuid:generated_3}}\",",
|
||||
@ -3848,8 +3797,7 @@
|
||||
" \"organization_id\": \"explicit-org-id\",",
|
||||
" \"order_id\": \"{{uuid:generated_3}}\",",
|
||||
" \"type\": \"order_line\"",
|
||||
" },",
|
||||
" \"kind\": \"create\"",
|
||||
" }",
|
||||
"}'))"
|
||||
]
|
||||
]
|
||||
|
||||
@ -159,7 +159,9 @@ impl Schema {
|
||||
},
|
||||
"null" => None,
|
||||
custom => {
|
||||
if db.enums.contains_key(custom) {
|
||||
if custom.ends_with(".condition") || custom.ends_with(".filter") {
|
||||
Some(vec![custom.to_string()])
|
||||
} else if db.enums.contains_key(custom) {
|
||||
Some(vec![format!("{}.condition", custom)])
|
||||
} else {
|
||||
// Assume anything else is a Relational cross-boundary that already has its own .filter dynamically built
|
||||
|
||||
@ -85,7 +85,6 @@ impl DatabaseExecutor for MockExecutor {
|
||||
Ok("2026-03-10T00:00:00Z".to_string())
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
fn get_queries(&self) -> Vec<String> {
|
||||
MOCK_STATE.with(|state| state.borrow().captured_queries.clone())
|
||||
|
||||
@ -20,7 +20,6 @@ pub trait DatabaseExecutor: Send + Sync {
|
||||
/// Returns the current transaction timestamp
|
||||
fn timestamp(&self) -> Result<String, String>;
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
fn get_queries(&self) -> Vec<String>;
|
||||
|
||||
|
||||
@ -150,5 +150,4 @@ impl DatabaseExecutor for SpiExecutor {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -138,7 +138,9 @@ impl Merger {
|
||||
is_child: bool,
|
||||
) -> Result<Value, String> {
|
||||
match data {
|
||||
Value::Array(items) => self.merge_array(schema, items, notifications, parent_org_id, is_child),
|
||||
Value::Array(items) => {
|
||||
self.merge_array(schema, items, notifications, parent_org_id, is_child)
|
||||
}
|
||||
Value::Object(map) => {
|
||||
if let Some(options) = schema.obj.compiled_options.get() {
|
||||
if let Some(disc) = schema.obj.compiled_discriminator.get() {
|
||||
@ -210,7 +212,13 @@ impl Merger {
|
||||
|
||||
let mut resolved_items = Vec::new();
|
||||
for item in items {
|
||||
let resolved = self.merge_internal(item_schema.clone(), item, notifications, parent_org_id.clone(), is_child)?;
|
||||
let resolved = self.merge_internal(
|
||||
item_schema.clone(),
|
||||
item,
|
||||
notifications,
|
||||
parent_org_id.clone(),
|
||||
is_child,
|
||||
)?;
|
||||
resolved_items.push(resolved);
|
||||
}
|
||||
Ok(Value::Array(resolved_items))
|
||||
@ -340,7 +348,10 @@ impl Merger {
|
||||
if let Some(relation) = self.db.relations.get(&edge.constraint) {
|
||||
let parent_is_source = edge.forward;
|
||||
|
||||
let org_id_to_pass = entity_fields.get("organization_id").and_then(|v| v.as_str()).map(|s| s.to_string());
|
||||
let org_id_to_pass = entity_fields
|
||||
.get("organization_id")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string());
|
||||
if parent_is_source {
|
||||
let mut merged_relative = match self.merge_internal(
|
||||
rel_schema.clone(),
|
||||
@ -443,7 +454,10 @@ impl Merger {
|
||||
}
|
||||
}
|
||||
|
||||
let org_id_to_pass = entity_fields.get("organization_id").and_then(|v| v.as_str()).map(|s| s.to_string());
|
||||
let org_id_to_pass = entity_fields
|
||||
.get("organization_id")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string());
|
||||
let mut relative_responses = Vec::new();
|
||||
for relative_item_val in relative_arr {
|
||||
if let Value::Object(mut relative_item) = relative_item_val {
|
||||
@ -574,7 +588,7 @@ impl Merger {
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("");
|
||||
let id_val = if entity_id.is_empty() {
|
||||
Value::String(uuid::Uuid::new_v4().to_string())
|
||||
Value::String(uuid::Uuid::now_v7().to_string())
|
||||
} else {
|
||||
Value::String(entity_id.to_string())
|
||||
};
|
||||
@ -946,12 +960,10 @@ impl Merger {
|
||||
Value::Object(old_vals)
|
||||
};
|
||||
|
||||
let entity_type_name = type_name.as_str().unwrap_or(&type_obj.name);
|
||||
|
||||
let mut notification = serde_json::Map::new();
|
||||
notification.insert("kind".to_string(), Value::String(change_kind.to_string()));
|
||||
notification.insert("complete".to_string(), Value::Object(complete));
|
||||
notification.insert("new".to_string(), new_val_obj.clone());
|
||||
notification.insert("kind".to_string(), Value::String(change_kind.to_string()));
|
||||
|
||||
if old_val_obj != Value::Null {
|
||||
notification.insert("old".to_string(), old_val_obj.clone());
|
||||
@ -964,15 +976,14 @@ impl Merger {
|
||||
let mut notify_sql = None;
|
||||
if type_obj.historical && change_kind != "replace" {
|
||||
let change_sql = format!(
|
||||
"INSERT INTO agreego.change (\"old\", \"new\", \"entity_id\", \"id\", \"kind\", \"modified_at\", \"modified_by\", \"entity_type\") VALUES ({}, {}, {}, {}, {}, {}, {}, {})",
|
||||
"INSERT INTO agreego.change (\"old\", \"new\", \"entity_id\", \"id\", \"kind\", \"modified_at\", \"modified_by\") VALUES ({}, {}, {}, {}, {}, {}, {})",
|
||||
Self::quote_literal(&old_val_obj),
|
||||
Self::quote_literal(&new_val_obj),
|
||||
Self::quote_literal(id_str),
|
||||
Self::quote_literal(&Value::String(uuid::Uuid::new_v4().to_string())),
|
||||
Self::quote_literal(&Value::String(uuid::Uuid::now_v7().to_string())),
|
||||
Self::quote_literal(&Value::String(change_kind.to_string())),
|
||||
Self::quote_literal(&Value::String(timestamp.to_string())),
|
||||
Self::quote_literal(&Value::String(user_id.to_string())),
|
||||
Self::quote_literal(&Value::String(entity_type_name.to_string()))
|
||||
Self::quote_literal(&Value::String(user_id.to_string()))
|
||||
);
|
||||
|
||||
self.db.execute(&change_sql, None)?;
|
||||
|
||||
Reference in New Issue
Block a user