✨ feat: implement new feature for enhanced user experience
This commit is contained in:
@@ -344,7 +344,6 @@ Edit `types/global.d.ts`:
|
||||
```typescript
|
||||
interface MyCollectionEntry {
|
||||
id?: string
|
||||
_id?: string
|
||||
active?: boolean
|
||||
name?: string
|
||||
// ... fields matching your YAML
|
||||
|
||||
@@ -292,6 +292,31 @@ const result = await postDBEntry("content", { name: "New Page", active: true })
|
||||
const { data, count } = await api<MyType[]>("mycollection", { filter: { active: true }, limit: 20 })
|
||||
```
|
||||
|
||||
### `aggregate` for sub-queries
|
||||
|
||||
The server supports an `aggregate` parameter to compute reverse aggregates against another collection and store the result under `_aggregate`. This efficiently calculates counts, sums, existence, etc. without embedding the target documents.
|
||||
|
||||
```typescript
|
||||
const res = await api<MyEntry[]>("mycollection", {
|
||||
filter: { active: true },
|
||||
params: {
|
||||
// String syntax: "collection:foreignField:op:valueField:as"
|
||||
aggregate: "posts:categoryId:count",
|
||||
// JSON syntax for advanced use cases (custom source field, filtering)
|
||||
aggregate: JSON.stringify({
|
||||
collection: "comments",
|
||||
foreignField: "entryId",
|
||||
op: "count",
|
||||
filter: { approved: true },
|
||||
as: "approvedComments",
|
||||
}),
|
||||
},
|
||||
})
|
||||
// Result in res.data[0]._aggregate.postsCount and res.data[0]._aggregate.approvedComments
|
||||
```
|
||||
|
||||
Available operations: `count` (default), `exists`, `sum`, `avg`, `min`, `max`.
|
||||
|
||||
### Error handling
|
||||
|
||||
```typescript
|
||||
@@ -311,6 +336,31 @@ try {
|
||||
}
|
||||
```
|
||||
|
||||
### `aggregate` for sub-queries
|
||||
|
||||
The server supports an `aggregate` parameter to compute reverse aggregates against another collection and store the result under `_aggregate`. This efficiently calculates counts, sums, existence, etc. without embedding the target documents.
|
||||
|
||||
```typescript
|
||||
const res = await api<MyEntry[]>("mycollection", {
|
||||
filter: { active: true },
|
||||
params: {
|
||||
// String syntax: "collection:foreignField:op:valueField:as"
|
||||
aggregate: "posts:categoryId:count",
|
||||
// JSON syntax for advanced use cases (custom source field, filtering)
|
||||
aggregate: JSON.stringify({
|
||||
collection: "comments",
|
||||
foreignField: "entryId",
|
||||
op: "count",
|
||||
filter: { approved: true },
|
||||
as: "approvedComments",
|
||||
}),
|
||||
},
|
||||
})
|
||||
// Result in res.data[0]._aggregate.postsCount and res.data[0]._aggregate.approvedComments
|
||||
```
|
||||
|
||||
Available operations: `count` (default), `exists`, `sum`, `avg`, `min`, `max`.
|
||||
|
||||
### Error handling guidelines
|
||||
|
||||
| Scenario | Approach |
|
||||
@@ -426,7 +476,7 @@ Nicht aufgeführte Felder (z.B. `description`, `specs`) entfallen – spart Band
|
||||
- **Never `spaNavigate()` in SSR** — always guard with `typeof window !== "undefined"`.
|
||||
- **Store subscriptions in modules** — if subscribing to stores outside components, remember to unsubscribe to prevent memory leaks.
|
||||
- **API PUT returns only changed fields** — don't expect a full object back from PUT requests.
|
||||
- **`_id` not `id` for filters** — API filters use MongoDB's `_id`, but response objects may have both `id` and `_id`.
|
||||
- **`_id` not `id` for filters** — API filters use MongoDB's `_id`, but response objects only have `id` as string via API.
|
||||
- **`$location` strips trailing slashes** — `/about/` becomes `/about` (except root `/`).
|
||||
- **Content cache is 1 hour** — `getCachedEntries` caches in memory for 1h. For admin previews, use `getDBEntries` (uncached).
|
||||
- **`$effect` alone is not SSR** — server-side rendering must trigger the same data path explicitly outside browser-only reactive effects.
|
||||
|
||||
Reference in New Issue
Block a user