sonamu 0.10.6 → 0.10.8

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 (74) hide show
  1. package/dist/api/base-frame.d.ts +2 -0
  2. package/dist/api/base-frame.d.ts.map +1 -1
  3. package/dist/api/base-frame.js +8 -1
  4. package/dist/api/decorators.js +1 -1
  5. package/dist/api/sonamu.js +1 -1
  6. package/dist/bin/cli.js +10 -253
  7. package/dist/database/base-model.js +2 -2
  8. package/dist/entity/entity-manager.js +1 -1
  9. package/dist/index.js +3 -3
  10. package/dist/migration/code-generation.js +2 -2
  11. package/dist/migration/migrator.js +1 -1
  12. package/dist/migration/slack-confirm.js +1 -1
  13. package/dist/naite/naite-reporter.js +1 -1
  14. package/dist/syncer/checksum.js +1 -1
  15. package/dist/syncer/code-generator.js +1 -1
  16. package/dist/syncer/entity-operations.js +1 -1
  17. package/dist/syncer/syncer-actions.js +1 -1
  18. package/dist/syncer/syncer.js +1 -1
  19. package/dist/ui-web/assets/{index-D0MHYbxl.js → index-CJf8uJYf.js} +47 -41
  20. package/dist/ui-web/assets/index-GMMIVGja.css +1 -0
  21. package/dist/ui-web/index.html +2 -2
  22. package/dist/utils/formatter.js +1 -1
  23. package/package.json +3 -3
  24. package/src/api/base-frame.ts +14 -1
  25. package/src/bin/cli.ts +12 -375
  26. package/src/migration/code-generation.ts +1 -1
  27. package/dist/ui-web/assets/index-Dx_JX4aQ.css +0 -1
  28. package/src/skills/AGENTS.md +0 -108
  29. package/src/skills/sonamu/SKILL.md +0 -75
  30. package/src/skills/sonamu-ai-agents/SKILL.md +0 -205
  31. package/src/skills/sonamu-api/SKILL.md +0 -480
  32. package/src/skills/sonamu-auth/SKILL.md +0 -327
  33. package/src/skills/sonamu-auth/references/plugins.md +0 -310
  34. package/src/skills/sonamu-auth/references/user-id-migration-followups.md +0 -192
  35. package/src/skills/sonamu-auth/references/user-id-migration.md +0 -455
  36. package/src/skills/sonamu-config/SKILL.md +0 -203
  37. package/src/skills/sonamu-config/references/database.md +0 -452
  38. package/src/skills/sonamu-config/references/environments.md +0 -178
  39. package/src/skills/sonamu-config/references/server-options.md +0 -400
  40. package/src/skills/sonamu-entity/SKILL.md +0 -180
  41. package/src/skills/sonamu-entity/references/creation-workflow.md +0 -581
  42. package/src/skills/sonamu-entity/references/design-guides.md +0 -243
  43. package/src/skills/sonamu-entity/references/field-types.md +0 -170
  44. package/src/skills/sonamu-entity/references/relations-detail.md +0 -245
  45. package/src/skills/sonamu-entity/references/relations.md +0 -463
  46. package/src/skills/sonamu-entity/references/subset.md +0 -156
  47. package/src/skills/sonamu-fixture/SKILL.md +0 -180
  48. package/src/skills/sonamu-fixture/references/cli-usage.md +0 -439
  49. package/src/skills/sonamu-fixture/references/cone.md +0 -298
  50. package/src/skills/sonamu-frontend/SKILL.md +0 -142
  51. package/src/skills/sonamu-frontend/references/components.md +0 -323
  52. package/src/skills/sonamu-frontend/references/examples.md +0 -64
  53. package/src/skills/sonamu-frontend/references/hooks.md +0 -273
  54. package/src/skills/sonamu-frontend/references/runtime.md +0 -165
  55. package/src/skills/sonamu-frontend/references/scaffolding.md +0 -439
  56. package/src/skills/sonamu-i18n/SKILL.md +0 -287
  57. package/src/skills/sonamu-migration/SKILL.md +0 -316
  58. package/src/skills/sonamu-naite/SKILL.md +0 -266
  59. package/src/skills/sonamu-query/SKILL.md +0 -48
  60. package/src/skills/sonamu-query/references/model-patterns.md +0 -390
  61. package/src/skills/sonamu-query/references/model.md +0 -366
  62. package/src/skills/sonamu-query/references/puri.md +0 -413
  63. package/src/skills/sonamu-query/references/search.md +0 -238
  64. package/src/skills/sonamu-query/references/upsert.md +0 -324
  65. package/src/skills/sonamu-tasks/SKILL.md +0 -236
  66. package/src/skills/sonamu-testing/SKILL.md +0 -251
  67. package/src/skills/sonamu-testing/references/devrunner.md +0 -405
  68. package/src/skills/sonamu-testing/references/helpers.md +0 -185
  69. package/src/skills/sonamu-testing/references/patterns.md +0 -263
  70. package/src/skills/sonamu-testing/references/pitfalls.md +0 -588
  71. package/src/skills/sonamu-testing/references/quick-start.md +0 -285
  72. package/src/skills/sonamu-testing/references/type-safety.md +0 -172
  73. package/src/skills/sonamu-testing/references/writing-plan.md +0 -375
  74. package/src/skills/sonamu-vector/SKILL.md +0 -222
@@ -1,375 +0,0 @@
1
- # Test Writing Plan and Rollout Strategy
2
-
3
- ## Test Writing Plan
4
-
5
- ### Planning Based on Entity Design Prompt
6
-
7
- After entity design is complete (confirming migration + scaffolding succeed), group tests according to **the business processes and data flows specified at the time of entity design**.
8
-
9
- **CRITICAL:** Group tests by **business flow units**, not by simple alphabetical order or individual entities.
10
-
11
- ### Step 1: Re-examine the Entity Design Prompt
12
-
13
- Extract the following from the prompt written at the time of the design request:
14
-
15
- - Business process flow
16
- - Relationships between entities (relations)
17
- - Data creation order
18
- - Key usage scenarios
19
-
20
- ### Step 2: Group by Business Process
21
-
22
- Group entities by **business flow units**, not simple priority.
23
-
24
- **Customer consultation system example:**
25
-
26
- ```
27
- Group 1: Core Infrastructure
28
- Organization (related agency)
29
- └─ User
30
- └─ LoginHistory
31
-
32
- Business flow: register agency → create user → login
33
- Test order: Organization → User → LoginHistory
34
-
35
- Group 2: Damage Type Management
36
- DamageType (self-referencing)
37
- └─ CounterMeasure
38
-
39
- Business flow: build damage type hierarchy → write countermeasures for each type
40
- Test order: DamageType → CounterMeasure
41
-
42
- Group 3: Consultation Process (core business)
43
- User (applicant) + User (counselor) + DamageType
44
- └─ Consultation
45
- ├─ ConsultationChannelLog
46
- └─ ConsultationHistory
47
-
48
- Business flow:
49
- 1. Applicant submits consultation request
50
- 2. Assign counselor
51
- 3. Classify damage type
52
- 4. Communication by channel (online/phone/SMS/KakaoTalk)
53
- 5. Record status change history
54
-
55
- Test order: Consultation → ConsultationChannelLog → ConsultationHistory
56
-
57
- Group 4: Content Management (independent)
58
- FAQ
59
- Banner
60
- Material
61
- Notice
62
-
63
- Business flow: independent CRUD for each
64
- Test order: any order (can be written in parallel)
65
- ```
66
-
67
- ### Step 3: Work Order per Group
68
-
69
- **For each group:**
70
-
71
- 1. **Modify types.ts** - handle nullable fields for all entities in the group at once
72
- 2. **Extend test-helpers.ts** - write helper functions for entities in the group together
73
- 3. **Write test files** - write in dependency order within the group
74
- 4. **Business Logic tests** - implement real business scenarios (the key!)
75
- 5. **Verify tests pass** - proceed to next group
76
-
77
- **test-helpers.ts example (considering dependency chains):**
78
-
79
- ```typescript
80
- // Write helpers considering dependency chains
81
- export async function createTestUserWithDeps() {
82
- const organizationId = await createTestOrganization();
83
- const userId = await createTestUser(organizationId);
84
- return { organizationId, userId };
85
- }
86
-
87
- export async function createTestConsultationWithDeps() {
88
- const { userId: applicantId } = await createTestUserWithDeps({
89
- role: "applicant",
90
- });
91
- const { userId: counselorId } = await createTestUserWithDeps({
92
- role: "counselor",
93
- });
94
- const damageTypeId = await createTestDamageType(null);
95
- const consultationId = await createTestConsultation(applicantId, counselorId, damageTypeId);
96
- return { applicantId, counselorId, damageTypeId, consultationId };
97
- }
98
- ```
99
-
100
- ### Step 4: Business Logic Tests (the key!)
101
-
102
- **IMPORTANT:** The E. Business Logic section is the most important.
103
-
104
- In this section:
105
-
106
- - Implement **real business scenarios** specified in the entity design prompt
107
- - Test **interactions** between entities
108
- - Validate **data flows**
109
-
110
- This is what differentiates it from simple CRUD tests, and it's **the core that validates design intent**.
111
-
112
- **Business Logic test example (consultation process):**
113
-
114
- ```typescript
115
- describe("E. Business Logic", () => {
116
- test("full process from consultation submission to completion", async () => {
117
- // 1. submit consultation + create dependencies
118
- const { consultationId, counselorId } = await createTestConsultationWithDeps();
119
- // 2. record channel logs (online submission, phone consultation)
120
- await createTestConsultationChannelLog(consultationId, {
121
- channel: "online",
122
- });
123
- await createTestConsultationChannelLog(consultationId, {
124
- channel: "phone",
125
- });
126
- // 3. record status history
127
- await createTestConsultationHistory(consultationId, counselorId, {
128
- status: "consulting",
129
- });
130
- // 4. complete consultation
131
- await ConsultationModel.save([{ id: consultationId, status: "completed" }]);
132
- // 5. verify: status, 2 channel logs, history
133
- const c = await ConsultationModel.findById("A", consultationId);
134
- expect(c.status).toBe("completed");
135
- });
136
- });
137
- ```
138
-
139
- ### Notes
140
-
141
- **DO:**
142
-
143
- - Always reference the entity design prompt
144
- - Group by business process flow
145
- - Test order that considers dependency order
146
- - Business Logic tests based on real usage scenarios
147
- - Clearly implement dependency chains in test-helpers
148
-
149
- **DON'T:**
150
-
151
- - Write tests in simple alphabetical order
152
- - Only test entities individually (missing integration perspective)
153
- - Set priorities unrelated to business flow
154
- - Write tests that ignore the intent of the entity design
155
-
156
- ### Checklist per Group
157
-
158
- When test writing for a process group is complete:
159
-
160
- - [ ] Nullable field handling in types.ts completed for all entities in the group
161
- - [ ] test-helpers written reflecting dependency chains within the group
162
- - [ ] Module test file written for each entity in the group
163
- - [ ] **Key business scenarios included in Business Logic tests**
164
- - [ ] All tests pass confirmed (`pnpm sonamu test`)
165
- - [ ] Proceed to next group
166
-
167
- ## Tasks to Do Immediately After Entity Creation
168
-
169
- ### Handling nullable Fields in types.ts (Required)
170
-
171
- After creating an entity and generating types.ts with `sonamu generate`, immediately handle nullable fields **before writing tests**.
172
-
173
- #### Work Order
174
-
175
- 1. Run `sonamu generate`
176
- 2. Check the generated `*.types.ts` file
177
- 3. Apply partial + extend + nullish handling for nullable fields
178
- 4. Start writing tests
179
-
180
- #### Fields to Process
181
-
182
- - All fields with `nullable: true`
183
- - Fields with `dbDefault` (`.optional().default(value)`)
184
- - FK relation fields that are nullable
185
-
186
- #### Practical Example
187
-
188
- **STEP 1: File generated after running sonamu generate**
189
-
190
- ```typescript
191
- // faq.types.ts (auto-generated)
192
- import type { z } from "zod"; // WRONG: type import
193
- import { FAQBaseListParams, FAQBaseSchema } from "../sonamu.generated";
194
-
195
- export const FAQListParams = FAQBaseListParams;
196
- export type FAQListParams = z.infer<typeof FAQListParams>;
197
-
198
- export const FAQSaveParams = FAQBaseSchema.partial({
199
- id: true,
200
- created_at: true,
201
- updated_at: true,
202
- });
203
- export type FAQSaveParams = z.infer<typeof FAQSaveParams>;
204
- ```
205
-
206
- **STEP 2: Immediate fix (nullable fields + Zod import handling)**
207
-
208
- ```typescript
209
- // faq.types.ts (fix complete)
210
- import { z } from "zod"; // CORRECT: change to regular import
211
- import { FAQBaseListParams, FAQBaseSchema } from "../sonamu.generated";
212
-
213
- export const FAQListParams = FAQBaseListParams;
214
- export type FAQListParams = z.infer<typeof FAQListParams>;
215
-
216
- export const FAQSaveParams = FAQBaseSchema.partial({
217
- id: true,
218
- created_at: true,
219
- updated_at: true,
220
- // add nullable fields
221
- category: true,
222
- order_num: true,
223
- }).extend({
224
- // redefine nullable fields as nullish
225
- category: z.string().nullish(), // string | null | undefined
226
- order_num: z.number().nullish(), // number | null | undefined
227
- updated_at: z.date().nullish(), // date | null | undefined
228
- });
229
-
230
- export type FAQSaveParams = z.infer<typeof FAQSaveParams>;
231
- ```
232
-
233
- #### Why Is This Necessary?
234
-
235
- **Problem:** Zod's `nullable()` gives `T | null` but it's still required.
236
-
237
- ```typescript
238
- // entity.json
239
- { "name": "category", "type": "string", "nullable": true }
240
-
241
- // Generated BaseSchema
242
- z.object({
243
- category: z.string().nullable(), // string | null (required!)
244
- })
245
-
246
- // applying partial only
247
- .partial({ category: true }) // category?: string | null
248
-
249
- // WRONG: undefined cannot be assigned to string | null
250
- const [id] = await FAQModel.save([{
251
- question: "Question",
252
- answer: "Answer",
253
- // omitting category causes type error!
254
- }]);
255
- ```
256
-
257
- **Solution:** Combination of `partial()` + `extend()` + `nullish()`
258
-
259
- ```typescript
260
- // CORRECT: proper handling
261
- FAQBaseSchema.partial({ category: true }).extend({
262
- category: z.string().nullish(),
263
- }); // string | null | undefined
264
-
265
- // Can freely omit in tests
266
- const [id] = await FAQModel.save([
267
- {
268
- question: "Question",
269
- answer: "Answer",
270
- // category can be omitted!
271
- },
272
- ]);
273
- ```
274
-
275
- #### Application Criteria
276
-
277
- | Field type | Handling |
278
- | -------------------------------- | ------------------------------- |
279
- | `id`, `created_at`, `updated_at` | Always partial (auto-generated) |
280
- | Fields with `dbDefault` | `.optional().default(value)` |
281
- | Fields with `nullable: true` | partial + extend + `.nullish()` |
282
- | Required fields | Excluded from partial |
283
-
284
- #### Checklist
285
-
286
- - [ ] Change `import type { z }` to `import { z }`
287
- - [ ] Add nullable fields to partial
288
- - [ ] Redefine as nullish via extend
289
- - [ ] Use `.optional().default()` for dbDefault fields
290
- - [ ] Confirm required fields are excluded from partial
291
-
292
- **Detailed type safety guide:** See "TypeScript Type Safety" and "Type Safety Notes" sections below
293
-
294
-
295
- ## Large-Scale Project Strategy (10 or more entities)
296
-
297
- **CRITICAL: Do not work on all entities at once if a project has 10 or more entities.**
298
-
299
- ### Problems
300
-
301
- - Working on 55 entities at once causes context confusion
302
- - Serious risk of errors such as modifying the wrong file or deleting required content
303
- - Cannot track relationships, lose direction while writing tests
304
-
305
- ### Solution: Batch Work Units
306
-
307
- **Rule: Group related entities together and work in batches of 5–10**
308
-
309
- ```
310
- Batch 1: User, Institution, Role related (5 entities)
311
- → Tests complete → Commit
312
-
313
- Batch 2: Survey, Question, Response related (7 entities)
314
- → Tests complete → Commit
315
-
316
- Batch 3: Report, Statistics related (6 entities)
317
- → Tests complete → Commit
318
- ```
319
-
320
- ### Batch Grouping Criteria
321
-
322
- **Grouping by domain (recommended):**
323
-
324
- ```
325
- Auth/Permissions: User, Role, Permission, Session
326
- Surveys: Survey, Question, Choice, Response
327
- Reports: Report, Chart, Export
328
- Administration: Institution, Department, Settings
329
- ```
330
-
331
- **Grouping by dependencies:**
332
-
333
- ```
334
- 1st: Independent entities (User, Institution, etc.)
335
- 2nd: Entities depending on 1st (Survey → Institution)
336
- 3rd: Entities depending on 2nd (Question → Survey)
337
- ```
338
-
339
- ### Batch Work Process
340
-
341
- **For each batch:**
342
-
343
- 1. List entities in the batch explicitly
344
- 2. Write test helpers (createTest...)
345
- 3. Complete tests for all entities
346
- 4. Confirm all tests pass
347
- 5. **Git commit, then proceed to next batch**
348
-
349
- **Between-batch checklist:**
350
-
351
- - [ ] All tests in current batch pass
352
- - [ ] Previous batch tests still pass (prevent regression)
353
- - [ ] Commit complete (establish rollback point)
354
-
355
- ### Declare Before Starting Work
356
-
357
- **IMPORTANT: Declare explicitly before starting each batch**
358
-
359
- ```
360
- "Starting batch 1: User, Institution, Role entities (5)
361
- - User: write user.model.test.ts
362
- - Institution: write institution.model.test.ts
363
- - Role: write role.model.test.ts
364
- Only work on files to be modified, do not touch other files
365
- Shall we proceed?"
366
- ```
367
-
368
- ### Warning Signs
369
-
370
- **Stop work immediately** if any of the following occur:
371
-
372
- - Attempting to modify entities outside the batch scope
373
- - Asking the same question repeatedly
374
- - Confusing entity relationships
375
- - Trying to re-modify files already completed
@@ -1,222 +0,0 @@
1
- ---
2
- name: sonamu-vector
3
- description: Implements semantic and hybrid search with pgvector. Use when generating embeddings, chunking documents, or combining vector similarity with full-text search. Covers the Voyage AI and OpenAI embedding providers, chunking strategies, and hybrid ranking.
4
- ---
5
-
6
- # Vector Search Guide
7
-
8
- Sonamu supports pgvector-based vector search. It integrates both Voyage AI and OpenAI embedding providers, and also supports hybrid search (Vector + Full-Text Search).
9
-
10
- **Source code:** `modules/sonamu/src/vector/`
11
-
12
- ---
13
-
14
- ## Structure
15
-
16
- | File | Role |
17
- | -------------- | --------------------------------------------------------------------------------- |
18
- | `types.ts` | Full type definitions (EmbeddingProvider, VectorSearchResult, VectorConfig, etc.) |
19
- | `config.ts` | Default configuration values + `createVectorConfig()` helper |
20
- | `embedding.ts` | Embedding client (Voyage AI and OpenAI integration) |
21
- | `chunking.ts` | Text chunking (splitting long documents) |
22
-
23
- ---
24
-
25
- ## Embedding Providers
26
-
27
- | Provider | Model | Dimensions | maxTokens | batchSize | Package |
28
- | -------- | ------------------------ | ---------- | --------- | --------- | ---------------- |
29
- | `voyage` | `voyage-3` | 1024 | 32000 | 128 | `voyageai` |
30
- | `openai` | `text-embedding-3-small` | 1536 | 8191 | 100 | `@ai-sdk/openai` |
31
-
32
- ### API Key Configuration
33
-
34
- ```bash
35
- # Environment variables
36
- export VOYAGE_API_KEY=pa-...
37
- export OPENAI_API_KEY=sk-...
38
- ```
39
-
40
- Or in `sonamu.config.ts`:
41
-
42
- ```typescript
43
- export default defineConfig({
44
- secret: {
45
- voyage_api_key: "pa-...",
46
- openai_api_key: "sk-...",
47
- },
48
- });
49
- ```
50
-
51
- Key priority: `Sonamu.secrets.voyage_api_key` → `process.env.VOYAGE_API_KEY`
52
-
53
- ---
54
-
55
- ## Embedding Usage
56
-
57
- ```typescript
58
- import { Embedding } from "sonamu/vector";
59
-
60
- // Single text
61
- const result = await Embedding.embedOne("text to search", "voyage", "query");
62
- // result: { embedding: number[], model: "voyage-3", tokenCount: 15 }
63
-
64
- // Multiple texts (auto-splits when exceeding batchSize)
65
- const results = await Embedding.embed(
66
- ["text1", "text2", ...],
67
- "voyage",
68
- "document", // inputType: "document" | "query"
69
- (processed, total) => console.log(`${processed}/${total}`), // progress callback
70
- );
71
-
72
- // Check number of dimensions
73
- Embedding.getDimensions("voyage"); // 1024
74
- Embedding.getDimensions("openai"); // 1536
75
- ```
76
-
77
- ### Voyage AI inputType (Asymmetric Embedding)
78
-
79
- | inputType | Use case |
80
- | ------------ | --------------------------------------- |
81
- | `"document"` | When embedding documents to store in DB |
82
- | `"query"` | When embedding search queries |
83
-
84
- **CRITICAL: Use `"document"` when storing and `"query"` when searching for asymmetric embedding to work correctly.**
85
-
86
- ---
87
-
88
- ## Chunking Usage
89
-
90
- Splits long documents into appropriately-sized pieces.
91
-
92
- ```typescript
93
- import { Chunking } from "sonamu/vector";
94
-
95
- const chunker = new Chunking({
96
- chunkSize: 500, // Maximum chunk size (character count)
97
- chunkOverlap: 50, // Overlap between chunks
98
- minChunkSize: 50, // Minimum chunk size
99
- });
100
-
101
- // Check if chunking is needed
102
- chunker.needsChunking("short text"); // false
103
-
104
- // Split into chunks
105
- const chunks = chunker.chunk(longText);
106
- // chunks: [{ index: 0, text: "...", startOffset: 0, endOffset: 500 }, ...]
107
-
108
- // Estimate number of chunks
109
- chunker.estimateChunkCount(longText); // 5
110
- ```
111
-
112
- ### Chunking Default Settings
113
-
114
- | Option | Default | Description |
115
- | --------------- | --------------------------------- | -------------------------------------------------------- |
116
- | `chunkSize` | 500 | Maximum chunk size (character count) |
117
- | `chunkOverlap` | 50 | Overlap between chunks |
118
- | `minChunkSize` | 50 | Minimum chunk size |
119
- | `skipThreshold` | 200 | Passes through without chunking if at or below this size |
120
- | `separators` | `["\n\n", "\n", "。", ". ", ...]` | Split delimiters (in priority order) |
121
-
122
- ---
123
-
124
- ## Search Configuration
125
-
126
- ```typescript
127
- import { createVectorConfig } from "sonamu/vector";
128
-
129
- const config = createVectorConfig({
130
- search: {
131
- defaultLimit: 10,
132
- similarityThreshold: 0.5, // Results below this value are excluded
133
- vectorWeight: 0.7, // Vector weight in hybrid search
134
- ftsWeight: 0.3, // FTS weight in hybrid search
135
- },
136
- pgvector: {
137
- iterativeScan: true, // Use pgvector iterative scan
138
- efSearch: 100, // HNSW index search accuracy
139
- },
140
- });
141
- ```
142
-
143
- ---
144
-
145
- ## Type Definitions
146
-
147
- ### VectorSearchResult
148
-
149
- ```typescript
150
- interface VectorSearchResult<T = Record<string, unknown>> {
151
- id: number | string;
152
- similarity: number;
153
- data: T;
154
- }
155
- ```
156
-
157
- ### HybridSearchResult
158
-
159
- ```typescript
160
- interface HybridSearchResult<T> extends VectorSearchResult<T> {
161
- vectorScore?: number;
162
- ftsScore?: number;
163
- }
164
- ```
165
-
166
- ### VectorSearchOptions
167
-
168
- ```typescript
169
- interface VectorSearchOptions {
170
- embeddingColumn?: string; // Embedding column name (default: "embedding")
171
- limit?: number;
172
- threshold?: number; // Similarity threshold
173
- where?: string; // SQL WHERE condition
174
- }
175
- ```
176
-
177
- ### HybridSearchOptions
178
-
179
- ```typescript
180
- interface HybridSearchOptions extends VectorSearchOptions {
181
- vectorWeight?: number; // Vector search weight
182
- ftsWeight?: number; // FTS weight
183
- ftsColumn?: string; // Target column name for FTS
184
- }
185
- ```
186
-
187
- ---
188
-
189
- ## pgvector DB Setup
190
-
191
- ### Install Extension
192
-
193
- ```sql
194
- CREATE EXTENSION IF NOT EXISTS vector;
195
- ```
196
-
197
- ### Add Embedding Column
198
-
199
- ```sql
200
- -- Voyage AI (1024 dimensions)
201
- ALTER TABLE documents ADD COLUMN embedding vector(1024);
202
-
203
- -- OpenAI (1536 dimensions)
204
- ALTER TABLE documents ADD COLUMN embedding vector(1536);
205
- ```
206
-
207
- ### HNSW Index
208
-
209
- ```sql
210
- -- Cosine similarity-based index
211
- CREATE INDEX ON documents
212
- USING hnsw (embedding vector_cosine_ops)
213
- WITH (m = 16, ef_construction = 64);
214
- ```
215
-
216
- ---
217
-
218
- ## References
219
-
220
- - **Source code**: `modules/sonamu/src/vector/`
221
- - **pgvector official**: https://github.com/pgvector/pgvector
222
- - **Voyage AI**: https://docs.voyageai.com/