--- name: flower-db-access description: Read-only database access for the Flower ERP system. Allows querying all tables except authentication/authorization tables. Use this skill to inspect business data, analyze trends, debug issues, or generate reports. All write operations are strictly prohibited. allowed-tools: Bash(ssh:*), Bash(psql:*), Bash(PGPASSWORD:*) --- # Flower ERP Database Access (Read-Only) This skill provides read-only access to the Flower ERP PostgreSQL database for data inspection, analysis, and debugging. ## ⚠️ IMPORTANT: Remote Access Required **This database is hosted on a remote server. You MUST establish an SSH connection first before accessing the database.** ### SSH Connection Details - **Remote Server**: `8.148.215.233` - **SSH Port**: `18762` - **SSH User**: `root` - **Authentication**: SSH Key (passwordless) - **Database Host** (on remote): `127.0.0.1` - **Database Port**: `5432` ### Step 1: Establish SSH Connection #### Option A: Interactive SSH Session ```bash # Connect to remote server (SSH key authentication) ssh -p 18762 root@8.148.215.233 # Once connected, access the database PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower ``` #### Option B: SSH with Command Execution (Recommended for Agents) ```bash # Execute single query via SSH ssh -p 18762 root@8.148.215.233 "PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c 'YOUR_QUERY'" ``` #### Option C: SSH Tunnel (For Local Development) ```bash # Create SSH tunnel to access remote database as if it's local ssh -p 18762 -L 15432:127.0.0.1:5432 root@8.148.215.233 -N # In another terminal, connect to the tunneled database PGPASSWORD=postgres psql -h 127.0.0.1 -p 15432 -U postgres -d flower ``` ## Database Connection **After establishing SSH connection**, connect to the database: ```bash # Connect to the database (on remote server) psql -h 127.0.0.1 -p 5432 -U postgres -d flower # Or with password in one line PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c "YOUR_QUERY" ``` **Connection Details (on remote server):** - Host: `127.0.0.1` - Port: `5432` - Database: `flower` - User: `postgres` - Password: `postgres` ## Access Rules ### ✅ Allowed Operations - **SELECT queries** on all business tables - **Data inspection** for debugging and analysis - **Aggregate queries** for reporting - **JOIN queries** across business tables ### ❌ Prohibited Operations 1. **All write operations:** - INSERT - UPDATE - DELETE - TRUNCATE - DROP - ALTER - CREATE - GRANT - REVOKE 2. **Prohibited tables (authentication/authorization):** - `auth_user` - `auth_permission` - `auth_group` - `auth_group_permissions` - `auth_user_groups` - `auth_user_user_permissions` - `django_content_type` - `django_session` - `django_admin_log` **⚠️ CRITICAL:** Never attempt to read or write to authentication-related tables. Violations will be logged and reported. ## Database Schema Overview ### Core Business Tables #### Basic Info Module (`basic_info` app) - `basic_info_merchant` - 商户(多租户) - `basic_info_customer` - 客户 - `basic_info_supplier` - 供应商 - `basic_info_employee` - 员工 - `basic_info_product` - 产品 - `basic_info_productcategory` - 产品分类 - `basic_info_warehouse` - 仓库 - `basic_info_bankaccount` - 银行账户 - `basic_info_merchantsetting` - 商户设置 #### Business Module (`business` app) - `business_purchaseorder` - 采购订单 - `business_purchaseorderitem` - 采购订单明细 - `business_salesorder` - 销售订单 - `business_salesorderitem` - 销售订单明细 - `business_purchasereturnorder` - 采购退货单 - `business_purchasereturnorderitem` - 采购退货单明细 - `business_salesreturnorder` - 销售退货单 - `business_salesreturnorderitem` - 销售退货单明细 - `business_paymentorder` - 付款单 - `business_receiptorder` - 收款单 - `business_customerbalance` - 客户余额 - `business_supplierbalance` - 供应商余额 - `business_balancechangerecord` - 余额变动记录 #### Stock Module (`stock` app) - `stock_stockchangerecord` - 库存变动记录 - `stock_stockchangedetail` - 库存变动明细 - `stock_stockfreeze` - 库存冻结记录 - `stock_inventory` - 库存汇总 #### Printing Module (`printing` app) - `printing_plateorder` - 开版订单 - `printing_printingorder` - 印染订单 - `printing_printingjob` - 印染任务明细 - `printing_printingjobbatchadvancerecord` - 批量操作记录 - `printing_plateordertiiauploadfailure` - 图片上传失败记录 #### Stateflow Module (`stateflow` app) - `stateflow_process` - 流程定义 - `stateflow_state` - 流程节点 - `stateflow_businessobject` - 业务对象(流程实例) - `stateflow_stateflowrecord` - 状态流转记录 - `stateflow_stateparameter` - 状态参数 - `stateflow_statelogparameterrecord` - 参数记录 #### Other Modules - `shipment_shipment` - 发货单 - `settlement_dailysettlement` - 日结记录 - `api_v1_mdyplateorderstaging` - 明道云开版暂存 ## Common Query Examples **Note**: All queries below assume you're either: 1. Already connected to the remote server via SSH, OR ### Quick Examples with SSH #### Method 1: Using SSH key authentication ```bash # List all tables ssh -p 18762 root@8.148.215.233 \ "PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c '\dt'" # Query with WHERE clause ssh -p 18762 root@8.148.215.233 \ "PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c 'SELECT * FROM business_salesorder LIMIT 10'" ``` #### Method: SSH with command execution ```bash # List all tables ssh -p 18762 root@8.148.215.233 "PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c '\dt'" # Query recent orders ssh -p 18762 root@8.148.215.233 "PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c 'SELECT id, customer_id, sales_date FROM business_salesorder ORDER BY created_at DESC LIMIT 10'" ``` #### List all tables in a schema ```bash ssh -p 18762 root@8.148.215.233 \ "PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c '\dt'" # Or if already in SSH session PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c "\dt" ``` #### Describe table structure ```bash ssh -p 18762 root@8.148.215.233 \ "PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c '\d business_purchaseorder'" ``` #### Query recent orders ```bash ssh -p 18762 root@8.148.215.233 \ "PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c \" SELECT id, customer_id, sales_date, status, created_at FROM business_salesorder ORDER BY created_at DESC LIMIT 10; \"" ``` ### Query with JOIN ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT so.id, so.sales_date, c.name as customer_name, so.status FROM business_salesorder so JOIN basic_info_customer c ON so.customer_id = c.id ORDER BY so.created_at DESC LIMIT 10; " ``` ### Aggregate query (statistics) ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT DATE(created_at) as date, COUNT(*) as order_count, SUM(total_amount) as total_sales FROM business_salesorder WHERE status = 2 -- APPROVED GROUP BY DATE(created_at) ORDER BY date DESC LIMIT 7; " ``` ### Search text fields (case-insensitive) ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT id, fabric, craft, customer_id FROM printing_printingorder WHERE fabric ILIKE '%棉%' OR craft ILIKE '%活性%'; " ``` ### Query inventory status ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT p.name as product_name, w.name as warehouse, si.quantity, p.unit FROM stock_inventory si JOIN basic_info_product p ON si.product_id = p.id JOIN basic_info_warehouse w ON si.warehouse_id = w.id WHERE si.quantity > 0 ORDER BY si.quantity DESC; " ``` ### Query workflow progress ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT po.id as plate_order_id, po.style_name, p.name as process_name, s.name as current_state, COUNT(sfr.id) as completed_steps FROM printing_plateorder po LEFT JOIN stateflow_businessobject bo ON bo.plate_order_id = po.id LEFT JOIN stateflow_process p ON bo.process_id = p.id LEFT JOIN stateflow_stateflowrecord sfr ON sfr.business_object_id = bo.id AND sfr.is_cancelled = false LEFT JOIN stateflow_state s ON sfr.state_id = s.id GROUP BY po.id, po.style_name, p.name, s.name ORDER BY po.created_at DESC LIMIT 10; " ``` ## Safety Guidelines ### Before Running Queries 1. **Always use SELECT** - Never use INSERT, UPDATE, DELETE, or other modifying commands 2. **Avoid prohibited tables** - Do not query authentication tables 3. **Use LIMIT** - Always add LIMIT clause to prevent large result sets 4. **Test with EXPLAIN** - For complex queries, use EXPLAIN ANALYZE to check performance ### Example with EXPLAIN ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " EXPLAIN ANALYZE SELECT * FROM business_salesorder WHERE customer_id = 1; " ``` ### Query Best Practices 1. **Use specific columns instead of \***: ```sql SELECT id, name, created_at FROM basic_info_customer; -- Instead of: SELECT * FROM basic_info_customer; ``` 2. **Add WHERE clauses to filter data**: ```sql SELECT * FROM business_salesorder WHERE created_at >= '2024-01-01' LIMIT 100; ``` 3. **Use indexes effectively**: - Most foreign keys have indexes - `created_at`, `updated_at` are commonly indexed - Check with `\d table_name` to see indexes 4. **Avoid expensive operations on large tables**: - Be careful with `LIKE '%text%'` patterns (cannot use indexes) - Use `ILIKE` for case-insensitive matching - Consider using `LIMIT` with text searches ## Useful psql Commands ```bash # List all databases PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -c "\l" # List all tables in current database PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c "\dt" # List all schemas PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c "\dn" # Describe table structure PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c "\d table_name" # List indexes on a table PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c "\di table_name" # View table size PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size FROM pg_tables WHERE schemaname = 'public' ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC; " # Exit psql \q ``` ## Multi-Tenant Considerations **IMPORTANT:** This is a multi-tenant system. All business tables have a `merchant_id` column. ### Always include merchant_id in queries ```sql -- Good: Filter by merchant SELECT * FROM business_salesorder WHERE merchant_id = 1 ORDER BY created_at DESC LIMIT 10; -- Bad: Cross-tenant query SELECT * FROM business_salesorder LIMIT 10; ``` ### Check merchant context ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT id, name, type FROM basic_info_merchant; " ``` ## Common Use Cases ### 1. Debug Order Issues ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT o.*, c.name as customer_name FROM business_salesorder o JOIN basic_info_customer c ON o.customer_id = c.id WHERE o.id = 123; " ``` ### 2. Check Inventory Levels ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT p.name, w.name as warehouse, ss.quantity, ss.unit FROM stock_stocksummary ss JOIN basic_info_product p ON ss.product_id = p.id JOIN basic_info_warehouse w ON ss.warehouse_id = w.id WHERE ss.merchant_id = 1 AND ss.quantity < 100 ORDER BY ss.quantity ASC; " ``` ### 3. Analyze Sales Trends ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT DATE_TRUNC('week', sales_date) as week, COUNT(*) as orders, SUM( (SELECT SUM(quantity * price) FROM business_salesorderitem WHERE sales_order_id = business_salesorder.id) ) as revenue FROM business_salesorder WHERE merchant_id = 1 AND status = 2 -- APPROVED AND sales_date >= CURRENT_DATE - INTERVAL '4 weeks' GROUP BY DATE_TRUNC('week', sales_date) ORDER BY week DESC; " ``` ### 4. Track Printing Job Progress ```bash PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " SELECT po.human_id, po.fabric, COUNT(pj.id) as job_count, SUM(CASE WHEN pj.business_object_id IS NOT NULL THEN 1 ELSE 0 END) as started_jobs FROM printing_printingorder po LEFT JOIN printing_printingjob pj ON pj.printing_order_id = po.id WHERE po.merchant_id = 1 AND po.is_invalid = false GROUP BY po.id, po.human_id, po.fabric ORDER BY po.created_at DESC LIMIT 20; " ``` ## Troubleshooting ### Connection refused ```bash # Check if PostgreSQL is running sudo systemctl status postgresql # Or check process ps aux | grep postgres ``` ### Permission denied ```bash # Check database permissions PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c "\du" ``` ### Query too slow ```bash # Use EXPLAIN to analyze PGPASSWORD=postgres psql -h 127.0.0.1 -p 5432 -U postgres -d flower -c " EXPLAIN (ANALYZE, BUFFERS) YOUR_QUERY_HERE; " ``` ## Emergency Contacts If you encounter any issues or accidentally attempt a write operation: 1. **STOP** - Do not proceed with the operation 2. **REPORT** - Document what happened 3. **CONTACT** - Notify system administrator immediately --- **Remember:** This skill provides READ-ONLY access for a reason. The integrity of business data is critical. When in doubt, ask for clarification rather than risk data corruption.