@open-mercato/search 0.4.7-develop-74069040de → 0.4.7-develop-bdeaa0fc10
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/agentic/standalone-guide.md +115 -0
- package/package.json +4 -4
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Search Package — Standalone Developer Guide
|
|
2
|
+
|
|
3
|
+
`@open-mercato/search` provides fulltext, vector, and token-based search. Configure search for your entities via `search.ts` in your module.
|
|
4
|
+
|
|
5
|
+
## Strategy Overview
|
|
6
|
+
|
|
7
|
+
| Strategy | Backend | Use when |
|
|
8
|
+
|----------|---------|----------|
|
|
9
|
+
| **Fulltext** | Meilisearch | Fast, typo-tolerant search (names, titles, descriptions) |
|
|
10
|
+
| **Vector** | OpenAI / Ollama | Semantic, meaning-based search ("find customers interested in X") |
|
|
11
|
+
| **Tokens** | PostgreSQL | Baseline keyword search, always available, no external services |
|
|
12
|
+
|
|
13
|
+
Strategies auto-degrade when their backend is not configured.
|
|
14
|
+
|
|
15
|
+
## Adding Search to a Module
|
|
16
|
+
|
|
17
|
+
Create `src/modules/<module>/search.ts`:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import type { SearchModuleConfig, SearchBuildContext } from '@open-mercato/shared/modules/search'
|
|
21
|
+
|
|
22
|
+
export const searchConfig: SearchModuleConfig = {
|
|
23
|
+
entities: [{
|
|
24
|
+
entityId: 'my_module:my_entity', // MUST match entity registry
|
|
25
|
+
priority: 10,
|
|
26
|
+
|
|
27
|
+
// Fulltext: control field indexing
|
|
28
|
+
fieldPolicy: {
|
|
29
|
+
searchable: ['name', 'description'],
|
|
30
|
+
hashOnly: ['email', 'phone'], // exact match only
|
|
31
|
+
excluded: ['password', 'api_key'], // never indexed
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
// Vector: generate text for embeddings
|
|
35
|
+
buildSource: async (ctx: SearchBuildContext) => ({
|
|
36
|
+
text: [`Name: ${ctx.record.name}`, `Description: ${ctx.record.description}`],
|
|
37
|
+
presenter: { title: ctx.record.name, subtitle: ctx.record.status, icon: 'lucide:file', badge: 'Item' },
|
|
38
|
+
links: [{ href: `/backend/my-module/${ctx.record.id}`, label: 'View', kind: 'primary' }],
|
|
39
|
+
checksumSource: { record: ctx.record, customFields: ctx.customFields },
|
|
40
|
+
}),
|
|
41
|
+
|
|
42
|
+
// Tokens: format at search time
|
|
43
|
+
formatResult: async (ctx: SearchBuildContext) => ({
|
|
44
|
+
title: ctx.record.name ?? 'Unknown',
|
|
45
|
+
subtitle: ctx.record.status,
|
|
46
|
+
icon: 'lucide:file',
|
|
47
|
+
badge: 'Item',
|
|
48
|
+
}),
|
|
49
|
+
|
|
50
|
+
resolveUrl: async (ctx) => `/backend/my-module/${ctx.record.id}`,
|
|
51
|
+
}],
|
|
52
|
+
}
|
|
53
|
+
export default searchConfig
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Run `yarn generate` after creating the file.
|
|
57
|
+
|
|
58
|
+
## MUST Rules
|
|
59
|
+
|
|
60
|
+
1. **MUST create `search.ts`** for every module with searchable entities
|
|
61
|
+
2. **MUST define `fieldPolicy.excluded`** for sensitive fields (passwords, tokens, SSNs)
|
|
62
|
+
3. **MUST define `formatResult`** for every entity using the tokens strategy
|
|
63
|
+
4. **MUST include `checksumSource`** in every `buildSource` return value
|
|
64
|
+
5. **MUST NOT** include encrypted/sensitive fields in `buildSource` text
|
|
65
|
+
6. **MUST NOT** use raw `fetch` against search API — use `apiCall`/`apiCallOrThrow`
|
|
66
|
+
|
|
67
|
+
## Auto-Indexing
|
|
68
|
+
|
|
69
|
+
When CRUD routes have `indexer: { entityType }`, the search module automatically subscribes to entity CRUD events and indexes/removes records. No manual indexing code needed.
|
|
70
|
+
|
|
71
|
+
## CLI Commands
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
yarn mercato search status # Check strategies and connectivity
|
|
75
|
+
yarn mercato search query -q "term" --tenant <id> # Run a search
|
|
76
|
+
yarn mercato search reindex --tenant <id> # Reindex all entities
|
|
77
|
+
yarn mercato search reindex --entity my_module:my_entity --tenant <id> # Reindex specific entity
|
|
78
|
+
yarn mercato search test-meilisearch # Test Meilisearch connection
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Environment Variables
|
|
82
|
+
|
|
83
|
+
| Variable | Purpose |
|
|
84
|
+
|----------|---------|
|
|
85
|
+
| `MEILISEARCH_HOST` | Meilisearch URL (enables fulltext) |
|
|
86
|
+
| `MEILISEARCH_API_KEY` | Meilisearch auth key |
|
|
87
|
+
| `OPENAI_API_KEY` | OpenAI API key (enables vector search) |
|
|
88
|
+
| `OM_SEARCH_DEBUG` | Enable verbose debug logging |
|
|
89
|
+
|
|
90
|
+
## Programmatic Search via DI
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const searchService = container.resolve('searchService')
|
|
94
|
+
const results = await searchService.search('query', {
|
|
95
|
+
tenantId: 'tenant-123',
|
|
96
|
+
limit: 20,
|
|
97
|
+
strategies: ['fulltext', 'vector'],
|
|
98
|
+
})
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## SearchBuildContext
|
|
102
|
+
|
|
103
|
+
Both `buildSource` and `formatResult` receive this context:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
interface SearchBuildContext {
|
|
107
|
+
record: Record<string, unknown> // The database record
|
|
108
|
+
customFields: Record<string, unknown> // Custom fields (without cf: prefix)
|
|
109
|
+
tenantId?: string | null
|
|
110
|
+
organizationId?: string | null
|
|
111
|
+
queryEngine?: QueryEngine // For loading related entities
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Use `queryEngine` to load parent/related entities for richer presenter data.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/search",
|
|
3
|
-
"version": "0.4.7-develop-
|
|
3
|
+
"version": "0.4.7-develop-bdeaa0fc10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -126,9 +126,9 @@
|
|
|
126
126
|
"zod": "^4.0.0"
|
|
127
127
|
},
|
|
128
128
|
"peerDependencies": {
|
|
129
|
-
"@open-mercato/core": "0.4.7-develop-
|
|
130
|
-
"@open-mercato/queue": "0.4.7-develop-
|
|
131
|
-
"@open-mercato/shared": "0.4.7-develop-
|
|
129
|
+
"@open-mercato/core": "0.4.7-develop-bdeaa0fc10",
|
|
130
|
+
"@open-mercato/queue": "0.4.7-develop-bdeaa0fc10",
|
|
131
|
+
"@open-mercato/shared": "0.4.7-develop-bdeaa0fc10"
|
|
132
132
|
},
|
|
133
133
|
"devDependencies": {
|
|
134
134
|
"@types/jest": "^30.0.0",
|