@harperfast/template-react-ts-ssr-studio 1.13.3 → 1.13.5

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.
Files changed (48) hide show
  1. package/.agents/skills/harper-best-practices/AGENTS.md +687 -453
  2. package/.agents/skills/harper-best-practices/SKILL.md +24 -21
  3. package/.agents/skills/harper-best-practices/rules/adding-tables-with-schemas.md +2 -0
  4. package/.agents/skills/harper-best-practices/rules/automatic-apis.md +2 -0
  5. package/.agents/skills/harper-best-practices/rules/caching.md +2 -0
  6. package/.agents/skills/harper-best-practices/rules/checking-authentication.md +2 -0
  7. package/.agents/skills/harper-best-practices/rules/custom-resources.md +2 -0
  8. package/.agents/skills/harper-best-practices/rules/defining-relationships.md +102 -40
  9. package/.agents/skills/harper-best-practices/rules/deploying-from-ci.md +121 -93
  10. package/.agents/skills/harper-best-practices/rules/deploying-to-harper-fabric.md +149 -103
  11. package/.agents/skills/harper-best-practices/rules/extending-tables.md +2 -0
  12. package/.agents/skills/harper-best-practices/rules/handling-binary-data.md +2 -0
  13. package/.agents/skills/harper-best-practices/rules/load-env.md +2 -0
  14. package/.agents/skills/harper-best-practices/rules/logging.md +2 -0
  15. package/.agents/skills/harper-best-practices/rules/programmatic-table-requests.md +124 -91
  16. package/.agents/skills/harper-best-practices/rules/querying-rest-apis.md +86 -82
  17. package/.agents/skills/harper-best-practices/rules/real-time-apps.md +2 -0
  18. package/.agents/skills/harper-best-practices/rules/schema-design-tooling.md +92 -59
  19. package/.agents/skills/harper-best-practices/rules/serving-web-content.md +2 -0
  20. package/.agents/skills/harper-best-practices/rules/typescript-type-stripping.md +2 -0
  21. package/.agents/skills/harper-best-practices/rules/using-blob-datatype.md +2 -0
  22. package/.agents/skills/harper-best-practices/rules/vector-indexing.md +2 -0
  23. package/.agents/skills/harper-best-practices/rules.manifest.yaml +44 -0
  24. package/agent/skills/harper-best-practices/AGENTS.md +687 -453
  25. package/agent/skills/harper-best-practices/SKILL.md +26 -21
  26. package/agent/skills/harper-best-practices/rules/adding-tables-with-schemas.md +2 -0
  27. package/agent/skills/harper-best-practices/rules/automatic-apis.md +2 -0
  28. package/agent/skills/harper-best-practices/rules/caching.md +2 -0
  29. package/agent/skills/harper-best-practices/rules/checking-authentication.md +2 -0
  30. package/agent/skills/harper-best-practices/rules/custom-resources.md +2 -0
  31. package/agent/skills/harper-best-practices/rules/defining-relationships.md +102 -40
  32. package/agent/skills/harper-best-practices/rules/deploying-from-ci.md +121 -93
  33. package/agent/skills/harper-best-practices/rules/deploying-to-harper-fabric.md +149 -103
  34. package/agent/skills/harper-best-practices/rules/extending-tables.md +2 -0
  35. package/agent/skills/harper-best-practices/rules/handling-binary-data.md +2 -0
  36. package/agent/skills/harper-best-practices/rules/load-env.md +2 -0
  37. package/agent/skills/harper-best-practices/rules/logging.md +2 -0
  38. package/agent/skills/harper-best-practices/rules/programmatic-table-requests.md +124 -91
  39. package/agent/skills/harper-best-practices/rules/querying-rest-apis.md +86 -82
  40. package/agent/skills/harper-best-practices/rules/real-time-apps.md +2 -0
  41. package/agent/skills/harper-best-practices/rules/schema-design-tooling.md +92 -59
  42. package/agent/skills/harper-best-practices/rules/serving-web-content.md +2 -0
  43. package/agent/skills/harper-best-practices/rules/typescript-type-stripping.md +2 -0
  44. package/agent/skills/harper-best-practices/rules/using-blob-datatype.md +2 -0
  45. package/agent/skills/harper-best-practices/rules/vector-indexing.md +2 -0
  46. package/agent/skills/harper-best-practices/rules.manifest.yaml +44 -0
  47. package/package.json +1 -1
  48. package/skills-lock.json +1 -1
@@ -1,9 +1,10 @@
1
1
  ---
2
2
  name: harper-best-practices
3
- description: Best practices for building Harper applications, covering schema definition,
4
- automatic APIs, authentication, custom resources, and data handling.
5
- Triggers on tasks involving Harper database design, API implementation,
6
- and deployment.
3
+ description: How to implement a specific Harper feature correctly, with one rule per feature
4
+ (tables and schemas, relationships, automatic REST and WebSocket APIs, extending tables,
5
+ custom resources, caching, real-time, auth, blobs, vector indexes, static and Vite web serving,
6
+ logging, env loading, and deploying to Harper Fabric). Use when building or changing one of
7
+ these features. For deciding which services an app needs, read harper-architecture first.
7
8
  license: Apache-2.0
8
9
  metadata:
9
10
  author: harper
@@ -12,6 +13,8 @@ metadata:
12
13
 
13
14
  # Harper Best Practices
14
15
 
16
+ > Deciding what to build or which services an app needs? Read the `harper-architecture` skill first. This skill covers how to implement each Harper feature once that decision is made.
17
+
15
18
  Guidelines for building scalable, secure, and performant applications on Harper. These practices cover everything from initial schema design to advanced deployment strategies.
16
19
 
17
20
  ## When to Use
@@ -53,37 +56,37 @@ See the concrete examples embedded in each rule subsection below (GraphQL schema
53
56
 
54
57
  ### 1. Schema & Data Design (HIGH)
55
58
 
56
- - `adding-tables-with-schemas` — Guidelines for adding tables to a Harper database using GraphQL schemas.
59
+ - `adding-tables-with-schemas` — Guidelines for adding tables to a Harper database using GraphQL schemas. (instead of: Postgres, MySQL, MongoDB, DynamoDB, Supabase, Firebase)
57
60
  - `schema-design-tooling` — Best practices for Harper schema design, including core directives and GraphQL tooling configuration.
58
- - `defining-relationships` — How to define and use relationships between tables in Harper using GraphQL.
59
- - `vector-indexing` — How to enable and query vector indexes for similarity search in Harper.
60
- - `using-blob-datatype` — How to use the Blob data type for efficient binary storage in Harper.
61
- - `handling-binary-data` — How to store and serve binary data like images or audio in Harper.
61
+ - `defining-relationships` — How to define and use relationships between tables in Harper using GraphQL. (instead of: ORM relations and join tables (Prisma, Drizzle, Sequelize))
62
+ - `vector-indexing` — How to enable and query vector indexes for similarity search in Harper. (instead of: Pinecone, Weaviate, pgvector)
63
+ - `using-blob-datatype` — How to use the Blob data type for efficient binary storage in Harper. (instead of: S3 or GCS buckets for app-managed files)
64
+ - `handling-binary-data` — How to store and serve binary data like images or audio in Harper. (instead of: S3 or GCS buckets for app-managed files)
62
65
 
63
66
  ### 2. API & Communication (HIGH)
64
67
 
65
- - `automatic-apis` — How to use Harper's automatically generated REST and WebSocket APIs.
68
+ - `automatic-apis` — How to use Harper's automatically generated REST and WebSocket APIs. (instead of: Hand-written CRUD routes (Express, Fastify, Next.js API routes))
66
69
  - `querying-rest-apis` — How to use query parameters to filter, sort, and paginate Harper REST APIs.
67
- - `real-time-apps` — How to build real-time features in Harper using WebSockets and Pub/Sub.
68
- - `checking-authentication` — How to handle user authentication and sessions in Harper Resources.
70
+ - `real-time-apps` — How to build real-time features in Harper using WebSockets and Pub/Sub. (instead of: Socket.io, `ws`, Pusher, Ably, Redis pub/sub, a separate MQTT broker)
71
+ - `checking-authentication` — How to handle user authentication and sessions in Harper Resources. (instead of: Hand-rolled sessions, `passport`, `jsonwebtoken`, `bcrypt`)
69
72
 
70
73
  ### 3. Logic & Extension (MEDIUM)
71
74
 
72
- - `custom-resources` — How to define custom REST endpoints with JavaScript or TypeScript in Harper.
73
- - `extending-tables` — How to add custom logic to automatically generated table resources in Harper.
74
- - `programmatic-table-requests` — How to interact with Harper tables programmatically using the `tables` object.
75
- - `typescript-type-stripping` — How to run TypeScript files directly in Harper without a build step.
76
- - `caching` — How to implement integrated data caching in Harper from external sources.
75
+ - `custom-resources` — How to define custom REST endpoints with JavaScript or TypeScript in Harper. (instead of: Express, Fastify, or Koa route handlers; serverless functions)
76
+ - `extending-tables` — How to add custom logic to automatically generated table resources in Harper. (instead of: Middleware and controllers wrapped around CRUD routes)
77
+ - `programmatic-table-requests` — How to interact with Harper tables programmatically using the `tables` object. (instead of: ORM and query-builder clients (Prisma, Drizzle, Knex))
78
+ - `typescript-type-stripping` — How to run TypeScript files directly in Harper without a build step. (instead of: `tsc` or `ts-node` build steps for server code)
79
+ - `caching` — How to implement integrated data caching in Harper from external sources. (instead of: Redis or Memcached cache-aside layers)
77
80
 
78
81
  ### 4. Infrastructure & Ops (MEDIUM)
79
82
 
80
- - `deploying-to-harper-fabric` — How to deploy a Harper application to Harper Fabric with the CLI, check that the release was certified, and roll back by activating a previous release's `deployment_id`.
83
+ - `deploying-to-harper-fabric` — How to deploy a Harper application to Harper Fabric with the CLI, check that the release was certified, and roll back by activating a previous release's `deployment_id`. (instead of: Docker Compose stacks; deploying several services separately)
81
84
  - `deploying-from-ci` — How to deploy a Harper application from GitHub Actions with OIDC trusted publishing, so CI stores no Harper credential, including the one-command setup with `harper deploy setup=true provider=github-actions`.
82
85
  - `creating-a-fabric-account-and-cluster` — How to create a Harper Fabric account, organization, and cluster.
83
86
  - `creating-harper-apps` — How to initialize a new Harper application using the CLI.
84
- - `serving-web-content` — How to serve static files and integrated Vite/React applications in Harper.
85
- - `logging` — Best practices for logging in Harper, including console capture, the granular logger interface, and programmatic log retrieval.
86
- - `load-env` — How to load environment variables from .env files into a Harper application using the loadEnv plugin.
87
+ - `serving-web-content` — How to serve static files and integrated Vite/React applications in Harper. (instead of: Nginx, Vercel, or Netlify for the frontend; a separate Vite dev server)
88
+ - `logging` — Best practices for logging in Harper, including console capture, the granular logger interface, and programmatic log retrieval. (instead of: Separate log shippers for app logs (pino or winston transports))
89
+ - `load-env` — How to load environment variables from .env files into a Harper application using the loadEnv plugin. (instead of: `dotenv`)
87
90
  - `v5-upgrade` — Breaking changes and recommended updates when migrating a Harper application to v5.
88
91
  - `delegating-to-the-built-in-agent` — How to delegate tasks to Harper's built-in agent via the CLI and the agent operations API.
89
92
 
@@ -9,6 +9,8 @@ metadata:
9
9
 
10
10
  Instructions for the agent to follow when adding tables to a Harper database.
11
11
 
12
+ **Instead of:** Postgres, MySQL, MongoDB, DynamoDB, Supabase, Firebase. Use this rule rather than adding that service. See `harper-architecture`.
13
+
12
14
  ## When to Use
13
15
 
14
16
  Use this skill when you need to define new data structures or modify existing ones in a Harper database.
@@ -20,6 +20,8 @@ metadata:
20
20
 
21
21
  Instructions for the agent to follow when using Harper's automatically generated REST and WebSocket APIs for exported tables and resources.
22
22
 
23
+ **Instead of:** Hand-written CRUD routes (Express, Fastify, Next.js API routes). Use this rule rather than adding that service. See `harper-architecture`.
24
+
23
25
  ## When to Use
24
26
 
25
27
  Apply this rule when enabling HTTP REST endpoints or WebSocket subscriptions for Harper tables and custom resources. Use it whenever you need to configure the REST plugin, understand the auto-generated endpoint surface, or wire up real-time WebSocket connections. See [querying-rest-apis.md](querying-rest-apis.md) for query syntax and [real-time-apps.md](real-time-apps.md) for real-time patterns.
@@ -13,6 +13,8 @@ metadata:
13
13
 
14
14
  Instructions for the agent to implement integrated data caching from external sources using Harper's cache table directives and `sourcedFrom` API.
15
15
 
16
+ **Instead of:** Redis or Memcached cache-aside layers. Use this rule rather than adding that service. See `harper-architecture`.
17
+
16
18
  ## When to Use
17
19
 
18
20
  Apply this rule when an application needs to wrap an external API, microservice, or database with a fast local cache. Use it when you need to define TTL-based cache expiration, connect an upstream data source to a Harper table, or implement on-demand cache invalidation.
@@ -27,6 +27,8 @@ metadata:
27
27
 
28
28
  Instructions for the agent to handle user authentication, sessions, and JWT token issuance in Harper Resources.
29
29
 
30
+ **Instead of:** Hand-rolled sessions, `passport`, `jsonwebtoken`, `bcrypt`. Use this rule rather than adding that service. See `harper-architecture`.
31
+
30
32
  ## When to Use
31
33
 
32
34
  Apply this rule when implementing login/logout flows, reading the current authenticated user, issuing or refreshing JWT tokens, or minting scoped tokens from a custom Resource. Use it whenever a Resource must gate behavior on identity or credentials. See [custom-resources.md](custom-resources.md) for the broader Resource authoring model.
@@ -15,6 +15,8 @@ metadata:
15
15
 
16
16
  Instructions for the agent to follow when defining custom REST endpoints with JavaScript or TypeScript in Harper.
17
17
 
18
+ **Instead of:** Express, Fastify, or Koa route handlers; serverless functions. Use this rule rather than adding that service. See `harper-architecture`.
19
+
18
20
  ## When to Use
19
21
 
20
22
  Apply this rule when you need to create custom HTTP endpoints, wrap external APIs, or register routes programmatically in a Harper application. Use it any time business logic must live outside a table-backed schema, or when you need fine-grained control over URL shape and path parameters.
@@ -6,21 +6,23 @@ metadata:
6
6
  sources:
7
7
  - reference/v5/database/schema.md#Relationships
8
8
  - reference/v5/rest/querying.md#Relationships and Joins
9
- sourceCommit: 3749d0c54be457a2a65d9a63c738a5dc88989ecd
10
- inputHash: fd399fd81a88f13e
9
+ sourceCommit: bea4e62cb7efd809bb67e00cbda01a410c1177b1
10
+ inputHash: 58ffc789fa71ffe6
11
11
  ---
12
12
 
13
13
  # Defining Relationships Between Tables in Harper
14
14
 
15
- Instructions for the agent to follow when defining and querying relationships between tables in Harper using the `@relationship` directive.
15
+ Instructions for the agent to define and query relationships between Harper tables using the `@relationship` directive in GraphQL schemas.
16
+
17
+ **Instead of:** ORM relations and join tables (Prisma, Drizzle, Sequelize). Use this rule rather than adding that service. See `harper-architecture`.
16
18
 
17
19
  ## When to Use
18
20
 
19
- Apply this rule when adding foreign key relationships between schema tables, enabling join queries, or returning nested related records in query results. Use it any time a schema type needs to reference records in another table via a foreign key attribute.
21
+ Apply this rule when writing Harper schemas that require join queries across tables, or when query results must include related records as nested properties. Use it whenever a foreign key exists in one table that references another, or when modeling one-to-many, many-to-one, or many-to-many associations.
20
22
 
21
23
  ## How It Works
22
24
 
23
- 1. **Use `@relationship(from: attribute)` for many-to-one or many-to-many**: Place this on the field in the table that holds the foreign key. The `from` parameter names the attribute on this table that stores the foreign key referencing the target table's primary key.
25
+ 1. **Declare a many-to-one relationship with `from`**: Place `@relationship(from: attribute)` on a field when the foreign key lives in the current table and references the primary key of the target table. The result type is a single object.
24
26
 
25
27
  ```graphql
26
28
  type RealityShow @table @export {
@@ -36,17 +38,7 @@ Apply this rule when adding foreign key relationships between schema tables, ena
36
38
  }
37
39
  ```
38
40
 
39
- If the foreign key attribute is an array, the relationship becomes many-to-many:
40
-
41
- ```graphql
42
- type RealityShow @table @export {
43
- id: Long @primaryKey
44
- networkIds: [Long] @indexed
45
- networks: [Network] @relationship(from: networkIds)
46
- }
47
- ```
48
-
49
- 2. **Use `@relationship(to: attribute)` for one-to-many or many-to-many**: Place this on the table whose primary key is referenced by the foreign key in the target table. The `to` parameter names the attribute on the target table that holds the foreign key. The result type **must** be an array.
41
+ 2. **Declare a one-to-many relationship with `to`**: Place `@relationship(to: attribute)` on a field when the foreign key lives in the target table and references the primary key of the current table. The result type **must** be an array.
50
42
 
51
43
  ```graphql
52
44
  type Network @table @export {
@@ -56,14 +48,14 @@ Apply this rule when adding foreign key relationships between schema tables, ena
56
48
  }
57
49
  ```
58
50
 
59
- 3. **Use `@relationship(from: attribute, to: attribute)` for foreign key to foreign key joins**: Specify both `from` and `to` when neither side uses the primary key. Harper resolves the relationship by searching the target table's `to` attribute for matches using this record's `from` attribute value. The result type must be an array.
51
+ 3. **Declare a foreign-key-to-foreign-key relationship with `@relationship(from: attribute, to: attribute)`**: Specify both `from` and `to` when neither side uses the primary key. Harper resolves the relationship by searching the target table's `to` attribute for matches using the current record's `from` attribute value. The result type must be an array.
60
52
 
61
53
  ```graphql
62
54
  type OrderItem @table @export {
63
55
  id: Long @primaryKey
64
56
  orderId: Long @indexed
65
57
  productSku: Long @indexed
66
- products: [Product] @relationship(from: productSku, to: sku)
58
+ products: [Product] @relationship(from: productSku, to: sku) # matches products by sku, not primary key
67
59
  }
68
60
 
69
61
  type Product @table @export {
@@ -73,14 +65,25 @@ Apply this rule when adding foreign key relationships between schema tables, ena
73
65
  }
74
66
  ```
75
67
 
76
- 4. **Query across relationships using dot-syntax**: Filter records by related table attributes using chained dot notation. This behaves as an INNER JOIN — only records with a matching related record are returned.
68
+ 4. **Declare a many-to-many relationship using an array foreign key with `from`**: When the foreign key field is an array, `@relationship(from: attribute)` establishes a many-to-many relationship. The result type must be an array.
69
+
70
+ ```graphql
71
+ type RealityShow @table @export {
72
+ id: Long @primaryKey
73
+ networkIds: [Long] @indexed
74
+ networks: [Network] @relationship(from: networkIds)
75
+ }
76
+ ```
77
+
78
+ 5. **Query across relationships using dot-syntax**: Filter records by related table attributes using dot-chained attribute names. This behaves as an INNER JOIN — only parents with a qualifying related record are returned.
77
79
 
78
80
  ```
81
+ GET /RealityShow?network.name=Bravo
79
82
  GET /Product/?brand.name=Microsoft
80
83
  GET /Brand/?products.name=Keyboard
81
84
  ```
82
85
 
83
- 5. **Include relationship fields in results using `select()`**: Relationship attributes are not returned by default. Use `select()` to include them, optionally specifying nested fields with `{}`.
86
+ 6. **Include relationship fields in results using `select()`**: Relationship attributes are not included by default. Use `select()` to project them, optionally with a nested field list using `{}`.
84
87
 
85
88
  ```
86
89
  GET /Product/?brand.name=Microsoft&select(name,brand)
@@ -88,24 +91,27 @@ Apply this rule when adding foreign key relationships between schema tables, ena
88
91
  GET /Product/?name=Keyboard&select(name,brand{name,id})
89
92
  ```
90
93
 
91
- When selecting a relationship without filtering on it, Harper performs a LEFT JOIN — the relationship property is omitted if the foreign key is null or references a non-existent record.
94
+ Selecting a relationship without an outer dot-syntax filter on it behaves as a LEFT JOIN: parents remain even when there are no related records.
92
95
 
93
- 6. **Model many-to-many without a junction table**: Store an array of foreign key values and use `@relationship(from: ...)` pointing to that array attribute. The array order of the foreign key values is preserved when resolving the relationship.
96
+ 7. **Filter and page nested relationship results using `[]` inside `select()`**: Apply conditions, sort, and pagination to each parent's related records by placing them inside square brackets in the `select()` expression.
94
97
 
95
- ```graphql
96
- type Product @table @export {
97
- id: Long @primaryKey
98
- name: String
99
- resellerIds: [Long] @indexed
100
- resellers: [Reseller] @relationship(from: "resellerIds")
101
- }
102
98
  ```
99
+ GET /Brand/?select(id,name,products[price=ge=number:30&sort(price)&limit(1)&select(id,name,price)])
100
+ ```
101
+
102
+ An outer relationship filter (e.g., `products.price=ge=number:30`) removes parents without a qualifying child **and** narrows the nested candidates. A filter inside `products[...]` only narrows projected children without removing their parent.
103
103
 
104
- 7. **Define self-referential relationships** for parent-child hierarchies by pointing `@relationship` back at the same table type.
104
+ | Nested option | Behavior |
105
+ | ------------------ | -------------------------------------------------------------------------- |
106
+ | Conditions | Qualify children; combine with `&` (AND), `\|` (OR), and groups. |
107
+ | `sort(price)` | Order eligible children before pagination. |
108
+ | `limit(end)` | Return at most `end` children per parent. |
109
+ | `limit(start,end)` | Skip `start` eligible children and return at most `end - start`. |
110
+ | `select(id,price)` | Project fields from returned children; omit to return whole child records. |
105
111
 
106
112
  ## Examples
107
113
 
108
- **Full schema with bidirectional relationships:**
114
+ ### Schema with bidirectional relationships
109
115
 
110
116
  ```graphql
111
117
  type Product @table @export {
@@ -122,22 +128,78 @@ type Brand @table @export {
122
128
  }
123
129
  ```
124
130
 
125
- **Querying with joins and nested select:**
131
+ ### Many-to-many without a junction table
132
+
133
+ ```graphql
134
+ type Product @table @export {
135
+ id: Long @primaryKey
136
+ name: String
137
+ resellerIds: [Long] @indexed
138
+ resellers: [Reseller] @relationship(from: "resellerIds")
139
+ }
140
+ ```
141
+
142
+ ```
143
+ GET /Product/?resellers.name=Cool Shop&select(id,name,resellers{name,id})
144
+ ```
145
+
146
+ The array order of `resellerIds` is preserved when resolving the relationship.
147
+
148
+ ### Nested filtering and pagination scenarios
149
+
150
+ Schema for the following examples:
151
+
152
+ ```graphql
153
+ type Brand @table @export {
154
+ id: Int @primaryKey
155
+ name: String @indexed
156
+ products: [Product] @relationship(to: "brandId")
157
+ }
158
+
159
+ type Product @table @export {
160
+ id: ID @primaryKey
161
+ brandId: Int @indexed
162
+ name: String
163
+ price: Int @indexed
164
+ }
165
+ ```
166
+
167
+ **Keep every brand; show its cheapest product costing at least 30** (LEFT JOIN behavior — Budget Basics returns with an empty product list):
126
168
 
127
169
  ```
128
- GET /Product/?brand.name=Microsoft&select(name,brand{name,id})
129
- GET /Brand/?products.name=Keyboard
170
+ GET /Brand/?select(id,name,products[price=ge=number:30&sort(price)&limit(1)&select(id,name,price)])
130
171
  ```
131
172
 
132
- **Many-to-many query with nested select:**
173
+ **Return only qualifying brands; inherit the outer price filter** (INNER JOIN behavior — Budget Basics is removed):
133
174
 
134
175
  ```
135
- GET /Product/?resellers.name=Cool Shop&select(id,name,resellers{name,id})
176
+ GET /Brand/?products.price=ge=number:30&select(id,name,products[sort(price)&limit(1)&select(id,name,price)])
177
+ ```
178
+
179
+ **Page through each brand's qualifying products** (offset applies independently per brand):
180
+
181
+ ```
182
+ GET /Brand/?products.price=ge=number:30&select(id,name,products[sort(price)&limit(1,2)&select(id,name,price)])
183
+ ```
184
+
185
+ **Bound parent pages with stable sorting**:
186
+
187
+ ```
188
+ GET /Brand/?products.price=ge=number:30&sort(name,id)&limit(0,20)&select(id,name,products[sort(price,id)&limit(1)&select(id,name,price)])
189
+ ```
190
+
191
+ **Combine OR filters with child sorting and pagination**:
192
+
193
+ ```
194
+ GET /Brand/?sort(name,id)&limit(0,20)&select(id,name,products[[price=lt=number:30|price=ge=number:60]&sort(-price,id)&limit(1,2)&select(id,name,price)])
136
195
  ```
137
196
 
138
197
  ## Notes
139
198
 
140
- - Every attribute named in `from` or `to` must exist on the respective table and be annotated with `@indexed` to support join queries.
141
- - The `to`-only and `from`+`to` forms both require the result field type to be an array (e.g., `[RealityShow]`).
142
- - The `from`-only form on a non-array attribute produces a many-to-one relationship; on an array attribute it produces many-to-many.
143
- - Self-referential relationships are supported for hierarchical data within a single table.
199
+ - Index all foreign key fields (e.g., `brandId`, `price`) and outer filter fields to support efficient join queries.
200
+ - Use a unique field as the final sort key (e.g., `sort(price,id)`) to ensure deterministic ordering when values are equal.
201
+ - A nested `limit()` bounds children per parent, not the number of parents. Apply a separate outer `limit()` to bound the parent result set.
202
+ - Nested filters require a table-backed relationship. Filters on plain JSON projections or full-text predicates inside a relationship selection return HTTP 400.
203
+ - Invalid `limit()` bounds (negative or fractional values) return HTTP 400. `limit(0)` returns no children without reading them.
204
+ - A condition traversing another relationship qualifies the immediate child only; it does not narrow that child's projected descendants. Place grandchild constraints in the grandchild's own bracket selection.
205
+ - Schemas can define self-referential relationships to enable parent-child hierarchies within a single table.