Commit ae5a294d3f93b6542de1831d70c239f2213e1145

Authored by tangwang
1 parent 37e994bb

命名修改、代码清理

.cursor/plans/API响应格式优化与SPU索引重构.2.md
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 2. SPU维度的索引结构(包含嵌套variants数组) 9 2. SPU维度的索引结构(包含嵌套variants数组)
10 3. 所有客户共用同一索引(使用tenant_id隔离) 10 3. 所有客户共用同一索引(使用tenant_id隔离)
11 4. 配置简化(移除MySQL相关配置,只保留ES搜索配置) 11 4. 配置简化(移除MySQL相关配置,只保留ES搜索配置)
12 -5. 添加新客户(customer2)测试数据和配置 12 +5. 添加新客户(tenant2)测试数据和配置
13 13
14 ## Phase 1: 配置文件重构 14 ## Phase 1: 配置文件重构
15 15
@@ -27,14 +27,14 @@ @@ -27,14 +27,14 @@
27 - 多语言字段:`title_zh`, `title_en`, `description_zh`, `description_en` 等 27 - 多语言字段:`title_zh`, `title_en`, `description_zh`, `description_en` 等
28 - 嵌套variants结构定义 28 - 嵌套variants结构定义
29 29
30 -### 1.2 创建customer2配置文件 30 +### 1.2 创建tenant2配置文件
31 31
32 -**文件**: [`config/schema/customer2/config.yaml`](config/schema/customer2/config.yaml) (NEW) 32 +**文件**: [`config/schema/tenant2/config.yaml`](config/schema/tenant2/config.yaml) (NEW)
33 33
34 -基于BASE配置,为customer2创建配置文件: 34 +基于BASE配置,为tenant2创建配置文件:
35 35
36 - 继承BASE配置结构 36 - 继承BASE配置结构
37 -- 定义customer2特定的字段和搜索域 37 +- 定义tenant2特定的字段和搜索域
38 - 支持多语言(中文、英文) 38 - 支持多语言(中文、英文)
39 39
40 ### 1.3 更新配置加载器 40 ### 1.3 更新配置加载器
@@ -168,16 +168,16 @@ @@ -168,16 +168,16 @@
168 168
169 - 连接MySQL数据库 169 - 连接MySQL数据库
170 - 导入测试数据到 `shoplazza_product_spu` 和 `shoplazza_product_sku` 表 170 - 导入测试数据到 `shoplazza_product_spu` 和 `shoplazza_product_sku` 表
171 -- 设置 `tenant_id` 为customer2的ID 171 +- 设置 `tenant_id` 为tenant2的ID
172 - 验证数据导入结果 172 - 验证数据导入结果
173 173
174 ## Phase 5: 测试脚本和文档 174 ## Phase 5: 测试脚本和文档
175 175
176 ### 5.1 创建测试脚本 176 ### 5.1 创建测试脚本
177 177
178 -**文件**: [`scripts/test_customer2.py`](scripts/test_customer2.py) (NEW) 178 +**文件**: [`scripts/test_tenant2.py`](scripts/test_tenant2.py) (NEW)
179 179
180 -创建customer2测试脚本: 180 +创建tenant2测试脚本:
181 181
182 - 测试数据导入 182 - 测试数据导入
183 - 测试搜索API 183 - 测试搜索API
@@ -187,9 +187,9 @@ @@ -187,9 +187,9 @@
187 187
188 ### 5.2 创建说明文档 188 ### 5.2 创建说明文档
189 189
190 -**文件**: [`docs/CUSTOMER2_TEST_GUIDE.md`](docs/CUSTOMER2_TEST_GUIDE.md) (NEW) 190 +**文件**: [`docs/TENANT2_TEST_GUIDE.md`](docs/TENANT2_TEST_GUIDE.md) (NEW)
191 191
192 -创建customer2测试指南: 192 +创建tenant2测试指南:
193 193
194 - 数据导入步骤 194 - 数据导入步骤
195 - 配置说明 195 - 配置说明
@@ -208,7 +208,7 @@ @@ -208,7 +208,7 @@
208 - 更新配置说明(移除MySQL相关配置) 208 - 更新配置说明(移除MySQL相关配置)
209 - 更新API响应格式说明 209 - 更新API响应格式说明
210 - 更新数据导入流程说明 210 - 更新数据导入流程说明
211 -- 添加customer2测试说明 211 +- 添加tenant2测试说明
212 212
213 ## 关键修改点 213 ## 关键修改点
214 214
@@ -241,7 +241,7 @@ @@ -241,7 +241,7 @@
241 ### To-dos 241 ### To-dos
242 242
243 - [ ] 创建BASE配置文件(config/schema/base/config.yaml),移除MySQL相关配置,定义SPU级别字段和嵌套variants结构 243 - [ ] 创建BASE配置文件(config/schema/base/config.yaml),移除MySQL相关配置,定义SPU级别字段和嵌套variants结构
244 -- [ ] 创建customer2配置文件(config/schema/customer2/config.yaml),基于BASE配置定义customer2特定字段 244 +- [ ] 创建tenant2配置文件(config/schema/tenant2/config.yaml),基于BASE配置定义tenant2特定字段
245 - [ ] 更新配置加载器(config/config_loader.py),移除MySQL相关配置解析,支持嵌套字段和tenant_id验证 245 - [ ] 更新配置加载器(config/config_loader.py),移除MySQL相关配置解析,支持嵌套字段和tenant_id验证
246 - [ ] 更新字段类型定义(config/field_types.py),移除source_table和source_column,添加嵌套字段支持 246 - [ ] 更新字段类型定义(config/field_types.py),移除source_table和source_column,添加嵌套字段支持
247 - [ ] 更新Mapping生成器(indexer/mapping_generator.py),生成SPU级别mapping,添加tenant_id和嵌套variants字段 247 - [ ] 更新Mapping生成器(indexer/mapping_generator.py),生成SPU级别mapping,添加tenant_id和嵌套variants字段
@@ -253,6 +253,6 @@ @@ -253,6 +253,6 @@
253 - [ ] 更新API路由(api/routes/search.py),添加tenant_id参数,返回新的响应格式 253 - [ ] 更新API路由(api/routes/search.py),添加tenant_id参数,返回新的响应格式
254 - [ ] 创建测试数据生成脚本(scripts/generate_test_data.py),生成100条SPU测试数据 254 - [ ] 创建测试数据生成脚本(scripts/generate_test_data.py),生成100条SPU测试数据
255 - [ ] 创建数据导入脚本(scripts/import_test_data.py),导入测试数据到MySQL 255 - [ ] 创建数据导入脚本(scripts/import_test_data.py),导入测试数据到MySQL
256 -- [ ] 创建customer2测试脚本(scripts/test_customer2.py),测试数据导入和搜索API  
257 -- [ ] 创建customer2测试指南(docs/CUSTOMER2_TEST_GUIDE.md),包含数据导入步骤和API测试示例 256 +- [ ] 创建tenant2测试脚本(scripts/test_tenant2.py),测试数据导入和搜索API
  257 +- [ ] 创建tenant2测试指南(docs/TENANT2_TEST_GUIDE.md),包含数据导入步骤和API测试示例
258 - [ ] 更新设计文档(设计文档.md),更新索引结构、配置说明和API响应格式说明 258 - [ ] 更新设计文档(设计文档.md),更新索引结构、配置说明和API响应格式说明
259 \ No newline at end of file 259 \ No newline at end of file
.cursor/plans/API响应格式优化与SPU索引重构.4.md
@@ -44,7 +44,7 @@ @@ -44,7 +44,7 @@
44 44
45 修改: 45 修改:
46 46
47 -- **删除** `CustomerConfig` 中的 `mysql_config`, `main_table`, `extension_table` 字段定义 47 +- **删除** `TenantConfig` 中的 `mysql_config`, `main_table`, `extension_table` 字段定义
48 - **删除** `_parse_config` 中解析这些字段的代码 48 - **删除** `_parse_config` 中解析这些字段的代码
49 - **删除** `_parse_field_config` 中解析 `source_table`, `source_column` 的代码 49 - **删除** `_parse_field_config` 中解析 `source_table`, `source_column` 的代码
50 - 保持其他配置解析逻辑不变 50 - 保持其他配置解析逻辑不变
@@ -181,13 +181,13 @@ @@ -181,13 +181,13 @@
181 181
182 ## Phase 4: DataTransformer重构 182 ## Phase 4: DataTransformer重构
183 183
184 -### 4.1 重构DataTransformer(向后兼容,用于customer1) 184 +### 4.1 重构DataTransformer(向后兼容,用于tenant1)
185 185
186 **文件**: [`indexer/data_transformer.py`](indexer/data_transformer.py) 186 **文件**: [`indexer/data_transformer.py`](indexer/data_transformer.py)
187 187
188 修改: 188 修改:
189 189
190 -- **保持** 现有逻辑(用于customer1等旧配置) 190 +- **保持** 现有逻辑(用于tenant1等旧配置)
191 - **添加** 检查:如果 `field.source_column` 不存在,跳过该字段(向后兼容) 191 - **添加** 检查:如果 `field.source_column` 不存在,跳过该字段(向后兼容)
192 - **注意**:base配置不使用DataTransformer,使用SPU转换器 192 - **注意**:base配置不使用DataTransformer,使用SPU转换器
193 193
@@ -299,9 +299,9 @@ @@ -299,9 +299,9 @@
299 - [ ] Create ResponseTransformer to convert ES hits to Shoplazza format (results, facets, suggestions, related_searches) 299 - [ ] Create ResponseTransformer to convert ES hits to Shoplazza format (results, facets, suggestions, related_searches)
300 - [ ] Update API models: add VariantOption, ProductVariant, ProductResult, update SearchResponse with new format 300 - [ ] Update API models: add VariantOption, ProductVariant, ProductResult, update SearchResponse with new format
301 - [ ] Update search route to use ResponseTransformer and return Shoplazza format 301 - [ ] Update search route to use ResponseTransformer and return Shoplazza format
302 -- [ ] Create script to generate 100 SPU+SKU test records for customer2 in Shoplazza tables  
303 -- [ ] Create customer2 config.yaml with search-only fields (no pipeline details) 302 +- [ ] Create script to generate 100 SPU+SKU test records for tenant2 in Shoplazza tables
  303 +- [ ] Create tenant2 config.yaml with search-only fields (no pipeline details)
304 - [ ] Create or update SPUDataTransformer to join SPU+SKU and create nested variants structure 304 - [ ] Create or update SPUDataTransformer to join SPU+SKU and create nested variants structure
305 -- [ ] Create customer2 ingestion script that loads from MySQL and uses SPU transformer  
306 -- [ ] Create test script and documentation for customer2 setup and testing 305 +- [ ] Create tenant2 ingestion script that loads from MySQL and uses SPU transformer
  306 +- [ ] Create test script and documentation for tenant2 setup and testing
307 - [ ] Update design document: SPU-level indexing, unified index, config separation, pipeline decisions 307 - [ ] Update design document: SPU-level indexing, unified index, config separation, pipeline decisions
308 \ No newline at end of file 308 \ No newline at end of file
.cursor/plans/API响应格式优化与SPU索引重构.5.最终执行.md
@@ -54,7 +54,7 @@ @@ -54,7 +54,7 @@
54 54
55 修改: 55 修改:
56 56
57 -- **删除** `CustomerConfig` 中的 `mysql_config`, `main_table`, `extension_table` 字段定义 57 +- **删除** `TenantConfig` 中的 `mysql_config`, `main_table`, `extension_table` 字段定义
58 - **删除** `_parse_config` 中解析这些字段的代码 58 - **删除** `_parse_config` 中解析这些字段的代码
59 - **删除** `_parse_field_config` 中解析 `source_table`, `source_column` 的代码 59 - **删除** `_parse_field_config` 中解析 `source_table`, `source_column` 的代码
60 - 保持其他配置解析逻辑不变 60 - 保持其他配置解析逻辑不变
@@ -191,13 +191,13 @@ @@ -191,13 +191,13 @@
191 191
192 ## Phase 4: DataTransformer重构 192 ## Phase 4: DataTransformer重构
193 193
194 -### 4.1 重构DataTransformer(向后兼容,用于customer1) 194 +### 4.1 重构DataTransformer(向后兼容,用于tenant1)
195 195
196 **文件**: [`indexer/data_transformer.py`](indexer/data_transformer.py) 196 **文件**: [`indexer/data_transformer.py`](indexer/data_transformer.py)
197 197
198 修改: 198 修改:
199 199
200 -- **保持** 现有逻辑(用于customer1等旧配置) 200 +- **保持** 现有逻辑(用于tenant1等旧配置)
201 - **添加** 检查:如果 `field.source_column` 不存在,跳过该字段(向后兼容) 201 - **添加** 检查:如果 `field.source_column` 不存在,跳过该字段(向后兼容)
202 - **注意**:base配置不使用DataTransformer,使用SPU转换器 202 - **注意**:base配置不使用DataTransformer,使用SPU转换器
203 203
@@ -309,9 +309,9 @@ @@ -309,9 +309,9 @@
309 - [ ] Create ResponseTransformer to convert ES hits to Shoplazza format (results, facets, suggestions, related_searches) 309 - [ ] Create ResponseTransformer to convert ES hits to Shoplazza format (results, facets, suggestions, related_searches)
310 - [ ] Update API models: add VariantOption, ProductVariant, ProductResult, update SearchResponse with new format 310 - [ ] Update API models: add VariantOption, ProductVariant, ProductResult, update SearchResponse with new format
311 - [ ] Update search route to use ResponseTransformer and return Shoplazza format 311 - [ ] Update search route to use ResponseTransformer and return Shoplazza format
312 -- [ ] Create script to generate 100 SPU+SKU test records for customer2 in Shoplazza tables  
313 -- [ ] Create customer2 config.yaml with search-only fields (no pipeline details) 312 +- [ ] Create script to generate 100 SPU+SKU test records for tenant2 in Shoplazza tables
  313 +- [ ] Create tenant2 config.yaml with search-only fields (no pipeline details)
314 - [ ] Create or update SPUDataTransformer to join SPU+SKU and create nested variants structure 314 - [ ] Create or update SPUDataTransformer to join SPU+SKU and create nested variants structure
315 -- [ ] Create customer2 ingestion script that loads from MySQL and uses SPU transformer  
316 -- [ ] Create test script and documentation for customer2 setup and testing 315 +- [ ] Create tenant2 ingestion script that loads from MySQL and uses SPU transformer
  316 +- [ ] Create test script and documentation for tenant2 setup and testing
317 - [ ] Update design document: SPU-level indexing, unified index, config separation, pipeline decisions 317 - [ ] Update design document: SPU-level indexing, unified index, config separation, pipeline decisions
318 \ No newline at end of file 318 \ No newline at end of file
.cursor/plans/API响应格式优化与SPU索引重构.纠正.md
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 2. SPU维度的索引结构(包含嵌套variants数组) 8 2. SPU维度的索引结构(包含嵌套variants数组)
9 3. 所有客户共用同一索引(使用tenant_id隔离) 9 3. 所有客户共用同一索引(使用tenant_id隔离)
10 4. 配置简化(移除MySQL相关配置,只保留ES搜索配置) 10 4. 配置简化(移除MySQL相关配置,只保留ES搜索配置)
11 -5. 添加新客户(customer2)测试数据和配置 11 +5. 添加新客户(tenant2)测试数据和配置
12 12
13 ## Phase 1: 配置文件重构 13 ## Phase 1: 配置文件重构
14 14
@@ -27,8 +27,8 @@ @@ -27,8 +27,8 @@
27 - 嵌套variants结构定义 27 - 嵌套variants结构定义
28 28
29 务必注意:对于店匠的店铺,我们应该都通用的用base配置即可,不需要另外单独针对某个店铺新建一套配置,也就是所有店匠的商品都用这个base配置。 29 务必注意:对于店匠的店铺,我们应该都通用的用base配置即可,不需要另外单独针对某个店铺新建一套配置,也就是所有店匠的商品都用这个base配置。
30 -但是允许有其他某个深度定制客户有自己的索引,比如当前有一套索引customer1,我们不用动他,他的数据灌入流程是另外一份,写死的,他的索引配置也是另外一份。也就是我们的搜索服务可以支持多种配置,索引结构变了、字段变了,就是多一分配置,只是店匠多数用户都用base配置即可。  
31 -下面,如果有用到 customer2 的,应该就是指base客户,并注意帮我纠正。 30 +但是允许有其他某个深度定制客户有自己的索引,比如当前有一套索引tenant1,我们不用动他,他的数据灌入流程是另外一份,写死的,他的索引配置也是另外一份。也就是我们的搜索服务可以支持多种配置,索引结构变了、字段变了,就是多一分配置,只是店匠多数用户都用base配置即可。
  31 +下面,如果有用到 tenant2 的,应该就是指base客户,并注意帮我纠正。
32 32
33 ### 1.3 更新配置加载器 33 ### 1.3 更新配置加载器
34 34
@@ -161,16 +161,16 @@ @@ -161,16 +161,16 @@
161 161
162 - 连接MySQL数据库 162 - 连接MySQL数据库
163 - 导入测试数据到 `shoplazza_product_spu` 和 `shoplazza_product_sku` 表 163 - 导入测试数据到 `shoplazza_product_spu` 和 `shoplazza_product_sku` 表
164 -- 设置 `tenant_id` 为customer2的ID 164 +- 设置 `tenant_id` 为tenant2的ID
165 - 验证数据导入结果 165 - 验证数据导入结果
166 166
167 ## Phase 5: 测试脚本和文档 167 ## Phase 5: 测试脚本和文档
168 168
169 ### 5.1 创建测试脚本 169 ### 5.1 创建测试脚本
170 170
171 -**文件**: [`scripts/test_customer2.py`](scripts/test_customer2.py) (NEW) 171 +**文件**: [`scripts/test_tenant2.py`](scripts/test_tenant2.py) (NEW)
172 172
173 -创建customer2测试脚本: 173 +创建tenant2测试脚本:
174 174
175 - 测试数据导入 175 - 测试数据导入
176 - 测试搜索API 176 - 测试搜索API
@@ -180,9 +180,9 @@ @@ -180,9 +180,9 @@
180 180
181 ### 5.2 创建说明文档 181 ### 5.2 创建说明文档
182 182
183 -**文件**: [`docs/CUSTOMER2_TEST_GUIDE.md`](docs/CUSTOMER2_TEST_GUIDE.md) (NEW) 183 +**文件**: [`docs/TENANT2_TEST_GUIDE.md`](docs/TENANT2_TEST_GUIDE.md) (NEW)
184 184
185 -创建customer2测试指南: 185 +创建tenant2测试指南:
186 186
187 - 数据导入步骤 187 - 数据导入步骤
188 - 配置说明 188 - 配置说明
@@ -201,7 +201,7 @@ @@ -201,7 +201,7 @@
201 - 更新配置说明(移除MySQL相关配置) 201 - 更新配置说明(移除MySQL相关配置)
202 - 更新API响应格式说明 202 - 更新API响应格式说明
203 - 更新数据导入流程说明 203 - 更新数据导入流程说明
204 -- 添加customer2测试说明 204 +- 添加tenant2测试说明
205 205
206 ## 关键修改点 206 ## 关键修改点
207 207
.cursor/plans/API响应格式优化与SPU索引重构3.md
@@ -28,7 +28,7 @@ @@ -28,7 +28,7 @@
28 - 多语言字段:`title_zh`, `title_en`, `description_zh`, `description_en` 等 28 - 多语言字段:`title_zh`, `title_en`, `description_zh`, `description_en` 等
29 - 嵌套variants结构定义 29 - 嵌套variants结构定义
30 30
31 -**注意**:店匠的店铺都使用base配置,不需要单独配置。允许其他深度定制客户(如customer1)有自己的配置。 31 +**注意**:店匠的店铺都使用base配置,不需要单独配置。允许其他深度定制客户(如tenant1)有自己的配置。
32 32
33 ### 1.2 更新配置加载器 33 ### 1.2 更新配置加载器
34 34
@@ -244,9 +244,9 @@ @@ -244,9 +244,9 @@
244 - [ ] Create ResponseTransformer to convert ES hits to Shoplazza format (results, facets, suggestions, related_searches) 244 - [ ] Create ResponseTransformer to convert ES hits to Shoplazza format (results, facets, suggestions, related_searches)
245 - [ ] Update API models: add VariantOption, ProductVariant, ProductResult, update SearchResponse with new format 245 - [ ] Update API models: add VariantOption, ProductVariant, ProductResult, update SearchResponse with new format
246 - [ ] Update search route to use ResponseTransformer and return Shoplazza format 246 - [ ] Update search route to use ResponseTransformer and return Shoplazza format
247 -- [ ] Create script to generate 100 SPU+SKU test records for customer2 in Shoplazza tables  
248 -- [ ] Create customer2 config.yaml with search-only fields (no pipeline details) 247 +- [ ] Create script to generate 100 SPU+SKU test records for tenant2 in Shoplazza tables
  248 +- [ ] Create tenant2 config.yaml with search-only fields (no pipeline details)
249 - [ ] Create or update SPUDataTransformer to join SPU+SKU and create nested variants structure 249 - [ ] Create or update SPUDataTransformer to join SPU+SKU and create nested variants structure
250 -- [ ] Create customer2 ingestion script that loads from MySQL and uses SPU transformer  
251 -- [ ] Create test script and documentation for customer2 setup and testing 250 +- [ ] Create tenant2 ingestion script that loads from MySQL and uses SPU transformer
  251 +- [ ] Create test script and documentation for tenant2 setup and testing
252 - [ ] Update design document: SPU-level indexing, unified index, config separation, pipeline decisions 252 - [ ] Update design document: SPU-level indexing, unified index, config separation, pipeline decisions
253 \ No newline at end of file 253 \ No newline at end of file
.cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.md
@@ -245,7 +245,7 @@ if enable_rerank and self.rerank_engine.enabled: @@ -245,7 +245,7 @@ if enable_rerank and self.rerank_engine.enabled:
245 ) 245 )
246 ``` 246 ```
247 247
248 -#### `/home/tw/SearchEngine/config/schema/customer1/config.yaml` 248 +#### `/home/tw/SearchEngine/config/schema/tenant1/config.yaml`
249 249
250 **添加配置项**(254行后): 250 **添加配置项**(254行后):
251 251
@@ -274,7 +274,7 @@ function_score: @@ -274,7 +274,7 @@ function_score:
274 weight: 1.1 274 weight: 1.1
275 ``` 275 ```
276 276
277 -#### `/home/tw/SearchEngine/config/customer_config.py` 277 +#### `/home/tw/SearchEngine/config/tenant_config.py`
278 278
279 **更新配置类**: 279 **更新配置类**:
280 280
@@ -293,7 +293,7 @@ class FunctionScoreConfig: @@ -293,7 +293,7 @@ class FunctionScoreConfig:
293 functions: List[Dict[str, Any]] = field(default_factory=list) 293 functions: List[Dict[str, Any]] = field(default_factory=list)
294 294
295 @dataclass 295 @dataclass
296 -class CustomerConfig: 296 +class TenantConfig:
297 # ... 其他字段 ... 297 # ... 其他字段 ...
298 ranking: RankingConfig # 保留用于兼容 298 ranking: RankingConfig # 保留用于兼容
299 rerank: RerankConfig # 新增 299 rerank: RerankConfig # 新增
.cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.基于ES_fuction_score原生能力优化.md
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 30
31 ## 配置设计(简化版) 31 ## 配置设计(简化版)
32 32
33 -### `/home/tw/SearchEngine/config/schema/customer1/config.yaml` 33 +### `/home/tw/SearchEngine/config/schema/tenant1/config.yaml`
34 34
35 ```yaml 35 ```yaml
36 # Function Score配置(ES层打分规则) 36 # Function Score配置(ES层打分规则)
@@ -131,7 +131,7 @@ rerank: @@ -131,7 +131,7 @@ rerank:
131 131
132 ### 1. 定义配置模型 132 ### 1. 定义配置模型
133 133
134 -**文件**: `/home/tw/SearchEngine/config/models.py`(新建或更新customer_config.py) 134 +**文件**: `/home/tw/SearchEngine/config/models.py`(新建或更新tenant_config.py)
135 135
136 ```python 136 ```python
137 from dataclasses import dataclass, field 137 from dataclasses import dataclass, field
@@ -282,7 +282,7 @@ if fs_config and fs_config.max_boost: @@ -282,7 +282,7 @@ if fs_config and fs_config.max_boost:
282 282
283 ### 4. 更新示例配置 283 ### 4. 更新示例配置
284 284
285 -**文件**: `/home/tw/SearchEngine/config/schema/customer1/config.yaml` 285 +**文件**: `/home/tw/SearchEngine/config/schema/tenant1/config.yaml`
286 286
287 在 `ranking` 配置后添加新配置(参见上面完整YAML) 287 在 `ranking` 配置后添加新配置(参见上面完整YAML)
288 288
.cursor/plans/将数据pipeline相关配置从索引配置中剥离.md
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 3
4 ## Overview 4 ## Overview
5 5
6 -Implement clean separation between **Search Configuration** (customer-facing, ES/search focused) and **Data Pipeline** (internal ETL, script-controlled). Configuration files will only contain search engine settings, while data source and transformation logic will be controlled entirely by script parameters. 6 +Implement clean separation between **Search Configuration** (tenant-facing, ES/search focused) and **Data Pipeline** (internal ETL, script-controlled). Configuration files will only contain search engine settings, while data source and transformation logic will be controlled entirely by script parameters.
7 7
8 ## Phase 1: Configuration File Cleanup 8 ## Phase 1: Configuration File Cleanup
9 9
@@ -22,7 +22,7 @@ Implement clean separation between **Search Configuration** (customer-facing, ES @@ -22,7 +22,7 @@ Implement clean separation between **Search Configuration** (customer-facing, ES
22 22
23 **Keep** (search configuration): 23 **Keep** (search configuration):
24 24
25 -- `customer_name` 25 +- `tenant_name`
26 - `es_index_name` 26 - `es_index_name`
27 - `es_settings` 27 - `es_settings`
28 - `fields` (simplified, no source mapping) 28 - `fields` (simplified, no source mapping)
@@ -49,7 +49,7 @@ fields: @@ -49,7 +49,7 @@ fields:
49 49
50 ### 1.2 Update Legacy Configuration 50 ### 1.2 Update Legacy Configuration
51 51
52 -**File**: [`config/schema/customer1_legacy/config.yaml`](config/schema/customer1_legacy/config.yaml) 52 +**File**: [`config/schema/tenant1_legacy/config.yaml`](config/schema/tenant1_legacy/config.yaml)
53 53
54 Apply same cleanup as BASE config, marking it as legacy in comments. 54 Apply same cleanup as BASE config, marking it as legacy in comments.
55 55
@@ -101,7 +101,7 @@ class TransformerFactory: @@ -101,7 +101,7 @@ class TransformerFactory:
101 @staticmethod 101 @staticmethod
102 def create( 102 def create(
103 transformer_type: str, # 'sku' or 'spu' 103 transformer_type: str, # 'sku' or 'spu'
104 - config: CustomerConfig, 104 + config: TenantConfig,
105 text_encoder=None, 105 text_encoder=None,
106 image_encoder=None 106 image_encoder=None
107 ) -> BaseDataTransformer: 107 ) -> BaseDataTransformer:
@@ -247,9 +247,9 @@ Changes: @@ -247,9 +247,9 @@ Changes:
247 - Simplify field parsing (no source mapping) 247 - Simplify field parsing (no source mapping)
248 - Keep validation of ES/search related config 248 - Keep validation of ES/search related config
249 249
250 -### 4.2 Update CustomerConfig Model 250 +### 4.2 Update TenantConfig Model
251 251
252 -**File**: [`config/__init__.py`](config/**init**.py) or wherever CustomerConfig is defined 252 +**File**: [`config/__init__.py`](config/**init**.py) or wherever TenantConfig is defined
253 253
254 Remove attributes: 254 Remove attributes:
255 255
@@ -377,7 +377,7 @@ Add deprecation warnings to scripts that still use old config format. @@ -377,7 +377,7 @@ Add deprecation warnings to scripts that still use old config format.
377 377
378 ### 1. Separation of Concerns 378 ### 1. Separation of Concerns
379 379
380 -**Search Configuration** (customer-facing): 380 +**Search Configuration** (tenant-facing):
381 381
382 - What fields exist in ES 382 - What fields exist in ES
383 - How fields are analyzed/indexed 383 - How fields are analyzed/indexed
@@ -445,7 +445,7 @@ Pipeline decisions (transformer, data source, field mapping) made at runtime, no @@ -445,7 +445,7 @@ Pipeline decisions (transformer, data source, field mapping) made at runtime, no
445 445
446 ✅ **Configuration reusability across data sources** 446 ✅ **Configuration reusability across data sources**
447 447
448 -✅ **Customer doesn't need to understand ETL** 448 +✅ **Tenant doesn't need to understand ETL**
449 449
450 ✅ **Easier to add new data sources** 450 ✅ **Easier to add new data sources**
451 451
.cursor/plans/所有tenant按同一份所有_返回接口优化.md
@@ -142,10 +142,10 @@ New models: @@ -142,10 +142,10 @@ New models:
142 142
143 ## Phase 6: Legacy Migration 143 ## Phase 6: Legacy Migration
144 144
145 -### 6.1 Rename Customer1 to Legacy 145 +### 6.1 Rename Tenant1 to Legacy
146 146
147 -- Rename [`config/schema/customer1/`](config/schema/customer1/) to [`config/schema/customer1_legacy/`](config/schema/customer1_legacy/)  
148 -- Update config to use old index `search_customer1` (preserve for backward compatibility) 147 +- Rename [`config/schema/tenant1/`](config/schema/tenant1/) to [`config/schema/tenant1_legacy/`](config/schema/tenant1_legacy/)
  148 +- Update config to use old index `search_tenant1` (preserve for backward compatibility)
149 - Mark as deprecated in comments 149 - Mark as deprecated in comments
150 150
151 ### 6.2 Update Scripts for BASE 151 ### 6.2 Update Scripts for BASE
@@ -159,7 +159,7 @@ New models: @@ -159,7 +159,7 @@ New models:
159 159
160 **Files**: [`frontend/`](frontend/) HTML/JS files 160 **Files**: [`frontend/`](frontend/) HTML/JS files
161 161
162 -- Change index name references from `search_customer1` to `search_products` 162 +- Change index name references from `search_tenant1` to `search_products`
163 - Use BASE config endpoints 163 - Use BASE config endpoints
164 - Archive old frontend as `frontend_legacy/` if needed 164 - Archive old frontend as `frontend_legacy/` if needed
165 165
@@ -205,7 +205,7 @@ Updates: @@ -205,7 +205,7 @@ Updates:
205 - **API响应格式**: 采用 Shoplazza 标准格式 205 - **API响应格式**: 采用 Shoplazza 标准格式
206 - **Price扁平化**: 说明高频字段的性能优化策略 206 - **Price扁平化**: 说明高频字段的性能优化策略
207 - **Nested变体**: 详细说明 variants 数组结构 207 - **Nested变体**: 详细说明 variants 数组结构
208 -- **Legacy配置**: customer1等为遗留配置,仅用于兼容 208 +- **Legacy配置**: tenant1等为遗留配置,仅用于兼容
209 209
210 ### 8.2 Create BASE Guide 210 ### 8.2 Create BASE Guide
211 211
@@ -258,7 +258,7 @@ Steps: @@ -258,7 +258,7 @@ Steps:
258 258
259 ### BASE Configuration Philosophy 259 ### BASE Configuration Philosophy
260 260
261 -**BASE = Universal Standard**: All new merchants use BASE config with Shoplazza tables. No per-customer schema customization. Customization happens through: 261 +**BASE = Universal Standard**: All new merchants use BASE config with Shoplazza tables. No per-tenant schema customization. Customization happens through:
262 262
263 - Configuration parameters (analyzers, function_score, etc.) 263 - Configuration parameters (analyzers, function_score, etc.)
264 - Extension tables (if needed for additional fields) 264 - Extension tables (if needed for additional fields)
@@ -280,7 +280,7 @@ High-frequency operations (filtering, sorting) on price require optimal performa @@ -280,7 +280,7 @@ High-frequency operations (filtering, sorting) on price require optimal performa
280 ### Legacy vs BASE 280 ### Legacy vs BASE
281 281
282 - **BASE**: New standard, all future merchants 282 - **BASE**: New standard, all future merchants
283 -- **Legacy (customer1_legacy)**: Deprecated, exists only for backward compatibility 283 +- **Legacy (tenant1_legacy)**: Deprecated, exists only for backward compatibility
284 - All scripts/frontend default to BASE 284 - All scripts/frontend default to BASE
285 - Legacy access requires explicit suffix (`_legacy`) 285 - Legacy access requires explicit suffix (`_legacy`)
286 286
@@ -291,12 +291,12 @@ High-frequency operations (filtering, sorting) on price require optimal performa @@ -291,12 +291,12 @@ High-frequency operations (filtering, sorting) on price require optimal performa
291 - [ ] Add NESTED field type support to field_types.py and mapping generator 291 - [ ] Add NESTED field type support to field_types.py and mapping generator
292 - [ ] Create SPU-level data transformer that joins SPU+SKU tables and creates nested variant array 292 - [ ] Create SPU-level data transformer that joins SPU+SKU tables and creates nested variant array
293 - [ ] Create script to generate 100 realistic SPU+SKU test records in Shoplazza tables 293 - [ ] Create script to generate 100 realistic SPU+SKU test records in Shoplazza tables
294 -- [ ] Create customer2 configuration using unified schema and Shoplazza tables only  
295 -- [ ] Create customer2 ingestion script that loads from MySQL Shoplazza tables 294 +- [ ] Create tenant2 configuration using unified schema and Shoplazza tables only
  295 +- [ ] Create tenant2 ingestion script that loads from MySQL Shoplazza tables
296 - [ ] Update query builder to support tenant_id filtering and nested variant queries 296 - [ ] Update query builder to support tenant_id filtering and nested variant queries
297 - [ ] Create response transformer to convert ES format to Shoplazza-compatible format 297 - [ ] Create response transformer to convert ES format to Shoplazza-compatible format
298 - [ ] Update API models with new Shoplazza response format (ProductResult, variants, suggestions, etc.) 298 - [ ] Update API models with new Shoplazza response format (ProductResult, variants, suggestions, etc.)
299 - [ ] Update search routes to use response transformer and return new format 299 - [ ] Update search routes to use response transformer and return new format
300 -- [ ] Migrate customer1 configuration to unified schema and SPU-level indexing  
301 -- [ ] Create customer2 guide, update design docs, API docs, and create migration guide  
302 -- [ ] Create comprehensive test script for customer2 with data generation, ingestion, and search validation  
303 \ No newline at end of file 300 \ No newline at end of file
  301 +- [ ] Migrate tenant1 configuration to unified schema and SPU-level indexing
  302 +- [ ] Create tenant2 guide, update design docs, API docs, and create migration guide
  303 +- [ ] Create comprehensive test script for tenant2 with data generation, ingestion, and search validation
304 \ No newline at end of file 304 \ No newline at end of file
.cursor/plans/所有租户共用一套统一配置.tenantID只在请求层级.服务层级没有tenantID相关的独立配置.md
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 将搜索服务从按租户启动改造为真正的多租户架构: 6 将搜索服务从按租户启动改造为真正的多租户架构:
7 7
8 - 服务启动时不指定租户ID,所有租户共用一套配置 8 - 服务启动时不指定租户ID,所有租户共用一套配置
9 -- 删除customer1配置,去掉base层级,统一为config.yaml 9 +- 删除tenant1配置,去掉base层级,统一为config.yaml
10 - 统一脚本接口:启动、停止、重启、数据灌入 10 - 统一脚本接口:启动、停止、重启、数据灌入
11 - 统一数据灌入流程,ES只有一份索引 11 - 统一数据灌入流程,ES只有一份索引
12 - 前端支持在搜索框左侧输入租户ID 12 - 前端支持在搜索框左侧输入租户ID
@@ -18,30 +18,30 @@ @@ -18,30 +18,30 @@
18 **文件**: `config/config.yaml` (NEW) 18 **文件**: `config/config.yaml` (NEW)
19 19
20 - 将 `config/schema/base/config.yaml` 移动到 `config/config.yaml` 20 - 将 `config/schema/base/config.yaml` 移动到 `config/config.yaml`
21 -- 删除 `customer_name` 字段(不再需要)  
22 -- 删除 `customer_id` 相关逻辑 21 +- 删除 `tenant_name` 字段(不再需要)
  22 +- 删除 `tenant_id` 相关逻辑
23 - 固定索引名称为 `search_products` 23 - 固定索引名称为 `search_products`
24 - 确保包含 `tenant_id` 字段(必需) 24 - 确保包含 `tenant_id` 字段(必需)
25 25
26 -### 1.2 删除customer1配置 26 +### 1.2 删除tenant1配置
27 27
28 **删除文件**: 28 **删除文件**:
29 29
30 -- `config/schema/customer1/config.yaml`  
31 -- `config/schema/customer1/` 目录(如果为空) 30 +- `config/schema/tenant1/config.yaml`
  31 +- `config/schema/tenant1/` 目录(如果为空)
32 32
33 ### 1.3 更新ConfigLoader 33 ### 1.3 更新ConfigLoader
34 34
35 **文件**: `config/config_loader.py` 35 **文件**: `config/config_loader.py`
36 36
37 -修改 `load_customer_config()` 方法: 37 +修改 `load_tenant_config()` 方法:
38 38
39 -- 移除 `customer_id` 参数 39 +- 移除 `tenant_id` 参数
40 - 改为 `load_config()` 方法 40 - 改为 `load_config()` 方法
41 - 直接加载 `config/config.yaml` 41 - 直接加载 `config/config.yaml`
42 -- 移除对 `config/schema/{customer_id}/config.yaml` 的查找逻辑  
43 -- 移除 `customer_id` 字段验证  
44 -- 更新 `CustomerConfig` 类:移除 `customer_id` 字段 42 +- 移除对 `config/schema/{tenant_id}/config.yaml` 的查找逻辑
  43 +- 移除 `tenant_id` 字段验证
  44 +- 更新 `TenantConfig` 类:移除 `tenant_id` 字段
45 45
46 ### 1.4 更新配置验证 46 ### 1.4 更新配置验证
47 47
@@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
50 修改 `validate_config()` 方法: 50 修改 `validate_config()` 方法:
51 51
52 - 确保 `tenant_id` 字段存在且为必需 52 - 确保 `tenant_id` 字段存在且为必需
53 -- 移除对 `customer_id` 的验证 53 +- 移除对 `tenant_id` 的验证
54 54
55 ## Phase 2: 服务启动改造 55 ## Phase 2: 服务启动改造
56 56
@@ -60,14 +60,14 @@ @@ -60,14 +60,14 @@
60 60
61 修改 `init_service()` 方法: 61 修改 `init_service()` 方法:
62 62
63 -- 移除 `customer_id` 参数 63 +- 移除 `tenant_id` 参数
64 - 直接加载统一配置(`config/config.yaml`) 64 - 直接加载统一配置(`config/config.yaml`)
65 -- 移除 `CUSTOMER_ID` 环境变量依赖  
66 -- 更新日志输出(不再显示customer_id) 65 +- 移除 `TENANT_ID` 环境变量依赖
  66 +- 更新日志输出(不再显示tenant_id)
67 67
68 修改 `startup_event()` 方法: 68 修改 `startup_event()` 方法:
69 69
70 -- 移除 `CUSTOMER_ID` 环境变量读取 70 +- 移除 `TENANT_ID` 环境变量读取
71 - 直接调用 `init_service()` 不传参数 71 - 直接调用 `init_service()` 不传参数
72 72
73 ### 2.2 更新main.py 73 ### 2.2 更新main.py
@@ -76,8 +76,8 @@ @@ -76,8 +76,8 @@
76 76
77 修改 `cmd_serve()` 方法: 77 修改 `cmd_serve()` 方法:
78 78
79 -- 移除 `--customer` 参数  
80 -- 移除 `CUSTOMER_ID` 环境变量设置 79 +- 移除 `--tenant` 参数
  80 +- 移除 `TENANT_ID` 环境变量设置
81 - 更新帮助信息 81 - 更新帮助信息
82 82
83 ### 2.3 更新启动脚本 83 ### 2.3 更新启动脚本
@@ -86,16 +86,16 @@ @@ -86,16 +86,16 @@
86 86
87 修改: 87 修改:
88 88
89 -- 移除 `CUSTOMER_ID` 环境变量  
90 -- 移除 `--customer` 参数 89 +- 移除 `TENANT_ID` 环境变量
  90 +- 移除 `--tenant` 参数
91 - 简化启动命令 91 - 简化启动命令
92 92
93 **文件**: `scripts/start_servers.py` 93 **文件**: `scripts/start_servers.py`
94 94
95 修改 `start_api_server()` 方法: 95 修改 `start_api_server()` 方法:
96 96
97 -- 移除 `customer` 参数  
98 -- 移除 `CUSTOMER_ID` 环境变量设置 97 +- 移除 `tenant` 参数
  98 +- 移除 `TENANT_ID` 环境变量设置
99 - 简化启动命令 99 - 简化启动命令
100 100
101 ## Phase 3: 脚本体系统一 101 ## Phase 3: 脚本体系统一
@@ -139,7 +139,7 @@ @@ -139,7 +139,7 @@
139 功能: 139 功能:
140 140
141 - 从MySQL读取数据 141 - 从MySQL读取数据
142 -- 转换数据格式(统一处理base和customer1数据源) 142 +- 转换数据格式(统一处理base和tenant1数据源)
143 - 灌入到ES索引 `search_products` 143 - 灌入到ES索引 `search_products`
144 - 支持指定租户ID过滤数据 144 - 支持指定租户ID过滤数据
145 - 自动处理字段映射:缺失字段随机生成,多余字段忽略 145 - 自动处理字段映射:缺失字段随机生成,多余字段忽略
@@ -204,7 +204,7 @@ @@ -204,7 +204,7 @@
204 204
205 - 移除 `--config` 参数(不再需要) 205 - 移除 `--config` 参数(不再需要)
206 - 直接加载统一配置(`config/config.yaml`) 206 - 直接加载统一配置(`config/config.yaml`)
207 -- 统一处理所有数据源(不再区分base和customer1) 207 +- 统一处理所有数据源(不再区分base和tenant1)
208 - 支持 `--tenant-id` 参数过滤数据 208 - 支持 `--tenant-id` 参数过滤数据
209 - 字段映射逻辑: 209 - 字段映射逻辑:
210 - 如果字段在配置中但数据源中没有,随机生成 210 - 如果字段在配置中但数据源中没有,随机生成
@@ -217,7 +217,7 @@ @@ -217,7 +217,7 @@
217 217
218 修改: 218 修改:
219 219
220 -- 移除对配置中 `customer_id` 的依赖 220 +- 移除对配置中 `tenant_id` 的依赖
221 - 统一处理所有数据源 221 - 统一处理所有数据源
222 - 确保字段映射正确(缺失字段随机生成,多余字段忽略) 222 - 确保字段映射正确(缺失字段随机生成,多余字段忽略)
223 223
@@ -299,8 +299,8 @@ @@ -299,8 +299,8 @@
299 299
300 ### 7.1 清理废弃代码 300 ### 7.1 清理废弃代码
301 301
302 -- 删除所有对 `customer_id` 的引用  
303 -- 删除所有对 `customer1` 配置的引用 302 +- 删除所有对 `tenant_id` 的引用
  303 +- 删除所有对 `tenant1` 配置的引用
304 - 删除所有对 `base` 配置层级的引用 304 - 删除所有对 `base` 配置层级的引用
305 - 清理不再使用的脚本 305 - 清理不再使用的脚本
306 306
@@ -316,12 +316,12 @@ @@ -316,12 +316,12 @@
316 316
317 ### 需要修改的文件: 317 ### 需要修改的文件:
318 318
319 -1. `config/config_loader.py` - 移除customer_id逻辑 319 +1. `config/config_loader.py` - 移除tenant_id逻辑
320 2. `config/config.yaml` - 统一配置文件(从base移动) 320 2. `config/config.yaml` - 统一配置文件(从base移动)
321 -3. `api/app.py` - 移除customer_id参数  
322 -4. `main.py` - 移除customer参数  
323 -5. `scripts/start_backend.sh` - 移除CUSTOMER_ID  
324 -6. `scripts/start_servers.py` - 移除customer参数 321 +3. `api/app.py` - 移除tenant_id参数
  322 +4. `main.py` - 移除tenant参数
  323 +5. `scripts/start_backend.sh` - 移除TENANT_ID
  324 +6. `scripts/start_servers.py` - 移除tenant参数
325 7. `scripts/ingest_shoplazza.py` - 统一数据灌入 325 7. `scripts/ingest_shoplazza.py` - 统一数据灌入
326 8. `frontend/index.html` - 添加租户ID输入框 326 8. `frontend/index.html` - 添加租户ID输入框
327 9. `frontend/static/js/app_base.js` - 读取租户ID 327 9. `frontend/static/js/app_base.js` - 读取租户ID
@@ -329,8 +329,8 @@ @@ -329,8 +329,8 @@
329 329
330 ### 需要删除的文件: 330 ### 需要删除的文件:
331 331
332 -1. `config/schema/customer1/config.yaml`  
333 -2. `config/schema/customer1/` 目录 332 +1. `config/schema/tenant1/config.yaml`
  333 +2. `config/schema/tenant1/` 目录
334 3. `scripts/demo_base.sh` 334 3. `scripts/demo_base.sh`
335 4. `scripts/stop_base.sh` 335 4. `scripts/stop_base.sh`
336 5. 其他废弃脚本 336 5. 其他废弃脚本
.github/workflows/test.yml
@@ -209,7 +209,7 @@ EOF @@ -209,7 +209,7 @@ EOF
209 - name: Run integration tests 209 - name: Run integration tests
210 env: 210 env:
211 ES_HOST: http://localhost:9200 211 ES_HOST: http://localhost:9200
212 - CUSTOMER_ID: test_customer 212 + TENANT_ID: test_tenant
213 TESTING_MODE: true 213 TESTING_MODE: true
214 run: | 214 run: |
215 python -m pytest tests/integration/ \ 215 python -m pytest tests/integration/ \
@@ -312,7 +312,7 @@ EOF @@ -312,7 +312,7 @@ EOF
312 - name: Start API service 312 - name: Start API service
313 env: 313 env:
314 ES_HOST: http://localhost:9200 314 ES_HOST: http://localhost:9200
315 - CUSTOMER_ID: test_customer 315 + TENANT_ID: test_tenant
316 API_HOST: 127.0.0.1 316 API_HOST: 127.0.0.1
317 API_PORT: 6003 317 API_PORT: 6003
318 TESTING_MODE: true 318 TESTING_MODE: true
@@ -320,7 +320,7 @@ EOF @@ -320,7 +320,7 @@ EOF
320 python -m api.app \ 320 python -m api.app \
321 --host $API_HOST \ 321 --host $API_HOST \
322 --port $API_PORT \ 322 --port $API_PORT \
323 - --customer $CUSTOMER_ID \ 323 + --tenant $TENANT_ID \
324 --es-host $ES_HOST & 324 --es-host $ES_HOST &
325 echo $! > api.pid 325 echo $! > api.pid
326 326
@@ -339,7 +339,7 @@ EOF @@ -339,7 +339,7 @@ EOF
339 ES_HOST: http://localhost:9200 339 ES_HOST: http://localhost:9200
340 API_HOST: 127.0.0.1 340 API_HOST: 127.0.0.1
341 API_PORT: 6003 341 API_PORT: 6003
342 - CUSTOMER_ID: test_customer 342 + TENANT_ID: test_tenant
343 TESTING_MODE: true 343 TESTING_MODE: true
344 run: | 344 run: |
345 python -m pytest tests/integration/test_api_integration.py \ 345 python -m pytest tests/integration/test_api_integration.py \
API_DOCUMENTATION.md
@@ -527,7 +527,7 @@ curl "http://localhost:6002/search/12345" @@ -527,7 +527,7 @@ curl "http://localhost:6002/search/12345"
527 { 527 {
528 "status": "healthy", 528 "status": "healthy",
529 "elasticsearch": "connected", 529 "elasticsearch": "connected",
530 - "customer_id": "customer1" 530 + "tenant_id": "tenant1"
531 } 531 }
532 ``` 532 ```
533 533
@@ -543,9 +543,9 @@ curl "http://localhost:6002/search/12345" @@ -543,9 +543,9 @@ curl "http://localhost:6002/search/12345"
543 543
544 ```json 544 ```json
545 { 545 {
546 - "customer_id": "customer1",  
547 - "customer_name": "Customer1 Test Instance",  
548 - "es_index_name": "search_customer1", 546 + "tenant_id": "tenant1",
  547 + "tenant_name": "Tenant1 Test Instance",
  548 + "es_index_name": "search_tenant1",
549 "num_fields": 20, 549 "num_fields": 20,
550 "num_indexes": 4, 550 "num_indexes": 4,
551 "supported_languages": ["zh", "en", "ru"], 551 "supported_languages": ["zh", "en", "ru"],
@@ -566,7 +566,7 @@ curl "http://localhost:6002/search/12345" @@ -566,7 +566,7 @@ curl "http://localhost:6002/search/12345"
566 566
567 ```json 567 ```json
568 { 568 {
569 - "index_name": "search_customer1", 569 + "index_name": "search_tenant1",
570 "document_count": 10000, 570 "document_count": 10000,
571 "size_mb": 523.45 571 "size_mb": 523.45
572 } 572 }
@@ -31,17 +31,17 @@ password: P89cZHS5d7dFyc9R @@ -31,17 +31,17 @@ password: P89cZHS5d7dFyc9R
31 ## Architecture 31 ## Architecture
32 32
33 ### Data Flow 33 ### Data Flow
34 -1. **Data Source (MySQL)** → Main tables (`shoplazza_product_sku`, `shoplazza_product_spu`) + customer extension tables 34 +1. **Data Source (MySQL)** → Main tables (`shoplazza_product_sku`, `shoplazza_product_spu`) + tenant extension tables
35 2. **Indexer** → Reads from MySQL, applies transformations (embeddings, etc.), writes to Elasticsearch 35 2. **Indexer** → Reads from MySQL, applies transformations (embeddings, etc.), writes to Elasticsearch
36 3. **Query Parser** → Query rewriting, translation, text embedding conversion 36 3. **Query Parser** → Query rewriting, translation, text embedding conversion
37 4. **Searcher** → Executes searches against Elasticsearch with configurable ranking 37 4. **Searcher** → Executes searches against Elasticsearch with configurable ranking
38 38
39 ### Multi-Tenant Design 39 ### Multi-Tenant Design
40 -Each customer has their own extension table to store custom attributes, multi-language fields (titles, brand names, tags, categories), and business-specific metadata. The main SKU table is joined with customer extension tables during indexing. 40 +Each tenant has their own extension table to store custom attributes, multi-language fields (titles, brand names, tags, categories), and business-specific metadata. The main SKU table is joined with tenant extension tables during indexing.
41 41
42 ### Configuration System 42 ### Configuration System
43 43
44 -The system uses two types of configurations per customer: 44 +The system uses two types of configurations per tenant:
45 45
46 1. **Application Structure Config** (`IndexerConfig`) - Defines: 46 1. **Application Structure Config** (`IndexerConfig`) - Defines:
47 - Input field mappings from MySQL to Elasticsearch 47 - Input field mappings from MySQL to Elasticsearch
@@ -89,10 +89,10 @@ The `searcher` supports: @@ -89,10 +89,10 @@ The `searcher` supports:
89 89
90 ## Test Data 90 ## Test Data
91 91
92 -**Customer1 Test Dataset:**  
93 -- Location: `data/customer1/goods_with_pic.5years_congku.csv.shuf.1w` 92 +**Tenant1 Test Dataset:**
  93 +- Location: `data/tenant1/goods_with_pic.5years_congku.csv.shuf.1w`
94 - Contains 10,000 shuffled product records with images 94 - Contains 10,000 shuffled product records with images
95 -- Processing script: `data/customer1/task2_process_goods.py` 95 +- Processing script: `data/tenant1/task2_process_goods.py`
96 - Extracts product data from MySQL 96 - Extracts product data from MySQL
97 - Maps images from filebank database 97 - Maps images from filebank database
98 - Creates inverted index (URL → SKU list) 98 - Creates inverted index (URL → SKU list)
@@ -101,7 +101,7 @@ The `searcher` supports: @@ -101,7 +101,7 @@ The `searcher` supports:
101 101
102 1. **Data Sync:** Full data sync from MySQL to Elasticsearch is handled by a separate Java project (not in this repo). This repo may include a simple full-load implementation for testing purposes. 102 1. **Data Sync:** Full data sync from MySQL to Elasticsearch is handled by a separate Java project (not in this repo). This repo may include a simple full-load implementation for testing purposes.
103 103
104 -2. **Extension Tables:** When designing customer configurations, determine which fields exist in the main SKU table vs. which need to be added to customer-specific extension tables. 104 +2. **Extension Tables:** When designing tenant configurations, determine which fields exist in the main SKU table vs. which need to be added to tenant-specific extension tables.
105 105
106 3. **Embedding Caching:** For periodic full indexing, embedding results should be cached to avoid recomputation. 106 3. **Embedding Caching:** For periodic full indexing, embedding results should be cached to avoid recomputation.
107 107
@@ -86,7 +86,7 @@ REDIS_PASSWORD=BMfv5aI31kgHWtlx @@ -86,7 +86,7 @@ REDIS_PASSWORD=BMfv5aI31kgHWtlx
86 86
87 DEEPL_AUTH_KEY=c9293ab4-ad25-479b-919f-ab4e63b429ed 87 DEEPL_AUTH_KEY=c9293ab4-ad25-479b-919f-ab4e63b429ed
88 88
89 -CUSTOMER_ID=customer1 89 +TENANT_ID=tenant1
90 API_HOST=0.0.0.0 90 API_HOST=0.0.0.0
91 API_PORT=6002 91 API_PORT=6002
92 ``` 92 ```
@@ -146,7 +146,7 @@ from config import ConfigLoader @@ -146,7 +146,7 @@ from config import ConfigLoader
146 146
147 es_config = get_es_config() 147 es_config = get_es_config()
148 es_client = ESClient(hosts=[es_config['host']], username=es_config.get('username'), password=es_config.get('password')) 148 es_client = ESClient(hosts=[es_config['host']], username=es_config.get('username'), password=es_config.get('password'))
149 -config = ConfigLoader('config/schema').load_customer_config('customer1') 149 +config = ConfigLoader('config/schema').load_tenant_config('tenant1')
150 count = es_client.count(config.es_index_name) 150 count = es_client.count(config.es_index_name)
151 print(f'Documents in index: {count}') 151 print(f'Documents in index: {count}')
152 " 152 "
@@ -255,7 +255,7 @@ kill -9 <PID> @@ -255,7 +255,7 @@ kill -9 <PID>
255 - 了解所有可用的API端点 255 - 了解所有可用的API端点
256 256
257 3. **自定义配置** 257 3. **自定义配置**
258 - - 编辑 `config/schema/customer1_config.yaml` 258 + - 编辑 `config/schema/tenant1_config.yaml`
259 - 添加查询重写规则 259 - 添加查询重写规则
260 - 调整ranking表达式 260 - 调整ranking表达式
261 261
FUNCTION_SCORE_CONFIG_COMPLETE.md
@@ -29,9 +29,9 @@ class RerankConfig: @@ -29,9 +29,9 @@ class RerankConfig:
29 description: str = "" 29 description: str = ""
30 ``` 30 ```
31 31
32 -添加到 `CustomerConfig`: 32 +添加到 `TenantConfig`:
33 ```python 33 ```python
34 -class CustomerConfig: 34 +class TenantConfig:
35 # ... 其他字段 35 # ... 其他字段
36 function_score: FunctionScoreConfig 36 function_score: FunctionScoreConfig
37 rerank: RerankConfig 37 rerank: RerankConfig
@@ -104,7 +104,7 @@ def _build_score_functions(self) -> List[Dict[str, Any]]: @@ -104,7 +104,7 @@ def _build_score_functions(self) -> List[Dict[str, Any]]:
104 104
105 ### 3. 配置文件示例 105 ### 3. 配置文件示例
106 106
107 -**文件**: `/home/tw/SearchEngine/config/schema/customer1/config.yaml` 107 +**文件**: `/home/tw/SearchEngine/config/schema/tenant1/config.yaml`
108 108
109 添加完整的`function_score`配置: 109 添加完整的`function_score`配置:
110 110
@@ -489,7 +489,7 @@ https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-functi @@ -489,7 +489,7 @@ https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-functi
489 489
490 1. **编辑配置文件** 490 1. **编辑配置文件**
491 ```bash 491 ```bash
492 -vi config/schema/customer1/config.yaml 492 +vi config/schema/tenant1/config.yaml
493 ``` 493 ```
494 494
495 2. **添加打分规则** 495 2. **添加打分规则**
HighLevelDesign.md
@@ -71,10 +71,10 @@ deleted bit(1) @@ -71,10 +71,10 @@ deleted bit(1)
71 ### 测试数据灌入 71 ### 测试数据灌入
72 72
73 灌入数据、mysql到ES的自动同步,不在本项目的范围内,另外有java项目负责。 73 灌入数据、mysql到ES的自动同步,不在本项目的范围内,另外有java项目负责。
74 -但是,该项目 为了提供测试数据,需要 构造一个实例 customer1. 74 +但是,该项目 为了提供测试数据,需要 构造一个实例 tenant1.
75 我们为他构造一套应用配置和索引配置。 75 我们为他构造一套应用配置和索引配置。
76 灌入一批测试数据,可以些一个简单的 全量灌入的实现。 76 灌入一批测试数据,可以些一个简单的 全量灌入的实现。
77 -数据源地址在:data/customer1/goods_with_pic.5years_congku.csv.shuf.1w 77 +数据源地址在:data/tenant1/goods_with_pic.5years_congku.csv.shuf.1w
78 请根据这里面的字段,建设辅助表(注意看哪些字段在主表有,哪些需要放到辅表) 78 请根据这里面的字段,建设辅助表(注意看哪些字段在主表有,哪些需要放到辅表)
79 然后写一个程序,将数据分别灌入主表和辅表。 79 然后写一个程序,将数据分别灌入主表和辅表。
80 80
@@ -83,7 +83,7 @@ deleted bit(1) @@ -83,7 +83,7 @@ deleted bit(1)
83 query分析,做以下几个事情: 83 query分析,做以下几个事情:
84 84
85 1. 查询改写。 配置词典的key是query,value是改写后的查询表达式,比如。比如品牌词 改写为在brand|query OR name|query,类别词、标签词等都可以放进去。纠错、规范化、查询改写等 都可以通过这个词典来配置。 85 1. 查询改写。 配置词典的key是query,value是改写后的查询表达式,比如。比如品牌词 改写为在brand|query OR name|query,类别词、标签词等都可以放进去。纠错、规范化、查询改写等 都可以通过这个词典来配置。
86 -2. 翻译。配置需要得到的几种目标语言。 在customer1测试案例中,我们配置 zh en两种语言。先对query做语言检测,如果query是中文那么要翻译一下en,如果是en那么要翻译zh,如果两者都不是那么zh en都需要翻译。 86 +2. 翻译。配置需要得到的几种目标语言。 在tenant1测试案例中,我们配置 zh en两种语言。先对query做语言检测,如果query是中文那么要翻译一下en,如果是en那么要翻译zh,如果两者都不是那么zh en都需要翻译。
87 3. 如果配置打开了text_embedding查询,并且query 包含了default域的查询,那么要把default域的查询词转向量,后面searcher会用这个向量参与查询。 87 3. 如果配置打开了text_embedding查询,并且query 包含了default域的查询,那么要把default域的查询词转向量,后面searcher会用这个向量参与查询。
88 翻译代码参考: 88 翻译代码参考:
89 ``` 89 ```
MULTILANG_FEATURE.md
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 14
15 ### 字段配置 15 ### 字段配置
16 16
17 -在 `customer1_config.yaml` 中,需要为不同语言的标题字段配置对应的分词器: 17 +在 `tenant1_config.yaml` 中,需要为不同语言的标题字段配置对应的分词器:
18 18
19 ```yaml 19 ```yaml
20 fields: 20 fields:
@@ -24,8 +24,8 @@ export ES_HOST="http://localhost:9200" @@ -24,8 +24,8 @@ export ES_HOST="http://localhost:9200"
24 # DeepL API (for translation) 24 # DeepL API (for translation)
25 export DEEPL_API_KEY="your-api-key-here" 25 export DEEPL_API_KEY="your-api-key-here"
26 26
27 -# Customer ID  
28 -export CUSTOMER_ID="customer1" 27 +# Tenant ID
  28 +export TENANT_ID="tenant1"
29 ``` 29 ```
30 30
31 ## Running the System 31 ## Running the System
@@ -37,8 +37,8 @@ export CUSTOMER_ID="customer1" @@ -37,8 +37,8 @@ export CUSTOMER_ID="customer1"
37 docker run -d -p 9200:9200 -e "discovery.type=single-node" elasticsearch:8.11.0 37 docker run -d -p 9200:9200 -e "discovery.type=single-node" elasticsearch:8.11.0
38 38
39 # 2. Ingest sample data (100 documents for quick test) 39 # 2. Ingest sample data (100 documents for quick test)
40 -cd data/customer1  
41 -python ingest_customer1.py \ 40 +cd data/tenant1
  41 +python ingest_tenant1.py \
42 --limit 100 \ 42 --limit 100 \
43 --recreate-index \ 43 --recreate-index \
44 --es-host http://localhost:9200 \ 44 --es-host http://localhost:9200 \
@@ -61,8 +61,8 @@ curl -X POST http://localhost:6002/search/ \ @@ -61,8 +61,8 @@ curl -X POST http://localhost:6002/search/ \
61 docker run -d -p 9200:9200 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms4g -Xmx4g" elasticsearch:8.11.0 61 docker run -d -p 9200:9200 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms4g -Xmx4g" elasticsearch:8.11.0
62 62
63 # 2. Ingest full dataset with embeddings (requires GPU, takes ~10-30 min) 63 # 2. Ingest full dataset with embeddings (requires GPU, takes ~10-30 min)
64 -cd data/customer1  
65 -python ingest_customer1.py \ 64 +cd data/tenant1
  65 +python ingest_tenant1.py \
66 --csv goods_with_pic.5years_congku.csv.shuf.1w \ 66 --csv goods_with_pic.5years_congku.csv.shuf.1w \
67 --recreate-index \ 67 --recreate-index \
68 --batch-size 100 \ 68 --batch-size 100 \
@@ -73,7 +73,7 @@ cd ../.. @@ -73,7 +73,7 @@ cd ../..
73 python -m api.app \ 73 python -m api.app \
74 --host 0.0.0.0 \ 74 --host 0.0.0.0 \
75 --port 6002 \ 75 --port 6002 \
76 - --customer customer1 \ 76 + --tenant tenant1 \
77 --es-host http://localhost:9200 77 --es-host http://localhost:9200
78 78
79 # 4. Test various searches 79 # 4. Test various searches
@@ -118,7 +118,7 @@ python -c "from embeddings import CLIPImageEncoder; CLIPImageEncoder()" @@ -118,7 +118,7 @@ python -c "from embeddings import CLIPImageEncoder; CLIPImageEncoder()"
118 ### Issue: Out of memory during embedding generation 118 ### Issue: Out of memory during embedding generation
119 **Solution**: Reduce batch size or skip embeddings initially 119 **Solution**: Reduce batch size or skip embeddings initially
120 ```bash 120 ```bash
121 -python ingest_customer1.py --skip-embeddings --limit 1000 121 +python ingest_tenant1.py --skip-embeddings --limit 1000
122 ``` 122 ```
123 123
124 ### Issue: Translation not working 124 ### Issue: Translation not working
@@ -164,7 +164,7 @@ curl -X POST http://localhost:6002/search/ \ @@ -164,7 +164,7 @@ curl -X POST http://localhost:6002/search/ \
164 164
165 ## What's Next? 165 ## What's Next?
166 166
167 -1. **Customize Configuration**: Edit `config/schema/customer1_config.yaml` 167 +1. **Customize Configuration**: Edit `config/schema/tenant1_config.yaml`
168 2. **Add More Data**: Ingest your own product data 168 2. **Add More Data**: Ingest your own product data
169 3. **Tune Ranking**: Adjust ranking expression in config 169 3. **Tune Ranking**: Adjust ranking expression in config
170 4. **Add Rewrite Rules**: Update via API `/admin/rewrite-rules` 170 4. **Add Rewrite Rules**: Update via API `/admin/rewrite-rules`
@@ -96,7 +96,7 @@ REDIS_PASSWORD=BMfv5aI31kgHWtlx @@ -96,7 +96,7 @@ REDIS_PASSWORD=BMfv5aI31kgHWtlx
96 DEEPL_AUTH_KEY=c9293ab4-ad25-479b-919f-ab4e63b429ed 96 DEEPL_AUTH_KEY=c9293ab4-ad25-479b-919f-ab4e63b429ed
97 97
98 # 客户配置 98 # 客户配置
99 -CUSTOMER_ID=customer1 99 +TENANT_ID=tenant1
100 100
101 # API服务配置 101 # API服务配置
102 API_HOST=0.0.0.0 102 API_HOST=0.0.0.0
@@ -292,7 +292,7 @@ from search import Searcher @@ -292,7 +292,7 @@ from search import Searcher
292 from config.env_config import get_es_config 292 from config.env_config import get_es_config
293 293
294 config_loader = ConfigLoader('config/schema') 294 config_loader = ConfigLoader('config/schema')
295 -config = config_loader.load_customer_config('customer1') 295 +config = config_loader.load_tenant_config('tenant1')
296 296
297 es_config = get_es_config() 297 es_config = get_es_config()
298 es_client = ESClient(hosts=[es_config['host']], 298 es_client = ESClient(hosts=[es_config['host']],
@@ -326,7 +326,7 @@ for hit in result.hits: @@ -326,7 +326,7 @@ for hit in result.hits:
326 ### 2. 批量大小调整 326 ### 2. 批量大小调整
327 327
328 ```bash 328 ```bash
329 -# 修改批量大小(在ingest_customer1.py中) 329 +# 修改批量大小(在ingest_tenant1.py中)
330 --batch-size 200 # 默认100 330 --batch-size 200 # 默认100
331 ``` 331 ```
332 332
@@ -369,4 +369,4 @@ SearchEngine/ @@ -369,4 +369,4 @@ SearchEngine/
369 遇到问题请查看: 369 遇到问题请查看:
370 - **日志**: `logs/backend.log` 370 - **日志**: `logs/backend.log`
371 - **API文档**: http://localhost:6002/docs 371 - **API文档**: http://localhost:6002/docs
372 -- **配置**: `config/schema/customer1_config.yaml` 372 +- **配置**: `config/schema/tenant1_config.yaml`
VISUAL_COMPARISON.md
@@ -69,7 +69,7 @@ @@ -69,7 +69,7 @@
69 #### 旧版 69 #### 旧版
70 ``` 70 ```
71 🔍 电商搜索引擎 71 🔍 电商搜索引擎
72 -E-Commerce Search Engine - Customer1 Demo 72 +E-Commerce Search Engine - Tenant1 Demo
73 ``` 73 ```
74 - 大标题 + 副标题 74 - 大标题 + 副标题
75 - 表情符号 75 - 表情符号
docs/TestingPipeline_README.md
@@ -193,7 +193,7 @@ python scripts/run_performance_tests.py @@ -193,7 +193,7 @@ python scripts/run_performance_tests.py
193 export ES_PASSWORD="changeme" 193 export ES_PASSWORD="changeme"
194 export API_HOST="127.0.0.1" 194 export API_HOST="127.0.0.1"
195 export API_PORT="6003" 195 export API_PORT="6003"
196 - export CUSTOMER_ID="test_customer" 196 + export TENANT_ID="test_tenant"
197 export TESTING_MODE="true" 197 export TESTING_MODE="true"
198 ``` 198 ```
199 199
@@ -323,9 +323,9 @@ test_logs/ @@ -323,9 +323,9 @@ test_logs/
323 ```python 323 ```python
324 # 使用fixture提供测试数据 324 # 使用fixture提供测试数据
325 @pytest.fixture 325 @pytest.fixture
326 -def sample_customer_config():  
327 - return CustomerConfig(  
328 - customer_id="test_customer", 326 +def sample_tenant_config():
  327 + return TenantConfig(
  328 + tenant_id="test_tenant",
329 es_index_name="test_products" 329 es_index_name="test_products"
330 ) 330 )
331 331
docs/店匠相关资料/SHOPLAZZA_INTEGRATION_GUIDE.md
@@ -157,7 +157,7 @@ https://your-domain.com/oauth/callback @@ -157,7 +157,7 @@ https://your-domain.com/oauth/callback
157 | `read_product` | 读取商品信息 | ✅ 必需 | 157 | `read_product` | 读取商品信息 | ✅ 必需 |
158 | `write_product` | 修改商品信息 | ❌ 可选 | 158 | `write_product` | 修改商品信息 | ❌ 可选 |
159 | `read_order` | 读取订单信息 | ✅ 必需 | 159 | `read_order` | 读取订单信息 | ✅ 必需 |
160 -| `read_customer` | 读取客户信息 | ✅ 必需 | 160 +| `read_tenant` | 读取客户信息 | ✅ 必需 |
161 | `read_app_proxy` | APP 代理访问 | ✅ 必需 | 161 | `read_app_proxy` | APP 代理访问 | ✅ 必需 |
162 | `write_cart_transform` | 购物车转换(如需价格调整) | ❌ 可选 | 162 | `write_cart_transform` | 购物车转换(如需价格调整) | ❌ 可选 |
163 163
@@ -167,7 +167,7 @@ Scopes: []string{ @@ -167,7 +167,7 @@ Scopes: []string{
167 "read_shop", 167 "read_shop",
168 "read_product", 168 "read_product",
169 "read_order", 169 "read_order",
170 - "read_customer", 170 + "read_tenant",
171 "read_app_proxy", 171 "read_app_proxy",
172 } 172 }
173 ``` 173 ```
@@ -239,7 +239,7 @@ config := &OAuthConfig{ @@ -239,7 +239,7 @@ config := &OAuthConfig{
239 "read_shop", 239 "read_shop",
240 "read_product", 240 "read_product",
241 "read_order", 241 "read_order",
242 - "read_customer", 242 + "read_tenant",
243 "read_app_proxy", 243 "read_app_proxy",
244 }, 244 },
245 AuthURL: "https://partners.shoplazza.com/partner/oauth/authorize", 245 AuthURL: "https://partners.shoplazza.com/partner/oauth/authorize",
@@ -286,7 +286,7 @@ func buildAuthURL(config *OAuthConfig, shop string) string { @@ -286,7 +286,7 @@ func buildAuthURL(config *OAuthConfig, shop string) string {
286 https://partners.shoplazza.com/partner/oauth/authorize? 286 https://partners.shoplazza.com/partner/oauth/authorize?
287 client_id=m8F9PrPnxpyrlz4ONBWRoINsa5xyNT4Qd-Fh_h7o1es 287 client_id=m8F9PrPnxpyrlz4ONBWRoINsa5xyNT4Qd-Fh_h7o1es
288 &redirect_uri=https://your-domain.com/oauth/callback 288 &redirect_uri=https://your-domain.com/oauth/callback
289 - &scope=read_shop read_product read_order read_customer read_app_proxy 289 + &scope=read_shop read_product read_order read_tenant read_app_proxy
290 &state=47167113-1.myshoplaza.com 290 &state=47167113-1.myshoplaza.com
291 ``` 291 ```
292 292
@@ -742,13 +742,13 @@ GET /openapi/2022-01/orders/count @@ -742,13 +742,13 @@ GET /openapi/2022-01/orders/count
742 742
743 ```bash 743 ```bash
744 # 获取客户列表 744 # 获取客户列表
745 -GET /openapi/2022-01/customers?page=1&limit=50 745 +GET /openapi/2022-01/tenants?page=1&limit=50
746 746
747 # 获取客户详情 747 # 获取客户详情
748 -GET /openapi/2022-01/customers/{customer_id} 748 +GET /openapi/2022-01/tenants/{tenant_id}
749 749
750 # 获取客户总数 750 # 获取客户总数
751 -GET /openapi/2022-01/customers/count 751 +GET /openapi/2022-01/tenants/count
752 ``` 752 ```
753 753
754 ### 5.4 请求和响应格式 754 ### 5.4 请求和响应格式
@@ -1222,14 +1222,14 @@ public class ProductSyncService { @@ -1222,14 +1222,14 @@ public class ProductSyncService {
1222 1222
1223 #### 6.2.1 数据表设计 1223 #### 6.2.1 数据表设计
1224 1224
1225 -**客户表(shoplazza_customer):** 1225 +**客户表(shoplazza_tenant):**
1226 1226
1227 ```sql 1227 ```sql
1228 -CREATE TABLE `shoplazza_customer` ( 1228 +CREATE TABLE `shoplazza_tenant` (
1229 `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', 1229 `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
1230 `tenant_id` BIGINT NOT NULL COMMENT '租户ID', 1230 `tenant_id` BIGINT NOT NULL COMMENT '租户ID',
1231 `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID', 1231 `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID',
1232 - `customer_id` VARCHAR(64) NOT NULL COMMENT '店匠客户ID', 1232 + `tenant_id` VARCHAR(64) NOT NULL COMMENT '店匠客户ID',
1233 `email` VARCHAR(255) DEFAULT NULL COMMENT '邮箱', 1233 `email` VARCHAR(255) DEFAULT NULL COMMENT '邮箱',
1234 `phone` VARCHAR(64) DEFAULT NULL COMMENT '电话', 1234 `phone` VARCHAR(64) DEFAULT NULL COMMENT '电话',
1235 `first_name` VARCHAR(128) DEFAULT NULL COMMENT '名', 1235 `first_name` VARCHAR(128) DEFAULT NULL COMMENT '名',
@@ -1241,20 +1241,20 @@ CREATE TABLE `shoplazza_customer` ( @@ -1241,20 +1241,20 @@ CREATE TABLE `shoplazza_customer` (
1241 `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 1241 `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
1242 `deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 1242 `deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1243 PRIMARY KEY (`id`), 1243 PRIMARY KEY (`id`),
1244 - UNIQUE KEY `uk_store_customer` (`store_id`, `customer_id`), 1244 + UNIQUE KEY `uk_store_tenant` (`store_id`, `tenant_id`),
1245 KEY `idx_tenant_id` (`tenant_id`), 1245 KEY `idx_tenant_id` (`tenant_id`),
1246 KEY `idx_email` (`email`) 1246 KEY `idx_email` (`email`)
1247 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店匠客户表'; 1247 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店匠客户表';
1248 ``` 1248 ```
1249 1249
1250 -**客户地址表(shoplazza_customer_address):** 1250 +**客户地址表(shoplazza_tenant_address):**
1251 1251
1252 ```sql 1252 ```sql
1253 -CREATE TABLE `shoplazza_customer_address` ( 1253 +CREATE TABLE `shoplazza_tenant_address` (
1254 `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', 1254 `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
1255 `tenant_id` BIGINT NOT NULL COMMENT '租户ID', 1255 `tenant_id` BIGINT NOT NULL COMMENT '租户ID',
1256 `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID', 1256 `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID',
1257 - `customer_id` VARCHAR(64) NOT NULL COMMENT '店匠客户ID', 1257 + `tenant_id` VARCHAR(64) NOT NULL COMMENT '店匠客户ID',
1258 `address_id` VARCHAR(64) NOT NULL COMMENT '店匠地址ID', 1258 `address_id` VARCHAR(64) NOT NULL COMMENT '店匠地址ID',
1259 `first_name` VARCHAR(128) DEFAULT NULL COMMENT '名', 1259 `first_name` VARCHAR(128) DEFAULT NULL COMMENT '名',
1260 `last_name` VARCHAR(128) DEFAULT NULL COMMENT '姓', 1260 `last_name` VARCHAR(128) DEFAULT NULL COMMENT '姓',
@@ -1272,7 +1272,7 @@ CREATE TABLE `shoplazza_customer_address` ( @@ -1272,7 +1272,7 @@ CREATE TABLE `shoplazza_customer_address` (
1272 PRIMARY KEY (`id`), 1272 PRIMARY KEY (`id`),
1273 UNIQUE KEY `uk_store_address` (`store_id`, `address_id`), 1273 UNIQUE KEY `uk_store_address` (`store_id`, `address_id`),
1274 KEY `idx_tenant_id` (`tenant_id`), 1274 KEY `idx_tenant_id` (`tenant_id`),
1275 - KEY `idx_customer_id` (`customer_id`) 1275 + KEY `idx_tenant_id` (`tenant_id`)
1276 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店匠客户地址表'; 1276 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店匠客户地址表';
1277 ``` 1277 ```
1278 1278
@@ -1280,7 +1280,7 @@ CREATE TABLE `shoplazza_customer_address` ( @@ -1280,7 +1280,7 @@ CREATE TABLE `shoplazza_customer_address` (
1280 1280
1281 ```bash 1281 ```bash
1282 curl --request GET \ 1282 curl --request GET \
1283 - --url 'https://47167113-1.myshoplaza.com/openapi/2022-01/customers?page=1&limit=50' \ 1283 + --url 'https://47167113-1.myshoplaza.com/openapi/2022-01/tenants?page=1&limit=50' \
1284 --header 'access-token: V2WDYgkTvrN68QCESZ9eHb3EjpR6EBrPyAKe-m_JwYY' \ 1284 --header 'access-token: V2WDYgkTvrN68QCESZ9eHb3EjpR6EBrPyAKe-m_JwYY' \
1285 --header 'accept: application/json' 1285 --header 'accept: application/json'
1286 ``` 1286 ```
@@ -1298,7 +1298,7 @@ CREATE TABLE `shoplazza_order` ( @@ -1298,7 +1298,7 @@ CREATE TABLE `shoplazza_order` (
1298 `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID', 1298 `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID',
1299 `order_id` VARCHAR(64) NOT NULL COMMENT '店匠订单ID', 1299 `order_id` VARCHAR(64) NOT NULL COMMENT '店匠订单ID',
1300 `order_number` VARCHAR(128) NOT NULL COMMENT '订单号', 1300 `order_number` VARCHAR(128) NOT NULL COMMENT '订单号',
1301 - `customer_id` VARCHAR(64) DEFAULT NULL COMMENT '客户ID', 1301 + `tenant_id` VARCHAR(64) DEFAULT NULL COMMENT '客户ID',
1302 `email` VARCHAR(255) DEFAULT NULL COMMENT '客户邮箱', 1302 `email` VARCHAR(255) DEFAULT NULL COMMENT '客户邮箱',
1303 `total_price` DECIMAL(12,2) NOT NULL COMMENT '订单总价', 1303 `total_price` DECIMAL(12,2) NOT NULL COMMENT '订单总价',
1304 `subtotal_price` DECIMAL(12,2) DEFAULT NULL COMMENT '小计', 1304 `subtotal_price` DECIMAL(12,2) DEFAULT NULL COMMENT '小计',
@@ -1314,7 +1314,7 @@ CREATE TABLE `shoplazza_order` ( @@ -1314,7 +1314,7 @@ CREATE TABLE `shoplazza_order` (
1314 PRIMARY KEY (`id`), 1314 PRIMARY KEY (`id`),
1315 UNIQUE KEY `uk_store_order` (`store_id`, `order_id`), 1315 UNIQUE KEY `uk_store_order` (`store_id`, `order_id`),
1316 KEY `idx_tenant_id` (`tenant_id`), 1316 KEY `idx_tenant_id` (`tenant_id`),
1317 - KEY `idx_customer_id` (`customer_id`), 1317 + KEY `idx_tenant_id` (`tenant_id`),
1318 KEY `idx_order_number` (`order_number`) 1318 KEY `idx_order_number` (`order_number`)
1319 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店匠订单表'; 1319 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店匠订单表';
1320 ``` 1320 ```
@@ -1365,7 +1365,7 @@ public class DataSyncService { @@ -1365,7 +1365,7 @@ public class DataSyncService {
1365 productSyncService.syncProducts(shopConfigId); 1365 productSyncService.syncProducts(shopConfigId);
1366 1366
1367 // 2. 同步客户 1367 // 2. 同步客户
1368 - customerSyncService.syncCustomers(shopConfigId); 1368 + tenantSyncService.syncTenants(shopConfigId);
1369 1369
1370 // 3. 同步订单 1370 // 3. 同步订单
1371 orderSyncService.syncOrders(shopConfigId); 1371 orderSyncService.syncOrders(shopConfigId);
@@ -1420,12 +1420,12 @@ public class ScheduledSyncTask { @@ -1420,12 +1420,12 @@ public class ScheduledSyncTask {
1420 * 每天同步一次客户和订单数据 1420 * 每天同步一次客户和订单数据
1421 */ 1421 */
1422 @Scheduled(cron = "0 0 3 * * ?") 1422 @Scheduled(cron = "0 0 3 * * ?")
1423 - public void syncCustomersAndOrdersDaily() { 1423 + public void syncTenantsAndOrdersDaily() {
1424 List<ShopConfig> activeShops = shopConfigMapper.selectActiveShops(); 1424 List<ShopConfig> activeShops = shopConfigMapper.selectActiveShops();
1425 1425
1426 for (ShopConfig shop : activeShops) { 1426 for (ShopConfig shop : activeShops) {
1427 try { 1427 try {
1428 - customerSyncService.syncCustomers(shop.getId()); 1428 + tenantSyncService.syncTenants(shop.getId());
1429 orderSyncService.syncOrders(shop.getId()); 1429 orderSyncService.syncOrders(shop.getId());
1430 } catch (Exception e) { 1430 } catch (Exception e) {
1431 log.error("Scheduled sync failed for shop: {}", shop.getStoreName(), e); 1431 log.error("Scheduled sync failed for shop: {}", shop.getStoreName(), e);
@@ -1453,8 +1453,8 @@ public class RobustSyncService { @@ -1453,8 +1453,8 @@ public class RobustSyncService {
1453 case "products": 1453 case "products":
1454 productSyncService.syncProducts(shopConfigId); 1454 productSyncService.syncProducts(shopConfigId);
1455 break; 1455 break;
1456 - case "customers":  
1457 - customerSyncService.syncCustomers(shopConfigId); 1456 + case "tenants":
  1457 + tenantSyncService.syncTenants(shopConfigId);
1458 break; 1458 break;
1459 case "orders": 1459 case "orders":
1460 orderSyncService.syncOrders(shopConfigId); 1460 orderSyncService.syncOrders(shopConfigId);
@@ -1512,9 +1512,9 @@ Webhook 是店匠平台的事件通知机制,当店铺发生特定事件(如 @@ -1512,9 +1512,9 @@ Webhook 是店匠平台的事件通知机制,当店铺发生特定事件(如
1512 1512
1513 | Topic | 说明 | 触发时机 | 1513 | Topic | 说明 | 触发时机 |
1514 |-------|------|----------| 1514 |-------|------|----------|
1515 -| `customers/create` | 客户创建 | 新客户注册时 |  
1516 -| `customers/update` | 客户更新 | 客户信息更新时 |  
1517 -| `customers/delete` | 客户删除 | 客户被删除时 | 1515 +| `tenants/create` | 客户创建 | 新客户注册时 |
  1516 +| `tenants/update` | 客户更新 | 客户信息更新时 |
  1517 +| `tenants/delete` | 客户删除 | 客户被删除时 |
1518 1518
1519 ### 7.3 注册 Webhook 1519 ### 7.3 注册 Webhook
1520 1520
@@ -1561,8 +1561,8 @@ public class WebhookService { @@ -1561,8 +1561,8 @@ public class WebhookService {
1561 "orders/create", 1561 "orders/create",
1562 "orders/updated", 1562 "orders/updated",
1563 "orders/paid", 1563 "orders/paid",
1564 - "customers/create",  
1565 - "customers/update" 1564 + "tenants/create",
  1565 + "tenants/update"
1566 ); 1566 );
1567 1567
1568 /** 1568 /**
@@ -1733,12 +1733,12 @@ public class WebhookService { @@ -1733,12 +1733,12 @@ public class WebhookService {
1733 case "orders/cancelled": 1733 case "orders/cancelled":
1734 handleOrderCancel(storeId, payload); 1734 handleOrderCancel(storeId, payload);
1735 break; 1735 break;
1736 - case "customers/create":  
1737 - case "customers/update":  
1738 - handleCustomerUpdate(storeId, payload); 1736 + case "tenants/create":
  1737 + case "tenants/update":
  1738 + handleTenantUpdate(storeId, payload);
1739 break; 1739 break;
1740 - case "customers/delete":  
1741 - handleCustomerDelete(storeId, payload); 1740 + case "tenants/delete":
  1741 + handleTenantDelete(storeId, payload);
1742 break; 1742 break;
1743 default: 1743 default:
1744 log.warn("Unknown webhook topic: {}", topic); 1744 log.warn("Unknown webhook topic: {}", topic);
@@ -2279,7 +2279,7 @@ public class SearchService { @@ -2279,7 +2279,7 @@ public class SearchService {
2279 String url = searchServiceUrl + "/search/"; 2279 String url = searchServiceUrl + "/search/";
2280 2280
2281 // 添加租户隔离参数 2281 // 添加租户隔离参数
2282 - request.setCustomer("tenant_" + tenantId); 2282 + request.setTenant("tenant_" + tenantId);
2283 2283
2284 ResponseEntity<SearchResponse> response = restTemplate.postForEntity( 2284 ResponseEntity<SearchResponse> response = restTemplate.postForEntity(
2285 url, 2285 url,
@@ -2309,8 +2309,8 @@ public class SearchService { @@ -2309,8 +2309,8 @@ public class SearchService {
2309 # Python 搜索服务 2309 # Python 搜索服务
2310 @app.post("/search/") 2310 @app.post("/search/")
2311 async def search_products(request: SearchRequest): 2311 async def search_products(request: SearchRequest):
2312 - # 根据 customer 参数确定租户 ID  
2313 - tenant_id = extract_tenant_id(request.customer) 2312 + # 根据 tenant 参数确定租户 ID
  2313 + tenant_id = extract_tenant_id(request.tenant)
2314 2314
2315 # 使用租户专属索引 2315 # 使用租户专属索引
2316 index_name = f"shoplazza_products_{tenant_id}" 2316 index_name = f"shoplazza_products_{tenant_id}"
@@ -2337,7 +2337,7 @@ CREATE TABLE `shoplazza_search_log` ( @@ -2337,7 +2337,7 @@ CREATE TABLE `shoplazza_search_log` (
2337 `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', 2337 `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
2338 `tenant_id` BIGINT NOT NULL COMMENT '租户ID', 2338 `tenant_id` BIGINT NOT NULL COMMENT '租户ID',
2339 `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID', 2339 `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID',
2340 - `customer_id` VARCHAR(64) DEFAULT NULL COMMENT '客户ID', 2340 + `tenant_id` VARCHAR(64) DEFAULT NULL COMMENT '客户ID',
2341 `session_id` VARCHAR(128) DEFAULT NULL COMMENT '会话ID', 2341 `session_id` VARCHAR(128) DEFAULT NULL COMMENT '会话ID',
2342 `query` VARCHAR(512) NOT NULL COMMENT '搜索关键词', 2342 `query` VARCHAR(512) NOT NULL COMMENT '搜索关键词',
2343 `results_count` INT DEFAULT 0 COMMENT '结果数量', 2343 `results_count` INT DEFAULT 0 COMMENT '结果数量',
@@ -2377,7 +2377,7 @@ public class SearchLogService { @@ -2377,7 +2377,7 @@ public class SearchLogService {
2377 SearchLog log = new SearchLog(); 2377 SearchLog log = new SearchLog();
2378 log.setTenantId(shop.getTenantId()); 2378 log.setTenantId(shop.getTenantId());
2379 log.setStoreId(shop.getStoreId()); 2379 log.setStoreId(shop.getStoreId());
2380 - log.setCustomerId(request.getCustomerId()); 2380 + log.setTenantId(request.getTenantId());
2381 log.setSessionId(request.getSessionId()); 2381 log.setSessionId(request.getSessionId());
2382 log.setQuery(request.getQuery()); 2382 log.setQuery(request.getQuery());
2383 log.setResultsCount(response.getTotal()); 2383 log.setResultsCount(response.getTotal());
@@ -2647,7 +2647,7 @@ window.AI_SEARCH_CONFIG = { @@ -2647,7 +2647,7 @@ window.AI_SEARCH_CONFIG = {
2647 size: 24, 2647 size: 24,
2648 filters: currentFilters, 2648 filters: currentFilters,
2649 facets: ['product_type', 'vendor', 'tags'], 2649 facets: ['product_type', 'vendor', 'tags'],
2650 - customer: `tenant_${config.storeId}` 2650 + tenant: `tenant_${config.storeId}`
2651 }) 2651 })
2652 }); 2652 });
2653 2653
@@ -3023,8 +3023,8 @@ server { @@ -3023,8 +3023,8 @@ server {
3023 | 订单列表 | `/openapi/2022-01/orders` | GET | 获取订单列表 | 3023 | 订单列表 | `/openapi/2022-01/orders` | GET | 获取订单列表 |
3024 | 订单详情 | `/openapi/2022-01/orders/{id}` | GET | 获取单个订单 | 3024 | 订单详情 | `/openapi/2022-01/orders/{id}` | GET | 获取单个订单 |
3025 | **客户** | 3025 | **客户** |
3026 -| 客户列表 | `/openapi/2022-01/customers` | GET | 获取客户列表 |  
3027 -| 客户详情 | `/openapi/2022-01/customers/{id}` | GET | 获取单个客户 | 3026 +| 客户列表 | `/openapi/2022-01/tenants` | GET | 获取客户列表 |
  3027 +| 客户详情 | `/openapi/2022-01/tenants/{id}` | GET | 获取单个客户 |
3028 | **Webhook** | 3028 | **Webhook** |
3029 | 注册 Webhook | `/openapi/2022-01/webhooks` | POST | 注册事件通知 | 3029 | 注册 Webhook | `/openapi/2022-01/webhooks` | POST | 注册事件通知 |
3030 | Webhook 列表 | `/openapi/2022-01/webhooks` | GET | 获取已注册列表 | 3030 | Webhook 列表 | `/openapi/2022-01/webhooks` | GET | 获取已注册列表 |
@@ -3039,7 +3039,7 @@ curl -X POST http://your-domain:6002/search/ \ @@ -3039,7 +3039,7 @@ curl -X POST http://your-domain:6002/search/ \
3039 -H "Content-Type: application/json" \ 3039 -H "Content-Type: application/json" \
3040 -d '{ 3040 -d '{
3041 "query": "bluetooth headphone", 3041 "query": "bluetooth headphone",
3042 - "customer": "tenant_1", 3042 + "tenant": "tenant_1",
3043 "size": 20, 3043 "size": 20,
3044 "from": 0, 3044 "from": 0,
3045 "filters": { 3045 "filters": {
@@ -3056,7 +3056,7 @@ curl -X POST http://your-domain:6002/search/image \ @@ -3056,7 +3056,7 @@ curl -X POST http://your-domain:6002/search/image \
3056 -H "Content-Type: application/json" \ 3056 -H "Content-Type: application/json" \
3057 -d '{ 3057 -d '{
3058 "image_url": "https://example.com/image.jpg", 3058 "image_url": "https://example.com/image.jpg",
3059 - "customer": "tenant_1", 3059 + "tenant": "tenant_1",
3060 "size": 20 3060 "size": 20
3061 }' 3061 }'
3062 ``` 3062 ```
@@ -3071,8 +3071,8 @@ curl -X POST http://your-domain:6002/search/image \ @@ -3071,8 +3071,8 @@ curl -X POST http://your-domain:6002/search/image \
3071 - `shoplazza_product_spu` - 商品 SPU 表 3071 - `shoplazza_product_spu` - 商品 SPU 表
3072 - `shoplazza_product_sku` - 商品 SKU 表 3072 - `shoplazza_product_sku` - 商品 SKU 表
3073 - `shoplazza_product_image` - 商品图片表 3073 - `shoplazza_product_image` - 商品图片表
3074 -- `shoplazza_customer` - 客户表  
3075 -- `shoplazza_customer_address` - 客户地址表 3074 +- `shoplazza_tenant` - 客户表
  3075 +- `shoplazza_tenant_address` - 客户地址表
3076 - `shoplazza_order` - 订单表 3076 - `shoplazza_order` - 订单表
3077 - `shoplazza_order_item` - 订单明细表 3077 - `shoplazza_order_item` - 订单明细表
3078 - `shoplazza_search_log` - 搜索日志表 3078 - `shoplazza_search_log` - 搜索日志表
@@ -3092,7 +3092,7 @@ shoplazza: @@ -3092,7 +3092,7 @@ shoplazza:
3092 - read_shop 3092 - read_shop
3093 - read_product 3093 - read_product
3094 - read_order 3094 - read_order
3095 - - read_customer 3095 + - read_tenant
3096 - read_app_proxy 3096 - read_app_proxy
3097 3097
3098 # Webhook 配置 3098 # Webhook 配置
@@ -3103,7 +3103,7 @@ shoplazza: @@ -3103,7 +3103,7 @@ shoplazza:
3103 - products/update 3103 - products/update
3104 - products/delete 3104 - products/delete
3105 - orders/create 3105 - orders/create
3106 - - customers/create 3106 + - tenants/create
3107 3107
3108 # 搜索服务配置 3108 # 搜索服务配置
3109 search: 3109 search:
@@ -3130,7 +3130,7 @@ sync: @@ -3130,7 +3130,7 @@ sync:
3130 schedule: 3130 schedule:
3131 products: "0 0 */1 * * ?" # 每小时 3131 products: "0 0 */1 * * ?" # 每小时
3132 orders: "0 0 3 * * ?" # 每天凌晨3点 3132 orders: "0 0 3 * * ?" # 每天凌晨3点
3133 - customers: "0 0 4 * * ?" # 每天凌晨4点 3133 + tenants: "0 0 4 * * ?" # 每天凌晨4点
3134 ``` 3134 ```
3135 3135
3136 ### 12.4 故障排查 3136 ### 12.4 故障排查
docs/店匠相关资料/记录tenant和token-获取商品信息.md
@@ -127,7 +127,7 @@ public void handleOAuthCallback(TokenResponse tokenResponse) { @@ -127,7 +127,7 @@ public void handleOAuthCallback(TokenResponse tokenResponse) {
127 1. **拉取数据** - 调用店匠 Admin API 127 1. **拉取数据** - 调用店匠 Admin API
128 - 拉取商品:`GET /openapi/2022-01/products` 128 - 拉取商品:`GET /openapi/2022-01/products`
129 - 拉取订单:`GET /openapi/2022-01/orders` 129 - 拉取订单:`GET /openapi/2022-01/orders`
130 - - 拉取客户:`GET /openapi/2022-01/customers` 130 + - 拉取客户:`GET /openapi/2022-01/tenants`
131 131
132 2. **注册 Webhook** - 让店匠主动推送数据变更 132 2. **注册 Webhook** - 让店匠主动推送数据变更
133 - 注册:`POST /openapi/2022-01/webhooks`(需要 Token) 133 - 注册:`POST /openapi/2022-01/webhooks`(需要 Token)
@@ -255,12 +255,12 @@ public void syncProducts(Long shopConfigId) { @@ -255,12 +255,12 @@ public void syncProducts(Long shopConfigId) {
255 255
256 **实现逻辑:** 256 **实现逻辑:**
257 ```java 257 ```java
258 -public void syncCustomers(Long shopConfigId) { 258 +public void syncTenants(Long shopConfigId) {
259 // 与 syncProducts 类似,遍历所有分页 259 // 与 syncProducts 类似,遍历所有分页
260 - String url = "https://{shop}/openapi/2022-01/customers?page={page}&limit=50"; 260 + String url = "https://{shop}/openapi/2022-01/tenants?page={page}&limit=50";
261 261
262 // 循环拉取所有页 262 // 循环拉取所有页
263 - // 保存到 shoplazza_customer 和 shoplazza_customer_address 表 263 + // 保存到 shoplazza_tenant 和 shoplazza_tenant_address 表
264 } 264 }
265 ``` 265 ```
266 266
@@ -342,7 +342,7 @@ public class WebhookService { @@ -342,7 +342,7 @@ public class WebhookService {
342 342
343 private static final List<String> WEBHOOK_TOPICS = Arrays.asList( 343 private static final List<String> WEBHOOK_TOPICS = Arrays.asList(
344 "products/create", "products/update", "products/delete", 344 "products/create", "products/update", "products/delete",
345 - "orders/create", "orders/updated", "customers/create" 345 + "orders/create", "orders/updated", "tenants/create"
346 ); 346 );
347 347
348 public void registerWebhooks(Long shopConfigId) { 348 public void registerWebhooks(Long shopConfigId) {
frontend/unified.html
@@ -54,7 +54,7 @@ @@ -54,7 +54,7 @@
54 <div class="tenant-selector"> 54 <div class="tenant-selector">
55 <label for="tenantSelect">选择租户:</label> 55 <label for="tenantSelect">选择租户:</label>
56 <select id="tenantSelect" onchange="switchTenant()"> 56 <select id="tenantSelect" onchange="switchTenant()">
57 - <option value="customer1">Customer1 (旧配置)</option> 57 + <option value="tenant1">Tenant1 (旧配置)</option>
58 <option value="base:1" selected>Base - Tenant 1 (店匠通用)</option> 58 <option value="base:1" selected>Base - Tenant 1 (店匠通用)</option>
59 <option value="base:2">Base - Tenant 2 (店匠通用)</option> 59 <option value="base:2">Base - Tenant 2 (店匠通用)</option>
60 </select> 60 </select>
scripts/start_test_environment.sh
@@ -61,7 +61,7 @@ export ES_PASSWORD=&quot;changeme&quot; @@ -61,7 +61,7 @@ export ES_PASSWORD=&quot;changeme&quot;
61 # API配置 61 # API配置
62 export API_HOST="127.0.0.1" 62 export API_HOST="127.0.0.1"
63 export API_PORT="6003" # 使用不同的端口避免冲突 63 export API_PORT="6003" # 使用不同的端口避免冲突
64 -export CUSTOMER_ID="test_customer" 64 +export TENANT_ID="test_tenant"
65 65
66 # 测试配置 66 # 测试配置
67 export TEST_TIMEOUT=60 67 export TEST_TIMEOUT=60
@@ -70,7 +70,7 @@ export TEST_RETRY_COUNT=3 @@ -70,7 +70,7 @@ export TEST_RETRY_COUNT=3
70 echo -e "${BLUE}环境配置:${NC}" 70 echo -e "${BLUE}环境配置:${NC}"
71 echo " ES_HOST: $ES_HOST" 71 echo " ES_HOST: $ES_HOST"
72 echo " API_HOST: $API_HOST:$API_PORT" 72 echo " API_HOST: $API_HOST:$API_PORT"
73 -echo " CUSTOMER_ID: $CUSTOMER_ID" 73 +echo " TENANT_ID: $TENANT_ID"
74 echo " LOG_LEVEL: $LOG_LEVEL" 74 echo " LOG_LEVEL: $LOG_LEVEL"
75 echo " TESTING_MODE: $TESTING_MODE" 75 echo " TESTING_MODE: $TESTING_MODE"
76 76
@@ -184,7 +184,7 @@ cd &quot;$PROJECT_ROOT&quot; @@ -184,7 +184,7 @@ cd &quot;$PROJECT_ROOT&quot;
184 python -m api.app \ 184 python -m api.app \
185 --host $API_HOST \ 185 --host $API_HOST \
186 --port $API_PORT \ 186 --port $API_PORT \
187 - --customer $CUSTOMER_ID \ 187 + --tenant $TENANT_ID \
188 --es-host $ES_HOST \ 188 --es-host $ES_HOST \
189 > "$API_LOG_FILE" 2>&1 & 189 > "$API_LOG_FILE" 2>&1 &
190 190
@@ -240,7 +240,7 @@ echo -e &quot;${GREEN}========================================${NC}&quot; @@ -240,7 +240,7 @@ echo -e &quot;${GREEN}========================================${NC}&quot;
240 echo -e "${BLUE}服务信息:${NC}" 240 echo -e "${BLUE}服务信息:${NC}"
241 echo " Elasticsearch: $ES_HOST" 241 echo " Elasticsearch: $ES_HOST"
242 echo " API服务: http://$API_HOST:$API_PORT" 242 echo " API服务: http://$API_HOST:$API_PORT"
243 -echo " 测试客户: $CUSTOMER_ID" 243 +echo " 测试客户: $TENANT_ID"
244 echo -e "${BLUE}进程信息:${NC}" 244 echo -e "${BLUE}进程信息:${NC}"
245 echo " API PID: $API_PID" 245 echo " API PID: $API_PID"
246 echo " PID文件: $PID_FILE" 246 echo " PID文件: $PID_FILE"
@@ -264,7 +264,7 @@ export ES_USERNAME=&quot;$ES_USERNAME&quot; @@ -264,7 +264,7 @@ export ES_USERNAME=&quot;$ES_USERNAME&quot;
264 export ES_PASSWORD="$ES_PASSWORD" 264 export ES_PASSWORD="$ES_PASSWORD"
265 export API_HOST="$API_HOST" 265 export API_HOST="$API_HOST"
266 export API_PORT="$API_PORT" 266 export API_PORT="$API_PORT"
267 -export CUSTOMER_ID="$CUSTOMER_ID" 267 +export TENANT_ID="$TENANT_ID"
268 export TESTING_MODE="$TESTING_MODE" 268 export TESTING_MODE="$TESTING_MODE"
269 export LOG_LEVEL="$LOG_LEVEL" 269 export LOG_LEVEL="$LOG_LEVEL"
270 export PYTHONPATH="$PROJECT_ROOT:\$PYTHONPATH" 270 export PYTHONPATH="$PROJECT_ROOT:\$PYTHONPATH"
支持多语言查询.md
@@ -36,7 +36,7 @@ index 8df15b3..f3fcaa3 100644 @@ -36,7 +36,7 @@ index 8df15b3..f3fcaa3 100644
36 36
37 @dataclass 37 @dataclass
38 class RankingConfig: 38 class RankingConfig:
39 -@@ -66,8 +69,6 @@ class CustomerConfig: 39 +@@ -66,8 +69,6 @@ class TenantConfig:
40 40
41 # Database settings 41 # Database settings
42 mysql_config: Dict[str, Any] 42 mysql_config: Dict[str, Any]
@@ -45,7 +45,7 @@ index 8df15b3..f3fcaa3 100644 @@ -45,7 +45,7 @@ index 8df15b3..f3fcaa3 100644
45 45
46 # Field definitions 46 # Field definitions
47 fields: List[FieldConfig] 47 fields: List[FieldConfig]
48 -@@ -86,6 +87,10 @@ class CustomerConfig: 48 +@@ -86,6 +87,10 @@ class TenantConfig:
49 49
50 # ES index settings 50 # ES index settings
51 es_index_name: str 51 es_index_name: str
@@ -74,7 +74,7 @@ index 8df15b3..f3fcaa3 100644 @@ -74,7 +74,7 @@ index 8df15b3..f3fcaa3 100644
74 + language_field_mapping=language_field_mapping 74 + language_field_mapping=language_field_mapping
75 ) 75 )
76 76
77 - def validate_config(self, config: CustomerConfig) -> List[str]: 77 + def validate_config(self, config: TenantConfig) -> List[str]:
78 @@ -360,11 +369,16 @@ class ConfigLoader: 78 @@ -360,11 +369,16 @@ class ConfigLoader:
79 79
80 def _index_to_dict(self, index: IndexConfig) -> Dict[str, Any]: 80 def _index_to_dict(self, index: IndexConfig) -> Dict[str, Any]:
@@ -96,10 +96,10 @@ index 8df15b3..f3fcaa3 100644 @@ -96,10 +96,10 @@ index 8df15b3..f3fcaa3 100644
96 + 96 +
97 + return result 97 + return result
98 \ No newline at end of file 98 \ No newline at end of file
99 -diff --git a/config/schema/customer1_config.yaml b/config/schema/customer1_config.yaml 99 +diff --git a/config/schema/tenant1_config.yaml b/config/schema/tenant1_config.yaml
100 index bfe2e53..84e9ba1 100644 100 index bfe2e53..84e9ba1 100644
101 ---- a/config/schema/customer1_config.yaml  
102 -+++ b/config/schema/customer1_config.yaml 101 +--- a/config/schema/tenant1_config.yaml
  102 ++++ b/config/schema/tenant1_config.yaml
103 @@ -177,6 +177,15 @@ indexes: 103 @@ -177,6 +177,15 @@ indexes:
104 analyzer: "chinese_ecommerce" 104 analyzer: "chinese_ecommerce"
105 boost: 1.0 105 boost: 1.0
@@ -70,7 +70,7 @@ @@ -70,7 +70,7 @@
70 70
71 ### 2.1 搴旂敤缁撴瀯閰嶇疆锛堝瓧娈靛畾涔夛級 71 ### 2.1 搴旂敤缁撴瀯閰嶇疆锛堝瓧娈靛畾涔夛級
72 72
73 -**閰嶇疆鏂囦欢浣嶇疆**锛歚config/schema/{customer_id}_config.yaml` 73 +**閰嶇疆鏂囦欢浣嶇疆**锛歚config/schema/{tenant_id}_config.yaml`
74 74
75 **閰嶇疆鍐呭**锛氬畾涔変簡 ES 鐨勮緭鍏ユ暟鎹湁鍝簺瀛楁銆佸叧鑱 MySQL 鐨勫摢浜涘瓧娈点 75 **閰嶇疆鍐呭**锛氬畾涔変簡 ES 鐨勮緭鍏ユ暟鎹湁鍝簺瀛楁銆佸叧鑱 MySQL 鐨勫摢浜涘瓧娈点
76 76
@@ -228,7 +228,7 @@ indexes: @@ -228,7 +228,7 @@ indexes:
228 - `shoplazza_product_spu` - SPU绾у埆鍟嗗搧鏁版嵁 228 - `shoplazza_product_spu` - SPU绾у埆鍟嗗搧鏁版嵁
229 - `shoplazza_product_sku` - SKU绾у埆鍟嗗搧鏁版嵁 229 - `shoplazza_product_sku` - SKU绾у埆鍟嗗搧鏁版嵁
230 230
231 -**鍏朵粬瀹㈡埛琛**锛坈ustomer1绛夛級锛 231 +**鍏朵粬瀹㈡埛琛**锛坱enant1绛夛級锛
232 - 浣跨敤鍚勮嚜鐨勬暟鎹簮琛ㄥ拰鎵╁睍琛 232 - 浣跨敤鍚勮嚜鐨勬暟鎹簮琛ㄥ拰鎵╁睍琛
233 233
234 ### 3.2 鏁版嵁瀵煎叆鏂瑰紡 234 ### 3.2 鏁版嵁瀵煎叆鏂瑰紡
@@ -585,7 +585,7 @@ API杩斿洖鏍煎紡涓嶅寘鍚獷S鍐呴儴瀛楁锛坄_id`, `_score`, `_source`锛夛紝浣跨敤 @@ -585,7 +585,7 @@ API杩斿洖鏍煎紡涓嶅寘鍚獷S鍐呴儴瀛楁锛坄_id`, `_score`, `_source`锛夛紝浣跨敤
585 585
586 **Base閰嶇疆**锛堝簵鍖犻氱敤锛夛細`config/schema/base/config.yaml` 586 **Base閰嶇疆**锛堝簵鍖犻氱敤锛夛細`config/schema/base/config.yaml`
587 587
588 -**鍏朵粬瀹㈡埛閰嶇疆**锛歚config/schema/customer1/config.yaml` 588 +**鍏朵粬瀹㈡埛閰嶇疆**锛歚config/schema/tenant1/config.yaml`
589 589
590 --- 590 ---
591 591