• 按 39 号设计文档落地 ceo 常驻监督:company.js 的 goals/tasks 端点
    放行内部令牌自环调用,POST /tasks 支持 draft 模式(agent 自主提任务
    不再立刻烧预算),ceo 补雇进公司创建流程;task-settle 新增事件驱动
    唤醒 + 30 分钟兜底轮询;graph-engine 的回退熔断收敛时顺手回写一条
    draft task,形成"卡住 → 自动/ceo 判断 → 重新规划"闭环。
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01BwG4b7Nq1NLR9eeE3M9Us9
    yibo authored
     
    Browse File »

  • company-service.js:company.json 加 ownerId(无 SQL 表,纯 JSON 字段);create() 接收
    ownerId;list({ user }) 按传入用户过滤,不传就不过滤(company-heartbeat-service.js 等
    系统内部巡检要看全部公司);新增 canAccessCompany(company, user) 作为全仓库唯一一份
    归属判据(admin 不过滤,判负一律 404 不是 403,不暴露"这个 id 存在只是不是你的")。
    
    company.js 用 router.param('companyId', ...) 统一收口(约 50 条路由,含 okrPath() 系列
    动态路由)。graph-run.js 的两个挂载点参数形状不一样,设计阶段的描述不准确,实现时才
    发现:companyRouter 唯一路由是 /:companyId/graph-runs 直接查;主 router 全部路由是
    /:id/...,:id 指的是 run 不是公司,改成先查 run 的 company_id 再判断,run 不存在或
    公司不是你的统一回"run 不存在"。devloop.js 用 :pid 反查 company_id;POST /projects
    单独校验 body 里的 company_id(放在基本字段校验之后,避免归属检查打乱输入校验的错误
    优先级);GET /projects 按归属过滤列表。
    
    okr.js 最终没有按原计划接入 companyId 归属校验——实现前查证发现 OkrDashboard.vue
    挂载的 /okr 页面全站没有任何导航入口指向它,是个孤儿页面,给访问不到的页面建"选公司"
    前端交互不划算,改成 requireAdmin(跟 dream.js 同款),先堵住直接拼 URL 看到跨公司
    聚合数据的口子。真正在用的公司级 OKR(company.js 的 /:id/okr)已随 company.js 一起隔离。
    
    存量数据迁移:scripts/backfill-company-owner.js(npm run backfill:company-owner),
    两家存量公司已划给种子账号,幂等验证过。
    
    8 个既有测试文件用的公司 id 都是从没真正建过的字符串标签,挂锁后集体 404——新增共享
    helper server/tests/helpers/ensure-test-company.js 修复;两处原有的"跳过已有
    company.json 的目录,那是真公司"防御逻辑,判据从"有没有 company.json"改成"ownerId
    是不是 -1 这个测试专用标记",否则新出现的测试夹具会被误判成真公司永远不清理。
    
    验证:真实 curl 走过(admin 看到全部存量公司、新用户看到空列表、新用户拼 URL 访问
    别人的公司 404、新建公司 ownerId 精确落在创建者、admin 和创建者都看得到其他人看不到);
    全量 vitest 1427 passed,3 个无关既有失败不受影响。
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse File »
  • 给此前完全零防护的 company.js/okr.js/tasks.js/devloop.js/graph-run.js(两个挂载点)/
    arena.js/config.js/evolution.js/whatsapp-auth.js 挂 requireAuth;dream.js 挂 requireAdmin
    (系统级经验汇流视图,只有 admin 能看)。open-api.js(自己一套 OPEN_API_KEYS)/auth.js
    自身/health 端点按计划排除。这一步只挡"没登录",公司归属过滤留到 Phase 2。
    
    agent-chat.js 不能直接挂 requireAuth:company.js(自动建公司/招聘后自动训练)、
    task-settle.js(goal 汇报回调)三处服务端自环调用会 fetch 自己的 /api/agent/* 端点,
    拿不到任何用户 cookie,直接挂锁会打断这几条核心自动化链路。新增 requireAuthOrInternal +
    jwt-auth.js 的进程内 INTERNAL_TOKEN(启动时随机生成,只活在内存里):自环调用带上
    x-internal-token 头放行,其余情况仍要求真实登录;三处调用点同步改造。
    
    17 个既有测试文件、67+ 处用例直接拿 supertest 打这些路由,从没设过登录 cookie(测的是
    业务逻辑不是鉴权)。没有逐个补登录态,改为 requireAuth/requireAdmin 在 NODE_ENV=test
    时默认放行,除非显式 FORCE_REAL_AUTH=1;新增 route-auth-gate.test.js 在放行关闭状态下
    做结构检查(router.stack 里中间件是否真的排在所有路由前面),确保"锁真的挂上了"这件事
    有测试兜底,不被业务测试的默认放行悄悄掩盖。
    
    验证:真实 curl 走过全部路由(无 cookie 401、admin 登录全通、非 admin 能看公司但
    dream.js 403);手工删过一行 requireAuth 确认守卫测试真的会红;全量 vitest 1427 passed,
    另 3 个失败与本次改动无关(stash 验证过改前改后一致,系仓库并发工作遗留)。
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse File »