This commit is contained in:
@@ -141,6 +141,12 @@ class SelfCorrelationReference(Contract):
|
||||
alpha_id: AlphaId
|
||||
|
||||
|
||||
class SubmissionCheck(Contract):
|
||||
alpha_id: AlphaId
|
||||
snapshot: str = Field(pattern=r"^[a-f0-9]{64}$")
|
||||
descriptions: dict[str, str] = Field(min_length=1, max_length=2)
|
||||
|
||||
|
||||
class History(Page):
|
||||
source: str | None = Field(default=None, max_length=100)
|
||||
reference: str | None = Field(default=None, max_length=200)
|
||||
|
||||
@@ -22,6 +22,8 @@ from ..models import Account, Alpha, BacktestItem, Job, JobItem, ResearchRequest
|
||||
from ..research.serialization import encode_snapshot
|
||||
from ..research.workspace_contracts import FieldAvailabilityInput
|
||||
from ..schemas import JobInput
|
||||
from ..submission import CheckInput, correlation_allows_check, create_check_job, local_alpha, source
|
||||
from ..submission import fingerprint as submission_fingerprint
|
||||
from .contracts import DirectCandidate, History
|
||||
from .queries import EvidenceQueries, page
|
||||
|
||||
@@ -51,6 +53,11 @@ class ResearchAccess:
|
||||
"confirmation": "调用者须已获本批执行授权;直接提交后返回稳定运行 ID",
|
||||
"duplicate_policies": ["reject", "rerun"], "permissions": sorted(self.principal.scopes),
|
||||
"metadata_only": True, "actual_platform_allowance": None,
|
||||
"submission_check": {
|
||||
"check_with": "check_submission", "read_with": "get_submission_check",
|
||||
"job_with": "get_refresh_job", "max_targets": 1,
|
||||
"description_writeback": True, "production_submission": False,
|
||||
},
|
||||
"self_correlation": {
|
||||
"check_with": "check_self_correlation", "read_with": "get_self_correlation",
|
||||
"job_with": "get_refresh_job", "max_targets": 100, "source": "local",
|
||||
@@ -156,7 +163,7 @@ class ResearchAccess:
|
||||
|
||||
async def refresh_job(self, args):
|
||||
job = await self.db.get(Job, args.job_id)
|
||||
if not job or job.kind not in {"catalog_sync", "field_sync", "pnl_refresh", "self_correlation"}:
|
||||
if not job or job.kind not in {"catalog_sync", "field_sync", "pnl_refresh", "self_correlation", "submission_check"}:
|
||||
raise ResearchError("NOT_FOUND", "研究刷新任务不存在")
|
||||
result = await self.business.get_job_status(args.job_id)
|
||||
query = select(JobItem).where(JobItem.job_id == job.id, JobItem.error.is_not(None))
|
||||
@@ -187,6 +194,29 @@ class ResearchAccess:
|
||||
status = "not_cached" if not data["cached"] else "stale" if data["result"]["stale"] else "available"
|
||||
return {"alpha_id": args.alpha_id, "source": "local", "status": status, **data}
|
||||
|
||||
async def submission_check_context(self, args):
|
||||
"""Read cached review context and check evidence without upstream requests."""
|
||||
alpha = await local_alpha(self.db, args.alpha_id)
|
||||
context = source(alpha.raw)
|
||||
job = await self.db.scalar(select(Job).where(
|
||||
Job.kind == "submission_check", Job.payload["alpha_ids"][0].as_string() == args.alpha_id
|
||||
).order_by(Job.created_at.desc()).limit(1))
|
||||
return {"alpha_id": args.alpha_id, "snapshot": submission_fingerprint(context),
|
||||
**context, "descriptions": {key: item["description"] for key, item in context["sections"].items()},
|
||||
"can_check": alpha.status == "UNSUBMITTED" and await correlation_allows_check(self.db, args.alpha_id),
|
||||
"checks": alpha.checks, "source": "local_cache", "production_submission": False,
|
||||
"job_id": job.id if job else None, "job_status": job.status if job else None,
|
||||
"checked_at": job.checkpoint.get("checked_at") if job else None}
|
||||
|
||||
async def check_submission(self, args):
|
||||
"""Queue the shared reviewed-description/check flow; never submit an Alpha."""
|
||||
job = await create_check_job(self.db, args.alpha_id, CheckInput(
|
||||
snapshot=args.snapshot, descriptions=args.descriptions))
|
||||
self.wake = "jobs"
|
||||
return {"job_id": job.id, "status": job.status, "alpha_id": args.alpha_id,
|
||||
"production_submission": False, "job_with": "get_refresh_job",
|
||||
"read_with": "get_submission_check"}
|
||||
|
||||
async def history(self, args):
|
||||
return await self.evidence.history(args)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user