- product.json: add resource_ref_id field
- core.py: _get_ref_id() helper extracts resource_ref_id from product
- All dispatch methods pass resource_ref_id instead of product_code
- Resource modules no longer need product_code→internal_id mapping
- Add resource_module field to product_category model (stores module name like 'llmage')
- Add resource_module appcode with llmage/supplychain entries to init/data.json
- Add '添加子产品类和产品导入' toolbar tool to tree CRUD (json + generated index.ui)
- Create import_category_products.dspy API endpoint
- Add import_categories_and_products() generic import engine to core.py
- Register import function on ServerEnv
- Update load_path.py with new API endpoint
- All 7 models: created_at/updated_at changed from datetime to timestamp type
(DDL template auto-generates DEFAULT CURRENT_TIMESTAMP for timestamp type)
- core.py: fix all sor.U() calls passing 3 args (id must be in data dict)
- core.py: fix sor.I() misuse for INSERT (should be sor.C())
- API dspy updates: fix sor.U() 3-arg bug in category/product/type_config/resource/subscription/supplier
- product_resource_supplier_update.dspy: add missing updated_at field
- product_category: org_id scoped tree, product_table_name -> product_type
- product: org_id scoped, added extra_json for custom attributes, product_type field
- product_type_config: org_id + operator_id dual isolation, unique key on (org_id, operator_id, category_id, config_name)
- All 18 API endpoints enforce org_id filtering via ServerEnv
- core.py: all methods accept optional org_id, default to current user's org
- CRUD definitions: logined_userorgid set to org_id on all lists
- init/data.json: removed hardcoded global categories (managed per reseller)
- Rebuilt mysql.ddl.sql and all CRUD UI files