- restructure from src/ + server/ to src/client/ + src/server/ + src/shared/ - switch backend runtime from Node (tsx) to Bun - merge server/package.json into root, remove @hono/node-server + tsx - convert server @/ imports to relative paths - standardize biome config (lineWidth 80, quoteStyle double) - add CLAUDE.md, .env.example at root - update vite.config, tsconfig, deploy.sh for new structure Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
36 lines
1003 B
TypeScript
36 lines
1003 B
TypeScript
import { BACKEND_URL } from "@/shared/lib/constants"
|
|
import { z } from "zod"
|
|
|
|
const politicianVoteSchema = z.object({
|
|
vote: z.string(),
|
|
pollId: z.number(),
|
|
pollLabel: z.string(),
|
|
pollDate: z.string().nullable(),
|
|
pollUrl: z.string().nullable(),
|
|
topics: z.array(z.string()),
|
|
})
|
|
|
|
const politicianProfileSchema = z.object({
|
|
id: z.number(),
|
|
label: z.string(),
|
|
party: z.string().nullable(),
|
|
fraction: z.string().nullable(),
|
|
constituency: z.string().nullable(),
|
|
mandateWon: z.string().nullable(),
|
|
votes: z.array(politicianVoteSchema),
|
|
})
|
|
|
|
export type PoliticianProfile = z.infer<typeof politicianProfileSchema>
|
|
export type PoliticianVote = z.infer<typeof politicianVoteSchema>
|
|
|
|
export async function fetchPoliticianProfile(
|
|
id: number,
|
|
): Promise<PoliticianProfile> {
|
|
const res = await fetch(`${BACKEND_URL}/politicians/${id}`)
|
|
if (!res.ok) {
|
|
throw new Error(`Failed to fetch politician profile: ${res.status}`)
|
|
}
|
|
const json = await res.json()
|
|
return politicianProfileSchema.parse(json)
|
|
}
|