| |
| |
|
|
| export type Role = "owner" | "finder" | "admin"; |
| export type DogSize = "small" | "medium" | "large"; |
| export type CaseType = "lost" | "found"; |
| export type CaseStatus = "open" | "matched" | "resolved" | "closed"; |
| export type MatchStatus = "pending" | "confirmed" | "rejected"; |
|
|
| export interface User { |
| id: number; |
| name: string; |
| email: string; |
| phone: string | null; |
| zip: string; |
| role: Role; |
| } |
|
|
| export interface Picture { |
| id: number; |
| subject_type: "known" | "unknown"; |
| subject_id: number; |
| is_primary: boolean; |
| is_probably_not_dog: boolean; |
| url: string | null; |
| thumb_url: string | null; |
| } |
|
|
| export interface KnownDog { |
| id: number; |
| owner_id: number; |
| name: string; |
| breed: string | null; |
| age: string | null; |
| color: string | null; |
| size: DogSize | null; |
| description: string; |
| other_info: string | null; |
| last_known_zip: string | null; |
| status: "home" | "lost" | "reunited"; |
| created_at: string; |
| pictures: Picture[]; |
| estimated_breeds: string[]; |
| } |
|
|
| export interface Case { |
| id: number; |
| type: CaseType; |
| status: CaseStatus; |
| event_zip: string; |
| event_date: string; |
| current_location: string | null; |
| search_radius_miles: number; |
| notes: string | null; |
| known_dog_id: number | null; |
| unknown_dog_id: number | null; |
| person_id: number | null; |
| created_at: string; |
| } |
|
|
| export interface MatchCandidate { |
| type: "known" | "unknown"; |
| id: number; |
| name?: string; |
| description?: string; |
| breed?: string | null; |
| est_breed?: string | null; |
| color?: string | null; |
| size?: string | null; |
| current_zip?: string | null; |
| current_location_detail?: string | null; |
| last_known_zip?: string | null; |
| status?: string; |
| estimated_breeds?: string[]; |
| pictures: Picture[]; |
| } |
|
|
| export interface Match { |
| id: number; |
| case_id: number; |
| candidate_type: "known" | "unknown"; |
| candidate_id: number; |
| candidate_case_id: number | null; |
| similarity_score: number; |
| rank: number; |
| status: MatchStatus; |
| model_name: string; |
| model_version: string; |
| candidate: MatchCandidate | null; |
| } |
|
|
| export interface FoundReportResponse { |
| case: Case; |
| matches: Match[]; |
| vet_guidance: { name: string; detail: string; type: string }[] | null; |
| } |
|
|
| export interface ReclaimContact { |
| name: string | null; |
| email: string | null; |
| phone: string | null; |
| } |
|
|
| export interface ReclaimInfo { |
| match_id: number; |
| match_status: MatchStatus; |
| your_dog_name: string | null; |
| your_photos: DogPhoto[]; |
| found: boolean; |
| held_at: "shelter_or_vet" | "finder_custody" | "unknown"; |
| location_name: string | null; |
| current_zip: string | null; |
| current_location: string | null; |
| found_date: string | null; |
| contact: ReclaimContact | null; |
| photos: DogPhoto[]; |
| nearby_shelters: { name: string; detail: string; type: string }[]; |
| } |
|
|
| export interface Page<T> { |
| items: T[]; |
| total: number; |
| limit: number; |
| offset: number; |
| } |
|
|
| |
|
|
| export type DatasetType = "test_known" | "test_found" | "known" | "unknown"; |
|
|
| export interface Dataset { |
| id: number; |
| name: string; |
| type: DatasetType; |
| description: string | null; |
| source_path: string | null; |
| dog_count: number; |
| creation_time: string; |
| case_count: number; |
| } |
|
|
| export interface DatasetStats { |
| known_dog_count: number; |
| unknown_dog_count: number; |
| dog_count: number; |
| user_count: number; |
| case_count: number; |
| match_count: number; |
| picture_count: number; |
| embedded_picture_count: number; |
| error_count: number; |
| } |
|
|
| export interface DatasetDetail extends Dataset { |
| stats: DatasetStats; |
| } |
|
|
| export interface DatasetDog { |
| kind: "known" | "unknown"; |
| id: number; |
| name: string; |
| status: string; |
| zip: string | null; |
| thumb_url: string | null; |
| } |
|
|
| export interface DatasetDogsPage { |
| items: DatasetDog[]; |
| total: number; |
| limit: number; |
| offset: number; |
| } |
|
|
| export interface PurgeResult { |
| dataset_id: number; |
| deleted: Record<string, number>; |
| } |
|
|
| export interface EmbedAllResult { |
| dataset_id: number; |
| total_pictures: number; |
| embedded: number; |
| breeds: number; |
| skipped: number; |
| errors: number; |
| } |
|
|
| export interface MatchDatasetResult { |
| dataset_id: number; |
| cases_processed: number; |
| matches_created: number; |
| candidate_dataset_id: number | null; |
| } |
|
|
| export interface AdminDog { |
| kind: "known" | "unknown"; |
| id: number; |
| name: string; |
| breed: string | null; |
| color: string | null; |
| size: string | null; |
| status: string; |
| zip: string | null; |
| dataset_id: number | null; |
| dataset_name: string | null; |
| picture_count: number; |
| thumb_url: string | null; |
| predicted_breeds: string[]; |
| } |
|
|
| export interface BreedOption { |
| label: string; |
| count: number; |
| } |
|
|
| export interface AdminDogsPage { |
| items: AdminDog[]; |
| total: number; |
| limit: number; |
| offset: number; |
| counts: { known: number; unknown: number }; |
| } |
|
|
| export interface TestMatchCandidate extends AdminDog { |
| score: number; |
| } |
|
|
| export interface TestMatchResult { |
| query: AdminDog; |
| results: TestMatchCandidate[]; |
| model: string; |
| candidate_count: number; |
| query_embedded: boolean; |
| } |
|
|
| export interface DogPhoto { |
| id: number; |
| url: string | null; |
| thumb_url: string | null; |
| is_primary: boolean; |
| } |
|
|
| export interface DogDetailResult { |
| profile: AdminDog; |
| photos: DogPhoto[]; |
| } |
|
|
| export interface CaseDog { |
| kind: "known" | "unknown" | null; |
| photos: DogPhoto[]; |
| } |
|
|
| export interface PhotoSearchMatch { |
| dog: AdminDog; |
| score: number; |
| distance_miles: number | null; |
| photos: DogPhoto[]; |
| } |
|
|
| export interface PhotoSearchResult { |
| results: PhotoSearchMatch[]; |
| model: string; |
| candidate_count: number; |
| zip: string | null; |
| radius_miles: number; |
| pool: "found" | "lost"; |
| } |
|
|
| export interface BreedEstimate { |
| label: string; |
| score: number; |
| } |
|
|
| export interface BreedEstimateResult { |
| breeds: BreedEstimate[]; |
| model: string; |
| } |
|
|
| export interface AdminCaseDog { |
| kind: "known" | "unknown"; |
| id: number; |
| name: string; |
| status: string; |
| zip: string | null; |
| thumb_url: string | null; |
| } |
|
|
| export interface AdminCase { |
| id: number; |
| type: "lost" | "found"; |
| status: string; |
| event_zip: string; |
| event_date: string; |
| created_at: string; |
| dog: AdminCaseDog | null; |
| person: { id: number; name: string; email: string } | null; |
| finder_name: string | null; |
| finder_email: string | null; |
| match_count: number; |
| } |
|
|
| export interface AdminCasesPage { |
| items: AdminCase[]; |
| total: number; |
| limit: number; |
| offset: number; |
| counts: { lost: number; found: number }; |
| } |
|
|
| export interface AdminCaseDetail { |
| case: AdminCase; |
| dog: { profile: AdminDog; photos: DogPhoto[] } | null; |
| matches: Match[]; |
| } |
|
|
| export interface AdminOwner { |
| id: number; |
| name: string; |
| email: string; |
| zip: string; |
| dog_count: number; |
| dogs: { id: number; name: string; status: string; zip: string | null; thumb_url: string | null }[]; |
| } |
|
|
| export interface AdminOwnersPage { |
| items: AdminOwner[]; |
| total: number; |
| limit: number; |
| offset: number; |
| } |
|
|
| export interface AdminOwnerDetail { |
| owner: { |
| id: number; |
| name: string; |
| email: string; |
| zip: string; |
| phone: string | null; |
| dog_count: number; |
| }; |
| dogs: AdminDog[]; |
| cases: AdminCase[]; |
| } |
|
|
| export interface Job { |
| id: string; |
| type: string; |
| status: "pending" | "running" | "done" | "error"; |
| progress: { processed?: number; total?: number; dataset_id?: number }; |
| result: Record<string, unknown> | null; |
| error: string | null; |
| created_at: string; |
| } |
|
|