feat(bot): centralize defaults, refine ambiguity lifecycle, improve entity resolution and auto-create new projects
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
"""Add-project flow: name + optional description."""
|
||||
import logging
|
||||
|
||||
from app import drafts as draft_store
|
||||
from app.api.client import ApiError
|
||||
from app.drafts import (
|
||||
KIND_PROJECT, merge_project_patch, new_project_payload, project_missing,
|
||||
)
|
||||
from app.keyboards import simple_review_keyboard
|
||||
from app.texts import ERR_GENERIC, esc, project_committed_report, project_review_text
|
||||
|
||||
logger = logging.getLogger("bot.project")
|
||||
|
||||
|
||||
async def handle_entities(ctx, chat_id, user, patch: dict, source: str | None) -> None:
|
||||
draft = await draft_store.get_active(chat_id, KIND_PROJECT)
|
||||
if draft is not None:
|
||||
payload = draft.payload
|
||||
merge_project_patch(payload, patch)
|
||||
else:
|
||||
payload = new_project_payload()
|
||||
merge_project_patch(payload, patch)
|
||||
draft = await draft_store.create(chat_id, KIND_PROJECT, payload, source=source)
|
||||
await draft_store.save_payload(draft, missing={"fields": project_missing(payload)})
|
||||
await render(ctx, chat_id, draft, fresh=draft.review_message_id is None)
|
||||
|
||||
|
||||
def _keyboard(payload: dict, draft_id: str) -> dict:
|
||||
return simple_review_keyboard(draft_id, KIND_PROJECT, [])
|
||||
|
||||
|
||||
async def render(ctx, chat_id, draft, fresh: bool = True) -> None:
|
||||
payload = draft.payload
|
||||
missing = project_missing(payload)
|
||||
text = project_review_text(payload, missing)
|
||||
keyboard = _keyboard(payload, draft.id)
|
||||
if fresh:
|
||||
message = await ctx.send(chat_id, text, reply_markup=keyboard)
|
||||
draft.review_message_id = (message or {}).get("message_id")
|
||||
await draft_store.save_payload(draft, missing={"fields": missing},
|
||||
review_message_id=draft.review_message_id)
|
||||
else:
|
||||
await ctx.edit(chat_id, draft.review_message_id, text, reply_markup=keyboard)
|
||||
await draft_store.save_payload(draft, missing={"fields": missing})
|
||||
|
||||
|
||||
async def commit(ctx, chat_id, user, draft) -> None:
|
||||
payload = draft.payload
|
||||
missing = {m["key"]: m["ok"] for m in project_missing(payload)}
|
||||
if not missing.get("name"):
|
||||
await ctx.send(chat_id, "ثبت ممکن نیست؛ نام پروژه مشخص نشده است.")
|
||||
return
|
||||
body = {"name": payload["name"]}
|
||||
if payload.get("description"):
|
||||
body["description"] = payload["description"]
|
||||
try:
|
||||
created = await ctx.api.create_project(body, actor_id=user.actor_id)
|
||||
except ApiError as exc:
|
||||
await ctx.send(chat_id, ERR_GENERIC.format(detail=esc(exc.message)))
|
||||
return
|
||||
except Exception:
|
||||
logger.exception("create_project failed")
|
||||
await ctx.send(chat_id, ERR_GENERIC.format(detail="خطای سرور"))
|
||||
return
|
||||
await draft_store.set_status(draft.id, "committed")
|
||||
ctx.resolver.invalidate("projects")
|
||||
await ctx.send(chat_id, project_committed_report(created))
|
||||
Reference in New Issue
Block a user