#!/usr/bin/env python3 """ 工程结构校验脚本 用法:python3 scripts/check-structure.py """ from pathlib import Path ROOT = Path(__file__).parent.parent REQUIRED_FILES = [ # 根配置 "package.json", "pnpm-workspace.yaml", "tsconfig.base.json", ".gitignore", ".env.example", "README.md", # 文档 "1-prd.md", "2-task.md", "3-architecture.md", "4-data-model.md", "5-api.md", "11-progress-log.md", # 共享包 "packages/shared/package.json", "packages/shared/tsconfig.json", "packages/shared/src/index.ts", "packages/shared/src/enums.ts", "packages/shared/src/types.ts", # 数据库包 "packages/db/package.json", "packages/db/tsconfig.json", "packages/db/src/index.ts", "packages/db/src/pool.ts", "packages/db/src/migrate.ts", "packages/db/src/seed.ts", "packages/db/migrations/001_init.sql", "packages/db/seeds/001_roles.sql", "packages/db/seeds/002_tag_categories.sql", "packages/db/seeds/003_test_institution.sql", "packages/db/seeds/004_test_artifacts.sql", # API "apps/api/package.json", "apps/api/tsconfig.json", "apps/api/nest-cli.json", "apps/api/src/main.ts", "apps/api/src/app.module.ts", "apps/api/src/health/health.controller.ts", # PC Web "apps/web/package.json", "apps/web/tsconfig.json", "apps/web/next.config.js", "apps/web/tailwind.config.ts", "apps/web/src/app/layout.tsx", "apps/web/src/app/page.tsx", "apps/web/src/app/map/page.tsx", # Admin "apps/admin/package.json", "apps/admin/tsconfig.json", "apps/admin/vite.config.ts", "apps/admin/index.html", "apps/admin/src/main.tsx", "apps/admin/src/App.tsx", # Infra "infra/docker-compose.yml", # Scripts "scripts/check-structure.py", ] KEYWORD_CHECKS = { "3-architecture.md": ["Next.js", "NestJS", "PostGIS", "测试策略"], "4-data-model.md": ["artifacts", "artifact_locations", "PostGIS", "operation_logs"], "5-api.md": ["/api/v1", "Map API", "Artifact API", "权限矩阵"], "packages/db/migrations/001_init.sql": ["PostGIS", "artifacts", "artifact_locations", "operation_logs"], "packages/shared/src/enums.ts": ["ArtifactCategory", "ArtifactLevel", "LocationPrecision"], } failed: list[str] = [] print("=== 工程结构校验 ===\n") # 1. 文件存在性检查 print("1. 文件存在性检查") for rel in REQUIRED_FILES: path = ROOT / rel if path.exists(): print(f" ✓ {rel}") else: print(f" ✗ {rel} <-- 缺失") failed.append(f"缺失文件: {rel}") # 2. 关键词检查 print("\n2. 关键词检查") for rel, keywords in KEYWORD_CHECKS.items(): path = ROOT / rel if not path.exists(): continue text = path.read_text(encoding="utf-8") for kw in keywords: if kw in text: print(f" ✓ {rel} ⊃ '{kw}'") else: msg = f"{rel} 缺少关键词: '{kw}'" print(f" ✗ {msg}") failed.append(msg) print() if failed: print(f"FAILED — {len(failed)} 项未通过:") for item in failed: print(f" - {item}") raise SystemExit(1) else: total = len(REQUIRED_FILES) print(f"PASSED — 共检查 {total} 个文件,所有关键词验证通过")