chore: prepare project for server deployment

This commit is contained in:
amb
2026-09-09 17:43:07 +08:00
commit d0bcff2311
83 changed files with 24163 additions and 0 deletions
+548
View File
@@ -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,
};