-
Notifications
You must be signed in to change notification settings - Fork 0
[codex] stabilize repository browsing and settings workflows #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
265fc77
a818b00
9947bb6
8eb4e12
6cf67c2
2f52254
69cb723
949c0f8
499dc5b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # CodaGraph-lite Project Memory | ||
|
|
||
| ## Required Workflow | ||
|
|
||
| - Reproduce the exact bug on the current branch before changing code. | ||
| - For interaction bugs, inspect browser behavior first: focus, active element, DOM replacement, network request, and backend log. | ||
| - Do not claim a fix based on a different branch, worktree, or prior patch. Verify the current branch contains the change. | ||
| - Do not report "fixed" until the same user path has been re-tested in the browser or with a direct request. | ||
|
|
||
| ## Known Failure Modes | ||
|
|
||
| ### Settings Password Inputs | ||
|
|
||
| - Symptom: on `/dashboard/settings`, the admin password fields only accept one character, then lose focus or appear to clear. | ||
| - Real root cause: helper components defined inside `SettingsPage()` can cause subtree remounts on every `setPasswordForm`. | ||
| - First things to check: | ||
| - whether local helper components are declared inside the page component | ||
| - whether the active input node/id changes after one keystroke | ||
| - whether password form updates use functional state updates | ||
| - Current fix location: `web/app/dashboard/settings/page.tsx` | ||
|
|
||
| ### Failed Login Returning 500 | ||
|
|
||
| - Symptom: wrong admin password returns `500 {"details":"FOREIGN KEY constraint failed"}` instead of `401`. | ||
| - Real root cause: failed login activity log attempted to insert an invalid `admin_id`. | ||
| - First things to check: | ||
| - `POST /api/auth/login` response code | ||
| - backend log stack under `server/src/auth/routes.ts` | ||
| - `server/src/models/ActivityLog.ts` | ||
| - Current fix locations: | ||
| - `server/src/auth/routes.ts` | ||
| - `server/src/models/ActivityLog.ts` | ||
|
|
||
| ### Local Frontend / Backend Validation | ||
|
|
||
| - Prefer `http://localhost:3000`, not `http://127.0.0.1:3000`, when validating the real app flow. | ||
| - Reason: the backend CORS configuration commonly allows `http://localhost:3000`; using `127.0.0.1` can create a false negative during login and settings verification. | ||
|
|
||
| ## Response Discipline | ||
|
|
||
| - Separate symptom from root cause. | ||
| - Fix one proven root cause at a time. | ||
| - If a patch only addresses an adjacent issue, do not present it as the root fix. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -124,14 +124,19 @@ main() { | |
| ((attempt++)) | ||
| sleep 2 | ||
|
|
||
| # 检查前端 | ||
| if curl -sf http://localhost:3000/api/health >/dev/null 2>&1; then | ||
| log_success "前端健康检查通过" | ||
| break | ||
| local frontend_ok=false | ||
| local backend_ok=false | ||
|
|
||
| if curl -sf "http://localhost:${FRONTEND_PORT}/api/health" >/dev/null 2>&1; then | ||
| frontend_ok=true | ||
| fi | ||
|
|
||
| # 检查后端 | ||
| if curl -sf http://localhost:7900/api/health >/dev/null 2>&1; then | ||
| if curl -sf "http://localhost:${BACKEND_PORT}/health" >/dev/null 2>&1; then | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CRITICAL · 后端健康检查路径与实际 API 不匹配 后端健康检查端点从 建议:确认 server/dist 中的路由实现。如果后端健康检查端点仍是 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CRITICAL · 后端健康检查端点被静默修改,可能导致部署失败 diff 显示后端健康检查端点从 建议:确认后端服务是否已实现 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 后端健康检查端点与原配置不一致 健康检查端点从 /api/health 变更为 /health。旧代码检查的是 /api/health,新代码检查 /health。这可能导致健康检查失败,如果后端服务实际只暴露了 /api/health 端点。 建议:确认 server/dist 的实际健康检查路由。如果 server 同时暴露两个端点则无问题,否则需将端点改回 /api/health 或同步更新 server 的路由配置。 |
||
| backend_ok=true | ||
| fi | ||
|
|
||
| if [ "$frontend_ok" = true ] && [ "$backend_ok" = true ]; then | ||
| log_success "前端健康检查通过" | ||
| log_success "后端健康检查通过" | ||
| break | ||
| fi | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -8,16 +8,18 @@ After=network.target | |||
| Wants=network.target | ||||
|
|
||||
| [Service] | ||||
| Type=notify | ||||
| Type=simple | ||||
| NotifyAccess=all | ||||
|
||||
| NotifyAccess=all |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -368,7 +368,7 @@ check_api_health() { | |
| check | ||
| log_info "检查 API 健康状态..." | ||
|
|
||
| local backend_url="http://localhost:${BACKEND_PORT:-7900}/api/health" | ||
| local backend_url="http://localhost:${BACKEND_PORT:-7900}/health" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 健康检查端点路径可能与服务端实际端点不匹配 将健康检查端点从 建议:确认服务端实际提供的健康检查端点路径。如果服务端使用统一 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 健康检查端点路径变更需确认服务器端实现 健康检查路径从 建议:确认服务器端健康检查端点的实际路径。如果服务器使用 Express,通常在入口文件中有 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · API 端点路径变更需与后端配置对齐 健康检查端点从 建议:确认后端健康检查端点的实际路径。如果后端同时支持两路径则无问题;如果只支持 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 健康检查端点路径变更可能导致验证失败 将健康检查端点从 建议:确认后端实际提供的健康检查端点路径。如果使用路径前缀 |
||
| local frontend_url="http://localhost:${FRONTEND_PORT:-3000}" | ||
|
|
||
| # 检查后端 API | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -392,6 +392,8 @@ WORKSPACE_ROOT=/opt/codagraph-lite/workspace | |
|
|
||
| ### LLM 提供商 | ||
|
|
||
| 这些环境变量会初始化后台里的默认 LLM 配置。需要多套 LLM API 时,可以在设置页继续新增、保存并切换。 | ||
|
|
||
| | 环境变量 | 默认值 | 可选值 | | ||
| |-----------|---------|--------| | ||
| | `LLM_PROVIDER` | `openai` | `openai`, `anthropic`, `deepseek`, `自定义` | | ||
|
|
@@ -611,9 +613,9 @@ node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" | |
| **配置示例**: | ||
| ```bash | ||
| # 开发环境 | ||
| CORS_ORIGINS=http://localhost:3000 | ||
| CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · CORS 配置示例同时包含 localhost 和 127.0.0.1 可能导致认证问题 AGENTS.md:37 指出 'using 127.0.0.1 can create a false negative during login and settings verification'。虽然 localhost 和 127.0.0.1 指向同一台机器,但浏览器可能将它们视为不同的 origin(域名 origin 的判断依赖字符串比较),这可能导致 cookie/session 无法正确共享,造成认证失败。文档明确建议两者都包含,但未警告潜在风险。 建议:在开发环境配置示例后添加说明,或改为只推荐使用 |
||
|
|
||
| # 生产环境(多个域名) | ||
| # 生产环境(多个可信域名) | ||
| CORS_ORIGINS=https://app1.com,https://app2.com | ||
|
|
||
| # 允许所有(不推荐生产环境) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| import { test, expect } from '@playwright/test'; | ||
| import { execSync } from 'child_process'; | ||
|
|
||
| const seededRepositoryName = 'codagraph-lite-e2e-fixture'; | ||
|
|
||
| test.beforeAll(() => { | ||
| execSync('node scripts/seed-e2e-data.js', { stdio: 'inherit' }); | ||
| }); | ||
|
|
@@ -19,9 +21,10 @@ test('repositories page renders seeded repository', async ({ page }) => { | |
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 页面错误监听器注册时机晚于页面导航 在第20行 建议:将 |
||
| await page.goto('/dashboard/repositories'); | ||
| await expect(page.getByRole('heading', { name: '仓库管理' })).toBeVisible(); | ||
| await expect(page.getByText('mars167')).toBeVisible(); | ||
| await expect(page.getByText('codagraph-lite')).toBeVisible(); | ||
| await expect(page.getByText('已连接', { exact: true })).toBeVisible(); | ||
| await page.getByRole('textbox', { name: 'Search' }).fill(`mars167/${seededRepositoryName}`); | ||
| await expect(page.getByText('搜索命中 1', { exact: true })).toBeVisible(); | ||
| await expect(page.getByRole('link', { name: seededRepositoryName, exact: true })).toBeVisible(); | ||
| await expect(page.getByRole('button', { name: '开启 Watch' })).toBeVisible(); | ||
| expect(pageErrors).toEqual([]); | ||
| }); | ||
|
|
||
|
|
@@ -31,7 +34,11 @@ test('jobs page renders seeded job stats and row', async ({ page }) => { | |
|
|
||
| await page.goto('/dashboard/jobs'); | ||
| await expect(page.getByRole('heading', { name: '作业状态' })).toBeVisible(); | ||
| await expect(page.getByText('analyze_pr')).toBeVisible(); | ||
| await expect( | ||
| page.getByRole('link', { | ||
| name: new RegExp(`Job #\\d+ · ${seededRepositoryName} · PR #\\d+`), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 正则表达式硬编码 Job 链接格式,脆弱且无回退断言 正则表达式 建议:增加一个或多个不依赖精确文本格式的断言,例如检查链接元素存在且 href 指向正确的端点: |
||
| }) | ||
| ).toBeVisible(); | ||
| expect(pageErrors).toEqual([]); | ||
| }); | ||
|
|
||
|
|
@@ -40,7 +47,8 @@ test('history page renders seeded analysis entry', async ({ page }) => { | |
| page.on('pageerror', (error) => pageErrors.push(error.message)); | ||
|
|
||
| await page.goto('/dashboard/history'); | ||
| await expect(page.getByRole('heading', { name: '分析历史' })).toBeVisible(); | ||
| await expect(page.getByRole('heading', { name: '按 PR 维度回看 Review 历史' })).toBeVisible(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 页面标题变更需确认 UI 同步更新 history 页面的标题从 '分析历史' 改为 '按 PR 维度回看 Review 历史'。这是一个用户可见的文本变更,如果后端代码已更新但前端页面尚未同步此文本,测试将失败。需确认这是预期的前端 UI 变更。 建议:确认 |
||
| await expect(page.getByRole('link', { name: `mars167/${seededRepositoryName}` })).toBeVisible(); | ||
| await expect(page.getByText('E2E validation PR')).toBeVisible(); | ||
| expect(pageErrors).toEqual([]); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,12 +13,16 @@ | |
| "build:web": "npm --prefix web run build", | ||
| "build:server": "npm --prefix server run build", | ||
| "build": "npm run build:web && npm run build:server", | ||
| "check:web": "npm --prefix web run lint", | ||
| "check:server": "npm --prefix server run typecheck", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · check:server 脚本依赖未验证的子项目配置 check:server 调用 server 目录下的 typecheck 命令,但未确认 server/package.json 中是否存在 typecheck 脚本。如果 server 项目未配置 TypeScript 类型检查,此命令将失败。 建议:在添加此脚本前,确保 server/package.json 中已正确定义 'typecheck' 脚本(如 tsc --noEmit)。 |
||
| "check": "npm run check:web && npm run check:server && npm run build", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · check 脚本的执行顺序可能导致资源浪费 check 脚本按顺序执行 建议:考虑将 check 脚本改为 |
||
| "start:web": "npm --prefix web run start", | ||
| "start:server": "npm --prefix server run start", | ||
| "start": "concurrently \"npm run start:web\" \"npm run start:server\"", | ||
| "seed:e2e": "node scripts/seed-e2e-data.js", | ||
| "e2e:playwright": "npm run seed:e2e && playwright test e2e/dashboard-pages.spec.ts", | ||
| "e2e:puppeteer": "npm run seed:e2e && node scripts/puppeteer-dashboard-smoke.js" | ||
| "e2e:puppeteer": "npm run seed:e2e && node scripts/puppeteer-dashboard-smoke.js", | ||
| "test:e2e": "NEXT_PUBLIC_API_URL=http://127.0.0.1:7901 npm run build && npm run e2e:playwright" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,21 @@ export default defineConfig({ | |
| testDir: './e2e', | ||
| timeout: 30_000, | ||
| use: { | ||
| baseURL: 'http://localhost:3000', | ||
| baseURL: 'http://127.0.0.1:3001', | ||
| headless: true, | ||
| }, | ||
| webServer: [ | ||
| { | ||
| command: 'SKIP_REMOTE_REPOSITORY_SYNC=1 BACKEND_PORT=7901 FRONTEND_PORT=3001 CORS_ORIGINS=http://127.0.0.1:3001 npm run start:server', | ||
| url: 'http://127.0.0.1:7901/api/health', | ||
| reuseExistingServer: !process.env.CI, | ||
| timeout: 30_000, | ||
| }, | ||
| { | ||
| command: 'cd web && mkdir -p .next/standalone/.next && if [ -d .next/static ]; then ln -sfn ../../static .next/standalone/.next/static; fi && PORT=3001 HOSTNAME=127.0.0.1 NEXT_PUBLIC_API_URL=http://127.0.0.1:7901 node .next/standalone/server.js', | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 前端服务器启动命令链过长,单点故障难以诊断 webServer 命令使用 && 链式执行 5 个操作:mkdir、if 条件判断、ln 命令、PORT/HOSTNAME/NEXT_PUBLIC_API_URL 设置、node 启动。如果任一步骤失败(如 standalone 构建缺失、文件权限问题、目录不存在),Playwright 仅报告超时,开发者需要手动运行命令才能定位具体故障点。这会显著增加调试成本,特别是在 CI 环境中。 建议:考虑拆分为两步:(1) 在项目根目录添加 |
||
| url: 'http://127.0.0.1:3001/api/health', | ||
| reuseExistingServer: !process.env.CI, | ||
| timeout: 30_000, | ||
| }, | ||
| ], | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,45 @@ | ||
| const path = require('path'); | ||
| const Database = require('../server/node_modules/better-sqlite3'); | ||
| const crypto = require('crypto'); | ||
| const Database = require(require.resolve('better-sqlite3', { | ||
| paths: [path.join(__dirname, '..', 'server')], | ||
| })); | ||
|
|
||
| const dbPath = path.join(__dirname, '..', 'server', 'data', 'codagraph-lite.db'); | ||
| const db = new Database(dbPath); | ||
| // Keep fixture data ahead of existing rows so the e2e smoke tests can locate it deterministically. | ||
| const seededTimestamp = "datetime('now', 'localtime', '+1 day')"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 未来时间戳可能导致测试断言不稳定 seededTimestamp 使用 datetime('now', 'localtime', '+1 day') 设置为未来1天的时间。如果E2E测试中有任何依赖当前时间的断言(如检查token是否过期、判断记录是否'最近'创建等),这些测试可能因为时间差而失败。特别是 oauth_installations.token_expires_at 字段虽然当前未填充值,但若应用代码未来依赖该字段与当前时间做比较,测试数据将无法覆盖这些场景。 建议:考虑使用 datetime('now', 'localtime') 获取当前时间戳,仅在明确需要测试'过期'或'未来'场景时才使用固定偏移。如果必须使用未来时间,建议在脚本顶部添加注释说明原因,并确保相关测试明确处理时间边界情况。 |
||
| const seededAdminPasswordHash = crypto | ||
| .createHash('sha256') | ||
| .update('changeme') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 硬编码测试凭证存在意外泄露风险 admin 密码和 OAuth token 使用硬编码字符串('changeme'、'e2e-token')。虽然这是 E2E 测试脚本,但如果错误地作为生产数据库初始化脚本运行,这些凭证可能被意外使用。 建议:考虑从环境变量读取敏感数据,例如:const adminPassword = process.env.E2E_ADMIN_PASSWORD || 'changeme';。或在脚本头部添加明确的危险警告注释。 |
||
| .digest('hex'); | ||
|
|
||
| try { | ||
| db.exec(` | ||
| CREATE TABLE IF NOT EXISTS admin ( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| username TEXT UNIQUE NOT NULL, | ||
| password_hash TEXT NOT NULL, | ||
| created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')), | ||
| updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')), | ||
| last_login_at TEXT | ||
| ); | ||
|
|
||
| CREATE TABLE IF NOT EXISTS oauth_installations ( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| platform TEXT NOT NULL CHECK(platform IN ('github', 'gitee', 'gitlab')), | ||
| auth_type TEXT DEFAULT 'oauth', | ||
| github_app_installation_id TEXT, | ||
| account_id TEXT NOT NULL, | ||
| account_name TEXT, | ||
| access_token TEXT NOT NULL, | ||
| refresh_token TEXT, | ||
| token_expires_at DATETIME, | ||
| permissions TEXT, | ||
| is_active INTEGER DEFAULT 1, | ||
| created_at DATETIME DEFAULT (datetime('now', 'localtime')), | ||
| updated_at DATETIME DEFAULT (datetime('now', 'localtime')) | ||
| ); | ||
|
|
||
| db.exec(` | ||
| CREATE TABLE IF NOT EXISTS repository ( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| platform TEXT NOT NULL, | ||
|
|
@@ -60,31 +95,45 @@ db.exec(` | |
| updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP | ||
| ); | ||
|
|
||
| INSERT OR REPLACE INTO admin ( | ||
| id, username, password_hash, created_at, updated_at, last_login_at | ||
| ) VALUES ( | ||
| 1, 'admin', '${seededAdminPasswordHash}', ${seededTimestamp}, ${seededTimestamp}, NULL | ||
| ); | ||
|
|
||
| INSERT OR REPLACE INTO oauth_installations ( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 新增 oauth_installations 表的 INSERT 缺少幂等性保护 repository、analysis、jobs 表都使用了 INSERT OR REPLACE 保证幂等性,但新增的 oauth_installations 表(第11-25行创建)也使用 INSERT OR REPLACE,却缺少表可能已存在数据的保护逻辑。如果该表已存在且包含其他记录,INSERT OR REPLACE 可能导致意外的数据丢失。 建议:确认 oauth_installations 表的预期状态,或考虑使用 DELETE 配合条件后再 INSERT,确保与测试预期一致。 |
||
| id, platform, auth_type, account_id, account_name, access_token, permissions, is_active, created_at, updated_at | ||
| ) VALUES ( | ||
| 9001, 'github', 'oauth', 'mars167-e2e', 'mars167 E2E', 'e2e-token', 'repo', 1, ${seededTimestamp}, ${seededTimestamp} | ||
| ); | ||
|
|
||
| INSERT OR REPLACE INTO repository ( | ||
| id, platform, owner, name, full_name, installation_id, webhook_url, is_active, created_at, updated_at, last_analyzed_at | ||
| ) VALUES ( | ||
| 9101, 'github', 'mars167', 'codagraph-lite', 'mars167/codagraph-lite', | ||
| 9001, 'https://example.com/webhook', 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP | ||
| 9101, 'github', 'mars167', 'codagraph-lite-e2e-fixture', 'mars167/codagraph-lite-e2e-fixture', | ||
| 9001, 'https://example.com/webhook', 1, ${seededTimestamp}, ${seededTimestamp}, ${seededTimestamp} | ||
| ); | ||
|
|
||
| INSERT OR REPLACE INTO analysis ( | ||
| id, platform, owner, repo_name, pr_number, pr_title, pr_author, base_commit, head_commit, | ||
| status, analysis_result, comment_count, file_count, issue_count, started_at, completed_at, | ||
| error_message, created_at, updated_at | ||
| ) VALUES ( | ||
| 9201, 'github', 'mars167', 'codagraph-lite', 42, 'E2E validation PR', 'mars167', | ||
| 'main', 'feature/e2e', 'completed', '{}', 3, 5, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, | ||
| NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP | ||
| 9201, 'github', 'mars167', 'codagraph-lite-e2e-fixture', 42, 'E2E validation PR', 'mars167', | ||
| 'main', 'feature/e2e', 'completed', '{}', 3, 5, 1, ${seededTimestamp}, ${seededTimestamp}, | ||
| NULL, ${seededTimestamp}, ${seededTimestamp} | ||
| ); | ||
|
|
||
| INSERT OR REPLACE INTO jobs ( | ||
| id, type, payload, status, priority, attempts, max_attempts, | ||
| error_message, created_at, updated_at, started_at, completed_at | ||
| ) VALUES ( | ||
| 9301, 'pr_analysis', '{"platform":"github","repo_name":"codagraph-lite","pr_number":"42"}', | ||
| 'completed', 3, 1, 3, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP | ||
| 9301, 'pr_analysis', '{"platform":"github","repo_name":"codagraph-lite-e2e-fixture","pr_number":"42"}', | ||
| 'completed', 3, 1, 3, NULL, ${seededTimestamp}, ${seededTimestamp}, ${seededTimestamp}, ${seededTimestamp} | ||
| ); | ||
| `); | ||
| `); | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HIGH · 缺少错误处理和数据库关闭保证 db.exec()执行可能因磁盘空间不足、权限问题或数据库锁而失败,当前代码没有try-catch包装。如果执行中途失败,数据库连接也不会被正确关闭(db.close()在L114),可能导致资源泄漏。 建议:使用try-finally或try-catch-finally确保db.close()始终执行: try {
db.exec(`...`);
console.log(`Seeded E2E data into ${dbPath}`);
} finally {
db.close();
} |
||
| console.log(`Seeded E2E data into ${dbPath}`); | ||
| db.close(); | ||
| console.log(`Seeded E2E data into ${dbPath}`); | ||
| } finally { | ||
| db.close(); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HIGH · 文档中暴露了内部错误信息格式,可能被用于探测系统
错误消息
{"details":"FOREIGN KEY constraint failed"}暴露了数据库约束细节和内部表关系。攻击者可利用此信息:(1) 确认用户账号是否存在(返回500而非401);(2) 推断数据库表结构。虽然这是对现有 bug 的文档化记录,但文档本身无需包含完整的 JSON 响应体示例。建议:将 L24 改为:'Symptom: wrong admin password returns 500 with internal database error details instead of 401.' 移除具体的 JSON 响应体示例,避免在文档中固化敏感的错误响应格式。