@harperfast/template-react-ts-studio 1.11.2 → 1.11.4
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/.agents/skills/harper-best-practices/AGENTS.md +702 -490
- package/.agents/skills/harper-best-practices/SKILL.md +1 -0
- package/.agents/skills/harper-best-practices/rules/automatic-apis.md +46 -78
- package/.agents/skills/harper-best-practices/rules/defining-relationships.md +41 -63
- package/.agents/skills/harper-best-practices/rules/delegating-to-the-built-in-agent.md +141 -0
- package/.agents/skills/harper-best-practices/rules/deploying-to-harper-fabric.md +59 -45
- package/.agents/skills/harper-best-practices/rules/load-env.md +24 -23
- package/.agents/skills/harper-best-practices/rules/programmatic-table-requests.md +62 -78
- package/.agents/skills/harper-best-practices/rules/querying-rest-apis.md +92 -65
- package/.agents/skills/harper-best-practices/rules/schema-design-tooling.md +53 -55
- package/.agents/skills/harper-best-practices/rules/v5-upgrade.md +98 -62
- package/.agents/skills/harper-best-practices/rules/vector-indexing.md +113 -42
- package/.agents/skills/harper-best-practices/rules.manifest.yaml +9 -0
- package/.agents/skills/harper-mcp/AGENTS.md +501 -0
- package/.agents/skills/harper-mcp/SKILL.md +91 -0
- package/.agents/skills/harper-mcp/rules/automatic-verb-tools.md +50 -0
- package/.agents/skills/harper-mcp/rules/connecting-clients.md +59 -0
- package/.agents/skills/harper-mcp/rules/custom-mcp-prompts.md +52 -0
- package/.agents/skills/harper-mcp/rules/custom-mcp-resources.md +64 -0
- package/.agents/skills/harper-mcp/rules/custom-mcp-tools.md +72 -0
- package/.agents/skills/harper-mcp/rules/durable-quotas.md +73 -0
- package/.agents/skills/harper-mcp/rules/enabling-mcp.md +63 -0
- package/.agents/skills/harper-mcp/rules/rate-limiting.md +62 -0
- package/.agents/skills/harper-mcp/rules/resources-surface.md +44 -0
- package/.agents/skills/harper-mcp/rules/security-posture.md +36 -0
- package/.agents/skills/harper-mcp/rules.manifest.yaml +203 -0
- package/agent/skills/harper-best-practices/AGENTS.md +702 -490
- package/agent/skills/harper-best-practices/SKILL.md +1 -0
- package/agent/skills/harper-best-practices/rules/automatic-apis.md +46 -78
- package/agent/skills/harper-best-practices/rules/defining-relationships.md +41 -63
- package/agent/skills/harper-best-practices/rules/delegating-to-the-built-in-agent.md +141 -0
- package/agent/skills/harper-best-practices/rules/deploying-to-harper-fabric.md +59 -45
- package/agent/skills/harper-best-practices/rules/load-env.md +24 -23
- package/agent/skills/harper-best-practices/rules/programmatic-table-requests.md +62 -78
- package/agent/skills/harper-best-practices/rules/querying-rest-apis.md +92 -65
- package/agent/skills/harper-best-practices/rules/schema-design-tooling.md +53 -55
- package/agent/skills/harper-best-practices/rules/v5-upgrade.md +98 -62
- package/agent/skills/harper-best-practices/rules/vector-indexing.md +113 -42
- package/agent/skills/harper-best-practices/rules.manifest.yaml +9 -0
- package/agent/skills/harper-mcp/AGENTS.md +501 -0
- package/agent/skills/harper-mcp/SKILL.md +83 -0
- package/agent/skills/harper-mcp/rules/automatic-verb-tools.md +50 -0
- package/agent/skills/harper-mcp/rules/connecting-clients.md +59 -0
- package/agent/skills/harper-mcp/rules/custom-mcp-prompts.md +52 -0
- package/agent/skills/harper-mcp/rules/custom-mcp-resources.md +64 -0
- package/agent/skills/harper-mcp/rules/custom-mcp-tools.md +72 -0
- package/agent/skills/harper-mcp/rules/durable-quotas.md +73 -0
- package/agent/skills/harper-mcp/rules/enabling-mcp.md +63 -0
- package/agent/skills/harper-mcp/rules/rate-limiting.md +62 -0
- package/agent/skills/harper-mcp/rules/resources-surface.md +44 -0
- package/agent/skills/harper-mcp/rules/security-posture.md +36 -0
- package/agent/skills/harper-mcp/rules.manifest.yaml +203 -0
- package/package.json +1 -1
- package/skills-lock.json +7 -1
|
@@ -5,17 +5,17 @@ metadata:
|
|
|
5
5
|
mode: generate
|
|
6
6
|
sources:
|
|
7
7
|
- reference/v5/rest/querying.md
|
|
8
|
-
sourceCommit:
|
|
9
|
-
inputHash:
|
|
8
|
+
sourceCommit: 3749d0c54be457a2a65d9a63c738a5dc88989ecd
|
|
9
|
+
inputHash: d5ed0e937cd2d7e0
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
# Querying REST APIs
|
|
12
|
+
# Querying Harper REST APIs
|
|
13
13
|
|
|
14
|
-
Instructions for the agent to filter, sort, select, and paginate Harper
|
|
14
|
+
Instructions for the agent to filter, sort, select, and paginate records using Harper's URL-based query language on REST collection endpoints.
|
|
15
15
|
|
|
16
16
|
## When to Use
|
|
17
17
|
|
|
18
|
-
Apply this rule when building or
|
|
18
|
+
Apply this rule when building or debugging REST API calls against Harper tables that require filtering by attribute values, comparison ranges, sorting, field selection, or result pagination. This rule also covers OR logic, grouping, and querying across related tables via dot-syntax joins. See [automatic-apis.md](automatic-apis.md) for how Harper exposes tables as REST endpoints.
|
|
19
19
|
|
|
20
20
|
## How It Works
|
|
21
21
|
|
|
@@ -26,21 +26,27 @@ Apply this rule when building or modifying code that queries Harper REST endpoin
|
|
|
26
26
|
GET /Product/?category=software&inStock=true
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
2. **
|
|
29
|
+
2. **Filter for null values**: Use `=null` as the value to match null or non-null records.
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
| `=
|
|
41
|
-
| `=
|
|
42
|
-
|
|
|
43
|
-
|
|
|
31
|
+
```
|
|
32
|
+
GET /Product/?discount=null
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
3. **Apply comparison operators (FIQL syntax)**: Use FIQL operators in query parameters for range and string matching.
|
|
36
|
+
|
|
37
|
+
| Operator | Meaning |
|
|
38
|
+
| -------------------- | -------------------------------------- |
|
|
39
|
+
| `==` | Equal |
|
|
40
|
+
| `=lt=` | Less than |
|
|
41
|
+
| `=le=` | Less than or equal |
|
|
42
|
+
| `=gt=` | Greater than |
|
|
43
|
+
| `=ge=` | Greater than or equal |
|
|
44
|
+
| `=ne=`, `!=` | Not equal |
|
|
45
|
+
| `=ct=` | Contains (strings) |
|
|
46
|
+
| `=sw=`, `==<value>*` | Starts with (strings) |
|
|
47
|
+
| `=ew=` | Ends with (strings) |
|
|
48
|
+
| `=`, `===` | Strict equality (no type conversion) |
|
|
49
|
+
| `!==` | Strict inequality (no type conversion) |
|
|
44
50
|
|
|
45
51
|
```
|
|
46
52
|
GET /Product/?price=gt=100
|
|
@@ -55,32 +61,52 @@ Apply this rule when building or modifying code that queries Harper REST endpoin
|
|
|
55
61
|
GET /Product/?listDate=gt=2017-03-08T09%3A30%3A00.000Z
|
|
56
62
|
```
|
|
57
63
|
|
|
58
|
-
|
|
64
|
+
4. **Chain conditions for range queries**: Omit the attribute name on the second condition to apply it to the same attribute. Only `gt`/`ge` combined with `lt`/`le` is supported for chaining.
|
|
59
65
|
|
|
60
66
|
```
|
|
61
67
|
GET /Product/?price=gt=100<=200
|
|
62
68
|
```
|
|
63
69
|
|
|
64
|
-
|
|
70
|
+
5. **Apply type conversion**: For FIQL comparators, Harper converts values automatically. Use explicit prefixes to force a type.
|
|
71
|
+
|
|
72
|
+
| Syntax | Behavior |
|
|
73
|
+
| ----------------------------------------- | ------------------------------------------- |
|
|
74
|
+
| `name==null` | Converts to `null` |
|
|
75
|
+
| `name==123` | Converts to number if attribute is untyped |
|
|
76
|
+
| `name==true` | Converts to boolean if attribute is untyped |
|
|
77
|
+
| `name==number:123` | Explicit number conversion |
|
|
78
|
+
| `name==boolean:true` | Explicit boolean conversion |
|
|
79
|
+
| `name==string:some%20text` | Keep as string with URL decode |
|
|
80
|
+
| `name==date:2024-01-05T20%3A07%3A27.955Z` | Explicit Date conversion |
|
|
81
|
+
|
|
82
|
+
For strict operators (`=`, `===`, `!==`), no automatic type conversion is applied.
|
|
83
|
+
|
|
84
|
+
6. **Combine conditions with OR logic**: Use `|` instead of `&` to express OR between conditions.
|
|
65
85
|
|
|
66
86
|
```
|
|
67
87
|
GET /Product/?rating=5|featured=true
|
|
68
88
|
```
|
|
69
89
|
|
|
70
|
-
|
|
90
|
+
7. **Group conditions**: Use parentheses or square brackets to control evaluation order. Prefer square brackets when building queries from user input, since `[` and `]` are safely URI-encoded.
|
|
71
91
|
|
|
72
92
|
```
|
|
73
93
|
GET /Product/?rating=5|(price=gt=100&price=lt=200)
|
|
74
94
|
GET /Product/?rating=5&[tag=fast|tag=scalable|tag=efficient]
|
|
75
95
|
```
|
|
76
96
|
|
|
77
|
-
|
|
97
|
+
Build grouped queries in JavaScript:
|
|
78
98
|
|
|
79
99
|
```javascript
|
|
80
100
|
let url = `/Product/?rating=5&[${tags.map(encodeURIComponent).join('|')}]`;
|
|
81
101
|
```
|
|
82
102
|
|
|
83
|
-
|
|
103
|
+
Nest groups for complex conditions:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
GET /Product/?price=lt=100|[rating=5&[tag=fast|tag=scalable|tag=efficient]&inStock=true]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
8. **Select specific properties with `select(`**: Append `select(...)` as a query function separated by `&` to control which fields are returned.
|
|
84
110
|
|
|
85
111
|
| Syntax | Returns |
|
|
86
112
|
| -------------------------------------- | ------------------------------------------- |
|
|
@@ -95,108 +121,109 @@ Apply this rule when building or modifying code that queries Harper REST endpoin
|
|
|
95
121
|
GET /Product/?brand.name=Microsoft&select(name,brand{name})
|
|
96
122
|
```
|
|
97
123
|
|
|
98
|
-
|
|
124
|
+
9. **Paginate results with `limit(`**: Use `limit(end)` or `limit(start,end)` to restrict the number of records returned.
|
|
99
125
|
|
|
100
126
|
```
|
|
101
127
|
GET /Product/?rating=gt=3&inStock=true&select(rating,name)&limit(20)
|
|
102
128
|
GET /Product/?rating=gt=3&limit(10,30)
|
|
103
129
|
```
|
|
104
130
|
|
|
105
|
-
|
|
131
|
+
10. **Sort results with `sort(`**: Use `sort(property)` or `sort(+property,-property,...)` to order results. Prefix `+` or no prefix = ascending; `-` = descending.
|
|
106
132
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
133
|
+
```
|
|
134
|
+
GET /Product/?rating=gt=3&sort(+name)
|
|
135
|
+
GET /Product/?sort(+rating,-price)
|
|
136
|
+
```
|
|
111
137
|
|
|
112
|
-
|
|
138
|
+
11. **Query across relationships using dot-syntax**: Filter on related table attributes using dot-chained property names. Relationships must be defined in the schema with `@relationship`.
|
|
113
139
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
140
|
+
```
|
|
141
|
+
GET /Product/?brand.name=Microsoft
|
|
142
|
+
GET /Brand/?products.name=Keyboard
|
|
143
|
+
```
|
|
118
144
|
|
|
119
|
-
|
|
145
|
+
Use `select()` to include relationship attributes in the response (they are excluded by default):
|
|
120
146
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
147
|
+
```
|
|
148
|
+
GET /Product/?brand.name=Microsoft&select(name,brand)
|
|
149
|
+
GET /Product/?brand.name=Microsoft&select(name,brand{name})
|
|
150
|
+
```
|
|
124
151
|
|
|
125
|
-
|
|
152
|
+
12. **Access a specific property by URL**: Append `.propertyName` to a record ID in the URL path. Only works for properties declared in the schema.
|
|
126
153
|
```
|
|
127
154
|
GET /MyTable/123.propertyName
|
|
128
155
|
```
|
|
129
156
|
|
|
130
157
|
## Examples
|
|
131
158
|
|
|
132
|
-
**Range filter with select and limit
|
|
159
|
+
**Range filter with select and limit**:
|
|
133
160
|
|
|
134
161
|
```
|
|
135
162
|
GET /Product/?category=software&price=gt=100&price=lt=200&select(name,price)&limit(20)
|
|
136
163
|
```
|
|
137
164
|
|
|
138
|
-
**Sort
|
|
165
|
+
**Sort and paginate**:
|
|
139
166
|
|
|
140
167
|
```
|
|
141
|
-
GET /Product/?sort(+rating,-price)
|
|
168
|
+
GET /Product/?rating=gt=3&sort(+rating,-price)&limit(10,30)
|
|
142
169
|
```
|
|
143
170
|
|
|
144
|
-
**OR
|
|
171
|
+
**OR with grouping**:
|
|
145
172
|
|
|
146
173
|
```
|
|
147
174
|
GET /Product/?price=lt=100|[rating=5&[tag=fast|tag=scalable|tag=efficient]&inStock=true]
|
|
148
175
|
```
|
|
149
176
|
|
|
150
|
-
**
|
|
151
|
-
|
|
152
|
-
```
|
|
153
|
-
GET /Product/?brand.name=Microsoft&select(name,brand{name,id})
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
**Schema defining a relationship for join queries:**
|
|
177
|
+
**Join query with nested select** — schema first:
|
|
157
178
|
|
|
158
179
|
```graphql
|
|
159
180
|
type Product @table @export {
|
|
160
181
|
id: Long @primaryKey
|
|
161
182
|
name: String
|
|
162
183
|
brandId: Long @indexed
|
|
163
|
-
brand: Brand @
|
|
184
|
+
brand: Brand @relationship(from: "brandId")
|
|
164
185
|
}
|
|
165
186
|
type Brand @table @export {
|
|
166
187
|
id: Long @primaryKey
|
|
167
188
|
name: String
|
|
168
|
-
products: [Product] @
|
|
189
|
+
products: [Product] @relationship(to: "brandId")
|
|
169
190
|
}
|
|
170
191
|
```
|
|
171
192
|
|
|
172
|
-
|
|
193
|
+
Then query:
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
GET /Product/?brand.name=Microsoft&select(name,brand{name,id})
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Many-to-many relationship** — schema:
|
|
173
200
|
|
|
174
201
|
```graphql
|
|
175
202
|
type Product @table @export {
|
|
176
203
|
id: Long @primaryKey
|
|
177
204
|
name: String
|
|
178
205
|
resellerIds: [Long] @indexed
|
|
179
|
-
resellers: [Reseller] @
|
|
206
|
+
resellers: [Reseller] @relationship(from: "resellerIds")
|
|
180
207
|
}
|
|
181
208
|
```
|
|
182
209
|
|
|
210
|
+
Query:
|
|
211
|
+
|
|
183
212
|
```
|
|
184
213
|
GET /Product/?resellers.name=Cool Shop&select(id,name,resellers{name,id})
|
|
185
214
|
```
|
|
186
215
|
|
|
187
|
-
**
|
|
216
|
+
**Date range with URL-encoded colons**:
|
|
188
217
|
|
|
189
218
|
```
|
|
190
|
-
GET /Product/?
|
|
191
|
-
GET /Product/?active==boolean:true
|
|
192
|
-
GET /Product/?listDate==date:2024-01-05T20%3A07%3A27.955Z
|
|
219
|
+
GET /Product/?listDate=gt=2017-03-08T09%3A30%3A00.000Z
|
|
193
220
|
```
|
|
194
221
|
|
|
195
222
|
## Notes
|
|
196
223
|
|
|
197
|
-
-
|
|
198
|
-
-
|
|
199
|
-
-
|
|
200
|
-
-
|
|
201
|
-
-
|
|
202
|
-
-
|
|
224
|
+
- All filtered attributes must be indexed unless at least one other attribute in the same query is indexed.
|
|
225
|
+
- Null queries (`?attr=null`) require indexes created after null indexing support was added. Rebuild existing indexes (remove and re-add) to enable null queries on them.
|
|
226
|
+
- When selecting a related attribute without filtering on it, the join behaves as a LEFT JOIN — the relationship property is omitted if the foreign key is null or references a non-existent record.
|
|
227
|
+
- The array order of foreign key values (e.g., `resellerIds`) is preserved when resolving many-to-many relationships.
|
|
228
|
+
- Square brackets (`[`, `]`) are preferred over parentheses for grouping when constructing queries programmatically, because standard URI encoding safely encodes them.
|
|
229
|
+
- `directURLMapping: true` can be set on a resource to change URL path handling semantics; see your schema configuration for details.
|
|
@@ -9,8 +9,8 @@ metadata:
|
|
|
9
9
|
- reference/v5/database/schema.md#Overview
|
|
10
10
|
- reference/v5/database/schema.md#Type Directives
|
|
11
11
|
- reference/v5/database/schema.md#Field Directives
|
|
12
|
-
sourceCommit:
|
|
13
|
-
inputHash:
|
|
12
|
+
sourceCommit: 3749d0c54be457a2a65d9a63c738a5dc88989ecd
|
|
13
|
+
inputHash: ce22f3fefb660c6e
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# Schema Design and GraphQL Tooling
|
|
@@ -19,13 +19,11 @@ Instructions for the agent to follow when designing Harper schemas, applying cor
|
|
|
19
19
|
|
|
20
20
|
## When to Use
|
|
21
21
|
|
|
22
|
-
Apply this rule when creating or modifying Harper schema files, configuring `graphqlSchema` in `config.yaml`, or deciding which directives to apply to
|
|
22
|
+
Apply this rule when creating or modifying Harper schema files (`.graphql`), configuring `graphqlSchema` in `config.yaml`, or deciding which directives to apply to types and fields. Use it any time you need to define tables, primary keys, indexes, or exported endpoints.
|
|
23
23
|
|
|
24
24
|
## How It Works
|
|
25
25
|
|
|
26
|
-
1. **
|
|
27
|
-
|
|
28
|
-
2. **Register the schema** in the component's `config.yaml` using the `graphqlSchema` plugin:
|
|
26
|
+
1. **Declare the schema file** in the component's `config.yaml` using the `graphqlSchema` plugin:
|
|
29
27
|
|
|
30
28
|
```yaml
|
|
31
29
|
graphqlSchema:
|
|
@@ -34,7 +32,7 @@ Apply this rule when creating or modifying Harper schema files, configuring `gra
|
|
|
34
32
|
|
|
35
33
|
Both plugins and applications can specify schemas.
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
2. **Mark types as tables** with `@table`. The type name becomes the table name by default:
|
|
38
36
|
|
|
39
37
|
```graphql
|
|
40
38
|
type Dog @table {
|
|
@@ -45,13 +43,13 @@ Apply this rule when creating or modifying Harper schema files, configuring `gra
|
|
|
45
43
|
}
|
|
46
44
|
```
|
|
47
45
|
|
|
48
|
-
|
|
46
|
+
3. **Set a primary key** on every table using `@primaryKey`. Primary keys must be unique; duplicate-key inserts are rejected. If no primary key is provided on insert, Harper auto-generates one based on the field type:
|
|
49
47
|
- `String` or `ID` → UUID string
|
|
50
48
|
- `Int`, `Long`, or `Any` → auto-incrementing integer
|
|
51
49
|
|
|
52
50
|
Use `Long` or `Any` for auto-generated numeric keys; `Int` is 32-bit and may be insufficient for large tables.
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
4. **Index fields for querying** with `@indexed`. Required for filtering by an attribute in REST queries, SQL, or NoSQL operations:
|
|
55
53
|
|
|
56
54
|
```graphql
|
|
57
55
|
type Breed @table {
|
|
@@ -62,7 +60,7 @@ Apply this rule when creating or modifying Harper schema files, configuring `gra
|
|
|
62
60
|
|
|
63
61
|
If the field value is an array, each element is individually indexed. Null values are indexed by default.
|
|
64
62
|
|
|
65
|
-
|
|
63
|
+
5. **Expose a table as an external endpoint** with `@export`. Available via REST, MQTT, and other interfaces. The optional `name` parameter sets the URL path segment:
|
|
66
64
|
|
|
67
65
|
```graphql
|
|
68
66
|
type MyTable @table @export(name: "my-table") {
|
|
@@ -70,9 +68,9 @@ Apply this rule when creating or modifying Harper schema files, configuring `gra
|
|
|
70
68
|
}
|
|
71
69
|
```
|
|
72
70
|
|
|
73
|
-
Without `name`, the type name is used
|
|
71
|
+
Without `name`, the type name is used.
|
|
74
72
|
|
|
75
|
-
|
|
73
|
+
6. **Configure `@table` arguments** as needed. All arguments are optional:
|
|
76
74
|
|
|
77
75
|
| Argument | Type | Default | Description |
|
|
78
76
|
| -------------- | --------- | ----------------------------- | ------------------------------------------------------------- |
|
|
@@ -83,13 +81,15 @@ Apply this rule when creating or modifying Harper schema files, configuring `gra
|
|
|
83
81
|
| `scanInterval` | `Int` | `(expiration + eviction) / 4` | Seconds between eviction scans |
|
|
84
82
|
| `replicate` | `Boolean` | `true` | Enable replication of this table |
|
|
85
83
|
|
|
86
|
-
|
|
87
|
-
- `@createdTime` — auto-assigns Unix epoch
|
|
88
|
-
- `@updatedTime` — auto-assigns Unix epoch
|
|
89
|
-
- `@
|
|
90
|
-
- `@
|
|
84
|
+
7. **Apply additional field directives** where needed:
|
|
85
|
+
- `@createdTime` — auto-assigns creation timestamp (Unix epoch ms)
|
|
86
|
+
- `@updatedTime` — auto-assigns update timestamp (Unix epoch ms)
|
|
87
|
+
- `@expiresAt` — marks a field as the record's absolute expiration time (Unix epoch ms)
|
|
88
|
+
- `@embed(source:, model:)` — computes an embedding vector when the source field is written; field type must be `[Float]`
|
|
89
|
+
- `@hidden` — suppresses the field from MCP tool descriptors and OpenAPI document (not an access-control mechanism)
|
|
90
|
+
|
|
91
|
+
8. **Use `@sealed`** on a type to prevent records from including properties beyond those declared in the schema:
|
|
91
92
|
|
|
92
|
-
9. **Restrict extra properties** with `@sealed` if records must not include properties beyond those declared:
|
|
93
93
|
```graphql
|
|
94
94
|
type StrictRecord @table @sealed {
|
|
95
95
|
id: Long @primaryKey
|
|
@@ -97,9 +97,11 @@ Apply this rule when creating or modifying Harper schema files, configuring `gra
|
|
|
97
97
|
}
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
+
9. **Use unique database names** in plugins or applications to avoid table naming collisions, since all tables default to the `data` database.
|
|
101
|
+
|
|
100
102
|
## Examples
|
|
101
103
|
|
|
102
|
-
**Minimal two
|
|
104
|
+
**Minimal schema with two tables:**
|
|
103
105
|
|
|
104
106
|
```graphql
|
|
105
107
|
type Dog @table {
|
|
@@ -115,7 +117,7 @@ type Breed @table {
|
|
|
115
117
|
}
|
|
116
118
|
```
|
|
117
119
|
|
|
118
|
-
**Table with expiration, eviction, and
|
|
120
|
+
**Table with expiration, eviction, and scan tuning:**
|
|
119
121
|
|
|
120
122
|
```graphql
|
|
121
123
|
# Expire after 5 minutes, evict after 1 hour, scan every 10 minutes
|
|
@@ -125,60 +127,56 @@ type WeatherCache @table(expiration: 300, eviction: 3300, scanInterval: 600) {
|
|
|
125
127
|
}
|
|
126
128
|
```
|
|
127
129
|
|
|
128
|
-
**
|
|
130
|
+
**Table with multiple `@table` arguments combined:**
|
|
129
131
|
|
|
130
132
|
```graphql
|
|
131
|
-
type
|
|
133
|
+
type Event @table(database: "analytics", expiration: 86400) {
|
|
132
134
|
id: Long @primaryKey
|
|
133
135
|
name: String @indexed
|
|
134
|
-
createdAt: Long @createdTime
|
|
135
|
-
updatedAt: Long @updatedTime
|
|
136
|
-
|
|
137
|
-
"""
|
|
138
|
-
Internal — do not surface to external consumers.
|
|
139
|
-
"""
|
|
140
|
-
creditScore: Int @hidden
|
|
141
136
|
}
|
|
142
137
|
```
|
|
143
138
|
|
|
144
|
-
**
|
|
139
|
+
**Exported table with overridden table name:**
|
|
145
140
|
|
|
146
141
|
```graphql
|
|
147
|
-
|
|
148
|
-
type Product @table(table: "products") {
|
|
142
|
+
type Product @table(table: "products") @export(name: "products") {
|
|
149
143
|
id: Long @primaryKey
|
|
144
|
+
category: String @indexed
|
|
145
|
+
price: Float @indexed
|
|
150
146
|
}
|
|
147
|
+
```
|
|
151
148
|
|
|
152
|
-
|
|
153
|
-
type Order @table(database: "commerce") {
|
|
154
|
-
id: Long @primaryKey
|
|
155
|
-
}
|
|
149
|
+
**Table with timestamps and per-record expiration:**
|
|
156
150
|
|
|
157
|
-
|
|
158
|
-
type Session @table
|
|
159
|
-
id:
|
|
160
|
-
|
|
151
|
+
```graphql
|
|
152
|
+
type Session @table {
|
|
153
|
+
id: ID @primaryKey
|
|
154
|
+
token: String
|
|
155
|
+
createdAt: Long @createdTime
|
|
156
|
+
updatedAt: Long @updatedTime
|
|
157
|
+
expiresAt: Long @expiresAt
|
|
161
158
|
}
|
|
159
|
+
```
|
|
162
160
|
|
|
163
|
-
|
|
164
|
-
type LocalRecord @table(replicate: false) {
|
|
165
|
-
id: Long @primaryKey
|
|
166
|
-
value: String
|
|
167
|
-
}
|
|
161
|
+
**Table with a hidden internal field:**
|
|
168
162
|
|
|
169
|
-
|
|
170
|
-
type
|
|
163
|
+
```graphql
|
|
164
|
+
type Customer @table {
|
|
171
165
|
id: Long @primaryKey
|
|
172
|
-
name: String
|
|
166
|
+
name: String
|
|
167
|
+
|
|
168
|
+
"""
|
|
169
|
+
Internal — do not surface to external consumers.
|
|
170
|
+
"""
|
|
171
|
+
creditScore: Int @hidden
|
|
173
172
|
}
|
|
174
173
|
```
|
|
175
174
|
|
|
176
175
|
## Notes
|
|
177
176
|
|
|
178
|
-
-
|
|
179
|
-
-
|
|
180
|
-
- `
|
|
181
|
-
-
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
- Disabling replication (`replicate: false`) and re-enabling it later will not catch up on writes made while replication was disabled.
|
|
177
|
+
- `@table`, `@export`, `@sealed`, and `@hidden` are type-level directives; `@primaryKey`, `@indexed`, `@embed`, `@createdTime`, `@updatedTime`, `@expiresAt`, and `@hidden` are field-level directives.
|
|
178
|
+
- `eviction` removes non-indexed record data but does **not** remove a record from its secondary indexes. Indexes remain functional for evicted records; Harper fetches the full record on demand when a query matches an evicted entry.
|
|
179
|
+
- `scanInterval` is clock-aligned to the server's local timezone, not startup-aligned. The server's startup time does not affect when eviction runs.
|
|
180
|
+
- Replication is enabled by default. If you disable replication on a table and re-enable it later, it will not catch up on writes made while replication was disabled.
|
|
181
|
+
- `@hidden` is a metadata-visibility directive only. Use `attribute_permissions` on roles to enforce data access control.
|
|
182
|
+
- A full-record `put` that omits an `@expiresAt` field clears it; a `patch` of other fields preserves it.
|