Add Jin10 QR connection with cancellable login tasks

Store account credentials encrypted and bind QR tasks to administrator sessions. Report calendar access as awaiting validation after login.

Prevent late polls and status responses from overwriting cancelled or newer operations, and clean up QR tasks when settings unmount. Cover authentication, cancellation races, and stale frontend responses.
This commit is contained in:
eezd committed 2026-10-30 22:42:26 +08:00
1 parent 5a991e3d29
commit 62d8c7eb65
14 files changed
+871 -1

No files matched your search

@@ -1,3 +1,4 @@
from alphapulse.models.jin10 import Jin10Connection
from alphapulse.models.risk import RiskSettings, RiskEvent, RiskAnalysis, RiskSnapshot
from alphapulse.core.db import Base
from alphapulse.models.ai import AiProvider, ChatMessage, ChatSession, ContextVersion, SkillNode, SkillVersion
@@ -7,6 +8,7 @@ from alphapulse.models.news import CrawlLog, CrawlRun, NewsItem, NewsRevision, R
from alphapulse.models.trading import NewsSignal, TradingAccount, TradingAnalysis, TradingCredential, TradingEvent, TradingFill, TradingOrder, TradingSymbol
__all__ = [
"Jin10Connection",
"RiskSettings", "RiskEvent", "RiskAnalysis", "RiskSnapshot",
"AiProvider",
"Base",
+21
View File
@@ -0,0 +1,21 @@
"""Encrypted connection and short-lived, session-owned QR login state."""
from datetime import datetime
from sqlalchemy import DateTime, LargeBinary, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from alphapulse.core.db import Base
class Jin10Connection(Base):
__tablename__ = "jin10_connection"
id: Mapped[int] = mapped_column(primary_key=True)
token_encrypted: Mapped[bytes | None] = mapped_column(LargeBinary)
connected_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
task_id: Mapped[str | None] = mapped_column(String(64))
owner: Mapped[str | None] = mapped_column(String(64))
qr_encrypted: Mapped[bytes | None] = mapped_column(LargeBinary)
expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
next_poll_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
error: Mapped[str | None] = mapped_column(Text)