chore: merge develop preserving documentation structure and console UX
Integrate develop at 523bade3 while retaining concise agent guidance, rustdoc-owned design rationale, and current console history/rewind behavior. Adapt incoming tests to public entry-ID rewind and synchronize OpenAPI/TypeScript artifacts.
Validation: default-member cargo test --all-features (4936 passed, 23 ignored), root cargo check, all-feature rustdoc with broken links denied, format/diff/name guards, OpenAPI and 11 TypeScript freshness checks. Web: 613 unit, 327 component, 7 Ticket browser and 3 Console browser tests; check/build passed. Merged-state Ticket visual review at 1440/768/390px in light/dark; no matching pre-merge image baseline. E2E/live-provider checks not run.
This commit is contained in:
+773
-130
File diff suppressed because it is too large
Load Diff
@@ -438,6 +438,34 @@ fn validate_ticket_browser_operations(
|
||||
paths: &Map<String, Value>,
|
||||
) -> Result<BTreeSet<String>, GenerationError> {
|
||||
let operations = [
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/ticket-tags",
|
||||
method: "get",
|
||||
operation_id: "workspace_ticket_tag_list",
|
||||
request: None,
|
||||
successes: &[("200", "Array_of_WorkspaceTag")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/ticket-tags",
|
||||
method: "post",
|
||||
operation_id: "workspace_ticket_tag_mutate",
|
||||
request: Some("WorkspaceTagMutation"),
|
||||
successes: &[("200", "WorkspaceTag")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/tickets/{id}/tags",
|
||||
method: "put",
|
||||
operation_id: "ticket_tags_set",
|
||||
request: Some("TicketTagSetRequest"),
|
||||
successes: &[("200", "Array_of_WorkspaceTag")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/tickets/query",
|
||||
method: "post",
|
||||
operation_id: "ticket_query",
|
||||
request: Some("TicketQueryRequest"),
|
||||
successes: &[("200", "TicketQueryResponse")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/tickets",
|
||||
method: "get",
|
||||
@@ -481,11 +509,74 @@ fn validate_ticket_browser_operations(
|
||||
successes: &[("200", "TicketDetail")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/tickets/{id}/state",
|
||||
path: "/workspaces/{workspace_id}/tickets/{ticket_id}/case",
|
||||
method: "post",
|
||||
operation_id: "ticket_state_transition",
|
||||
request: Some("BrowserTransitionTicketStateRequest"),
|
||||
successes: &[("200", "TicketDetail")],
|
||||
operation_id: "ticket_case_update",
|
||||
request: Some("TicketCaseUpdateRequest"),
|
||||
successes: &[("200", "TicketSummary")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/workspaces/{workspace_id}/tickets/{ticket_id}/assignment-tracking/assignments",
|
||||
method: "get",
|
||||
operation_id: "ticket_assignments_page",
|
||||
request: None,
|
||||
successes: &[("200", "TicketAssignmentsPage")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/workspaces/{workspace_id}/tickets/{ticket_id}/assignment-diagnostics",
|
||||
method: "get",
|
||||
operation_id: "ticket_assignment_diagnostics",
|
||||
request: None,
|
||||
successes: &[("200", "TicketAssignmentDiagnosticsPage")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/workspaces/{workspace_id}/tickets/{ticket_id}/assignment-answer",
|
||||
method: "post",
|
||||
operation_id: "ticket_assignment_answer",
|
||||
request: Some("TicketAssignmentAnswer"),
|
||||
successes: &[("200", "TicketAssignmentAnswerReceipt")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/tickets/{ticket_id}/assignment-tracking/assignments",
|
||||
method: "get",
|
||||
operation_id: "ticket_assignments_page_browser",
|
||||
request: None,
|
||||
successes: &[("200", "TicketAssignmentsPage")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/tickets/{ticket_id}/assignment-diagnostics",
|
||||
method: "get",
|
||||
operation_id: "ticket_assignment_diagnostics_browser",
|
||||
request: None,
|
||||
successes: &[("200", "TicketAssignmentDiagnosticsPage")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/tickets/{ticket_id}/assignment-answer",
|
||||
method: "post",
|
||||
operation_id: "ticket_assignment_answer_browser",
|
||||
request: Some("TicketAssignmentAnswer"),
|
||||
successes: &[("200", "TicketAssignmentAnswerReceipt")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/workspaces/{workspace_id}/tickets/{ticket_id}/assignment-tracking",
|
||||
method: "get",
|
||||
operation_id: "ticket_assignment_tracking_get",
|
||||
request: None,
|
||||
successes: &[("200", "Array_of_TicketAssignmentTrackingProjection")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/workspaces/{workspace_id}/tickets/{ticket_id}/assignment-tracking",
|
||||
method: "post",
|
||||
operation_id: "ticket_assignment_tracking_update",
|
||||
request: Some("TicketAssignmentTrackingUpdate"),
|
||||
successes: &[("200", "TicketAssignmentTrackingProjection")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/workspaces/{workspace_id}/tickets/{ticket_id}/assignment-tracking/history",
|
||||
method: "get",
|
||||
operation_id: "ticket_assignment_tracking_history",
|
||||
request: None,
|
||||
successes: &[("200", "TicketAssignmentTrackingHistoryPage")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/tickets/{id}/ready",
|
||||
@@ -508,13 +599,6 @@ fn validate_ticket_browser_operations(
|
||||
request: Some("BrowserQueueTicketRequest"),
|
||||
successes: &[("200", "TicketQueueOutcome")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/tickets/{id}/close",
|
||||
method: "post",
|
||||
operation_id: "ticket_close",
|
||||
request: Some("BrowserCloseTicketRequest"),
|
||||
successes: &[("200", "TicketDetail")],
|
||||
},
|
||||
OperationContract {
|
||||
path: "/api/w/{workspace_id}/objectives",
|
||||
method: "get",
|
||||
@@ -1906,6 +1990,54 @@ mod tests {
|
||||
assert!(!detail.contains(" target:"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ticket_browser_generator_exposes_case_judgment_and_closure_projections() {
|
||||
let openapi = crate::canonical_openapi_document()
|
||||
.unwrap()
|
||||
.to_json()
|
||||
.unwrap();
|
||||
let output = generate_ticket_browser_typescript(&openapi).unwrap();
|
||||
assert!(output.contains("export type BrowserTicketState = \"open\" | \"closed\";"));
|
||||
let request = output
|
||||
.lines()
|
||||
.find(|line| line.starts_with("export type TicketCaseUpdateRequest ="))
|
||||
.unwrap();
|
||||
for field in [
|
||||
"expected_content_digest: string",
|
||||
"expected_state: TicketState",
|
||||
"expected_closure_operation_key: string | null",
|
||||
"operation_key: string",
|
||||
"action: TicketCaseAction",
|
||||
"explanation: string",
|
||||
] {
|
||||
assert!(request.contains(field), "missing {field}: {request}");
|
||||
}
|
||||
assert!(!request.contains("author"));
|
||||
assert!(output.contains("export type TicketClosureReason = \"completed\" | \"not_planned\" | \"duplicate\" | \"unknown\" | { other: string; };"));
|
||||
let detail = output
|
||||
.lines()
|
||||
.find(|line| line.starts_with("export type TicketDetail ="))
|
||||
.unwrap();
|
||||
for field in [
|
||||
"state: BrowserTicketState",
|
||||
"closure_operation_key?: string | null",
|
||||
"current_closure?: TicketClosureJudgment | null",
|
||||
"closure_history: Array<TicketCaseHistoryEntry>",
|
||||
"legacy_handoff?: TicketLegacyWorkflowSnapshot | null",
|
||||
] {
|
||||
assert!(detail.contains(field), "missing {field}: {detail}");
|
||||
}
|
||||
for removed in [
|
||||
"BrowserTransitionTicketStateRequest",
|
||||
"BrowserCloseTicketRequest",
|
||||
"CompleteTicketRequest",
|
||||
"BrowserTicketWorkflowState",
|
||||
"done_not_closed",
|
||||
] {
|
||||
assert!(!output.contains(removed), "{removed}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checked_in_ticket_browser_typescript_is_current() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user