115 lines
3.2 KiB
TypeScript
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;
|
|
}
|