Commit Graph

48 Commits

Author SHA1 Message Date
Pine f067c02ec2 feat(compute): 新增 /admin/compute/proxy/{path} 透传 compute-engine 管理 API
- compute_client.proxy(): 转发到引擎 /api/<path>,保留原始状态码/响应体
- rbac_operator 新增 compute_proxy 端点(GET/POST/PUT/DELETE/PATCH),运营端鉴权
- 使 admin 端可 1:1 驱动 new-api 完整管理面(models/channels/groups/tokens/users/logs/redemption/ratio)
2026-08-25 01:52:35 +08:00
Pine 5f0acfa79e feat(park): 视频识别剥离,per-tenant 配置接入 park-vision 独立服务
- 删除 vision_yolo/vision_llm 及路由 /api/vision/frame|llm(保留遥测 event),去除 ultralytics 依赖
- 视频识别改为每园区(per-tenant)配置,经 park_settings(kv) 键 vision_api:<tid> 存取
- /park/api/vision/config GET/PUT(园区端读写本园区识别地址,可局域网);bind 下发含 vision_api
- 新增 alembic 0004(tenant_id 可空) / 0005(park_settings 表),迁移脚本执行
2026-08-25 01:52:23 +08:00
Pine 634ed22dcd fix(park): 园区子应用加 CORS(allow_origins=*) — 大屏跨域预检 405/ACAO 拒绝
大屏(Vite dev :1420 / Tauri tauri.localhost)与 server-core(:8090) 不同源;app.park 独立
FastAPI 未加 CORS → OPTIONS 预检 405、ACAO 拒绝。加 CORSMiddleware(allow_origins=['*']),
TestClient 验证 /park/api/config 与预检均 200 且带 ACAO。
2026-08-24 20:38:32 +08:00
Pine 585277b724 fix(park): /park/api/config 补顶层 mqtt_url/username/password — 兼容大屏 bootstrap 取 MQTT/API 引导
大屏 main.jsx 读 cfg.mqtt_url/mqtt_username/mqtt_password;此前仅返回嵌套 mqtt{},
大屏回退到构建期旧地址。补顶层字段(取 server-core .env MQTT_WS_URL/凭据)。
2026-08-24 20:33:15 +08:00
Pine 6de1b5a31b refactor(training): 培训数据层并入唯一总库 app.db(非运行态建表/种子,全列可空)
- 训练 ORM 模型改名回旧表名(accounts/events/bookings/tests/courses/policy_logs/plan_logs/survey_logs)
  并全列可空(兼容按部分字段插入);alembic 0003 丢弃重建并入唯一总库。
- training/db.py 指向 app.db、移除运行时 init_db;main.py lifespan 移除 init_db。
- seed.py 增培训种子(超管账号/排期/在线课程, 幂等)。
- 验证(真实库 migrate+seed+TestClient):auth/me、admin/*、park/*、training /api/health|events|courses 全 200。
2026-08-24 20:31:57 +08:00
Pine a9d14cb20e fix(db): 种子智能体彻底幂等 — INSERT OR IGNORE(复合唯一) + port 默认 ''
-add_agent 改用 SQLite on_conflict_do_nothing((id,user_id,port)),杜绝运行时/重跑 UNIQUE;
port 无端口身份默认 ''(agents.port NOT NULL)。真实库 migrate+seed 连续 3 次均成功。
2026-08-24 20:19:02 +08:00
Pine b6315f69b0 feat(park): 大屏设备绑定流 — 永久设备ID+连接码+园区端绑定+MQTT下发设备token
- park_screens 加 status/code/code_expires/bound_at、tenant_id 可空(alembic 0002)。
- auth 加 create/parse_device_token {tenant_id,device_id}。
- tenants 加 ensures_device/set_device_code/find_device_by_code/bind_device/unbind_device。
- 端点:/park/api/devices/register、/park/api/devices/{device_id}/code(8位码TTL10min)、
  /park/tenants/{tid}/screens/bind-by-code(校验码→绑定→MQTT opc/display/bind/<dev> 下发 token)、
  /park/api/devices/{device_id}/unbind。_resolve_tenant 支持设备 token。
- 验证(TestClient):register→code→建园区→绑码(bound/命名)→设备token取数据返回绑定园区。
2026-08-24 20:10:46 +08:00
Pine 5752b3816d refactor(park): 园区数据层迁唯一总库(async SQLAlchemy) — 去 raw sqlite3/park.db
- tenants.py 改为 async SQLAlchemy(ParkTenant/Company/KbDoc/Screen,共享 _ASYNC_ENGINE),
  不再开独立 park.db、不再 init_db;建表/种子走 alembic+seed.py。
- 同步只读 accessor(list_tenants_sync/list_companies_sync/get_tenant_data_sync/get_agent_sync)
  供 sim_engine 同步 tick/tools 用。
- sim_engine.get_engine 改读 get_tenant_data_sync;refresh_engine(tenant_id, data)。
- routers 全部 tenants 调用改 await,_resolve_tenant 改 async;app.py 移除 init_db;
  tools._query_companies 用 list_companies_sync。修复 ensure_default_tenant(T001)、Row→dict。
- 验证(migrate+seed+TestClient):tenants/companies/screens/screen/data/agent/kb/snapshot/display 全 200。
2026-08-24 20:01:03 +08:00
Pine e4d4dbd8c9 fix(park): 大屏前端契约对齐 — update_check download_url=/download、media 返回 relative_path
大屏 api.js 以 getApiBase()(=/park) + 相对路径拼接,download_url 应 '/' 相对、media 应 relative_path。
2026-08-24 19:45:28 +08:00
Pine 47d2a1b62b feat(park): 补全大屏迁移端点+静态资源 — 迁自 park-desktop/backend(可删原后端)
- 新增 /park/api/upload、/api/state、/api/control、/api/playlist(|add/remove/play)、/api/media/add-url、
  /api/delete、/park/download、/park/api/update/check(安装包取 serverdata/park/installers)。
- 迁入 app/park/static(admin.css/js + voice-worklets),挂 /park/static。
- media/data.json/安装包 落 serverdata/park/(gitignored 运行数据)。
- TestClient 冒烟:health/settings/playlist/media/control/download/update/static 均 200。
2026-08-24 19:44:26 +08:00
Pine c723675414 fix(db): AGENT_SEED 全局固定 id 种子冲突 — 智能体幂等播种
新增 _add_agent(按 (id,user_id,port) 已存在则跳过),base 路径/_ensure_extra_demo_users/
_ensure_port_agents 三处统一调用;修复多用户/多端口复用固定 agent id 触发唯一冲突。
验证:临时库 migrate+seed 完整通过且重跑幂等(pine 已灌入)。
2026-08-24 19:35:18 +08:00
Pine 75caab4d39 feat(db): P2 摘除运行时种子 + 脚本化迁移/种子(migrate.py/seed.py)
- Database.initialize() 不再 create_all/seed_data:运行时仅做库连通检查(不建表不灌种子)。
- 新增 scripts/db/migrate.py(封装 alembic upgrade/downgrade)、scripts/db/seed.py(非运行态灌平台种子)。
- 新增 serverdata/seed/(README) 存放种子 JSON。
- 迁移/种子流程:uv run python scripts/db/migrate.py + scripts/db/seed.py,再启动应用。
- 已知待修:seed 内 AGENT_SEED 全局固定 id 唯一冲突(既有缺陷, 待 P2 后续修);pine/角色已能灌入。
2026-08-24 19:32:41 +08:00
Pine 8b0bca36a1 feat(db): P1 Alembic+模型整合 — 唯一总库基线迁移 + 培训/园区 ORM 模型
- 新增 alembic(ini/env async/script.mako/versions/0001_initial)。
- models.py 并入培训表(training_accounts/events/bookings/tests/courses/policy/plan/survey_logs)
  与园区表(park_tenants/companies/kb_docs/screens),与平台同库、命名加域前缀避免撞名。
- baseline 迁移用 create_all(幂等):既有平台表保留,新增培训/园区表被建。
- 验证:对临时库 uv run alembic upgrade head 建出全部新表。
2026-08-24 19:28:18 +08:00
Pine c4fb4fb498 fix(server-core): 种子容错 + 智能体种子幂等 — 修复 lifespan 建库被种子唯一冲突拖垮(全500)
根因:AGENT_SEED 用全局固定 agent id,demo 用户补种时对多个用户复用同一 id → (id,user_id,port)
唯一冲突 → seed_data 抛 IntegrityError → 平台 lifespan 建库失败 → app.state.db 未设置 → 全 500。
- repositories.initialize:种子包 try/except + rollback(记 warn),种子失败不再拖垮 lifespan 建库。
- seed._ensure_port_agents:改为按 agent.id 逐条判断已存在,避免重复插入幂等。
验证:登录/me/users/courses/roles 全 200。
2026-08-24 19:15:20 +08:00
Pine 691cb83e97 fix(server-core): lifespan 关闭时释放数据库引擎连接池 — 修复重启后 lifespan 挂起/库被锁
平台 DB(SQLAlchemy) shutdown 仅 close 会话,未 dispose 引擎,连接残留导致下次启动
initialize() 被锁/挂起(uvicorn 报 lifespan unsupported → app.state.db 未设置 → 全 500)。
改为 shutdown 时 dispose _engine,释放连接池。
2026-08-24 19:09:35 +08:00
Pine 88882553a9 feat(园区端): 园区状态(禁用/启用)+联级删除 — 禁用禁止登录,删除一并删资源
park_tenants 增 status 列(migration)、set_status、/park/tenants/{id}/status 端点;
/ park/auth/login 对被禁用园区返回 403;delete_tenant 联级删 企业/知识库/屏幕+引擎缓存;
_summary 含 status。TestClient:禁用→登录403、启用→200、删除→资源清零。
2026-08-24 19:05:16 +08:00
Pine 6458d5eb98 feat(园区端): 园区不再自建账号 — 改为绑定已有平台账号为管理员
create_tenant 不再建账号(admin 留空);/park/tenants POST 仅名称/简介;新增 /park/tenants/{id}/bind|unbind;
/park/auth/login 改为校验平台账号密码 + 该账号已绑定为某园区管理员(签发 tenant token)。
park_tenants 增 admin_username 列(init_db 迁移)。TestClient:创建(无账号)→绑定pine→pine登录园区端成功。
2026-08-24 18:46:41 +08:00
Pine 83e542c2c2 feat(平台端): 完整用户管理 — 新增 修改(PUT /admin/users/{id}) + 删除(DELETE /admin/users/{id})
UserRepository.delete(硬删);UpdateUserRequest(昵称/角色/子角色/组织/区域);update_user 调 update_profile+set_role,
delete_user 调 delete;走 action:user.manage + write_audit。TestClient:create/update/delete 均 200。
2026-08-24 18:40:59 +08:00
Pine 080314aa44 feat(rbac): 平台管理方(operator/op_super_admin)恒授予全权限 — 平台端拥有所有操作
permission_granted 对平台管理方直接返回 True,使平台端能执行全部 /admin/* 操作
(用户/园区/算力/课程/活动/资讯/任务/服务商/配置/角色/审计);与其它端口(投资人/政务/企业/OPC)不关联。
2026-08-24 18:36:30 +08:00
Pine 0448ab57ab fix(park): /park/tenants PUT 改用 TenantPatch(exclude_none) — 仅改管理员账号不再清空名称/简介
平台端管理园区账号(改 username/password)时,原 TenantBody 默认 name/intro 会被写入覆盖;
改用全可选 TenantPatch + exclude_none,只 patch 提供的字段。TestClient 验证保存账号保留名称/简介。
2026-08-24 18:28:14 +08:00
Pine d26d3dc3fa feat(park): /park/api/screen/data 支持全量数据编辑(动态/区域/产业构成/营收/成立时间等)
ScreenBody 增 intro/feed/zones/industryMix/address/phone/email/region/revenue_total/revenue_tax;
update_screen 全量写入 data_json 并 refresh_engine;screen_view 返回 zones/industryMix/feed/region。
TestClient:PUT 名称+两段简介+动态+区域+产业+营收+成立时间 → snapshot 反映。
2026-08-24 18:09:23 +08:00
Pine 81f4dfd0ad feat(park): 园区多租户 — SQLite(tenants表+companies+kb) + 每租户引擎 + 认证 + 作用域隔离
- tenants.py:park_tenants/park_companies/park_kb_docs 三表(serverdata/park/park.db),
  每园区独立 name/intro(两段式)/auth(账密 salted hash)/data(大屏锚点)/agent/kb;
  ensure_default_tenant 自愈建默认园区+灌 39 家企业。
- sim_engine 重构为 SimEngine(data)——每租户独立实例,get_engine(tid)/refresh_engine(tid)。
- auth.py:/park/auth/login(账密→长效 tenant JWT)、/park/auth/me、require_tenant(401)。
- mqtt:register/publish_command/publish_tick 按 tenant_id 作用域(拓扑为 command/tid/clientId)。
- routers:/park/tenants CRUD + 全部数据/指令端点租户作用域(authorization token 或 ?tenant_id)。
- app.py lifespan init_db + 逐租户 tick/publish;tools._query_companies 读租户库。
- .gitignore 增 serverdata/park/。TestClient:建租户/登录/快照隔离/企业CRUD/指令鉴权(无token401) 全过。
2026-08-24 18:06:51 +08:00
Pine 560cdb44c0 fix(server-core): main.py 入口改走 dispatcher:app — 修复 /park 与 /api(培训) 子应用 404
原 main.py 直接运行 app.main:app(仅平台应用),/park、/api(培训) 未路由所以 404;
改为运行 dispatcher:app(统一入口,含 app.main + app.training + app.park),
等价 uvicorn dispatcher:app --port 8090。'uv run main.py' 即可完整启动。
2026-08-24 17:32:55 +08:00
Pine 21cfab58fa feat(park): 子应用 lifespan 接入 s2s 实时语音栈(S2S_ENABLED=1 时后台起 :8765)
导入 .s2s_bridge.start_s2s_backend 并以 stop 事件控制;依赖 speech_to_speech
(vendor/s2s-cloud),启用前需 uv pip install -e app/park/vendor/s2s-cloud。
2026-08-24 17:29:37 +08:00
Pine 064b06ecf0 feat(park): 全量迁入园区重模块 llm/rag/asr/s2s/vision + 重依赖
迁入 app/park:llm(对话)、rag(双路向量知识库)、tools/ai_tools(智能体工具)、
asr(语音识别)、s2s_bridge(实时语音桥)、vision_yolo/vision_llm(人脸/多模态)、
knowledge/*.md、vendor/s2s-cloud(s2s 云化栈);routers 补 /api/ai|kb|asr|vision|
s2s|tools 端点。智能体提示词/企业名录改读 park_config 主数据源。pyproject 加重依赖
(dashscope/numpy/openai/torch/transformers/ultralytics/websockets/soundfile/scipy/
nltk/jinja2)。TestClient 冒烟:ai/chat(无 Key 走本地规则)、kb、s2s、tools、display 均 200。
2026-08-24 17:28:53 +08:00
Pine 03ba0810ae feat(park): 园区主数据源 park_config + /park 写端点(企业/智能体/知识库/大屏数据)
新增 app/park/park_config.py(serverdata/park/park_config.json 主数据源,企业默认自 sim_engine
COMPANIES 39 家导入);routers.py 增 /park/api/park/companies CRUD、/park/api/agent/config、
/park/api/kb/docs CRUD+reindex、/park/api/screen/data GET/PUT;/park/api/config 的 api_base
修正为 /park 前缀(避免大屏 request() /api 双写)。TestClient 冒烟通过。
2026-08-24 17:11:17 +08:00
Pine 4d4d38fe0f feat(park): 园区子应用 app/park 骨架迁入 — dispatcher /park 前缀分流
迁自 park-desktop/backend/app:config(数据目录→serverdata/park)/storage/sim_engine/
mqtt/event_bus + 精简 routers(health/settings/config/dashboard/park/companies/display/
events) + app.py 子应用(lifespan 起 MQTT hub+tick 线程, include_router prefix=/park)。
dispatcher.py 增 ROUTE_PARK_PREFIX + _prefix_app,与 app.training(/api)、app.main 分流。
pyproject 增 paho-mqtt(MQTT 必需)。AI/知识库/语音/视觉重模块延后全量迁入。
2026-08-24 16:57:27 +08:00
Pine 866f82dbc4 feat(admin): 运营端培训业务 P0 — 新增 /admin/courses|activities|bookings|tests
新增 courses 表(app/training/db.py SEED_COURSES),经 training_admin_bridge 桥接
app.training 的课程/活动(events)/报名(bookings)/测评(tests) 数据为统一运营视图;
schemas 增 Course/Activity/Booking/Test 请求模型;rbac_operator.py 增四件套端点
(含 create/status/patch),走 operator 角色 + action:* 权限码 + write_audit。
2026-08-24 16:57:13 +08:00
Pine b90539a013 feat(server): 统一登录+算力打通(port 阶段0-1)落地四层架构
- 登录:/auth/send-code·phone-login·wx-login·wx-phone(复用 RBAC 签发)
- 算力:services/compute_client(loopback :3000)+ /admin/compute/ping·provision
- /v1 relay 改走 compute-engine(前端不直连引擎)
- 模型:User 补 wx_openid/phone;仓储 async create+新方法
- 契约:api/schemas(auth/compute)Pydantic
2026-08-24 14:16:34 +08:00
Pine 01ef3c9637 refactor: schemas 抽取(DTO 从 models.py 与路由内联迁至 api/schemas/)
- 新建 api/schemas/:auth/agents/admin/ecosystem/investor/opc/operator/org/portals
- models.py 移除 15 个 Pydantic DTO(保留 ORM 数据模型层)
- 13 个路由内联 DTO 全部迁出,路由瘦身仅剩处理逻辑
- 全量 66 测试通过
2026-08-24 09:51:52 +08:00
Pine 2c737478dc fix: UserAdminService.create_user 返回原始 user(含 id),路由转 profile
- 修复 create_user 后 write_audit 取 user.id 的 KeyError
- 22 受影响测试 + 全量 66 全绿
2026-08-24 09:39:52 +08:00
Pine c99662cfec feat: 业务层 services 抽取完成(工作台/用户管理)
- DashboardService:OPC 工作台聚合(统计/进行中任务/智能体建议/月度收入/消息)
- UserAdminService:建号+默认身份联动、角色分配提权防护(action:role.grant_perm 仅超管)
- rbac_opc dashboard / rbac_admin create_user+set_role 接线
- services 层覆盖全部核心业务域,路由全瘦身
2026-08-24 09:35:08 +08:00
Pine 681067f84b fix: 修正 OrgRepository/OrgMember 新增方法(类作用域,修复 _to_dict_org NameError)
- FinanceRepository.create / OrgRepository.all+list_by_ids / OrgMember.list_for_user+get 精准插入
- 移除误插入 Config/Region 的冗余方法
- 31 受影响测试 + 全量 66 全绿
2026-08-24 02:14:22 +08:00
Pine c82f430986 feat: 业务层 services 继续抽取(路演/机构)
- RoadshowService:路演发布审核规则(operator 免审/政务范围免审/其余需审)
- OrgService:my_orgs 批量查消除 N+1、成员管理(admin 校验)
- 新增 Repository:Org.list_by_ids、OrgMember.list_for_user/get
- rbac_investor/rbac_org 接线,路由瘦身
2026-08-24 01:58:26 +08:00
Pine 413bd29390 feat: 业务层 services 抽取(财务/结算/补贴)
- FinanceService:opc_add_finance 直写 ORM 改为走 Repository.create(修复四层依赖违规)
- SettlementService:结算佣金(5%)/电子合同幂等/争议联动/投资撮合评分
- SubsidyService:政务三级审批状态机(区县→市→省→发放)
- rbac_ecosystem/rbac_government/rbac_opc 接线,路由瘦身
2026-08-24 01:54:04 +08:00
Pine 557ec90229 docs: 培训子应用 README 更新(async + serverdata 路径 + dispatcher 接入) 2026-08-24 01:47:10 +08:00
Pine 1af1ab6c2f feat: 培训子应用异步化(async 路由 + to_thread 同步 db)
- main.py 43 个路由改 async def
- db 保持同步 sqlite3,经 asyncio.to_thread 原子调用(不阻塞事件循环,规避 aiosqlite ASGI 线程/循环脆弱性)
- 依赖分析识别 db 触碰辅助函数(_count_enrolled/_adopt_phone 等),作为原子单元经 to_thread 调用
- db.get_conn 加 check_same_thread=False(每请求独立连接,跨线程安全)
- db.init_db 移入 async lifespan
- 验证:48 路由全通(报名/签到/统计/测评/政策/调研)+ 66 测试全绿
2026-08-24 01:43:52 +08:00
Pine a813a139dc feat: serverrun/serverdata 全服务栈(参考 PineSoundServer)
- serverrun/:start-all.sh 一键编排 + start-compute/start-emqx + envcopy/encrypt-certs
- 服务编排:core(Dockerfile+compose)、compute-engine(build.sh+compose)、mysql、redis、mqtt(EMQX)
- serverdata/:新增 compute-data/compute-logs/mysql-data/redis-data/emqx-data/emqx-log
- 全服务仅 loopback 暴露,算力引擎 :3000 经 core 代理
2026-08-24 01:00:52 +08:00
Pine 0c0e2586ed feat: serverdata 资源目录 + serverrun 运维编排
- serverdata/:统一承载全部资源目录(data/logs/files/keys/prompts/uploads)
- data/→serverdata/data、templates/→serverdata/prompts、uploads/→serverdata/uploads
- config.py 集中 serverdata 路径;培训子应用 db/uploads 指到 serverdata
- serverrun/:start.sh(初始化资源目录+启动 dispatcher)、Dockerfile、docker-compose(core+compute-engine+redis+mysql)
- 66 测试全绿
2026-08-24 00:42:35 +08:00
Pine a869b2934a test: 平台测试套件适配异步四层,66 全绿
- conftest 改为 monkeypatch DATABASE_URL + lifespan 建库(解决异步引擎跨事件循环)
- 修复 seed_data 辅助函数 await、_to_dict 链式 await、get_current_user await
- 修复 Database.initialize 建表于本实例引擎
- 平台 19 路由全部经异步接口回归通过
2026-08-24 00:34:28 +08:00
Pine 4ac8b81755 test: conftest 适配异步 Database(async URL + asyncio 初始化) 2026-08-23 23:59:34 +08:00
Pine d754d6ca4e feat: 业务层 services + 领域层 domain
- 领域层 domain/rules.py:RBAC 判定规则纯函数(role/permission/scope),接口层守卫改调领域规则
- 业务层 services/task_service.py:统一任务状态机(grab/bid/deliver/win/review),修复 deliver 无状态预检缺陷
- rbac_opc 抢单/投标/交付改走 TaskService
2026-08-23 23:56:39 +08:00
Pine 980a2db6d9 refactor: 平台应用异步四层架构(接口/业务/领域/基础设施)
- 基础设施层 async:SQLAlchemy 异步引擎/会话、33 Repository async 化、models/security/seed 迁入 infrastructure、新增 cache.py(redis.asyncio) 与 oss.py(aioboto3)
- 接口层:routers 迁 api/routers 并全 async,dependencies 迁 api/dependencies(get_db/get_current_user async)
- 依赖:sqlalchemy[asyncio]/aiosqlite/asyncmy/redis/aioboto3;config 异步 URL + Redis/OSS 配置
- 删除废弃:旧同步 db/dependencies/repositories/storage
- 验证:平台 19 路由 + 培训 48 路由全注册;/health /auth/login /auth/me /admin/tasks /notifications 等接口 async 可用
2026-08-23 23:52:58 +08:00
Pine 079035ad65 docs: 配置与文档(.env.example/.gitignore/README) 2026-08-23 22:37:18 +08:00
Pine 2f13af2352 feat: 补充平台应用入口与模板(main/storage/templates) 2026-08-23 22:37:18 +08:00
Pine 6edcec4048 feat: 统一入口 dispatcher(对外 opc.pinesound.cn)
- /api/* /uploads/* /SpXvScDiDT.txt → 培训子应用
- 其余 → 平台应用;驱动双子应用 lifespan
2026-08-23 22:36:00 +08:00
Pine 8b43d3df52 feat: 培训子应用迁入(app/training,/api/*)
- 报名/测评/政策/调研,独立 data/opc.db
- 源自原培训后端,路径调整至 server-core
2026-08-23 22:36:00 +08:00
Pine 26fa546f67 feat: 核心服务端基础框架(身份/平台 API)
- 七端口 RBAC、select-identity、JWT、审计
- FastAPI + SQLAlchemy + SQLite,/auth /opc /admin /agents 等路由
2026-08-23 22:35:59 +08:00