chore: prepare project for server deployment
This commit is contained in:
@@ -0,0 +1,548 @@
|
||||
/**
|
||||
* 数据模型验证脚本
|
||||
* 验证P0系统微调后的数据模型一致性
|
||||
*/
|
||||
|
||||
const { getDb, closeDb } = require('../src/config/database');
|
||||
const { migrate } = require('../src/database/migrate');
|
||||
const Entity = require('../src/models/Entity');
|
||||
const Content = require('../src/models/Content');
|
||||
const Page = require('../src/models/Page');
|
||||
const Article = require('../src/models/Article');
|
||||
const Case = require('../src/models/Case');
|
||||
const FAQ = require('../src/models/FAQ');
|
||||
const Capability = require('../src/models/Capability');
|
||||
const Service = require('../src/models/Service');
|
||||
const DirectedRelationship = require('../src/models/DirectedRelationship');
|
||||
const EntityContentJoin = require('../src/models/EntityContentJoin');
|
||||
|
||||
// 测试结果
|
||||
const results = {
|
||||
entity: { passed: 0, failed: 0, details: [] },
|
||||
page: { passed: 0, failed: 0, details: [] },
|
||||
article: { passed: 0, failed: 0, details: [] },
|
||||
case: { passed: 0, failed: 0, details: [] },
|
||||
faq: { passed: 0, failed: 0, details: [] },
|
||||
capability: { passed: 0, failed: 0, details: [] },
|
||||
service: { passed: 0, failed: 0, details: [] },
|
||||
relation: { passed: 0, failed: 0, details: [] },
|
||||
join: { passed: 0, failed: 0, details: [] },
|
||||
lifecycle: { passed: 0, failed: 0, details: [] },
|
||||
authority: { passed: 0, failed: 0, details: [] },
|
||||
};
|
||||
|
||||
/**
|
||||
* 验证Entity模型
|
||||
*/
|
||||
function verifyEntity() {
|
||||
console.log('\n=== 验证Entity模型 ===');
|
||||
|
||||
// 测试创建Entity
|
||||
try {
|
||||
const entity = Entity.create({
|
||||
entity_type: 'concept',
|
||||
name: '测试实体',
|
||||
definition: '测试定义',
|
||||
description: '测试描述',
|
||||
status: 'active',
|
||||
public_flag: 1,
|
||||
authority_level: 2,
|
||||
});
|
||||
|
||||
if (entity.entity_id && entity.entity_type === 'concept' && entity.status === 'active' && entity.public_flag === 1) {
|
||||
results.entity.passed++;
|
||||
results.entity.details.push('Entity创建成功,新字段正确');
|
||||
} else {
|
||||
results.entity.failed++;
|
||||
results.entity.details.push('Entity创建失败:新字段不正确');
|
||||
}
|
||||
|
||||
// 测试读取Entity
|
||||
const foundEntity = Entity.findById(entity.entity_id);
|
||||
if (foundEntity && foundEntity.entity_type === 'concept' && foundEntity.status === 'active') {
|
||||
results.entity.passed++;
|
||||
results.entity.details.push('Entity读取成功,新字段正确');
|
||||
} else {
|
||||
results.entity.failed++;
|
||||
results.entity.details.push('Entity读取失败:新字段不正确');
|
||||
}
|
||||
|
||||
// 测试更新Entity
|
||||
const updatedEntity = Entity.update(entity.entity_id, {
|
||||
entity_type: 'method',
|
||||
status: 'inactive',
|
||||
public_flag: 0,
|
||||
});
|
||||
|
||||
if (updatedEntity.entity_type === 'method' && updatedEntity.status === 'inactive' && updatedEntity.public_flag === 0) {
|
||||
results.entity.passed++;
|
||||
results.entity.details.push('Entity更新成功,新字段正确');
|
||||
} else {
|
||||
results.entity.failed++;
|
||||
results.entity.details.push('Entity更新失败:新字段不正确');
|
||||
}
|
||||
|
||||
// 清理测试数据
|
||||
Entity.delete(entity.entity_id);
|
||||
|
||||
} catch (error) {
|
||||
results.entity.failed++;
|
||||
results.entity.details.push(`Entity测试失败: ${error.message}`);
|
||||
}
|
||||
|
||||
console.log(`Entity: ${results.entity.passed} passed, ${results.entity.failed} failed`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证Page模型
|
||||
*/
|
||||
function verifyPage() {
|
||||
console.log('\n=== 验证Page模型 ===');
|
||||
|
||||
try {
|
||||
// 测试创建Page
|
||||
const page = Page.create({
|
||||
title: '测试页面',
|
||||
body: '测试内容',
|
||||
slug: 'test-page',
|
||||
summary: '测试摘要',
|
||||
seo_title: '测试SEO标题',
|
||||
seo_description: '测试SEO描述',
|
||||
});
|
||||
|
||||
if (page.page_id && page.summary === '测试摘要') {
|
||||
results.page.passed++;
|
||||
results.page.details.push('Page创建成功,summary字段正确');
|
||||
} else {
|
||||
results.page.failed++;
|
||||
results.page.details.push('Page创建失败:summary字段不正确');
|
||||
}
|
||||
|
||||
// 测试读取Page
|
||||
const foundPage = Page.findById(page.page_id);
|
||||
if (foundPage && foundPage.summary === '测试摘要') {
|
||||
results.page.passed++;
|
||||
results.page.details.push('Page读取成功,summary字段正确');
|
||||
} else {
|
||||
results.page.failed++;
|
||||
results.page.details.push('Page读取失败:summary字段不正确');
|
||||
}
|
||||
|
||||
// 清理测试数据
|
||||
Content.delete(page.page_id);
|
||||
|
||||
} catch (error) {
|
||||
results.page.failed++;
|
||||
results.page.details.push(`Page测试失败: ${error.message}`);
|
||||
}
|
||||
|
||||
console.log(`Page: ${results.page.passed} passed, ${results.page.failed} failed`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证Article模型
|
||||
*/
|
||||
function verifyArticle() {
|
||||
console.log('\n=== 验证Article模型 ===');
|
||||
|
||||
try {
|
||||
// 测试创建Article
|
||||
const article = Article.create({
|
||||
title: '测试文章',
|
||||
body: '测试内容',
|
||||
category: '测试分类',
|
||||
author: '测试作者',
|
||||
published_at: '2026-09-08T00:00:00.000Z',
|
||||
});
|
||||
|
||||
if (article.article_id && article.published_at === '2026-09-08T00:00:00.000Z') {
|
||||
results.article.passed++;
|
||||
results.article.details.push('Article创建成功,published_at字段正确');
|
||||
} else {
|
||||
results.article.failed++;
|
||||
results.article.details.push('Article创建失败:published_at字段不正确');
|
||||
}
|
||||
|
||||
// 测试读取Article
|
||||
const foundArticle = Article.findById(article.article_id);
|
||||
if (foundArticle && foundArticle.published_at === '2026-09-08T00:00:00.000Z') {
|
||||
results.article.passed++;
|
||||
results.article.details.push('Article读取成功,published_at字段正确');
|
||||
} else {
|
||||
results.article.failed++;
|
||||
results.article.details.push('Article读取失败:published_at字段不正确');
|
||||
}
|
||||
|
||||
// 清理测试数据
|
||||
Content.delete(article.article_id);
|
||||
|
||||
} catch (error) {
|
||||
results.article.failed++;
|
||||
results.article.details.push(`Article测试失败: ${error.message}`);
|
||||
}
|
||||
|
||||
console.log(`Article: ${results.article.passed} passed, ${results.article.failed} failed`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证Case模型(P0-01扩展字段)
|
||||
*/
|
||||
function verifyCase() {
|
||||
console.log('\n=== 验证Case模型(P0-01扩展字段)===');
|
||||
|
||||
try {
|
||||
// 测试创建Case
|
||||
const caseData = Case.create({
|
||||
title: '测试案例',
|
||||
body: '测试内容',
|
||||
client_name: '测试客户',
|
||||
industry: '测试行业',
|
||||
background: '测试企业背景',
|
||||
enterprise_stage: 'A态',
|
||||
original_goal: '测试原始目标',
|
||||
current_state: '测试当前状态',
|
||||
surface_problem: '测试表面问题',
|
||||
amb_judgment: '测试阿美巴判断',
|
||||
key_obstacle: '测试关键障碍',
|
||||
root_cause: '测试根因',
|
||||
evolution_path: '测试进化路径',
|
||||
implementation: '测试实施过程',
|
||||
result: '测试结果',
|
||||
case_significance: '测试案例意义',
|
||||
});
|
||||
|
||||
// 验证所有新字段
|
||||
const expectedValues = {
|
||||
background: '测试企业背景',
|
||||
enterprise_stage: 'A态',
|
||||
original_goal: '测试原始目标',
|
||||
current_state: '测试当前状态',
|
||||
surface_problem: '测试表面问题',
|
||||
amb_judgment: '测试阿美巴判断',
|
||||
key_obstacle: '测试关键障碍',
|
||||
root_cause: '测试根因',
|
||||
evolution_path: '测试进化路径',
|
||||
implementation: '测试实施过程',
|
||||
case_significance: '测试案例意义',
|
||||
};
|
||||
|
||||
let allFieldsCorrect = true;
|
||||
for (const [field, expected] of Object.entries(expectedValues)) {
|
||||
if (caseData[field] !== expected) {
|
||||
allFieldsCorrect = false;
|
||||
console.log(`字段 ${field} 不正确: 期望 "${expected}", 实际 "${caseData[field]}"`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (caseData.case_id && allFieldsCorrect) {
|
||||
results.case.passed++;
|
||||
results.case.details.push('Case创建成功,所有P0-01扩展字段正确');
|
||||
} else {
|
||||
results.case.failed++;
|
||||
results.case.details.push('Case创建失败:P0-01扩展字段不正确');
|
||||
}
|
||||
|
||||
// 测试读取Case
|
||||
const foundCase = Case.findById(caseData.case_id);
|
||||
if (foundCase && foundCase.background === '测试企业背景' && foundCase.case_significance === '测试案例意义') {
|
||||
results.case.passed++;
|
||||
results.case.details.push('Case读取成功,所有P0-01扩展字段正确');
|
||||
} else {
|
||||
results.case.failed++;
|
||||
results.case.details.push('Case读取失败:P0-01扩展字段不正确');
|
||||
}
|
||||
|
||||
// 清理测试数据
|
||||
Content.delete(caseData.case_id);
|
||||
|
||||
} catch (error) {
|
||||
results.case.failed++;
|
||||
results.case.details.push(`Case测试失败: ${error.message}`);
|
||||
}
|
||||
|
||||
console.log(`Case: ${results.case.passed} passed, ${results.case.failed} failed`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证Entity-Content多对多关系
|
||||
*/
|
||||
function verifyEntityContentJoin() {
|
||||
console.log('\n=== 验证Entity-Content多对多关系 ===');
|
||||
|
||||
try {
|
||||
// 创建测试Entity
|
||||
const entity1 = Entity.create({
|
||||
entity_type: 'concept',
|
||||
name: '测试实体1',
|
||||
});
|
||||
|
||||
const entity2 = Entity.create({
|
||||
entity_type: 'concept',
|
||||
name: '测试实体2',
|
||||
});
|
||||
|
||||
// 创建测试Content
|
||||
const content = Content.create({
|
||||
title: '测试内容',
|
||||
body: '测试内容',
|
||||
content_type: 'article',
|
||||
});
|
||||
|
||||
// 创建关联:一个Content关联多个Entity
|
||||
const join1 = EntityContentJoin.create({
|
||||
entity_id: entity1.entity_id,
|
||||
content_id: content.content_id,
|
||||
});
|
||||
|
||||
const join2 = EntityContentJoin.create({
|
||||
entity_id: entity2.entity_id,
|
||||
content_id: content.content_id,
|
||||
});
|
||||
|
||||
// 验证一个Content关联多个Entity
|
||||
const contentJoins = EntityContentJoin.findByContentId(content.content_id);
|
||||
if (contentJoins.length === 2) {
|
||||
results.join.passed++;
|
||||
results.join.details.push('一个Content关联多个Entity成功');
|
||||
} else {
|
||||
results.join.failed++;
|
||||
results.join.details.push('一个Content关联多个Entity失败');
|
||||
}
|
||||
|
||||
// 创建另一个Content
|
||||
const content2 = Content.create({
|
||||
title: '测试内容2',
|
||||
body: '测试内容2',
|
||||
content_type: 'article',
|
||||
});
|
||||
|
||||
// 创建关联:一个Entity关联多个Content
|
||||
const join3 = EntityContentJoin.create({
|
||||
entity_id: entity1.entity_id,
|
||||
content_id: content2.content_id,
|
||||
});
|
||||
|
||||
// 验证一个Entity关联多个Content
|
||||
const entityJoins = EntityContentJoin.findByEntityId(entity1.entity_id);
|
||||
if (entityJoins.length === 2) {
|
||||
results.join.passed++;
|
||||
results.join.details.push('一个Entity关联多个Content成功');
|
||||
} else {
|
||||
results.join.failed++;
|
||||
results.join.details.push('一个Entity关联多个Content失败');
|
||||
}
|
||||
|
||||
// 清理测试数据
|
||||
EntityContentJoin.delete(join1.join_id);
|
||||
EntityContentJoin.delete(join2.join_id);
|
||||
EntityContentJoin.delete(join3.join_id);
|
||||
Entity.delete(entity1.entity_id);
|
||||
Entity.delete(entity2.entity_id);
|
||||
Content.delete(content.content_id);
|
||||
Content.delete(content2.content_id);
|
||||
|
||||
} catch (error) {
|
||||
results.join.failed++;
|
||||
results.join.details.push(`Entity-Content多对多测试失败: ${error.message}`);
|
||||
}
|
||||
|
||||
console.log(`Entity-Content多对多: ${results.join.passed} passed, ${results.join.failed} failed`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证内容生命周期
|
||||
*/
|
||||
function verifyContentLifecycle() {
|
||||
console.log('\n=== 验证内容生命周期 ===');
|
||||
|
||||
try {
|
||||
// 创建测试Content
|
||||
const content = Content.create({
|
||||
title: '测试内容',
|
||||
body: '测试内容',
|
||||
content_type: 'article',
|
||||
publish_status: 'draft',
|
||||
});
|
||||
|
||||
// 测试draft -> review
|
||||
const reviewContent = Content.transitionStatus(content.content_id, 'review');
|
||||
if (reviewContent.publish_status === 'review') {
|
||||
results.lifecycle.passed++;
|
||||
results.lifecycle.details.push('draft -> review 转换成功');
|
||||
} else {
|
||||
results.lifecycle.failed++;
|
||||
results.lifecycle.details.push('draft -> review 转换失败');
|
||||
}
|
||||
|
||||
// 测试review -> published
|
||||
const publishedContent = Content.transitionStatus(content.content_id, 'published');
|
||||
if (publishedContent.publish_status === 'published' && publishedContent.version_no === 2) {
|
||||
results.lifecycle.passed++;
|
||||
results.lifecycle.details.push('review -> published 转换成功,版本号递增');
|
||||
} else {
|
||||
results.lifecycle.failed++;
|
||||
results.lifecycle.details.push('review -> published 转换失败');
|
||||
}
|
||||
|
||||
// 测试published -> unpublished
|
||||
const unpublishedContent = Content.transitionStatus(content.content_id, 'unpublished');
|
||||
if (unpublishedContent.publish_status === 'unpublished') {
|
||||
results.lifecycle.passed++;
|
||||
results.lifecycle.details.push('published -> unpublished 转换成功');
|
||||
} else {
|
||||
results.lifecycle.failed++;
|
||||
results.lifecycle.details.push('published -> unpublished 转换失败');
|
||||
}
|
||||
|
||||
// 测试unpublished -> historical
|
||||
const historicalContent = Content.transitionStatus(content.content_id, 'historical');
|
||||
if (historicalContent.publish_status === 'historical' && historicalContent.archived_at) {
|
||||
results.lifecycle.passed++;
|
||||
results.lifecycle.details.push('unpublished -> historical 转换成功,记录归档时间');
|
||||
} else {
|
||||
results.lifecycle.failed++;
|
||||
results.lifecycle.details.push('unpublished -> historical 转换失败');
|
||||
}
|
||||
|
||||
// 清理测试数据
|
||||
Content.delete(content.content_id);
|
||||
|
||||
} catch (error) {
|
||||
results.lifecycle.failed++;
|
||||
results.lifecycle.details.push(`内容生命周期测试失败: ${error.message}`);
|
||||
}
|
||||
|
||||
console.log(`内容生命周期: ${results.lifecycle.passed} passed, ${results.lifecycle.failed} failed`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证Authority权威等级
|
||||
*/
|
||||
function verifyAuthority() {
|
||||
console.log('\n=== 验证Authority权威等级 ===');
|
||||
|
||||
try {
|
||||
// 测试Entity的authority_level
|
||||
const entity = Entity.create({
|
||||
entity_type: 'concept',
|
||||
name: '测试实体',
|
||||
authority_level: 3,
|
||||
});
|
||||
|
||||
if (entity.authority_level === 3) {
|
||||
results.authority.passed++;
|
||||
results.authority.details.push('Entity authority_level设置成功');
|
||||
} else {
|
||||
results.authority.failed++;
|
||||
results.authority.details.push('Entity authority_level设置失败');
|
||||
}
|
||||
|
||||
// 测试Relation的authority_level
|
||||
const entity2 = Entity.create({
|
||||
entity_type: 'concept',
|
||||
name: '测试实体2',
|
||||
});
|
||||
|
||||
const relation = DirectedRelationship.create({
|
||||
source_entity_id: entity.entity_id,
|
||||
relation_type: '测试关系',
|
||||
target_entity_id: entity2.entity_id,
|
||||
authority_level: 4,
|
||||
});
|
||||
|
||||
if (relation.authority_level === 4) {
|
||||
results.authority.passed++;
|
||||
results.authority.details.push('Relation authority_level设置成功');
|
||||
} else {
|
||||
results.authority.failed++;
|
||||
results.authority.details.push('Relation authority_level设置失败');
|
||||
}
|
||||
|
||||
// 测试Content的authority_level
|
||||
const content = Content.create({
|
||||
title: '测试内容',
|
||||
body: '测试内容',
|
||||
content_type: 'article',
|
||||
authority_level: 5,
|
||||
});
|
||||
|
||||
if (content.authority_level === 5) {
|
||||
results.authority.passed++;
|
||||
results.authority.details.push('Content authority_level设置成功');
|
||||
} else {
|
||||
results.authority.failed++;
|
||||
results.authority.details.push('Content authority_level设置失败');
|
||||
}
|
||||
|
||||
// 清理测试数据
|
||||
Entity.delete(entity.entity_id);
|
||||
Entity.delete(entity2.entity_id);
|
||||
DirectedRelationship.delete(relation.rel_id);
|
||||
Content.delete(content.content_id);
|
||||
|
||||
} catch (error) {
|
||||
results.authority.failed++;
|
||||
results.authority.details.push(`Authority测试失败: ${error.message}`);
|
||||
}
|
||||
|
||||
console.log(`Authority: ${results.authority.passed} passed, ${results.authority.failed} failed`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主函数
|
||||
*/
|
||||
function main() {
|
||||
console.log('开始数据模型验证...');
|
||||
|
||||
// 初始化数据库
|
||||
migrate();
|
||||
|
||||
// 执行验证
|
||||
verifyEntity();
|
||||
verifyPage();
|
||||
verifyArticle();
|
||||
verifyCase();
|
||||
verifyEntityContentJoin();
|
||||
verifyContentLifecycle();
|
||||
verifyAuthority();
|
||||
|
||||
// 统计结果
|
||||
let totalPassed = 0;
|
||||
let totalFailed = 0;
|
||||
|
||||
for (const key in results) {
|
||||
totalPassed += results[key].passed;
|
||||
totalFailed += results[key].failed;
|
||||
}
|
||||
|
||||
console.log('\n=== 验证结果汇总 ===');
|
||||
console.log(`总测试: ${totalPassed + totalFailed}`);
|
||||
console.log(`通过: ${totalPassed}`);
|
||||
console.log(`失败: ${totalFailed}`);
|
||||
console.log(`通过率: ${((totalPassed / (totalPassed + totalFailed)) * 100).toFixed(2)}%`);
|
||||
|
||||
// 输出详细结果
|
||||
console.log('\n=== 详细结果 ===');
|
||||
for (const key in results) {
|
||||
console.log(`\n${key}:`);
|
||||
results[key].details.forEach(detail => {
|
||||
console.log(` - ${detail}`);
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭数据库
|
||||
closeDb();
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
// 如果直接运行此脚本
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
main,
|
||||
results,
|
||||
};
|
||||
Reference in New Issue
Block a user