Initial Commit
This commit is contained in:
112
packages/api-stack/api/api-plugin-search/src/schemas/schemas.md
Normal file
112
packages/api-stack/api/api-plugin-search/src/schemas/schemas.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# schemas/schemas
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
The schemas module owns the public Zod surface of
|
||||
`@suaveplan/api-plugin-search`. Every HTTP route in the package validates
|
||||
its request body, path params, or query string against one of these
|
||||
schemas before invoking the service layer, and every response shape is
|
||||
declared here so `@hono/zod-openapi` can publish a typed `/openapi.json`
|
||||
document without per-route duplication. Inferred types are exported in
|
||||
parallel so direct programmatic consumers (e.g. another plugin building
|
||||
on top of the search service) can construct payloads with full type
|
||||
safety.
|
||||
|
||||
## Features
|
||||
|
||||
- Thirteen schemas covering the full upstream search surface — queries,
|
||||
hits, facets, sort orders, index status enums, index field
|
||||
declarations, document indexing, bulk indexing, suggest queries, and
|
||||
every response shape.
|
||||
- Two const-object enums (`SearchSortOrder`, `IndexStatus`) so consumers
|
||||
can branch on string literals without re-typing them.
|
||||
- Sensible defaults at the boundary (`sort: "relevance"`, `limit: 20`,
|
||||
`offset: 0`, `highlight: false`, `highlightTag: "mark"`,
|
||||
`analyzer: "standard"`, `weight: 1`, `facet: false`) so consumers only
|
||||
pass the fields they care about.
|
||||
- Hard upper bounds on every numeric and string field — `query` capped
|
||||
at 1000 chars, index names at 128 chars, `limit` ≤ 200, bulk docs ≤
|
||||
1000 — keeping the HTTP surface within sane resource budgets.
|
||||
- Inferred TypeScript types exported alongside each schema so call
|
||||
sites can type-check payloads at compile time without `z.infer`
|
||||
boilerplate.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import {
|
||||
SearchQuerySchema,
|
||||
type SearchQuery,
|
||||
} from "@suaveplan/api-plugin-search";
|
||||
|
||||
const parsed = SearchQuerySchema.safeParse({
|
||||
query: "hello world",
|
||||
index: "posts",
|
||||
});
|
||||
if (parsed.success) {
|
||||
const q: SearchQuery = parsed.data;
|
||||
// q.sort === "relevance" by default, q.limit === 20, ...
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Compose the schemas with `@hono/zod-openapi` to publish typed routes:
|
||||
|
||||
```ts
|
||||
import { createRoute } from "@hono/zod-openapi";
|
||||
import {
|
||||
SearchQuerySchema,
|
||||
SearchResultSchema,
|
||||
} from "@suaveplan/api-plugin-search";
|
||||
|
||||
export const searchRoute = createRoute({
|
||||
method: "post",
|
||||
path: "/query",
|
||||
request: {
|
||||
body: {
|
||||
content: { "application/json": { schema: SearchQuerySchema } },
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: "Search results",
|
||||
content: { "application/json": { schema: SearchResultSchema } },
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
| Symbol | Shape |
|
||||
|---|---|
|
||||
| `SearchSortOrder` | const object + type union — `"relevance"`, `"date_asc"`, `"date_desc"`, `"alpha_asc"`, `"alpha_desc"` |
|
||||
| `IndexStatus` | const object + type union — `"active"`, `"building"`, `"error"` |
|
||||
| `SearchQuerySchema` / `SearchQuery` | request body for `POST /query` |
|
||||
| `SearchHitSchema` / `SearchHit` | one hit returned by `search()` |
|
||||
| `FacetValueSchema` / `FacetValue` | `{ value, count }` |
|
||||
| `FacetSchema` / `Facet` | `{ field, values: FacetValue[] }` |
|
||||
| `SearchResultSchema` / `SearchResult` | response shape of `POST /query` |
|
||||
| `IndexFieldSchema` / `IndexField` | per-field config in `CreateIndex` |
|
||||
| `CreateIndexSchema` / `CreateIndex` | request body for `POST /indexes` |
|
||||
| `IndexInfoSchema` / `IndexInfo` | response shape of `GET /indexes/:name` |
|
||||
| `IndexListQuerySchema` / `IndexListQuery` | query string for `GET /indexes` |
|
||||
| `IndexDocumentSchema` / `IndexDocument` | request body for indexing |
|
||||
| `BulkIndexSchema` / `BulkIndex` | request body for bulk indexing |
|
||||
| `SuggestQuerySchema` / `SuggestQuery` | request body for `POST /suggest` |
|
||||
| `SuggestionSchema` / `Suggestion` | one entry in `SuggestResult.suggestions` |
|
||||
| `SuggestResultSchema` / `SuggestResult` | response shape of `POST /suggest` |
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
All numeric fields use `z.coerce.number()` so query-string values
|
||||
(`"20"`) parse correctly. `z.record(z.string(), z.unknown())` is used
|
||||
for free-form document fields and filter maps. The `createdAt` field
|
||||
on `IndexInfoSchema` accepts both ISO-string and `Date` so the schema
|
||||
can validate both the service-internal shape and the
|
||||
serialized-over-HTTP shape.
|
||||
Reference in New Issue
Block a user