From ae5a294d3f93b6542de1831d70c239f2213e1145 Mon Sep 17 00:00:00 2001 From: tangwang Date: Thu, 13 Nov 2025 15:20:38 +0800 Subject: [PATCH] 命名修改、代码清理 --- .cursor/plans/API响应格式优化与SPU索引重构.2.md | 28 ++++++++++++++-------------- .cursor/plans/API响应格式优化与SPU索引重构.4.md | 14 +++++++------- .cursor/plans/API响应格式优化与SPU索引重构.5.最终执行.md | 14 +++++++------- .cursor/plans/API响应格式优化与SPU索引重构.纠正.md | 18 +++++++++--------- .cursor/plans/API响应格式优化与SPU索引重构3.md | 10 +++++----- .cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.md | 6 +++--- .cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.基于ES_fuction_score原生能力优化.md | 6 +++--- .cursor/plans/将数据pipeline相关配置从索引配置中剥离.md | 16 ++++++++-------- .cursor/plans/所有tenant按同一份所有_返回接口优化.md | 24 ++++++++++++------------ .cursor/plans/所有租户共用一套统一配置.tenantID只在请求层级.服务层级没有tenantID相关的独立配置.md | 68 ++++++++++++++++++++++++++++++++++---------------------------------- .github/workflows/test.yml | 8 ++++---- API_DOCUMENTATION.md | 10 +++++----- CLAUDE.md | 14 +++++++------- DEPLOYMENT.md | 6 +++--- FUNCTION_SCORE_CONFIG_COMPLETE.md | 8 ++++---- HighLevelDesign.md | 6 +++--- MULTILANG_FEATURE.md | 2 +- QUICKSTART.md | 18 +++++++++--------- USER_GUIDE.md | 8 ++++---- VISUAL_COMPARISON.md | 2 +- docs/TestingPipeline_README.md | 8 ++++---- docs/店匠相关资料/SHOPLAZZA_INTEGRATION_GUIDE.md | 96 ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------ docs/店匠相关资料/记录tenant和token-获取商品信息.md | 10 +++++----- frontend/unified.html | 2 +- scripts/start_test_environment.sh | 10 +++++----- 支持多语言查询.md | 12 ++++++------ 设计文档.md | 6 +++--- 27 files changed, 215 insertions(+), 215 deletions(-) diff --git a/.cursor/plans/API响应格式优化与SPU索引重构.2.md b/.cursor/plans/API响应格式优化与SPU索引重构.2.md index ee8d1e3..568bff0 100644 --- a/.cursor/plans/API响应格式优化与SPU索引重构.2.md +++ b/.cursor/plans/API响应格式优化与SPU索引重构.2.md @@ -9,7 +9,7 @@ 2. SPU维度的索引结构(包含嵌套variants数组) 3. 所有客户共用同一索引(使用tenant_id隔离) 4. 配置简化(移除MySQL相关配置,只保留ES搜索配置) -5. 添加新客户(customer2)测试数据和配置 +5. 添加新客户(tenant2)测试数据和配置 ## Phase 1: 配置文件重构 @@ -27,14 +27,14 @@ - 多语言字段:`title_zh`, `title_en`, `description_zh`, `description_en` 等 - 嵌套variants结构定义 -### 1.2 创建customer2配置文件 +### 1.2 创建tenant2配置文件 -**文件**: [`config/schema/customer2/config.yaml`](config/schema/customer2/config.yaml) (NEW) +**文件**: [`config/schema/tenant2/config.yaml`](config/schema/tenant2/config.yaml) (NEW) -基于BASE配置,为customer2创建配置文件: +基于BASE配置,为tenant2创建配置文件: - 继承BASE配置结构 -- 定义customer2特定的字段和搜索域 +- 定义tenant2特定的字段和搜索域 - 支持多语言(中文、英文) ### 1.3 更新配置加载器 @@ -168,16 +168,16 @@ - 连接MySQL数据库 - 导入测试数据到 `shoplazza_product_spu` 和 `shoplazza_product_sku` 表 -- 设置 `tenant_id` 为customer2的ID +- 设置 `tenant_id` 为tenant2的ID - 验证数据导入结果 ## Phase 5: 测试脚本和文档 ### 5.1 创建测试脚本 -**文件**: [`scripts/test_customer2.py`](scripts/test_customer2.py) (NEW) +**文件**: [`scripts/test_tenant2.py`](scripts/test_tenant2.py) (NEW) -创建customer2测试脚本: +创建tenant2测试脚本: - 测试数据导入 - 测试搜索API @@ -187,9 +187,9 @@ ### 5.2 创建说明文档 -**文件**: [`docs/CUSTOMER2_TEST_GUIDE.md`](docs/CUSTOMER2_TEST_GUIDE.md) (NEW) +**文件**: [`docs/TENANT2_TEST_GUIDE.md`](docs/TENANT2_TEST_GUIDE.md) (NEW) -创建customer2测试指南: +创建tenant2测试指南: - 数据导入步骤 - 配置说明 @@ -208,7 +208,7 @@ - 更新配置说明(移除MySQL相关配置) - 更新API响应格式说明 - 更新数据导入流程说明 -- 添加customer2测试说明 +- 添加tenant2测试说明 ## 关键修改点 @@ -241,7 +241,7 @@ ### To-dos - [ ] 创建BASE配置文件(config/schema/base/config.yaml),移除MySQL相关配置,定义SPU级别字段和嵌套variants结构 -- [ ] 创建customer2配置文件(config/schema/customer2/config.yaml),基于BASE配置定义customer2特定字段 +- [ ] 创建tenant2配置文件(config/schema/tenant2/config.yaml),基于BASE配置定义tenant2特定字段 - [ ] 更新配置加载器(config/config_loader.py),移除MySQL相关配置解析,支持嵌套字段和tenant_id验证 - [ ] 更新字段类型定义(config/field_types.py),移除source_table和source_column,添加嵌套字段支持 - [ ] 更新Mapping生成器(indexer/mapping_generator.py),生成SPU级别mapping,添加tenant_id和嵌套variants字段 @@ -253,6 +253,6 @@ - [ ] 更新API路由(api/routes/search.py),添加tenant_id参数,返回新的响应格式 - [ ] 创建测试数据生成脚本(scripts/generate_test_data.py),生成100条SPU测试数据 - [ ] 创建数据导入脚本(scripts/import_test_data.py),导入测试数据到MySQL -- [ ] 创建customer2测试脚本(scripts/test_customer2.py),测试数据导入和搜索API -- [ ] 创建customer2测试指南(docs/CUSTOMER2_TEST_GUIDE.md),包含数据导入步骤和API测试示例 +- [ ] 创建tenant2测试脚本(scripts/test_tenant2.py),测试数据导入和搜索API +- [ ] 创建tenant2测试指南(docs/TENANT2_TEST_GUIDE.md),包含数据导入步骤和API测试示例 - [ ] 更新设计文档(设计文档.md),更新索引结构、配置说明和API响应格式说明 \ No newline at end of file diff --git a/.cursor/plans/API响应格式优化与SPU索引重构.4.md b/.cursor/plans/API响应格式优化与SPU索引重构.4.md index b05dd58..ae9824d 100644 --- a/.cursor/plans/API响应格式优化与SPU索引重构.4.md +++ b/.cursor/plans/API响应格式优化与SPU索引重构.4.md @@ -44,7 +44,7 @@ 修改: -- **删除** `CustomerConfig` 中的 `mysql_config`, `main_table`, `extension_table` 字段定义 +- **删除** `TenantConfig` 中的 `mysql_config`, `main_table`, `extension_table` 字段定义 - **删除** `_parse_config` 中解析这些字段的代码 - **删除** `_parse_field_config` 中解析 `source_table`, `source_column` 的代码 - 保持其他配置解析逻辑不变 @@ -181,13 +181,13 @@ ## Phase 4: DataTransformer重构 -### 4.1 重构DataTransformer(向后兼容,用于customer1) +### 4.1 重构DataTransformer(向后兼容,用于tenant1) **文件**: [`indexer/data_transformer.py`](indexer/data_transformer.py) 修改: -- **保持** 现有逻辑(用于customer1等旧配置) +- **保持** 现有逻辑(用于tenant1等旧配置) - **添加** 检查:如果 `field.source_column` 不存在,跳过该字段(向后兼容) - **注意**:base配置不使用DataTransformer,使用SPU转换器 @@ -299,9 +299,9 @@ - [ ] Create ResponseTransformer to convert ES hits to Shoplazza format (results, facets, suggestions, related_searches) - [ ] Update API models: add VariantOption, ProductVariant, ProductResult, update SearchResponse with new format - [ ] Update search route to use ResponseTransformer and return Shoplazza format -- [ ] Create script to generate 100 SPU+SKU test records for customer2 in Shoplazza tables -- [ ] Create customer2 config.yaml with search-only fields (no pipeline details) +- [ ] Create script to generate 100 SPU+SKU test records for tenant2 in Shoplazza tables +- [ ] Create tenant2 config.yaml with search-only fields (no pipeline details) - [ ] Create or update SPUDataTransformer to join SPU+SKU and create nested variants structure -- [ ] Create customer2 ingestion script that loads from MySQL and uses SPU transformer -- [ ] Create test script and documentation for customer2 setup and testing +- [ ] Create tenant2 ingestion script that loads from MySQL and uses SPU transformer +- [ ] Create test script and documentation for tenant2 setup and testing - [ ] Update design document: SPU-level indexing, unified index, config separation, pipeline decisions \ No newline at end of file diff --git a/.cursor/plans/API响应格式优化与SPU索引重构.5.最终执行.md b/.cursor/plans/API响应格式优化与SPU索引重构.5.最终执行.md index 8619593..2b436c2 100644 --- a/.cursor/plans/API响应格式优化与SPU索引重构.5.最终执行.md +++ b/.cursor/plans/API响应格式优化与SPU索引重构.5.最终执行.md @@ -54,7 +54,7 @@ 修改: -- **删除** `CustomerConfig` 中的 `mysql_config`, `main_table`, `extension_table` 字段定义 +- **删除** `TenantConfig` 中的 `mysql_config`, `main_table`, `extension_table` 字段定义 - **删除** `_parse_config` 中解析这些字段的代码 - **删除** `_parse_field_config` 中解析 `source_table`, `source_column` 的代码 - 保持其他配置解析逻辑不变 @@ -191,13 +191,13 @@ ## Phase 4: DataTransformer重构 -### 4.1 重构DataTransformer(向后兼容,用于customer1) +### 4.1 重构DataTransformer(向后兼容,用于tenant1) **文件**: [`indexer/data_transformer.py`](indexer/data_transformer.py) 修改: -- **保持** 现有逻辑(用于customer1等旧配置) +- **保持** 现有逻辑(用于tenant1等旧配置) - **添加** 检查:如果 `field.source_column` 不存在,跳过该字段(向后兼容) - **注意**:base配置不使用DataTransformer,使用SPU转换器 @@ -309,9 +309,9 @@ - [ ] Create ResponseTransformer to convert ES hits to Shoplazza format (results, facets, suggestions, related_searches) - [ ] Update API models: add VariantOption, ProductVariant, ProductResult, update SearchResponse with new format - [ ] Update search route to use ResponseTransformer and return Shoplazza format -- [ ] Create script to generate 100 SPU+SKU test records for customer2 in Shoplazza tables -- [ ] Create customer2 config.yaml with search-only fields (no pipeline details) +- [ ] Create script to generate 100 SPU+SKU test records for tenant2 in Shoplazza tables +- [ ] Create tenant2 config.yaml with search-only fields (no pipeline details) - [ ] Create or update SPUDataTransformer to join SPU+SKU and create nested variants structure -- [ ] Create customer2 ingestion script that loads from MySQL and uses SPU transformer -- [ ] Create test script and documentation for customer2 setup and testing +- [ ] Create tenant2 ingestion script that loads from MySQL and uses SPU transformer +- [ ] Create test script and documentation for tenant2 setup and testing - [ ] Update design document: SPU-level indexing, unified index, config separation, pipeline decisions \ No newline at end of file diff --git a/.cursor/plans/API响应格式优化与SPU索引重构.纠正.md b/.cursor/plans/API响应格式优化与SPU索引重构.纠正.md index 3c72c7e..48d8ae0 100644 --- a/.cursor/plans/API响应格式优化与SPU索引重构.纠正.md +++ b/.cursor/plans/API响应格式优化与SPU索引重构.纠正.md @@ -8,7 +8,7 @@ 2. SPU维度的索引结构(包含嵌套variants数组) 3. 所有客户共用同一索引(使用tenant_id隔离) 4. 配置简化(移除MySQL相关配置,只保留ES搜索配置) -5. 添加新客户(customer2)测试数据和配置 +5. 添加新客户(tenant2)测试数据和配置 ## Phase 1: 配置文件重构 @@ -27,8 +27,8 @@ - 嵌套variants结构定义 务必注意:对于店匠的店铺,我们应该都通用的用base配置即可,不需要另外单独针对某个店铺新建一套配置,也就是所有店匠的商品都用这个base配置。 -但是允许有其他某个深度定制客户有自己的索引,比如当前有一套索引customer1,我们不用动他,他的数据灌入流程是另外一份,写死的,他的索引配置也是另外一份。也就是我们的搜索服务可以支持多种配置,索引结构变了、字段变了,就是多一分配置,只是店匠多数用户都用base配置即可。 -下面,如果有用到 customer2 的,应该就是指base客户,并注意帮我纠正。 +但是允许有其他某个深度定制客户有自己的索引,比如当前有一套索引tenant1,我们不用动他,他的数据灌入流程是另外一份,写死的,他的索引配置也是另外一份。也就是我们的搜索服务可以支持多种配置,索引结构变了、字段变了,就是多一分配置,只是店匠多数用户都用base配置即可。 +下面,如果有用到 tenant2 的,应该就是指base客户,并注意帮我纠正。 ### 1.3 更新配置加载器 @@ -161,16 +161,16 @@ - 连接MySQL数据库 - 导入测试数据到 `shoplazza_product_spu` 和 `shoplazza_product_sku` 表 -- 设置 `tenant_id` 为customer2的ID +- 设置 `tenant_id` 为tenant2的ID - 验证数据导入结果 ## Phase 5: 测试脚本和文档 ### 5.1 创建测试脚本 -**文件**: [`scripts/test_customer2.py`](scripts/test_customer2.py) (NEW) +**文件**: [`scripts/test_tenant2.py`](scripts/test_tenant2.py) (NEW) -创建customer2测试脚本: +创建tenant2测试脚本: - 测试数据导入 - 测试搜索API @@ -180,9 +180,9 @@ ### 5.2 创建说明文档 -**文件**: [`docs/CUSTOMER2_TEST_GUIDE.md`](docs/CUSTOMER2_TEST_GUIDE.md) (NEW) +**文件**: [`docs/TENANT2_TEST_GUIDE.md`](docs/TENANT2_TEST_GUIDE.md) (NEW) -创建customer2测试指南: +创建tenant2测试指南: - 数据导入步骤 - 配置说明 @@ -201,7 +201,7 @@ - 更新配置说明(移除MySQL相关配置) - 更新API响应格式说明 - 更新数据导入流程说明 -- 添加customer2测试说明 +- 添加tenant2测试说明 ## 关键修改点 diff --git a/.cursor/plans/API响应格式优化与SPU索引重构3.md b/.cursor/plans/API响应格式优化与SPU索引重构3.md index 0e96eab..9abccd3 100644 --- a/.cursor/plans/API响应格式优化与SPU索引重构3.md +++ b/.cursor/plans/API响应格式优化与SPU索引重构3.md @@ -28,7 +28,7 @@ - 多语言字段:`title_zh`, `title_en`, `description_zh`, `description_en` 等 - 嵌套variants结构定义 -**注意**:店匠的店铺都使用base配置,不需要单独配置。允许其他深度定制客户(如customer1)有自己的配置。 +**注意**:店匠的店铺都使用base配置,不需要单独配置。允许其他深度定制客户(如tenant1)有自己的配置。 ### 1.2 更新配置加载器 @@ -244,9 +244,9 @@ - [ ] Create ResponseTransformer to convert ES hits to Shoplazza format (results, facets, suggestions, related_searches) - [ ] Update API models: add VariantOption, ProductVariant, ProductResult, update SearchResponse with new format - [ ] Update search route to use ResponseTransformer and return Shoplazza format -- [ ] Create script to generate 100 SPU+SKU test records for customer2 in Shoplazza tables -- [ ] Create customer2 config.yaml with search-only fields (no pipeline details) +- [ ] Create script to generate 100 SPU+SKU test records for tenant2 in Shoplazza tables +- [ ] Create tenant2 config.yaml with search-only fields (no pipeline details) - [ ] Create or update SPUDataTransformer to join SPU+SKU and create nested variants structure -- [ ] Create customer2 ingestion script that loads from MySQL and uses SPU transformer -- [ ] Create test script and documentation for customer2 setup and testing +- [ ] Create tenant2 ingestion script that loads from MySQL and uses SPU transformer +- [ ] Create test script and documentation for tenant2 setup and testing - [ ] Update design document: SPU-level indexing, unified index, config separation, pipeline decisions \ No newline at end of file diff --git a/.cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.md b/.cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.md index 1f6d784..20ed290 100644 --- a/.cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.md +++ b/.cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.md @@ -245,7 +245,7 @@ if enable_rerank and self.rerank_engine.enabled: ) ``` -#### `/home/tw/SearchEngine/config/schema/customer1/config.yaml` +#### `/home/tw/SearchEngine/config/schema/tenant1/config.yaml` **添加配置项**(254行后): @@ -274,7 +274,7 @@ function_score: weight: 1.1 ``` -#### `/home/tw/SearchEngine/config/customer_config.py` +#### `/home/tw/SearchEngine/config/tenant_config.py` **更新配置类**: @@ -293,7 +293,7 @@ class FunctionScoreConfig: functions: List[Dict[str, Any]] = field(default_factory=list) @dataclass -class CustomerConfig: +class TenantConfig: # ... 其他字段 ... ranking: RankingConfig # 保留用于兼容 rerank: RerankConfig # 新增 diff --git a/.cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.基于ES_fuction_score原生能力优化.md b/.cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.基于ES_fuction_score原生能力优化.md index 3bd5e28..7dea756 100644 --- a/.cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.基于ES_fuction_score原生能力优化.md +++ b/.cursor/plans/es-query-25a9f060.plan.检索表达式优化.ES_function表达式.基于ES_fuction_score原生能力优化.md @@ -30,7 +30,7 @@ ## 配置设计(简化版) -### `/home/tw/SearchEngine/config/schema/customer1/config.yaml` +### `/home/tw/SearchEngine/config/schema/tenant1/config.yaml` ```yaml # Function Score配置(ES层打分规则) @@ -131,7 +131,7 @@ rerank: ### 1. 定义配置模型 -**文件**: `/home/tw/SearchEngine/config/models.py`(新建或更新customer_config.py) +**文件**: `/home/tw/SearchEngine/config/models.py`(新建或更新tenant_config.py) ```python from dataclasses import dataclass, field @@ -282,7 +282,7 @@ if fs_config and fs_config.max_boost: ### 4. 更新示例配置 -**文件**: `/home/tw/SearchEngine/config/schema/customer1/config.yaml` +**文件**: `/home/tw/SearchEngine/config/schema/tenant1/config.yaml` 在 `ranking` 配置后添加新配置(参见上面完整YAML) diff --git a/.cursor/plans/将数据pipeline相关配置从索引配置中剥离.md b/.cursor/plans/将数据pipeline相关配置从索引配置中剥离.md index 64ed6b5..3c9127d 100644 --- a/.cursor/plans/将数据pipeline相关配置从索引配置中剥离.md +++ b/.cursor/plans/将数据pipeline相关配置从索引配置中剥离.md @@ -3,7 +3,7 @@ ## Overview -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. +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. ## Phase 1: Configuration File Cleanup @@ -22,7 +22,7 @@ Implement clean separation between **Search Configuration** (customer-facing, ES **Keep** (search configuration): -- `customer_name` +- `tenant_name` - `es_index_name` - `es_settings` - `fields` (simplified, no source mapping) @@ -49,7 +49,7 @@ fields: ### 1.2 Update Legacy Configuration -**File**: [`config/schema/customer1_legacy/config.yaml`](config/schema/customer1_legacy/config.yaml) +**File**: [`config/schema/tenant1_legacy/config.yaml`](config/schema/tenant1_legacy/config.yaml) Apply same cleanup as BASE config, marking it as legacy in comments. @@ -101,7 +101,7 @@ class TransformerFactory: @staticmethod def create( transformer_type: str, # 'sku' or 'spu' - config: CustomerConfig, + config: TenantConfig, text_encoder=None, image_encoder=None ) -> BaseDataTransformer: @@ -247,9 +247,9 @@ Changes: - Simplify field parsing (no source mapping) - Keep validation of ES/search related config -### 4.2 Update CustomerConfig Model +### 4.2 Update TenantConfig Model -**File**: [`config/__init__.py`](config/**init**.py) or wherever CustomerConfig is defined +**File**: [`config/__init__.py`](config/**init**.py) or wherever TenantConfig is defined Remove attributes: @@ -377,7 +377,7 @@ Add deprecation warnings to scripts that still use old config format. ### 1. Separation of Concerns -**Search Configuration** (customer-facing): +**Search Configuration** (tenant-facing): - What fields exist in ES - How fields are analyzed/indexed @@ -445,7 +445,7 @@ Pipeline decisions (transformer, data source, field mapping) made at runtime, no ✅ **Configuration reusability across data sources** -✅ **Customer doesn't need to understand ETL** +✅ **Tenant doesn't need to understand ETL** ✅ **Easier to add new data sources** diff --git a/.cursor/plans/所有tenant按同一份所有_返回接口优化.md b/.cursor/plans/所有tenant按同一份所有_返回接口优化.md index 693ae80..79bd029 100644 --- a/.cursor/plans/所有tenant按同一份所有_返回接口优化.md +++ b/.cursor/plans/所有tenant按同一份所有_返回接口优化.md @@ -142,10 +142,10 @@ New models: ## Phase 6: Legacy Migration -### 6.1 Rename Customer1 to Legacy +### 6.1 Rename Tenant1 to Legacy -- Rename [`config/schema/customer1/`](config/schema/customer1/) to [`config/schema/customer1_legacy/`](config/schema/customer1_legacy/) -- Update config to use old index `search_customer1` (preserve for backward compatibility) +- Rename [`config/schema/tenant1/`](config/schema/tenant1/) to [`config/schema/tenant1_legacy/`](config/schema/tenant1_legacy/) +- Update config to use old index `search_tenant1` (preserve for backward compatibility) - Mark as deprecated in comments ### 6.2 Update Scripts for BASE @@ -159,7 +159,7 @@ New models: **Files**: [`frontend/`](frontend/) HTML/JS files -- Change index name references from `search_customer1` to `search_products` +- Change index name references from `search_tenant1` to `search_products` - Use BASE config endpoints - Archive old frontend as `frontend_legacy/` if needed @@ -205,7 +205,7 @@ Updates: - **API响应格式**: 采用 Shoplazza 标准格式 - **Price扁平化**: 说明高频字段的性能优化策略 - **Nested变体**: 详细说明 variants 数组结构 -- **Legacy配置**: customer1等为遗留配置,仅用于兼容 +- **Legacy配置**: tenant1等为遗留配置,仅用于兼容 ### 8.2 Create BASE Guide @@ -258,7 +258,7 @@ Steps: ### BASE Configuration Philosophy -**BASE = Universal Standard**: All new merchants use BASE config with Shoplazza tables. No per-customer schema customization. Customization happens through: +**BASE = Universal Standard**: All new merchants use BASE config with Shoplazza tables. No per-tenant schema customization. Customization happens through: - Configuration parameters (analyzers, function_score, etc.) - Extension tables (if needed for additional fields) @@ -280,7 +280,7 @@ High-frequency operations (filtering, sorting) on price require optimal performa ### Legacy vs BASE - **BASE**: New standard, all future merchants -- **Legacy (customer1_legacy)**: Deprecated, exists only for backward compatibility +- **Legacy (tenant1_legacy)**: Deprecated, exists only for backward compatibility - All scripts/frontend default to BASE - Legacy access requires explicit suffix (`_legacy`) @@ -291,12 +291,12 @@ High-frequency operations (filtering, sorting) on price require optimal performa - [ ] Add NESTED field type support to field_types.py and mapping generator - [ ] Create SPU-level data transformer that joins SPU+SKU tables and creates nested variant array - [ ] Create script to generate 100 realistic SPU+SKU test records in Shoplazza tables -- [ ] Create customer2 configuration using unified schema and Shoplazza tables only -- [ ] Create customer2 ingestion script that loads from MySQL Shoplazza tables +- [ ] Create tenant2 configuration using unified schema and Shoplazza tables only +- [ ] Create tenant2 ingestion script that loads from MySQL Shoplazza tables - [ ] Update query builder to support tenant_id filtering and nested variant queries - [ ] Create response transformer to convert ES format to Shoplazza-compatible format - [ ] Update API models with new Shoplazza response format (ProductResult, variants, suggestions, etc.) - [ ] Update search routes to use response transformer and return new format -- [ ] Migrate customer1 configuration to unified schema and SPU-level indexing -- [ ] Create customer2 guide, update design docs, API docs, and create migration guide -- [ ] Create comprehensive test script for customer2 with data generation, ingestion, and search validation \ No newline at end of file +- [ ] Migrate tenant1 configuration to unified schema and SPU-level indexing +- [ ] Create tenant2 guide, update design docs, API docs, and create migration guide +- [ ] Create comprehensive test script for tenant2 with data generation, ingestion, and search validation \ No newline at end of file diff --git a/.cursor/plans/所有租户共用一套统一配置.tenantID只在请求层级.服务层级没有tenantID相关的独立配置.md b/.cursor/plans/所有租户共用一套统一配置.tenantID只在请求层级.服务层级没有tenantID相关的独立配置.md index e427dfb..910c884 100644 --- a/.cursor/plans/所有租户共用一套统一配置.tenantID只在请求层级.服务层级没有tenantID相关的独立配置.md +++ b/.cursor/plans/所有租户共用一套统一配置.tenantID只在请求层级.服务层级没有tenantID相关的独立配置.md @@ -6,7 +6,7 @@ 将搜索服务从按租户启动改造为真正的多租户架构: - 服务启动时不指定租户ID,所有租户共用一套配置 -- 删除customer1配置,去掉base层级,统一为config.yaml +- 删除tenant1配置,去掉base层级,统一为config.yaml - 统一脚本接口:启动、停止、重启、数据灌入 - 统一数据灌入流程,ES只有一份索引 - 前端支持在搜索框左侧输入租户ID @@ -18,30 +18,30 @@ **文件**: `config/config.yaml` (NEW) - 将 `config/schema/base/config.yaml` 移动到 `config/config.yaml` -- 删除 `customer_name` 字段(不再需要) -- 删除 `customer_id` 相关逻辑 +- 删除 `tenant_name` 字段(不再需要) +- 删除 `tenant_id` 相关逻辑 - 固定索引名称为 `search_products` - 确保包含 `tenant_id` 字段(必需) -### 1.2 删除customer1配置 +### 1.2 删除tenant1配置 **删除文件**: -- `config/schema/customer1/config.yaml` -- `config/schema/customer1/` 目录(如果为空) +- `config/schema/tenant1/config.yaml` +- `config/schema/tenant1/` 目录(如果为空) ### 1.3 更新ConfigLoader **文件**: `config/config_loader.py` -修改 `load_customer_config()` 方法: +修改 `load_tenant_config()` 方法: -- 移除 `customer_id` 参数 +- 移除 `tenant_id` 参数 - 改为 `load_config()` 方法 - 直接加载 `config/config.yaml` -- 移除对 `config/schema/{customer_id}/config.yaml` 的查找逻辑 -- 移除 `customer_id` 字段验证 -- 更新 `CustomerConfig` 类:移除 `customer_id` 字段 +- 移除对 `config/schema/{tenant_id}/config.yaml` 的查找逻辑 +- 移除 `tenant_id` 字段验证 +- 更新 `TenantConfig` 类:移除 `tenant_id` 字段 ### 1.4 更新配置验证 @@ -50,7 +50,7 @@ 修改 `validate_config()` 方法: - 确保 `tenant_id` 字段存在且为必需 -- 移除对 `customer_id` 的验证 +- 移除对 `tenant_id` 的验证 ## Phase 2: 服务启动改造 @@ -60,14 +60,14 @@ 修改 `init_service()` 方法: -- 移除 `customer_id` 参数 +- 移除 `tenant_id` 参数 - 直接加载统一配置(`config/config.yaml`) -- 移除 `CUSTOMER_ID` 环境变量依赖 -- 更新日志输出(不再显示customer_id) +- 移除 `TENANT_ID` 环境变量依赖 +- 更新日志输出(不再显示tenant_id) 修改 `startup_event()` 方法: -- 移除 `CUSTOMER_ID` 环境变量读取 +- 移除 `TENANT_ID` 环境变量读取 - 直接调用 `init_service()` 不传参数 ### 2.2 更新main.py @@ -76,8 +76,8 @@ 修改 `cmd_serve()` 方法: -- 移除 `--customer` 参数 -- 移除 `CUSTOMER_ID` 环境变量设置 +- 移除 `--tenant` 参数 +- 移除 `TENANT_ID` 环境变量设置 - 更新帮助信息 ### 2.3 更新启动脚本 @@ -86,16 +86,16 @@ 修改: -- 移除 `CUSTOMER_ID` 环境变量 -- 移除 `--customer` 参数 +- 移除 `TENANT_ID` 环境变量 +- 移除 `--tenant` 参数 - 简化启动命令 **文件**: `scripts/start_servers.py` 修改 `start_api_server()` 方法: -- 移除 `customer` 参数 -- 移除 `CUSTOMER_ID` 环境变量设置 +- 移除 `tenant` 参数 +- 移除 `TENANT_ID` 环境变量设置 - 简化启动命令 ## Phase 3: 脚本体系统一 @@ -139,7 +139,7 @@ 功能: - 从MySQL读取数据 -- 转换数据格式(统一处理base和customer1数据源) +- 转换数据格式(统一处理base和tenant1数据源) - 灌入到ES索引 `search_products` - 支持指定租户ID过滤数据 - 自动处理字段映射:缺失字段随机生成,多余字段忽略 @@ -204,7 +204,7 @@ - 移除 `--config` 参数(不再需要) - 直接加载统一配置(`config/config.yaml`) -- 统一处理所有数据源(不再区分base和customer1) +- 统一处理所有数据源(不再区分base和tenant1) - 支持 `--tenant-id` 参数过滤数据 - 字段映射逻辑: - 如果字段在配置中但数据源中没有,随机生成 @@ -217,7 +217,7 @@ 修改: -- 移除对配置中 `customer_id` 的依赖 +- 移除对配置中 `tenant_id` 的依赖 - 统一处理所有数据源 - 确保字段映射正确(缺失字段随机生成,多余字段忽略) @@ -299,8 +299,8 @@ ### 7.1 清理废弃代码 -- 删除所有对 `customer_id` 的引用 -- 删除所有对 `customer1` 配置的引用 +- 删除所有对 `tenant_id` 的引用 +- 删除所有对 `tenant1` 配置的引用 - 删除所有对 `base` 配置层级的引用 - 清理不再使用的脚本 @@ -316,12 +316,12 @@ ### 需要修改的文件: -1. `config/config_loader.py` - 移除customer_id逻辑 +1. `config/config_loader.py` - 移除tenant_id逻辑 2. `config/config.yaml` - 统一配置文件(从base移动) -3. `api/app.py` - 移除customer_id参数 -4. `main.py` - 移除customer参数 -5. `scripts/start_backend.sh` - 移除CUSTOMER_ID -6. `scripts/start_servers.py` - 移除customer参数 +3. `api/app.py` - 移除tenant_id参数 +4. `main.py` - 移除tenant参数 +5. `scripts/start_backend.sh` - 移除TENANT_ID +6. `scripts/start_servers.py` - 移除tenant参数 7. `scripts/ingest_shoplazza.py` - 统一数据灌入 8. `frontend/index.html` - 添加租户ID输入框 9. `frontend/static/js/app_base.js` - 读取租户ID @@ -329,8 +329,8 @@ ### 需要删除的文件: -1. `config/schema/customer1/config.yaml` -2. `config/schema/customer1/` 目录 +1. `config/schema/tenant1/config.yaml` +2. `config/schema/tenant1/` 目录 3. `scripts/demo_base.sh` 4. `scripts/stop_base.sh` 5. 其他废弃脚本 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 464c74f..218db5a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -209,7 +209,7 @@ EOF - name: Run integration tests env: ES_HOST: http://localhost:9200 - CUSTOMER_ID: test_customer + TENANT_ID: test_tenant TESTING_MODE: true run: | python -m pytest tests/integration/ \ @@ -312,7 +312,7 @@ EOF - name: Start API service env: ES_HOST: http://localhost:9200 - CUSTOMER_ID: test_customer + TENANT_ID: test_tenant API_HOST: 127.0.0.1 API_PORT: 6003 TESTING_MODE: true @@ -320,7 +320,7 @@ EOF python -m api.app \ --host $API_HOST \ --port $API_PORT \ - --customer $CUSTOMER_ID \ + --tenant $TENANT_ID \ --es-host $ES_HOST & echo $! > api.pid @@ -339,7 +339,7 @@ EOF ES_HOST: http://localhost:9200 API_HOST: 127.0.0.1 API_PORT: 6003 - CUSTOMER_ID: test_customer + TENANT_ID: test_tenant TESTING_MODE: true run: | python -m pytest tests/integration/test_api_integration.py \ diff --git a/API_DOCUMENTATION.md b/API_DOCUMENTATION.md index 690fd1f..4ce258c 100644 --- a/API_DOCUMENTATION.md +++ b/API_DOCUMENTATION.md @@ -527,7 +527,7 @@ curl "http://localhost:6002/search/12345" { "status": "healthy", "elasticsearch": "connected", - "customer_id": "customer1" + "tenant_id": "tenant1" } ``` @@ -543,9 +543,9 @@ curl "http://localhost:6002/search/12345" ```json { - "customer_id": "customer1", - "customer_name": "Customer1 Test Instance", - "es_index_name": "search_customer1", + "tenant_id": "tenant1", + "tenant_name": "Tenant1 Test Instance", + "es_index_name": "search_tenant1", "num_fields": 20, "num_indexes": 4, "supported_languages": ["zh", "en", "ru"], @@ -566,7 +566,7 @@ curl "http://localhost:6002/search/12345" ```json { - "index_name": "search_customer1", + "index_name": "search_tenant1", "document_count": 10000, "size_mb": 523.45 } diff --git a/CLAUDE.md b/CLAUDE.md index 40fb693..f2103ae 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -31,17 +31,17 @@ password: P89cZHS5d7dFyc9R ## Architecture ### Data Flow -1. **Data Source (MySQL)** → Main tables (`shoplazza_product_sku`, `shoplazza_product_spu`) + customer extension tables +1. **Data Source (MySQL)** → Main tables (`shoplazza_product_sku`, `shoplazza_product_spu`) + tenant extension tables 2. **Indexer** → Reads from MySQL, applies transformations (embeddings, etc.), writes to Elasticsearch 3. **Query Parser** → Query rewriting, translation, text embedding conversion 4. **Searcher** → Executes searches against Elasticsearch with configurable ranking ### Multi-Tenant Design -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. +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. ### Configuration System -The system uses two types of configurations per customer: +The system uses two types of configurations per tenant: 1. **Application Structure Config** (`IndexerConfig`) - Defines: - Input field mappings from MySQL to Elasticsearch @@ -89,10 +89,10 @@ The `searcher` supports: ## Test Data 、 -**Customer1 Test Dataset:** -- Location: `data/customer1/goods_with_pic.5years_congku.csv.shuf.1w` +**Tenant1 Test Dataset:** +- Location: `data/tenant1/goods_with_pic.5years_congku.csv.shuf.1w` - Contains 10,000 shuffled product records with images -- Processing script: `data/customer1/task2_process_goods.py` +- Processing script: `data/tenant1/task2_process_goods.py` - Extracts product data from MySQL - Maps images from filebank database - Creates inverted index (URL → SKU list) @@ -101,7 +101,7 @@ The `searcher` supports: 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. -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. +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. 3. **Embedding Caching:** For periodic full indexing, embedding results should be cached to avoid recomputation. diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index a612d14..2f2d080 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -86,7 +86,7 @@ REDIS_PASSWORD=BMfv5aI31kgHWtlx DEEPL_AUTH_KEY=c9293ab4-ad25-479b-919f-ab4e63b429ed -CUSTOMER_ID=customer1 +TENANT_ID=tenant1 API_HOST=0.0.0.0 API_PORT=6002 ``` @@ -146,7 +146,7 @@ from config import ConfigLoader es_config = get_es_config() es_client = ESClient(hosts=[es_config['host']], username=es_config.get('username'), password=es_config.get('password')) -config = ConfigLoader('config/schema').load_customer_config('customer1') +config = ConfigLoader('config/schema').load_tenant_config('tenant1') count = es_client.count(config.es_index_name) print(f'Documents in index: {count}') " @@ -255,7 +255,7 @@ kill -9 - 了解所有可用的API端点 3. **自定义配置** - - 编辑 `config/schema/customer1_config.yaml` + - 编辑 `config/schema/tenant1_config.yaml` - 添加查询重写规则 - 调整ranking表达式 diff --git a/FUNCTION_SCORE_CONFIG_COMPLETE.md b/FUNCTION_SCORE_CONFIG_COMPLETE.md index a284cf6..1b1f6d6 100644 --- a/FUNCTION_SCORE_CONFIG_COMPLETE.md +++ b/FUNCTION_SCORE_CONFIG_COMPLETE.md @@ -29,9 +29,9 @@ class RerankConfig: description: str = "" ``` -添加到 `CustomerConfig`: +添加到 `TenantConfig`: ```python -class CustomerConfig: +class TenantConfig: # ... 其他字段 function_score: FunctionScoreConfig rerank: RerankConfig @@ -104,7 +104,7 @@ def _build_score_functions(self) -> List[Dict[str, Any]]: ### 3. 配置文件示例 -**文件**: `/home/tw/SearchEngine/config/schema/customer1/config.yaml` +**文件**: `/home/tw/SearchEngine/config/schema/tenant1/config.yaml` 添加完整的`function_score`配置: @@ -489,7 +489,7 @@ https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-functi 1. **编辑配置文件** ```bash -vi config/schema/customer1/config.yaml +vi config/schema/tenant1/config.yaml ``` 2. **添加打分规则** diff --git a/HighLevelDesign.md b/HighLevelDesign.md index 3e728c9..7497eb2 100644 --- a/HighLevelDesign.md +++ b/HighLevelDesign.md @@ -71,10 +71,10 @@ deleted bit(1) ### 测试数据灌入 灌入数据、mysql到ES的自动同步,不在本项目的范围内,另外有java项目负责。 -但是,该项目 为了提供测试数据,需要 构造一个实例 customer1. +但是,该项目 为了提供测试数据,需要 构造一个实例 tenant1. 我们为他构造一套应用配置和索引配置。 灌入一批测试数据,可以些一个简单的 全量灌入的实现。 -数据源地址在:data/customer1/goods_with_pic.5years_congku.csv.shuf.1w +数据源地址在:data/tenant1/goods_with_pic.5years_congku.csv.shuf.1w 请根据这里面的字段,建设辅助表(注意看哪些字段在主表有,哪些需要放到辅表) 然后写一个程序,将数据分别灌入主表和辅表。 @@ -83,7 +83,7 @@ deleted bit(1) query分析,做以下几个事情: 1. 查询改写。 配置词典的key是query,value是改写后的查询表达式,比如。比如品牌词 改写为在brand|query OR name|query,类别词、标签词等都可以放进去。纠错、规范化、查询改写等 都可以通过这个词典来配置。 -2. 翻译。配置需要得到的几种目标语言。 在customer1测试案例中,我们配置 zh en两种语言。先对query做语言检测,如果query是中文那么要翻译一下en,如果是en那么要翻译zh,如果两者都不是那么zh en都需要翻译。 +2. 翻译。配置需要得到的几种目标语言。 在tenant1测试案例中,我们配置 zh en两种语言。先对query做语言检测,如果query是中文那么要翻译一下en,如果是en那么要翻译zh,如果两者都不是那么zh en都需要翻译。 3. 如果配置打开了text_embedding查询,并且query 包含了default域的查询,那么要把default域的查询词转向量,后面searcher会用这个向量参与查询。 翻译代码参考: ``` diff --git a/MULTILANG_FEATURE.md b/MULTILANG_FEATURE.md index 5571710..991564a 100644 --- a/MULTILANG_FEATURE.md +++ b/MULTILANG_FEATURE.md @@ -14,7 +14,7 @@ ### 字段配置 -在 `customer1_config.yaml` 中,需要为不同语言的标题字段配置对应的分词器: +在 `tenant1_config.yaml` 中,需要为不同语言的标题字段配置对应的分词器: ```yaml fields: diff --git a/QUICKSTART.md b/QUICKSTART.md index 2c10055..ebcdea2 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -24,8 +24,8 @@ export ES_HOST="http://localhost:9200" # DeepL API (for translation) export DEEPL_API_KEY="your-api-key-here" -# Customer ID -export CUSTOMER_ID="customer1" +# Tenant ID +export TENANT_ID="tenant1" ``` ## Running the System @@ -37,8 +37,8 @@ export CUSTOMER_ID="customer1" docker run -d -p 9200:9200 -e "discovery.type=single-node" elasticsearch:8.11.0 # 2. Ingest sample data (100 documents for quick test) -cd data/customer1 -python ingest_customer1.py \ +cd data/tenant1 +python ingest_tenant1.py \ --limit 100 \ --recreate-index \ --es-host http://localhost:9200 \ @@ -61,8 +61,8 @@ curl -X POST http://localhost:6002/search/ \ docker run -d -p 9200:9200 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms4g -Xmx4g" elasticsearch:8.11.0 # 2. Ingest full dataset with embeddings (requires GPU, takes ~10-30 min) -cd data/customer1 -python ingest_customer1.py \ +cd data/tenant1 +python ingest_tenant1.py \ --csv goods_with_pic.5years_congku.csv.shuf.1w \ --recreate-index \ --batch-size 100 \ @@ -73,7 +73,7 @@ cd ../.. python -m api.app \ --host 0.0.0.0 \ --port 6002 \ - --customer customer1 \ + --tenant tenant1 \ --es-host http://localhost:9200 # 4. Test various searches @@ -118,7 +118,7 @@ python -c "from embeddings import CLIPImageEncoder; CLIPImageEncoder()" ### Issue: Out of memory during embedding generation **Solution**: Reduce batch size or skip embeddings initially ```bash -python ingest_customer1.py --skip-embeddings --limit 1000 +python ingest_tenant1.py --skip-embeddings --limit 1000 ``` ### Issue: Translation not working @@ -164,7 +164,7 @@ curl -X POST http://localhost:6002/search/ \ ## What's Next? -1. **Customize Configuration**: Edit `config/schema/customer1_config.yaml` +1. **Customize Configuration**: Edit `config/schema/tenant1_config.yaml` 2. **Add More Data**: Ingest your own product data 3. **Tune Ranking**: Adjust ranking expression in config 4. **Add Rewrite Rules**: Update via API `/admin/rewrite-rules` diff --git a/USER_GUIDE.md b/USER_GUIDE.md index f5f8654..683f8f3 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -96,7 +96,7 @@ REDIS_PASSWORD=BMfv5aI31kgHWtlx DEEPL_AUTH_KEY=c9293ab4-ad25-479b-919f-ab4e63b429ed # 客户配置 -CUSTOMER_ID=customer1 +TENANT_ID=tenant1 # API服务配置 API_HOST=0.0.0.0 @@ -292,7 +292,7 @@ from search import Searcher from config.env_config import get_es_config config_loader = ConfigLoader('config/schema') -config = config_loader.load_customer_config('customer1') +config = config_loader.load_tenant_config('tenant1') es_config = get_es_config() es_client = ESClient(hosts=[es_config['host']], @@ -326,7 +326,7 @@ for hit in result.hits: ### 2. 批量大小调整 ```bash -# 修改批量大小(在ingest_customer1.py中) +# 修改批量大小(在ingest_tenant1.py中) --batch-size 200 # 默认100 ``` @@ -369,4 +369,4 @@ SearchEngine/ 遇到问题请查看: - **日志**: `logs/backend.log` - **API文档**: http://localhost:6002/docs -- **配置**: `config/schema/customer1_config.yaml` +- **配置**: `config/schema/tenant1_config.yaml` diff --git a/VISUAL_COMPARISON.md b/VISUAL_COMPARISON.md index 086a352..0e23399 100644 --- a/VISUAL_COMPARISON.md +++ b/VISUAL_COMPARISON.md @@ -69,7 +69,7 @@ #### 旧版 ``` 🔍 电商搜索引擎 -E-Commerce Search Engine - Customer1 Demo +E-Commerce Search Engine - Tenant1 Demo ``` - 大标题 + 副标题 - 表情符号 diff --git a/docs/TestingPipeline_README.md b/docs/TestingPipeline_README.md index 640c95a..06ca2c1 100644 --- a/docs/TestingPipeline_README.md +++ b/docs/TestingPipeline_README.md @@ -193,7 +193,7 @@ python scripts/run_performance_tests.py export ES_PASSWORD="changeme" export API_HOST="127.0.0.1" export API_PORT="6003" - export CUSTOMER_ID="test_customer" + export TENANT_ID="test_tenant" export TESTING_MODE="true" ``` @@ -323,9 +323,9 @@ test_logs/ ```python # 使用fixture提供测试数据 @pytest.fixture -def sample_customer_config(): - return CustomerConfig( - customer_id="test_customer", +def sample_tenant_config(): + return TenantConfig( + tenant_id="test_tenant", es_index_name="test_products" ) diff --git a/docs/店匠相关资料/SHOPLAZZA_INTEGRATION_GUIDE.md b/docs/店匠相关资料/SHOPLAZZA_INTEGRATION_GUIDE.md index 71fffeb..eaf60e8 100644 --- a/docs/店匠相关资料/SHOPLAZZA_INTEGRATION_GUIDE.md +++ b/docs/店匠相关资料/SHOPLAZZA_INTEGRATION_GUIDE.md @@ -157,7 +157,7 @@ https://your-domain.com/oauth/callback | `read_product` | 读取商品信息 | ✅ 必需 | | `write_product` | 修改商品信息 | ❌ 可选 | | `read_order` | 读取订单信息 | ✅ 必需 | -| `read_customer` | 读取客户信息 | ✅ 必需 | +| `read_tenant` | 读取客户信息 | ✅ 必需 | | `read_app_proxy` | APP 代理访问 | ✅ 必需 | | `write_cart_transform` | 购物车转换(如需价格调整) | ❌ 可选 | @@ -167,7 +167,7 @@ Scopes: []string{ "read_shop", "read_product", "read_order", - "read_customer", + "read_tenant", "read_app_proxy", } ``` @@ -239,7 +239,7 @@ config := &OAuthConfig{ "read_shop", "read_product", "read_order", - "read_customer", + "read_tenant", "read_app_proxy", }, AuthURL: "https://partners.shoplazza.com/partner/oauth/authorize", @@ -286,7 +286,7 @@ func buildAuthURL(config *OAuthConfig, shop string) string { https://partners.shoplazza.com/partner/oauth/authorize? client_id=m8F9PrPnxpyrlz4ONBWRoINsa5xyNT4Qd-Fh_h7o1es &redirect_uri=https://your-domain.com/oauth/callback - &scope=read_shop read_product read_order read_customer read_app_proxy + &scope=read_shop read_product read_order read_tenant read_app_proxy &state=47167113-1.myshoplaza.com ``` @@ -742,13 +742,13 @@ GET /openapi/2022-01/orders/count ```bash # 获取客户列表 -GET /openapi/2022-01/customers?page=1&limit=50 +GET /openapi/2022-01/tenants?page=1&limit=50 # 获取客户详情 -GET /openapi/2022-01/customers/{customer_id} +GET /openapi/2022-01/tenants/{tenant_id} # 获取客户总数 -GET /openapi/2022-01/customers/count +GET /openapi/2022-01/tenants/count ``` ### 5.4 请求和响应格式 @@ -1222,14 +1222,14 @@ public class ProductSyncService { #### 6.2.1 数据表设计 -**客户表(shoplazza_customer):** +**客户表(shoplazza_tenant):** ```sql -CREATE TABLE `shoplazza_customer` ( +CREATE TABLE `shoplazza_tenant` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', `tenant_id` BIGINT NOT NULL COMMENT '租户ID', `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID', - `customer_id` VARCHAR(64) NOT NULL COMMENT '店匠客户ID', + `tenant_id` VARCHAR(64) NOT NULL COMMENT '店匠客户ID', `email` VARCHAR(255) DEFAULT NULL COMMENT '邮箱', `phone` VARCHAR(64) DEFAULT NULL COMMENT '电话', `first_name` VARCHAR(128) DEFAULT NULL COMMENT '名', @@ -1241,20 +1241,20 @@ CREATE TABLE `shoplazza_customer` ( `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`), - UNIQUE KEY `uk_store_customer` (`store_id`, `customer_id`), + UNIQUE KEY `uk_store_tenant` (`store_id`, `tenant_id`), KEY `idx_tenant_id` (`tenant_id`), KEY `idx_email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店匠客户表'; ``` -**客户地址表(shoplazza_customer_address):** +**客户地址表(shoplazza_tenant_address):** ```sql -CREATE TABLE `shoplazza_customer_address` ( +CREATE TABLE `shoplazza_tenant_address` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', `tenant_id` BIGINT NOT NULL COMMENT '租户ID', `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID', - `customer_id` VARCHAR(64) NOT NULL COMMENT '店匠客户ID', + `tenant_id` VARCHAR(64) NOT NULL COMMENT '店匠客户ID', `address_id` VARCHAR(64) NOT NULL COMMENT '店匠地址ID', `first_name` VARCHAR(128) DEFAULT NULL COMMENT '名', `last_name` VARCHAR(128) DEFAULT NULL COMMENT '姓', @@ -1272,7 +1272,7 @@ CREATE TABLE `shoplazza_customer_address` ( PRIMARY KEY (`id`), UNIQUE KEY `uk_store_address` (`store_id`, `address_id`), KEY `idx_tenant_id` (`tenant_id`), - KEY `idx_customer_id` (`customer_id`) + KEY `idx_tenant_id` (`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店匠客户地址表'; ``` @@ -1280,7 +1280,7 @@ CREATE TABLE `shoplazza_customer_address` ( ```bash curl --request GET \ - --url 'https://47167113-1.myshoplaza.com/openapi/2022-01/customers?page=1&limit=50' \ + --url 'https://47167113-1.myshoplaza.com/openapi/2022-01/tenants?page=1&limit=50' \ --header 'access-token: V2WDYgkTvrN68QCESZ9eHb3EjpR6EBrPyAKe-m_JwYY' \ --header 'accept: application/json' ``` @@ -1298,7 +1298,7 @@ CREATE TABLE `shoplazza_order` ( `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID', `order_id` VARCHAR(64) NOT NULL COMMENT '店匠订单ID', `order_number` VARCHAR(128) NOT NULL COMMENT '订单号', - `customer_id` VARCHAR(64) DEFAULT NULL COMMENT '客户ID', + `tenant_id` VARCHAR(64) DEFAULT NULL COMMENT '客户ID', `email` VARCHAR(255) DEFAULT NULL COMMENT '客户邮箱', `total_price` DECIMAL(12,2) NOT NULL COMMENT '订单总价', `subtotal_price` DECIMAL(12,2) DEFAULT NULL COMMENT '小计', @@ -1314,7 +1314,7 @@ CREATE TABLE `shoplazza_order` ( PRIMARY KEY (`id`), UNIQUE KEY `uk_store_order` (`store_id`, `order_id`), KEY `idx_tenant_id` (`tenant_id`), - KEY `idx_customer_id` (`customer_id`), + KEY `idx_tenant_id` (`tenant_id`), KEY `idx_order_number` (`order_number`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店匠订单表'; ``` @@ -1365,7 +1365,7 @@ public class DataSyncService { productSyncService.syncProducts(shopConfigId); // 2. 同步客户 - customerSyncService.syncCustomers(shopConfigId); + tenantSyncService.syncTenants(shopConfigId); // 3. 同步订单 orderSyncService.syncOrders(shopConfigId); @@ -1420,12 +1420,12 @@ public class ScheduledSyncTask { * 每天同步一次客户和订单数据 */ @Scheduled(cron = "0 0 3 * * ?") - public void syncCustomersAndOrdersDaily() { + public void syncTenantsAndOrdersDaily() { List activeShops = shopConfigMapper.selectActiveShops(); for (ShopConfig shop : activeShops) { try { - customerSyncService.syncCustomers(shop.getId()); + tenantSyncService.syncTenants(shop.getId()); orderSyncService.syncOrders(shop.getId()); } catch (Exception e) { log.error("Scheduled sync failed for shop: {}", shop.getStoreName(), e); @@ -1453,8 +1453,8 @@ public class RobustSyncService { case "products": productSyncService.syncProducts(shopConfigId); break; - case "customers": - customerSyncService.syncCustomers(shopConfigId); + case "tenants": + tenantSyncService.syncTenants(shopConfigId); break; case "orders": orderSyncService.syncOrders(shopConfigId); @@ -1512,9 +1512,9 @@ Webhook 是店匠平台的事件通知机制,当店铺发生特定事件(如 | Topic | 说明 | 触发时机 | |-------|------|----------| -| `customers/create` | 客户创建 | 新客户注册时 | -| `customers/update` | 客户更新 | 客户信息更新时 | -| `customers/delete` | 客户删除 | 客户被删除时 | +| `tenants/create` | 客户创建 | 新客户注册时 | +| `tenants/update` | 客户更新 | 客户信息更新时 | +| `tenants/delete` | 客户删除 | 客户被删除时 | ### 7.3 注册 Webhook @@ -1561,8 +1561,8 @@ public class WebhookService { "orders/create", "orders/updated", "orders/paid", - "customers/create", - "customers/update" + "tenants/create", + "tenants/update" ); /** @@ -1733,12 +1733,12 @@ public class WebhookService { case "orders/cancelled": handleOrderCancel(storeId, payload); break; - case "customers/create": - case "customers/update": - handleCustomerUpdate(storeId, payload); + case "tenants/create": + case "tenants/update": + handleTenantUpdate(storeId, payload); break; - case "customers/delete": - handleCustomerDelete(storeId, payload); + case "tenants/delete": + handleTenantDelete(storeId, payload); break; default: log.warn("Unknown webhook topic: {}", topic); @@ -2279,7 +2279,7 @@ public class SearchService { String url = searchServiceUrl + "/search/"; // 添加租户隔离参数 - request.setCustomer("tenant_" + tenantId); + request.setTenant("tenant_" + tenantId); ResponseEntity response = restTemplate.postForEntity( url, @@ -2309,8 +2309,8 @@ public class SearchService { # Python 搜索服务 @app.post("/search/") async def search_products(request: SearchRequest): - # 根据 customer 参数确定租户 ID - tenant_id = extract_tenant_id(request.customer) + # 根据 tenant 参数确定租户 ID + tenant_id = extract_tenant_id(request.tenant) # 使用租户专属索引 index_name = f"shoplazza_products_{tenant_id}" @@ -2337,7 +2337,7 @@ CREATE TABLE `shoplazza_search_log` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', `tenant_id` BIGINT NOT NULL COMMENT '租户ID', `store_id` VARCHAR(64) NOT NULL COMMENT '店铺ID', - `customer_id` VARCHAR(64) DEFAULT NULL COMMENT '客户ID', + `tenant_id` VARCHAR(64) DEFAULT NULL COMMENT '客户ID', `session_id` VARCHAR(128) DEFAULT NULL COMMENT '会话ID', `query` VARCHAR(512) NOT NULL COMMENT '搜索关键词', `results_count` INT DEFAULT 0 COMMENT '结果数量', @@ -2377,7 +2377,7 @@ public class SearchLogService { SearchLog log = new SearchLog(); log.setTenantId(shop.getTenantId()); log.setStoreId(shop.getStoreId()); - log.setCustomerId(request.getCustomerId()); + log.setTenantId(request.getTenantId()); log.setSessionId(request.getSessionId()); log.setQuery(request.getQuery()); log.setResultsCount(response.getTotal()); @@ -2647,7 +2647,7 @@ window.AI_SEARCH_CONFIG = { size: 24, filters: currentFilters, facets: ['product_type', 'vendor', 'tags'], - customer: `tenant_${config.storeId}` + tenant: `tenant_${config.storeId}` }) }); @@ -3023,8 +3023,8 @@ server { | 订单列表 | `/openapi/2022-01/orders` | GET | 获取订单列表 | | 订单详情 | `/openapi/2022-01/orders/{id}` | GET | 获取单个订单 | | **客户** | -| 客户列表 | `/openapi/2022-01/customers` | GET | 获取客户列表 | -| 客户详情 | `/openapi/2022-01/customers/{id}` | GET | 获取单个客户 | +| 客户列表 | `/openapi/2022-01/tenants` | GET | 获取客户列表 | +| 客户详情 | `/openapi/2022-01/tenants/{id}` | GET | 获取单个客户 | | **Webhook** | | 注册 Webhook | `/openapi/2022-01/webhooks` | POST | 注册事件通知 | | Webhook 列表 | `/openapi/2022-01/webhooks` | GET | 获取已注册列表 | @@ -3039,7 +3039,7 @@ curl -X POST http://your-domain:6002/search/ \ -H "Content-Type: application/json" \ -d '{ "query": "bluetooth headphone", - "customer": "tenant_1", + "tenant": "tenant_1", "size": 20, "from": 0, "filters": { @@ -3056,7 +3056,7 @@ curl -X POST http://your-domain:6002/search/image \ -H "Content-Type: application/json" \ -d '{ "image_url": "https://example.com/image.jpg", - "customer": "tenant_1", + "tenant": "tenant_1", "size": 20 }' ``` @@ -3071,8 +3071,8 @@ curl -X POST http://your-domain:6002/search/image \ - `shoplazza_product_spu` - 商品 SPU 表 - `shoplazza_product_sku` - 商品 SKU 表 - `shoplazza_product_image` - 商品图片表 -- `shoplazza_customer` - 客户表 -- `shoplazza_customer_address` - 客户地址表 +- `shoplazza_tenant` - 客户表 +- `shoplazza_tenant_address` - 客户地址表 - `shoplazza_order` - 订单表 - `shoplazza_order_item` - 订单明细表 - `shoplazza_search_log` - 搜索日志表 @@ -3092,7 +3092,7 @@ shoplazza: - read_shop - read_product - read_order - - read_customer + - read_tenant - read_app_proxy # Webhook 配置 @@ -3103,7 +3103,7 @@ shoplazza: - products/update - products/delete - orders/create - - customers/create + - tenants/create # 搜索服务配置 search: @@ -3130,7 +3130,7 @@ sync: schedule: products: "0 0 */1 * * ?" # 每小时 orders: "0 0 3 * * ?" # 每天凌晨3点 - customers: "0 0 4 * * ?" # 每天凌晨4点 + tenants: "0 0 4 * * ?" # 每天凌晨4点 ``` ### 12.4 故障排查 diff --git a/docs/店匠相关资料/记录tenant和token-获取商品信息.md b/docs/店匠相关资料/记录tenant和token-获取商品信息.md index 4c995c3..bf6b78e 100644 --- a/docs/店匠相关资料/记录tenant和token-获取商品信息.md +++ b/docs/店匠相关资料/记录tenant和token-获取商品信息.md @@ -127,7 +127,7 @@ public void handleOAuthCallback(TokenResponse tokenResponse) { 1. **拉取数据** - 调用店匠 Admin API - 拉取商品:`GET /openapi/2022-01/products` - 拉取订单:`GET /openapi/2022-01/orders` - - 拉取客户:`GET /openapi/2022-01/customers` + - 拉取客户:`GET /openapi/2022-01/tenants` 2. **注册 Webhook** - 让店匠主动推送数据变更 - 注册:`POST /openapi/2022-01/webhooks`(需要 Token) @@ -255,12 +255,12 @@ public void syncProducts(Long shopConfigId) { **实现逻辑:** ```java -public void syncCustomers(Long shopConfigId) { +public void syncTenants(Long shopConfigId) { // 与 syncProducts 类似,遍历所有分页 - String url = "https://{shop}/openapi/2022-01/customers?page={page}&limit=50"; + String url = "https://{shop}/openapi/2022-01/tenants?page={page}&limit=50"; // 循环拉取所有页 - // 保存到 shoplazza_customer 和 shoplazza_customer_address 表 + // 保存到 shoplazza_tenant 和 shoplazza_tenant_address 表 } ``` @@ -342,7 +342,7 @@ public class WebhookService { private static final List WEBHOOK_TOPICS = Arrays.asList( "products/create", "products/update", "products/delete", - "orders/create", "orders/updated", "customers/create" + "orders/create", "orders/updated", "tenants/create" ); public void registerWebhooks(Long shopConfigId) { diff --git a/frontend/unified.html b/frontend/unified.html index bc396ed..175ef76 100644 --- a/frontend/unified.html +++ b/frontend/unified.html @@ -54,7 +54,7 @@
diff --git a/scripts/start_test_environment.sh b/scripts/start_test_environment.sh index 2587a7e..e9d3727 100755 --- a/scripts/start_test_environment.sh +++ b/scripts/start_test_environment.sh @@ -61,7 +61,7 @@ export ES_PASSWORD="changeme" # API配置 export API_HOST="127.0.0.1" export API_PORT="6003" # 使用不同的端口避免冲突 -export CUSTOMER_ID="test_customer" +export TENANT_ID="test_tenant" # 测试配置 export TEST_TIMEOUT=60 @@ -70,7 +70,7 @@ export TEST_RETRY_COUNT=3 echo -e "${BLUE}环境配置:${NC}" echo " ES_HOST: $ES_HOST" echo " API_HOST: $API_HOST:$API_PORT" -echo " CUSTOMER_ID: $CUSTOMER_ID" +echo " TENANT_ID: $TENANT_ID" echo " LOG_LEVEL: $LOG_LEVEL" echo " TESTING_MODE: $TESTING_MODE" @@ -184,7 +184,7 @@ cd "$PROJECT_ROOT" python -m api.app \ --host $API_HOST \ --port $API_PORT \ - --customer $CUSTOMER_ID \ + --tenant $TENANT_ID \ --es-host $ES_HOST \ > "$API_LOG_FILE" 2>&1 & @@ -240,7 +240,7 @@ echo -e "${GREEN}========================================${NC}" echo -e "${BLUE}服务信息:${NC}" echo " Elasticsearch: $ES_HOST" echo " API服务: http://$API_HOST:$API_PORT" -echo " 测试客户: $CUSTOMER_ID" +echo " 测试客户: $TENANT_ID" echo -e "${BLUE}进程信息:${NC}" echo " API PID: $API_PID" echo " PID文件: $PID_FILE" @@ -264,7 +264,7 @@ export ES_USERNAME="$ES_USERNAME" export ES_PASSWORD="$ES_PASSWORD" export API_HOST="$API_HOST" export API_PORT="$API_PORT" -export CUSTOMER_ID="$CUSTOMER_ID" +export TENANT_ID="$TENANT_ID" export TESTING_MODE="$TESTING_MODE" export LOG_LEVEL="$LOG_LEVEL" export PYTHONPATH="$PROJECT_ROOT:\$PYTHONPATH" diff --git a/支持多语言查询.md b/支持多语言查询.md index a40d477..bf439ec 100644 --- a/支持多语言查询.md +++ b/支持多语言查询.md @@ -36,7 +36,7 @@ index 8df15b3..f3fcaa3 100644 @dataclass class RankingConfig: -@@ -66,8 +69,6 @@ class CustomerConfig: +@@ -66,8 +69,6 @@ class TenantConfig: # Database settings mysql_config: Dict[str, Any] @@ -45,7 +45,7 @@ index 8df15b3..f3fcaa3 100644 # Field definitions fields: List[FieldConfig] -@@ -86,6 +87,10 @@ class CustomerConfig: +@@ -86,6 +87,10 @@ class TenantConfig: # ES index settings es_index_name: str @@ -74,7 +74,7 @@ index 8df15b3..f3fcaa3 100644 + language_field_mapping=language_field_mapping ) - def validate_config(self, config: CustomerConfig) -> List[str]: + def validate_config(self, config: TenantConfig) -> List[str]: @@ -360,11 +369,16 @@ class ConfigLoader: def _index_to_dict(self, index: IndexConfig) -> Dict[str, Any]: @@ -96,10 +96,10 @@ index 8df15b3..f3fcaa3 100644 + + return result \ No newline at end of file -diff --git a/config/schema/customer1_config.yaml b/config/schema/customer1_config.yaml +diff --git a/config/schema/tenant1_config.yaml b/config/schema/tenant1_config.yaml index bfe2e53..84e9ba1 100644 ---- a/config/schema/customer1_config.yaml -+++ b/config/schema/customer1_config.yaml +--- a/config/schema/tenant1_config.yaml ++++ b/config/schema/tenant1_config.yaml @@ -177,6 +177,15 @@ indexes: analyzer: "chinese_ecommerce" boost: 1.0 diff --git a/设计文档.md b/设计文档.md index 8e5e832..027c16a 100644 --- a/设计文档.md +++ b/设计文档.md @@ -70,7 +70,7 @@ ### 2.1 应用结构配置(字段定义) -**配置文件位置**:`config/schema/{customer_id}_config.yaml` +**配置文件位置**:`config/schema/{tenant_id}_config.yaml` **配置内容**:定义了 ES 的输入数据有哪些字段、关联 MySQL 的哪些字段。 @@ -228,7 +228,7 @@ indexes: - `shoplazza_product_spu` - SPU级别商品数据 - `shoplazza_product_sku` - SKU级别商品数据 -**其他客户表**(customer1等): +**其他客户表**(tenant1等): - 使用各自的数据源表和扩展表 ### 3.2 数据导入方式 @@ -585,7 +585,7 @@ API返回格式不包含ES内部字段(`_id`, `_score`, `_source`),使用 **Base配置**(店匠通用):`config/schema/base/config.yaml` -**其他客户配置**:`config/schema/customer1/config.yaml` +**其他客户配置**:`config/schema/tenant1/config.yaml` --- -- libgit2 0.21.2