| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- /**
- * 导出 QiWe 项目相关的所有表 Schema(供文档编写用)
- *
- * 用法: cd backend && npx tsx scripts/dump-qiwe-schema.ts
- */
- import 'dotenv/config';
- import Parse from '../src/db/parse-client.js';
- async function showTable(className: string): Promise<void> {
- const q = new Parse.Query(className);
- q.limit(1);
- q.descending('updatedAt');
- let rows: Parse.Object[] = [];
- try { rows = await q.find({ useMasterKey: true }); } catch { /* skip */ }
- let schema: Parse.Schema;
- try {
- schema = await new Parse.Schema(className).get({ useMasterKey: true });
- } catch (err: any) {
- console.log(`\n📦 ${className} — 表不存在 (${err.message})`);
- return;
- }
- const fields = schema.fields as Record<string, { type: string; targetClass?: string }>;
- const entries = Object.entries(fields)
- .filter(([n]) => !n.startsWith('_') && n !== 'ACL')
- .sort(([a], [b]) => a.localeCompare(b));
- const hasData = rows.length > 0;
- console.log(`\n📦 ${className}${hasData ? ' (有数据)' : ' (空)'}`);
- console.log('-'.repeat(65));
- for (const [name, def] of entries) {
- const typeStr = def.type === 'Pointer' ? `Pointer → ${def.targetClass || '?'}` : def.type;
- console.log(` ${name.padEnd(30)} ${typeStr}`);
- }
- if (hasData) {
- console.log('\n 示例字段值:');
- const r = rows[0] as any;
- for (const [name] of entries.slice(0, 12)) {
- const v = r.get(name);
- if (v === undefined || v === null || v === '') continue;
- let s: string;
- if (typeof v === 'object') {
- if (v.className) {
- s = `Pointer(${v.className}:${v.id?.slice(0, 8)}...)`;
- } else {
- s = JSON.stringify(v).substring(0, 100);
- }
- } else {
- s = String(v).substring(0, 100);
- }
- console.log(` ${name.padEnd(28)} ${s}`);
- }
- }
- }
- async function main(): Promise<void> {
- console.log('=== QiWe 项目数据库 Schema 完整导出 ===');
- console.log(`Server: ${Parse.serverURL}`);
- console.log(`App ID: ${Parse.applicationId}\n`);
- // 测试连接
- try {
- const n = await new Parse.Query('_User').count({ useMasterKey: true });
- console.log(`✅ Parse 连接正常 (_User: ${n} 条)\n`);
- } catch (err: any) {
- console.error('❌ Parse 连接失败:', err.message);
- process.exit(1);
- }
- // QiWe 核心表
- const qiweTables = [
- 'GroupChat', 'GroupMember', 'Message', 'MessageSyncCursor',
- 'WebhookLog', 'Contact',
- ];
- // 风控相关表
- const riskTables = [
- 'RiskEvent', 'RiskKeyword', 'AppNotification', 'ResponsibilityAssignment',
- ];
- // 组织结构表
- const orgTables = [
- 'Store', 'District', 'Community',
- ];
- // 其他
- const otherTables = [
- '_User', 'QiWeAccount',
- ];
- console.log('══════ QiWe 核心表 ══════');
- for (const t of qiweTables) await showTable(t);
- console.log('\n══════ 风控系统表 ══════');
- for (const t of riskTables) await showTable(t);
- console.log('\n══════ 组织结构表 ══════');
- for (const t of orgTables) await showTable(t);
- console.log('\n══════ 其他 ══════');
- for (const t of otherTables) await showTable(t);
- console.log('\n\n✅ 导出完成!\n');
- }
- main().catch((err) => {
- console.error('失败:', err.message);
- process.exit(1);
- });
|