Support selectable demo exchanges and configurable analysis limits

Persist manual requests until exchange confirmation, preserve stop protection, and reconcile fills before settling plans. Tighten model stream, crawler, skill, research accounting, and frontend race handling, with regression coverage. Keep queued analyses pending until a fresh account snapshot is available.
This commit is contained in:
eezd committed 2026-10-20 18:45:00 +08:00
1 parent fcaedfb358
commit 285b3952d7
33 files changed
+1890 -325

No files matched your search

+2 -2
View File
@@ -116,8 +116,8 @@ async def patch(node_id: int, body: NodePatch, session: Annotated[AsyncSession,
node = await get_node(session, node_id)
if body.name is not None:
name = body.name.strip()
if "/" in name:
raise HTTPException(status.HTTP_400_BAD_REQUEST, "名称不能包含 /")
if not name or "/" in name:
raise HTTPException(status.HTTP_400_BAD_REQUEST, "名称不能为空,也不能包含 /")
duplicate = await session.scalar(select(SkillNode.id).where(
SkillNode.parent_id.is_not_distinct_from(node.parent_id), SkillNode.name == name, SkillNode.id != node_id
))