learning_ai_notes/mobile/src/api/intake.ts

115 lines
3.2 KiB
TypeScript

import { getApiClient } from './client';
// ── Content Types ────────────────────────────────────────────────
export const INTAKE_CONTENT_TYPES = [
'youtube', 'article', 'pdf', 'tweet', 'reddit', 'github', 'generic',
] as const;
export type IntakeContentType = (typeof INTAKE_CONTENT_TYPES)[number];
export const INTAKE_JOB_STATUSES = [
'queued', 'extracting', 'processing', 'complete', 'failed',
] as const;
export type IntakeJobStatus = (typeof INTAKE_JOB_STATUSES)[number];
// ── Types ────────────────────────────────────────────────────────
export type IntakeSubmitResult = {
jobId: string;
noteId: string;
contentType: IntakeContentType;
ruleMatched: string | null;
templateSlug: string;
status: 'queued';
};
export type IntakeJob = {
id: string;
productId: string;
userId: string;
workspaceId: string;
noteId: string;
ruleId: string;
url: string;
contentType: IntakeContentType;
templateSlug: string;
status: IntakeJobStatus;
extractedText?: string;
error?: string;
startedAt: string;
completedAt?: string;
};
export type IntakeRule = {
id: string;
productId: string;
userId: string;
workspaceId: string;
name: string;
urlPattern: string;
contentType: IntakeContentType;
templateId: string;
enabled: boolean;
priority: number;
createdAt: string;
updatedAt: string;
};
type IntakeJobListResponse = {
items: IntakeJob[];
total: number;
};
type IntakeRuleListResponse = {
items: IntakeRule[];
total: number;
};
export type ListIntakeJobsOptions = {
status?: string;
since?: string;
limit?: number;
offset?: number;
};
// ── API Functions ────────────────────────────────────────────────
export async function submitIntake(
url: string,
workspaceId?: string,
templateOverride?: string,
): Promise<IntakeSubmitResult> {
return getApiClient().fetch<IntakeSubmitResult>('/intake', {
method: 'POST',
body: JSON.stringify({
url,
...(workspaceId ? { workspaceId } : {}),
...(templateOverride ? { templateOverride } : {}),
}),
});
}
export async function listIntakeJobs(
options?: ListIntakeJobsOptions,
): Promise<IntakeJob[]> {
const params = new URLSearchParams();
if (options?.status) params.set('status', options.status);
if (options?.since) params.set('since', options.since);
if (options?.limit) params.set('limit', String(options.limit));
if (options?.offset) params.set('offset', String(options.offset));
const qs = params.toString();
const path = qs ? `/intake/jobs?${qs}` : '/intake/jobs';
const res = await getApiClient().fetch<IntakeJobListResponse>(path);
return res.items;
}
export async function getIntakeJob(id: string): Promise<IntakeJob> {
return getApiClient().fetch<IntakeJob>(`/intake/jobs/${encodeURIComponent(id)}`);
}
export async function listIntakeRules(): Promise<IntakeRule[]> {
const res = await getApiClient().fetch<IntakeRuleListResponse>('/intake-rules');
return res.items;
}