You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
6.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/** 前端类型定义 — 与 PRD / API 契约一致 */
import type { Priority1DisplayLine } from "@/modules/priority1/quote-storage";
export type QuotePageStatus =
| "idle"
| "resolving_address"
| "validating"
| "processing"
| "success"
| "fallback"
| "manual_followup"
| "error"
| "expired";
export type DataPageStatus = "loading" | "success" | "empty" | "error";
/** MotherShip 已知 TabAPI 可能出现未注册的新 service_level */
export type KnownServiceLevel = "standard" | "guaranteed" | "dedicated";
export type ServiceLevel = KnownServiceLevel | (string & {});
export type RateOption = "lowest" | "fastest" | "bestValue" | (string & {});
export type UnitWeight = "lb" | "kg";
export type UnitDim = "in" | "cm";
export type DisplayUnit = "imperial" | "metric";
export type CargoType =
| "general_freight"
| "machinery"
| "furniture"
| "electronics"
| "building_materials"
| "auto_parts"
| "food_nonperishable"
| "apparel"
| "other";
export interface AddressInput {
street: string;
city: string;
state: string;
zip: string;
place_id: string;
formatted_address: string;
selected_from_suggestions: boolean;
mothership_option_id?: string;
mothership_display_label?: string;
selected_from_mothership?: boolean;
}
export interface MothershipAddressCandidate {
option_id: string;
display_label: string;
formatted_address: string;
street: string;
city: string;
state: string;
zip: string;
selectable?: boolean;
unavailable_reason?: string;
}
export interface MothershipCandidatesResult {
pickup_candidates: MothershipAddressCandidate[];
delivery_candidates: MothershipAddressCandidate[];
requires_selection: boolean;
quote_session_id?: string;
}
export interface QuoteRequestBody {
request_id: string;
customer_id: string;
pickup_address: AddressInput;
delivery_address: AddressInput;
weight: { value: number; unit: UnitWeight };
dimensions: {
length: number;
width: number;
height: number;
unit: UnitDim;
};
pallet_count: number;
cargo_type: CargoType;
service_level?: ServiceLevel;
rate_option?: RateOption;
display_unit?: DisplayUnit;
quote_session_id?: string;
}
export type QuoteStatus = "processing" | "done" | "failed" | "expired";
export type SourceType = "rpa" | "cache" | "stale";
export interface QuoteItem {
service_level: ServiceLevel;
rate_option: RateOption;
carrier: string;
transit_days: string;
transit_description: string;
raw_freight: number;
surcharges: number;
raw_total: number;
markup_percent: number;
markup_amount: number;
final_total: number;
breakdown: Array<{ item: string; amount: number }>;
}
export type Priority1QuoteLineDetail = Priority1DisplayLine;
export interface Priority1QuotePayload {
display_mode: "ltl_cards" | "ftl_calendar";
lines: Priority1DisplayLine[];
shipment_meta?: {
shipment_type?: string;
pickup_date?: string;
commodity?: string;
origin_zip?: string;
destination_zip?: string;
weight_lb?: number;
};
}
export interface QuoteDetail {
quote_id: string;
request_id: string;
status: QuoteStatus;
valid_until?: string | null;
source_type?: SourceType | null;
is_realtime?: boolean;
confidence_score?: number | null;
currency: string;
quotes?: QuoteItem[];
priority1?: Priority1QuotePayload;
error_code?: string | null;
error_message?: string | null;
}
export interface CreateQuoteResult {
quote_id: string;
status: "processing" | "done";
}
/** Priority1 模拟填表提交体 */
export interface Priority1QuoteRequestBody {
request_id: string;
customer_id: string;
priority1_input: Record<string, unknown>;
}
export type HostCustomerStatus = "active" | "disabled";
export type ServiceApiKeySummary = {
key_id: string;
key_prefix: string;
is_active: boolean;
permissions: string[];
created_at: string;
};
export type HostCustomerRecord = {
customer_id: string;
name: string;
status: HostCustomerStatus;
remark: string | null;
embed_password_set: boolean;
created_at: string;
updated_at: string;
api_keys: ServiceApiKeySummary[];
};
export type CreateHostCustomerResponse = HostCustomerRecord & {
api_key: string;
};
export type MarkupType = "percent" | "fixed";
export interface MarkupConfig {
customer_id: string;
markup_type: MarkupType;
markup_percent: number;
markup_fixed_amount: number | null;
operator_id: string;
remark: string | null;
updated_at: string;
}
export type AlertType =
| "PRICE_DEVIATION"
| "STALE_FALLBACK"
| "RPA_FAILED"
| "RPA_CAPTCHA"
| "STRUCT_CHANGE"
| "SESSION_EXPIRED"
| "SECURITY"
| "MANUAL_FALLBACK";
export interface AlertRecord {
id: string;
alert_type: AlertType;
quote_id: string | null;
cargo_hash: string | null;
detail_json: Record<string, unknown> | null;
status: "open" | "resolved";
resolver_id: string | null;
resolved_at: string | null;
created_at: string;
root_cause?: string;
customer_id?: string | null;
pickup_customer?: string;
pickup_selected?: string;
delivery_customer?: string;
delivery_selected?: string;
cargo_summary?: string;
}
export type QuoteQueryOutcome = "processing" | "success" | "failed" | "stale";
export interface QuoteQueryLogRecord {
quote_id: string;
request_id: string;
customer_id: string;
outcome: QuoteQueryOutcome;
failure_reason: string | null;
error_code: string | null;
source_type: string | null;
tier_count: number | null;
pickup_customer: string;
pickup_selected: string;
delivery_customer: string;
delivery_selected: string;
cargo_summary: string;
created_at: string;
completed_at: string | null;
}
export type ErrorCode =
| "VALIDATION_FAILED"
| "UNAUTHORIZED"
| "FORBIDDEN"
| "QUOTE_NOT_FOUND"
| "RATE_LIMITED"
| "QUOTE_UNAVAILABLE"
| "QUOTE_TIMEOUT"
| "INTERNAL_ERROR";
export interface ApiOk<T> {
code: 0;
message: string;
data: T;
}
export interface ApiErr {
code: ErrorCode | string;
message: string;
data: null;
}
export type ApiResponse<T> = ApiOk<T> | ApiErr;
export interface AdminUser {
user_id: string;
role: "admin";
}
export interface LoginResponse {
token: string;
user: AdminUser;
}
export interface PaginatedResult<T> {
list: T[];
total: number;
page: number;
size: number;
}
export interface MetricsDashboard {
api_success_rate: number;
rpa_success_rate: number;
realtime_rate: number;
cache_hit_rate: number;
p95_latency_ms: number;
queue_depth: number;
open_alerts_count: number;
}
export interface RpaStatus {
workers: Array<{
worker_id: string;
last_seen_ms: number | null;
paused_seconds: number;
online: boolean;
}>;
queue_depth: number;
circuit_open: boolean;
success_rate_24h: number;
}
export interface QueueStats {
queue_name: string;
waiting: number;
active: number;
delayed: number;
failed: number;
completed: number;
depth: number;
}