- Introduced new page component for library topics with type checks. - Added migration scripts to update access rules for various collections including badges, curriculum versions, and themes. - Implemented PocketBase integration for managing collection access rules dynamically. - Ensured proper type validation for page props and metadata generation functions.
96 lines
3.1 KiB
TypeScript
96 lines
3.1 KiB
TypeScript
import type {
|
|
IngestionJobStatus,
|
|
CompletePayload,
|
|
CompleteResponse,
|
|
LeaderboardEntry,
|
|
FeedEntry,
|
|
} from '@/types'
|
|
|
|
const INGESTION_URL = process.env.NEXT_PUBLIC_INGESTION_URL ?? 'http://localhost:3001'
|
|
const GENERATION_URL = process.env.NEXT_PUBLIC_GENERATION_URL ?? 'http://localhost:3002'
|
|
const CURRICULUM_URL = process.env.NEXT_PUBLIC_CURRICULUM_URL ?? 'http://localhost:3003'
|
|
const PROGRESS_URL = process.env.NEXT_PUBLIC_PROGRESS_URL ?? 'http://localhost:3005'
|
|
|
|
async function handleResponse<T>(res: Response): Promise<T> {
|
|
if (!res.ok) {
|
|
const text = await res.text().catch(() => res.statusText)
|
|
throw new Error(`HTTP ${res.status}: ${text}`)
|
|
}
|
|
return res.json() as Promise<T>
|
|
}
|
|
|
|
export async function postIngest(payload: {
|
|
documentId: string
|
|
filename: string
|
|
format: 'pdf' | 'md' | 'txt'
|
|
fileUrl: string
|
|
}): Promise<{ jobId: string }> {
|
|
const res = await fetch(`${INGESTION_URL}/ingest`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(payload),
|
|
})
|
|
return handleResponse<{ jobId: string }>(res)
|
|
}
|
|
|
|
export async function getIngestionStatus(jobId: string): Promise<IngestionJobStatus> {
|
|
const res = await fetch(`${INGESTION_URL}/ingest/status/${encodeURIComponent(jobId)}`)
|
|
return handleResponse<IngestionJobStatus>(res)
|
|
}
|
|
|
|
export async function postGenerateAll(themeId: string): Promise<{ queued: number }> {
|
|
const res = await fetch(`${GENERATION_URL}/generate/theme/${encodeURIComponent(themeId)}`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
return handleResponse<{ queued: number }>(res)
|
|
}
|
|
|
|
export async function postComplete(payload: CompletePayload): Promise<CompleteResponse> {
|
|
const res = await fetch(`${PROGRESS_URL}/complete`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(payload),
|
|
})
|
|
return handleResponse<CompleteResponse>(res)
|
|
}
|
|
|
|
export async function getLeaderboard(): Promise<LeaderboardEntry[]> {
|
|
const res = await fetch(`${PROGRESS_URL}/leaderboard`)
|
|
return handleResponse<LeaderboardEntry[]>(res)
|
|
}
|
|
|
|
export async function getFeed(): Promise<FeedEntry[]> {
|
|
const res = await fetch(`${PROGRESS_URL}/feed`)
|
|
return handleResponse<FeedEntry[]>(res)
|
|
}
|
|
|
|
export async function postCurriculumConfirm(versionId: string): Promise<void> {
|
|
const res = await fetch(
|
|
`${CURRICULUM_URL}/curriculum/versions/${encodeURIComponent(versionId)}/confirm`,
|
|
{
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
},
|
|
)
|
|
if (!res.ok) {
|
|
const text = await res.text().catch(() => res.statusText)
|
|
throw new Error(`HTTP ${res.status}: ${text}`)
|
|
}
|
|
}
|
|
|
|
export async function patchCurriculumWeekOrder(weekId: string, position: number): Promise<void> {
|
|
const res = await fetch(
|
|
`${CURRICULUM_URL}/curriculum/weeks/${encodeURIComponent(weekId)}/order`,
|
|
{
|
|
method: 'PATCH',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ position }),
|
|
},
|
|
)
|
|
if (!res.ok) {
|
|
const text = await res.text().catch(() => res.statusText)
|
|
throw new Error(`HTTP ${res.status}: ${text}`)
|
|
}
|
|
}
|