1 line
23 KiB
JSON
1 line
23 KiB
JSON
{"projectName":"OAFlow","domain":"enterprise","contract":{"projectName":"OAFlow","domain":"enterprise","entities":[{"name":"User","table":"users","description":"系统用户","fields":[{"name":"id","type":"UUID","isPrimary":true,"isAuto":true},{"name":"username","type":"VARCHAR(128)","required":true,"unique":true,"validation":{"minLength":2,"maxLength":50}},{"name":"password_hash","type":"VARCHAR(256)","required":true,"isSecret":true},{"name":"nickname","type":"VARCHAR(128)"},{"name":"role","type":"VARCHAR(32)","defaultValue":"user","enum":["user","admin"]},{"name":"phone","type":"VARCHAR(20)"},{"name":"avatar_url","type":"TEXT"},{"name":"created_at","type":"TIMESTAMP","isAuto":true},{"name":"updated_at","type":"TIMESTAMP","isAuto":true}],"relationships":[{"type":"hasMany","entity":"contracts","via":"user_id"},{"type":"hasMany","entity":"customers","via":"user_id"}]},{"name":"Contract","table":"contracts","description":"合同","fields":[{"name":"id","type":"UUID","isPrimary":true,"isAuto":true},{"name":"user_id","type":"UUID","required":true,"fkEntity":"users","fkColumn":"id"},{"name":"title","type":"VARCHAR(256)","required":true},{"name":"party_a","type":"VARCHAR(128)"},{"name":"party_b","type":"VARCHAR(128)"},{"name":"amount","type":"DECIMAL(14,2)"},{"name":"signed_at","type":"DATE"},{"name":"expires_at","type":"DATE"},{"name":"status","type":"VARCHAR(32)","defaultValue":"draft","enum":["draft","pending","active","expired","terminated"]},{"name":"file_url","type":"TEXT"},{"name":"created_at","type":"TIMESTAMP","isAuto":true},{"name":"updated_at","type":"TIMESTAMP","isAuto":true}],"relationships":[{"type":"belongsTo","entity":"users","via":"user_id"}]},{"name":"Approval","table":"approvals","description":"审批流程","fields":[{"name":"id","type":"UUID","isPrimary":true,"isAuto":true},{"name":"user_id","type":"UUID","required":true,"fkEntity":"users","fkColumn":"id"},{"name":"entity_type","type":"VARCHAR(32)","required":true},{"name":"entity_id","type":"UUID"},{"name":"applicant_id","type":"UUID","required":true,"fkEntity":"users","fkColumn":"id"},{"name":"status","type":"VARCHAR(32)","defaultValue":"pending","enum":["pending","approved","rejected"]},{"name":"form_data","type":"JSONB"},{"name":"created_at","type":"TIMESTAMP","isAuto":true},{"name":"updated_at","type":"TIMESTAMP","isAuto":true}],"relationships":[{"type":"belongsTo","entity":"users","via":"user_id"},{"type":"belongsTo","entity":"users","via":"applicant_id","as":"applicant"}]},{"name":"Customer","table":"customers","description":"客户","fields":[{"name":"id","type":"UUID","isPrimary":true,"isAuto":true},{"name":"user_id","type":"UUID","required":true,"fkEntity":"users","fkColumn":"id"},{"name":"name","type":"VARCHAR(128)","required":true},{"name":"email","type":"VARCHAR(256)"},{"name":"phone","type":"VARCHAR(20)"},{"name":"company","type":"VARCHAR(128)"},{"name":"source","type":"VARCHAR(64)"},{"name":"tags","type":"JSONB","defaultValue":"[]"},{"name":"created_at","type":"TIMESTAMP","isAuto":true},{"name":"updated_at","type":"TIMESTAMP","isAuto":true}],"relationships":[{"type":"belongsTo","entity":"users","via":"user_id"}]},{"name":"Reminder","table":"reminders","description":"到期提醒","fields":[{"name":"id","type":"UUID","isPrimary":true,"isAuto":true},{"name":"user_id","type":"UUID","required":true,"fkEntity":"users","fkColumn":"id"},{"name":"entity_type","type":"VARCHAR(32)","required":true},{"name":"entity_id","type":"UUID"},{"name":"remind_at","type":"TIMESTAMP","required":true},{"name":"message","type":"TEXT"},{"name":"sent","type":"BOOLEAN","defaultValue":"false"},{"name":"created_at","type":"TIMESTAMP","isAuto":true},{"name":"updated_at","type":"TIMESTAMP","isAuto":true}],"relationships":[{"type":"belongsTo","entity":"users","via":"user_id"}]},{"name":"Stats","table":"stats","description":"合同金额统计表","fields":[{"name":"id","type":"UUID","required":true,"isPrimary":true,"isAuto":true},{"name":"user_id","type":"UUID","required":false,"isPrimary":false,"isAuto":false,"fkEntity":"users","fkColumn":"id"},{"name":"metric","type":"VARCHAR(64)","required":true,"isPrimary":false,"isAuto":false},{"name":"value","type":"DECIMAL(12,2)","required":false,"isPrimary":false,"isAuto":false},{"name":"period","type":"VARCHAR(32)","required":false,"isPrimary":false,"isAuto":false},{"name":"recorded_at","type":"TIMESTAMPTZ","required":false,"isPrimary":false,"isAuto":true},{"name":"created_at","type":"TIMESTAMPTZ","required":false,"isPrimary":false,"isAuto":true},{"name":"updated_at","type":"TIMESTAMPTZ","required":false,"isPrimary":false,"isAuto":true}],"relationships":[{"type":"belongsTo","entity":"users","via":"user_id"}]},{"name":"OperationLogs","table":"operation_logs","description":"操作日志表","fields":[{"name":"id","type":"UUID","required":true,"isPrimary":true,"isAuto":true},{"name":"user_id","type":"UUID","required":false,"isPrimary":false,"isAuto":false,"fkEntity":"users","fkColumn":"id"},{"name":"title","type":"VARCHAR(256)","required":true,"isPrimary":false,"isAuto":false},{"name":"description","type":"TEXT","required":false,"isPrimary":false,"isAuto":false},{"name":"status","type":"VARCHAR(32)","required":false,"isPrimary":false,"isAuto":true},{"name":"data","type":"JSONB","required":false,"isPrimary":false,"isAuto":false},{"name":"created_at","type":"TIMESTAMPTZ","required":false,"isPrimary":false,"isAuto":true},{"name":"updated_at","type":"TIMESTAMPTZ","required":false,"isPrimary":false,"isAuto":true}],"relationships":[{"type":"belongsTo","entity":"users","via":"user_id"}]}],"auth":{"registrationFields":["username","password","nickname"],"loginFields":["username","password"],"jwtPayload":["userId","username","role"],"passwordPolicy":{"minLength":8,"requireSpecial":true}},"permissions":[{"role":"admin","allow":["*"]},{"role":"user","allow":["read:own","create:*","update:own","delete:own"]}],"fieldMapping":{"snakeToCamel":{"created_at":"createdAt","updated_at":"updatedAt","user_id":"userId","password_hash":"passwordHash","avatar_url":"avatarUrl","party_a":"partyA","party_b":"partyB","signed_at":"signedAt","expires_at":"expiresAt","file_url":"fileUrl","entity_type":"entityType","entity_id":"entityId","applicant_id":"applicantId","form_data":"formData","remind_at":"remindAt","recorded_at":"recordedAt","id":"id","username":"username","nickname":"nickname","role":"role","phone":"phone","title":"title","description":"description","status":"status","data":"data","amount":"amount","name":"name","email":"email","company":"company","source":"source","tags":"tags","breed":"breed","species":"species","birth_date":"birthDate","weight_kg":"weightKg","price":"price","stock":"stock","images":"images","total_amount":"totalAmount","address_id":"addressId","message":"message","sent":"sent"},"camelToSnake":{"createdAt":"created_at","updatedAt":"updated_at","userId":"user_id","passwordHash":"password_hash","avatarUrl":"avatar_url","partyA":"party_a","partyB":"party_b","signedAt":"signed_at","expiresAt":"expires_at","fileUrl":"file_url","entityType":"entity_type","entityId":"entity_id","applicantId":"applicant_id","formData":"form_data","remindAt":"remind_at","recordedAt":"recorded_at","id":"id","username":"username","nickname":"nickname","role":"role","phone":"phone","title":"title","description":"description","status":"status","data":"data","amount":"amount","name":"name","email":"email","company":"company","source":"source","tags":"tags","breed":"breed","species":"species","birthDate":"birth_date","weightKg":"weight_kg","price":"price","stock":"stock","images":"images","totalAmount":"total_amount","addressId":"address_id","message":"message","sent":"sent"}},"validation":{"User":{"username":{"minLength":2,"maxLength":50,"required":true,"unique":true},"password_hash":{"required":true},"role":{"enum":["user","admin"],"defaultValue":"user"}},"Contract":{"user_id":{"required":true},"title":{"required":true},"status":{"enum":["draft","pending","active","expired","terminated"],"defaultValue":"draft"}},"Approval":{"user_id":{"required":true},"entity_type":{"required":true},"applicant_id":{"required":true},"status":{"enum":["pending","approved","rejected"],"defaultValue":"pending"}},"Customer":{"user_id":{"required":true},"name":{"required":true},"tags":{"defaultValue":"[]"}},"Reminder":{"user_id":{"required":true},"entity_type":{"required":true},"remind_at":{"required":true},"sent":{"defaultValue":"false"}},"Stats":{"id":{"required":true},"metric":{"required":true}},"OperationLogs":{"id":{"required":true},"title":{"required":true}}}},"techStack":{"frontend":"React 19 + TypeScript + Vite","backend":"NestJS + Prisma","database":"PostgreSQL 15 + Redis 7","deployment":"Docker + Nginx","considerations":[]},"architectureDiagram":"┌─────────────────────────────────────────────────────────┐\n│ OAFlow — System Architecture │\n├─────────────────────────────────────────────────────────┤\n│ │\n│ ┌──────────────────────┐ ┌──────────────────────┐ │\n│ │ Client Layer │ │ Admin / Web │ │\n│ │ React 19 + TypeScript + Vite │ │ React + Vite (Web) │ │\n│ └──────────┬───────────┘ └──────────┬───────────┘ │\n│ │ │ │\n│ └──────────┬────────────────┘ │\n│ │ │\n│ ┌─────────▼──────────┐ │\n│ │ API Gateway │ │\n│ │ Nginx / Kong │ │\n│ └─────────┬──────────┘ │\n│ │ │\n│ ┌─────────▼──────────┐ │\n│ │ Backend Services │ │\n│ │ NestJS + Prisma │ │\n│ └─────────┬──────────┘ │\n│ │ │\n│ ┌───────────────┼───────────────┐ │\n│ │ │ │ │\n│ ┌─────▼─────┐ ┌──────▼──────┐ ┌────▼─────┐ │\n│ │ PostgreSQL 15│ │ Redis Cache │ │ MinIO │ │\n│ │ Primary │ │ Session │ │ Files │ │\n│ └───────────┘ └─────────────┘ └──────────┘ │\n│ │\n├─────────────────────────────────────────────────────────┤\n│ Modules: │\n│ 1 合同创建 │\n│ 2 Workflow │\n│ 3 Notification │\n│ 4 客户管理 │\n│ 5 Analytics │\n│ 6 操作日志 │\n│ │\n└─────────────────────────────────────────────────────────┘","dataFlows":[{"page":"合同创建","route":"/contracts","description":"合同创建","dataFlow":["GET /api/contracts → 获取合同创建列表","POST /api/contracts → 创建合同创建"],"direction":"Client → API Gateway → Backend → Database → Response → Client"},{"page":"合同审批","route":"/approvals","description":"合同审批","dataFlow":["GET /api/approvals → 获取合同审批列表","POST /api/approvals → 创建合同审批"],"direction":"Client → API Gateway → Backend → Database → Response → Client"},{"page":"合同到期提醒","route":"/reminders","description":"合同到期提醒","dataFlow":["GET /api/reminders → 获取合同到期提醒列表","POST /api/reminders → 创建合同到期提醒"],"direction":"Client → API Gateway → Backend → Database → Response → Client"},{"page":"客户管理","route":"/customers","description":"客户管理","dataFlow":["GET /api/customers → 获取客户管理列表","POST /api/customers → 创建客户管理"],"direction":"Client → API Gateway → Backend → Database → Response → Client"}],"modules":[{"name":"合同创建","label":"合同创建","features":["合同创建"],"responsibilities":["提供 合同创建 相关功能"]},{"name":"workflow","label":"Workflow","features":["合同审批"],"responsibilities":["提供 合同审批 相关功能"]},{"name":"notification","label":"Notification","features":["合同到期提醒"],"responsibilities":["提供 合同到期提醒 相关功能"]},{"name":"客户管理","label":"客户管理","features":["客户管理"],"responsibilities":["提供 客户管理 相关功能"]},{"name":"analytics","label":"Analytics","features":["合同金额统计"],"responsibilities":["提供 合同金额统计 相关功能"]},{"name":"操作日志","label":"操作日志","features":["操作日志"],"responsibilities":["提供 操作日志 相关功能"]},{"name":"approval","label":"审批引擎","features":["审批流程"],"responsibilities":["提供 审批流程 相关功能"]},{"name":"attendance","label":"考勤管理","features":["考勤打卡"],"responsibilities":["提供 考勤打卡 相关功能"]},{"name":"department","label":"组织架构","features":["部门管理"],"responsibilities":["提供 部门管理 相关功能"]}],"databaseSchema":[{"table":"users","description":"用户表","fields":[{"name":"id","type":"UUID","constraints":"PK, DEFAULT gen_random_uuid()"},{"name":"phone","type":"VARCHAR(20)","constraints":"UNIQUE"},{"name":"nickname","type":"VARCHAR(64)"},{"name":"avatar_url","type":"TEXT"},{"name":"created_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"},{"name":"updated_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"}],"indexes":["idx_users_phone ON users(phone)"]},{"table":"contracts","description":"合同创建表","fields":[{"name":"id","type":"UUID","constraints":"PK, DEFAULT gen_random_uuid()"},{"name":"user_id","type":"UUID","constraints":"FK → users.id"},{"name":"title","type":"VARCHAR(256)","constraints":"NOT NULL"},{"name":"party_a","type":"VARCHAR(128)"},{"name":"party_b","type":"VARCHAR(128)"},{"name":"amount","type":"DECIMAL(14,2)"},{"name":"signed_at","type":"DATE"},{"name":"expires_at","type":"DATE"},{"name":"status","type":"VARCHAR(32)","constraints":"DEFAULT 'draft'"},{"name":"file_url","type":"TEXT"},{"name":"created_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"},{"name":"updated_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"}],"indexes":["idx_contracts_user ON contracts(user_id)"]},{"table":"approvals","description":"合同审批表","fields":[{"name":"id","type":"UUID","constraints":"PK, DEFAULT gen_random_uuid()"},{"name":"user_id","type":"UUID","constraints":"FK → users.id"},{"name":"title","type":"VARCHAR(256)","constraints":"NOT NULL"},{"name":"party_a","type":"VARCHAR(128)"},{"name":"party_b","type":"VARCHAR(128)"},{"name":"amount","type":"DECIMAL(14,2)"},{"name":"signed_at","type":"DATE"},{"name":"expires_at","type":"DATE"},{"name":"status","type":"VARCHAR(32)","constraints":"DEFAULT 'draft'"},{"name":"file_url","type":"TEXT"},{"name":"created_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"},{"name":"updated_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"}],"indexes":["idx_approvals_user ON approvals(user_id)"]},{"table":"reminders","description":"合同到期提醒表","fields":[{"name":"id","type":"UUID","constraints":"PK, DEFAULT gen_random_uuid()"},{"name":"user_id","type":"UUID","constraints":"FK → users.id"},{"name":"title","type":"VARCHAR(256)","constraints":"NOT NULL"},{"name":"party_a","type":"VARCHAR(128)"},{"name":"party_b","type":"VARCHAR(128)"},{"name":"amount","type":"DECIMAL(14,2)"},{"name":"signed_at","type":"DATE"},{"name":"expires_at","type":"DATE"},{"name":"status","type":"VARCHAR(32)","constraints":"DEFAULT 'draft'"},{"name":"file_url","type":"TEXT"},{"name":"created_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"},{"name":"updated_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"}],"indexes":["idx_reminders_user ON reminders(user_id)"]},{"table":"customers","description":"客户管理表","fields":[{"name":"id","type":"UUID","constraints":"PK, DEFAULT gen_random_uuid()"},{"name":"user_id","type":"UUID","constraints":"FK → users.id"},{"name":"name","type":"VARCHAR(128)","constraints":"NOT NULL"},{"name":"email","type":"VARCHAR(256)"},{"name":"phone","type":"VARCHAR(20)"},{"name":"company","type":"VARCHAR(128)"},{"name":"source","type":"VARCHAR(64)"},{"name":"tags","type":"JSONB","constraints":"DEFAULT '[]'"},{"name":"created_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"},{"name":"updated_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"}],"indexes":["idx_customers_user ON customers(user_id)"]},{"table":"stats","description":"合同金额统计表","fields":[{"name":"id","type":"UUID","constraints":"PK, DEFAULT gen_random_uuid()"},{"name":"user_id","type":"UUID","constraints":"FK → users.id"},{"name":"metric","type":"VARCHAR(64)","constraints":"NOT NULL"},{"name":"value","type":"DECIMAL(12,2)"},{"name":"period","type":"VARCHAR(32)"},{"name":"recorded_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"},{"name":"created_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"},{"name":"updated_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"}],"indexes":["idx_stats_user ON stats(user_id)"]},{"table":"operation_logs","description":"操作日志表","fields":[{"name":"id","type":"UUID","constraints":"PK, DEFAULT gen_random_uuid()"},{"name":"user_id","type":"UUID","constraints":"FK → users.id"},{"name":"title","type":"VARCHAR(256)","constraints":"NOT NULL"},{"name":"description","type":"TEXT"},{"name":"status","type":"VARCHAR(32)","constraints":"DEFAULT 'active'"},{"name":"data","type":"JSONB"},{"name":"created_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"},{"name":"updated_at","type":"TIMESTAMPTZ","constraints":"DEFAULT NOW()"}],"indexes":["idx_operation_logs_user ON operation_logs(user_id)"]}],"apiDesign":[{"resource":"approvals","basePath":"/api/approvals","endpoints":[{"method":"GET","path":"/api/approvals","description":"获取合同审批列表"},{"method":"POST","path":"/api/approvals","description":"创建合同审批"}]},{"resource":"auth","basePath":"/api/auth","endpoints":[{"method":"POST","path":"/api/auth/login","description":"用户登录"},{"method":"GET","path":"/api/auth/me","description":"获取当前用户"}]},{"resource":"contracts","basePath":"/api/contracts","endpoints":[{"method":"GET","path":"/api/contracts","description":"获取合同创建列表"},{"method":"POST","path":"/api/contracts","description":"创建合同创建"}]},{"resource":"customers","basePath":"/api/customers","endpoints":[{"method":"GET","path":"/api/customers","description":"获取客户管理列表"},{"method":"POST","path":"/api/customers","description":"创建客户管理"}]},{"resource":"reminders","basePath":"/api/reminders","endpoints":[{"method":"GET","path":"/api/reminders","description":"获取合同到期提醒列表"},{"method":"POST","path":"/api/reminders","description":"创建合同到期提醒"}]}],"directoryStructure":["oaflow/","├── apps/","│ ├── mobile/ # React Native / Flutter 移动端","│ │ ├── src/","│ │ │ ├── screens/ # 页面组件","│ │ │ │ ├── 合同创建/","│ │ │ │ ├── workflow/","│ │ │ │ ├── notification/","│ │ │ │ ├── 客户管理/","│ │ │ ├── components/ # 通用组件","│ │ │ ├── hooks/ # 自定义 Hooks","│ │ │ ├── services/ # API 调用层","│ │ │ ├── store/ # 状态管理","│ │ │ └── utils/ # 工具函数","│ │ ├── app.json","│ │ └── package.json","│ └── web/ # Web 管理后台","│ ├── src/","│ │ ├── pages/","│ │ ├── components/","│ │ └── layouts/","│ └── package.json","├── packages/","│ └── shared/ # 共享类型/常量","├── server/ # NestJS 后端服务","│ ├── src/","│ │ ├── modules/ # 业务模块","│ │ │ ├── 合同创建/","│ │ │ │ ├── 合同创建.controller.ts","│ │ │ │ ├── 合同创建.service.ts","│ │ │ │ ├── 合同创建.module.ts","│ │ │ │ └── dto/","│ │ │ ├── workflow/","│ │ │ │ ├── workflow.controller.ts","│ │ │ │ ├── workflow.service.ts","│ │ │ │ ├── workflow.module.ts","│ │ │ │ └── dto/","│ │ │ ├── notification/","│ │ │ │ ├── notification.controller.ts","│ │ │ │ ├── notification.service.ts","│ │ │ │ ├── notification.module.ts","│ │ │ │ └── dto/","│ │ │ ├── 客户管理/","│ │ │ │ ├── 客户管理.controller.ts","│ │ │ │ ├── 客户管理.service.ts","│ │ │ │ ├── 客户管理.module.ts","│ │ │ │ └── dto/","│ │ │ ├── analytics/","│ │ │ │ ├── analytics.controller.ts","│ │ │ │ ├── analytics.service.ts","│ │ │ │ ├── analytics.module.ts","│ │ │ │ └── dto/","│ │ ├── common/ # 通用(guards, filters, interceptors)","│ │ ├── prisma/ # Prisma ORM","│ │ │ └── schema.prisma","│ │ ├── config/ # 环境配置","│ │ └── main.ts","│ ├── test/","│ ├── Dockerfile","│ └── package.json","├── docker-compose.yml","├── .github/workflows/ # CI/CD","│ └── ci.yml","├── .env.example","├── README.md","└── turbo.json # Monorepo 配置"],"deployment":{"environments":["development","staging","production"],"strategy":"Docker + Nginx","services":["API Server (NestJS)","PostgreSQL 15","Redis 7"],"ci":"GitHub Actions → Build → Test → Deploy"},"meta":{"generatedAt":"2026-06-05T13:43:26.925Z","sourceDomain":"enterprise","moduleCount":9,"tableCount":7,"apiEndpointCount":10}} |