feat(apiserver): surface human-readable job ID (fmt_jobid form) in responses

The MCP/apiserver returned the raw 64-bit job ID (e.g. 73930964699447296)
while xce_test/xcecli display the dash form (e.g. 1-0-1786585485-0) that
parse_jobid accepts. A user taking the numeric form into xce_test fails to
parse it. The apiserver is the data-correctness owner (MCP only reads), so
it now emits the controller's fmt_jobid form alongside the numeric ID:

- models: JobSubmitResponse gains job_id_human; job list rows gain
  job_id_human (processJobData), using the existing backend.FormatJobID.
- schedulerclient: URMJob.HumanID + SubmitJobResult.JobIDHuman parse it.
- Tests: backend.FormatJobID (real t1 job, pre-cluster1 job, array child);
  processJobData adds job_id_human.

Also rename the SSE permission event:subscribe → event:view so mcp_readonly
stays strictly *:view (the read-only invariant test enforces).

Verified live on t1: scheduler_submit returns job_id_human 1-0-1786586474-0
and scheduler_get_job returns human_id.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
lei.chen 2026-08-13 02:01:52 +00:00
parent 3d1560d69c
commit 673f2eb792
9 changed files with 135 additions and 10 deletions

View file

@ -150,7 +150,7 @@ func Router() *gin.Engine {
eventsHandler := &controllers.EventsController{}
// Server-Sent Events stream of job lifecycle events. Long-lived
// connection; keep-alive comments are sent when idle.
eventsApi.GET("", controllers.RequirePermission("event:subscribe"), eventsHandler.SubscribeJobs)
eventsApi.GET("", controllers.RequirePermission("event:view"), eventsHandler.SubscribeJobs)
}
// ################ case: resources route