feat(ui): פאנל אישור-תכניות — טאב /precedents + מרכז-אישורים (PR-B)
הטמעת ה-UI למרשם-התכניות אחרי אישור-עיצוב ב-Claude Design (מוקאפ 22-plans-review). - web-ui/src/lib/api/plans.ts: hooks (usePlansPending, usePlanDuplicates, useUpsertPlan, useUpdatePlan, useReviewPlan, useMergePlans) + טיפוס Plan מקומי. - plans-review-panel.tsx: כרטיס-תכנית עם משפט-הציטוט הקנוני (כפי שייכתב בבלוק ט), שדות-תוקף, סימון חוסר-תאריך, באנר "כפילות אפשרית → מזג לכאן" (find_similar_plans, מיזוג ידני — G10), עריכה/הוספה inline עם תצוגה-מקדימה חיה של הציטוט. - precedents/page.tsx: טאב "תכניות" + PlansPendingPill + deep-link tab=plans. - web/app.py: href קטגוריית-התכניות במרכז-האישורים → /precedents?tab=plans. - api:types: types.ts מחודש מ-openapi החי (5 נתיבי /api/plans). מרכז-האישורים (/approvals) מרנדר קטגוריות גנרית — קטגוריית-התכניות (PR-A) מופיעה אוטומטית. אימות: api:types ✓, tsc --noEmit ✓, lint exit=0 (ללא אזהרות חדשות). Invariants: G10 (אישור אנושי + מיזוג ידני) · INV-AH (ציטוט דטרמיניסטי, תצוגה-מקדימה תואמת format_plan_citation) · INV-IA (שער-אחד: טאב קיים + מרכז-אישורים, ללא עמוד חדש) · X6 (UI↔API, apiRequest + טיפוסים). עבר שער-העיצוב Claude Design (feedback_claude_design_gate). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
152
web-ui/src/lib/api/plans.ts
Normal file
152
web-ui/src/lib/api/plans.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* Planning-schemes registry (מרשם-התכניות, V38) — typed API hooks.
|
||||
*
|
||||
* SSOT for a plan's identity + validity, reused across cases. LLM-extracted rows
|
||||
* arrive pending_review; only approved validity feeds block-tet (INV-DM5/G10).
|
||||
* Variant duplicates are surfaced (usePlanDuplicates), never auto-merged — the
|
||||
* chair merges manually. Mirrors the precedent-library hook conventions.
|
||||
*/
|
||||
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { apiRequest } from "./client";
|
||||
|
||||
export type PlanReviewStatus = "pending_review" | "approved" | "rejected";
|
||||
|
||||
export type PlanDiscrepancy = {
|
||||
field: string;
|
||||
old: string;
|
||||
new: string;
|
||||
source_case_number?: string;
|
||||
via?: string;
|
||||
};
|
||||
|
||||
export type Plan = {
|
||||
id: string;
|
||||
plan_number: string;
|
||||
display_name: string;
|
||||
aliases: string[];
|
||||
plan_type: string;
|
||||
gazette_date: string | null; // ISO YYYY-MM-DD
|
||||
yalkut_number: string;
|
||||
purpose: string;
|
||||
citation_formatted: string; // the deterministic block-tet sentence
|
||||
review_status: PlanReviewStatus;
|
||||
source_case_number: string;
|
||||
source_document_id: string | null;
|
||||
model_used: string;
|
||||
discrepancies: PlanDiscrepancy[];
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
/** Only present on a duplicate-candidate hit. */
|
||||
match_reason?: string;
|
||||
};
|
||||
|
||||
export const planKeys = {
|
||||
all: ["plans"] as const,
|
||||
pending: () => [...planKeys.all, "pending"] as const,
|
||||
duplicates: (id: string) => [...planKeys.all, "duplicates", id] as const,
|
||||
};
|
||||
|
||||
/** All plans awaiting the chair gate (G10). */
|
||||
export function usePlansPending(limit = 500) {
|
||||
return useQuery({
|
||||
queryKey: planKeys.pending(),
|
||||
queryFn: ({ signal }) =>
|
||||
apiRequest<{ items: Plan[]; count: number }>(
|
||||
`/api/plans?review_status=pending_review&limit=${limit}`,
|
||||
{ signal },
|
||||
),
|
||||
staleTime: 5_000,
|
||||
refetchOnMount: "always",
|
||||
});
|
||||
}
|
||||
|
||||
/** Near-duplicate candidates for a plan — surfaced for manual merge. */
|
||||
export function usePlanDuplicates(planId: string, enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: planKeys.duplicates(planId),
|
||||
queryFn: ({ signal }) =>
|
||||
apiRequest<{ items: Plan[]; count: number }>(
|
||||
`/api/plans/${encodeURIComponent(planId)}/duplicates`,
|
||||
{ signal },
|
||||
),
|
||||
enabled: enabled && !!planId,
|
||||
staleTime: 10_000,
|
||||
});
|
||||
}
|
||||
|
||||
export type PlanUpsert = {
|
||||
plan_number: string;
|
||||
display_name?: string;
|
||||
plan_type?: string;
|
||||
gazette_date?: string; // ISO; "" = unknown
|
||||
yalkut_number?: string;
|
||||
purpose?: string;
|
||||
review_status?: PlanReviewStatus;
|
||||
aliases?: string[];
|
||||
};
|
||||
|
||||
export type PlanEdit = {
|
||||
plan_number: string;
|
||||
display_name?: string;
|
||||
plan_type?: string;
|
||||
gazette_date?: string;
|
||||
yalkut_number?: string;
|
||||
purpose?: string;
|
||||
aliases?: string[] | null;
|
||||
};
|
||||
|
||||
function invalidate(qc: ReturnType<typeof useQueryClient>) {
|
||||
qc.invalidateQueries({ queryKey: planKeys.all });
|
||||
// the chair-pending aggregate (/approvals) carries a plans count (INV-IA2)
|
||||
qc.invalidateQueries({ queryKey: ["chair", "pending"] });
|
||||
}
|
||||
|
||||
/** Manual chair add/upsert (idempotent on normalized plan_number). */
|
||||
export function useUpsertPlan() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (body: PlanUpsert) =>
|
||||
apiRequest<Plan>(`/api/plans`, { method: "POST", body }),
|
||||
onSuccess: () => invalidate(qc),
|
||||
});
|
||||
}
|
||||
|
||||
/** Edit/fix a plan by id (refuses a number collision → use merge). */
|
||||
export function useUpdatePlan() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ id, patch }: { id: string; patch: PlanEdit }) =>
|
||||
apiRequest<Plan>(
|
||||
`/api/plans/${encodeURIComponent(id)}`,
|
||||
{ method: "PATCH", body: patch },
|
||||
),
|
||||
onSuccess: () => invalidate(qc),
|
||||
});
|
||||
}
|
||||
|
||||
/** Chair gate (G10): approve / reject / reset. */
|
||||
export function useReviewPlan() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ id, status }: { id: string; status: PlanReviewStatus }) =>
|
||||
apiRequest<Plan>(
|
||||
`/api/plans/${encodeURIComponent(id)}/review`,
|
||||
{ method: "POST", body: { review_status: status } },
|
||||
),
|
||||
onSuccess: () => invalidate(qc),
|
||||
});
|
||||
}
|
||||
|
||||
/** Fold a source plan into a target (manual dedup); source is deleted. */
|
||||
export function useMergePlans() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ sourceId, targetId }: { sourceId: string; targetId: string }) =>
|
||||
apiRequest<Plan>(
|
||||
`/api/plans/merge`,
|
||||
{ method: "POST", body: { source_id: sourceId, target_id: targetId } },
|
||||
),
|
||||
onSuccess: () => invalidate(qc),
|
||||
});
|
||||
}
|
||||
@@ -2947,9 +2947,11 @@ export interface paths {
|
||||
* Operations Drain Toggle
|
||||
* @description Switch a cron drain on/off (the 'startup type' in the services panel).
|
||||
*
|
||||
* Written straight to drain_controls — no host roundtrip; the drain reads the
|
||||
* flag at startup and no-ops when disabled (pm2 cron_restart can't be trusted
|
||||
* to stay stopped).
|
||||
* Written to drain_controls so the drain no-ops at its NEXT startup (pm2
|
||||
* cron_restart can't be trusted to stay stopped). On disable we ALSO stop any
|
||||
* currently-running process immediately via the host pm2 bridge — the DB flag
|
||||
* alone wouldn't halt a drain mid-run. Best-effort: a bridge failure doesn't
|
||||
* fail the toggle (the supervisor stops it on its next tick as a backstop).
|
||||
*/
|
||||
post: operations["operations_drain_toggle_api_operations_drains__name__disabled_post"];
|
||||
delete?: never;
|
||||
@@ -3087,6 +3089,33 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/operations/agents/migrate-adapter": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* Operations Agent Migrate Adapter
|
||||
* @description Migrate an agent (or 'all') to a target adapter, in both companies.
|
||||
*
|
||||
* The migration is host-side (it needs the host filesystem — generated
|
||||
* instruction copies, the gemini settings file — and the embedded board DB),
|
||||
* so this proxies scripts/migrate_agent_adapter.py through the court-fetch host
|
||||
* bridge, Bearer-authenticated exactly like the pm2 controls. The script's exit
|
||||
* code + stdout/stderr are relayed verbatim so the dashboard can show preflight
|
||||
* warnings (a non-zero --check is a refusal to render, not a transport error).
|
||||
*/
|
||||
post: operations["operations_agent_migrate_adapter_api_operations_agents_migrate_adapter_post"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/digests/{digest_id}": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -3428,6 +3457,111 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/plans": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/**
|
||||
* Plans List
|
||||
* @description List the plans registry; filter by review_status (queue) or fuzzy q (search).
|
||||
*/
|
||||
get: operations["plans_list_api_plans_get"];
|
||||
put?: never;
|
||||
/**
|
||||
* Plan Create
|
||||
* @description Manual chair add/upsert (idempotent on normalized plan_number).
|
||||
*/
|
||||
post: operations["plan_create_api_plans_post"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/plans/{plan_id}/duplicates": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/**
|
||||
* Plan Duplicates
|
||||
* @description Near-duplicate candidates for a plan — for the chair to merge (G10, no auto-merge).
|
||||
*/
|
||||
get: operations["plan_duplicates_api_plans__plan_id__duplicates_get"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/plans/{plan_id}": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** Plan Get */
|
||||
get: operations["plan_get_api_plans__plan_id__get"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
/**
|
||||
* Plan Edit
|
||||
* @description Edit/fix a plan by id (chair). Refuses a number collision (→ merge instead).
|
||||
*/
|
||||
patch: operations["plan_edit_api_plans__plan_id__patch"];
|
||||
trace?: never;
|
||||
};
|
||||
"/api/plans/{plan_id}/review": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* Plan Review
|
||||
* @description Chair gate (G10): approve / reject / reset.
|
||||
*/
|
||||
post: operations["plan_review_api_plans__plan_id__review_post"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/plans/merge": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* Plan Merge
|
||||
* @description Fold source plan into target (chair-initiated dedup); source is deleted.
|
||||
*/
|
||||
post: operations["plan_merge_api_plans_merge_post"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/missing-precedents": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -3556,6 +3690,22 @@ export interface paths {
|
||||
export type webhooks = Record<string, never>;
|
||||
export interface components {
|
||||
schemas: {
|
||||
/** AdapterMigrationRequest */
|
||||
AdapterMigrationRequest: {
|
||||
/** Action */
|
||||
action: string;
|
||||
/** Agent */
|
||||
agent?: string | null;
|
||||
/** To */
|
||||
to?: string | null;
|
||||
/** Model */
|
||||
model?: string | null;
|
||||
/**
|
||||
* Relax Tools
|
||||
* @default false
|
||||
*/
|
||||
relax_tools: boolean;
|
||||
};
|
||||
/** AgentCommentRequest */
|
||||
AgentCommentRequest: {
|
||||
/** Body */
|
||||
@@ -4428,6 +4578,90 @@ export interface components {
|
||||
*/
|
||||
appeal_type: string;
|
||||
};
|
||||
/** PlanEditRequest */
|
||||
PlanEditRequest: {
|
||||
/** Plan Number */
|
||||
plan_number: string;
|
||||
/**
|
||||
* Display Name
|
||||
* @default
|
||||
*/
|
||||
display_name: string;
|
||||
/**
|
||||
* Plan Type
|
||||
* @default
|
||||
*/
|
||||
plan_type: string;
|
||||
/**
|
||||
* Gazette Date
|
||||
* @default
|
||||
*/
|
||||
gazette_date: string;
|
||||
/**
|
||||
* Yalkut Number
|
||||
* @default
|
||||
*/
|
||||
yalkut_number: string;
|
||||
/**
|
||||
* Purpose
|
||||
* @default
|
||||
*/
|
||||
purpose: string;
|
||||
/** Aliases */
|
||||
aliases?: string[] | null;
|
||||
};
|
||||
/** PlanMergeRequest */
|
||||
PlanMergeRequest: {
|
||||
/** Source Id */
|
||||
source_id: string;
|
||||
/** Target Id */
|
||||
target_id: string;
|
||||
};
|
||||
/** PlanReviewRequest */
|
||||
PlanReviewRequest: {
|
||||
/** Review Status */
|
||||
review_status: string;
|
||||
};
|
||||
/** PlanUpsertRequest */
|
||||
PlanUpsertRequest: {
|
||||
/** Plan Number */
|
||||
plan_number: string;
|
||||
/**
|
||||
* Display Name
|
||||
* @default
|
||||
*/
|
||||
display_name: string;
|
||||
/**
|
||||
* Plan Type
|
||||
* @default
|
||||
*/
|
||||
plan_type: string;
|
||||
/**
|
||||
* Gazette Date
|
||||
* @default
|
||||
*/
|
||||
gazette_date: string;
|
||||
/**
|
||||
* Yalkut Number
|
||||
* @default
|
||||
*/
|
||||
yalkut_number: string;
|
||||
/**
|
||||
* Purpose
|
||||
* @default
|
||||
*/
|
||||
purpose: string;
|
||||
/**
|
||||
* Review Status
|
||||
* @default approved
|
||||
*/
|
||||
review_status: string;
|
||||
/**
|
||||
* Aliases
|
||||
* @default []
|
||||
*/
|
||||
aliases: string[];
|
||||
};
|
||||
/** PrecedentCreateRequest */
|
||||
PrecedentCreateRequest: {
|
||||
/** Quote */
|
||||
@@ -9354,6 +9588,39 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
operations_agent_migrate_adapter_api_operations_agents_migrate_adapter_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["AdapterMigrationRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
digest_get_api_digests__digest_id__get: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -10016,6 +10283,237 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
plans_list_api_plans_get: {
|
||||
parameters: {
|
||||
query?: {
|
||||
review_status?: string;
|
||||
q?: string;
|
||||
limit?: number;
|
||||
};
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
plan_create_api_plans_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["PlanUpsertRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
plan_duplicates_api_plans__plan_id__duplicates_get: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
plan_id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
plan_get_api_plans__plan_id__get: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
plan_id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
plan_edit_api_plans__plan_id__patch: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
plan_id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["PlanEditRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
plan_review_api_plans__plan_id__review_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
plan_id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["PlanReviewRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
plan_merge_api_plans_merge_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["PlanMergeRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
missing_precedents_list_api_missing_precedents_get: {
|
||||
parameters: {
|
||||
query?: {
|
||||
|
||||
Reference in New Issue
Block a user