MingruiZhang's picture
feat: class list in project viewer (#29)
dfa7532 unverified
raw
history blame
4.22 kB
import { auth } from '@/auth';
import { v5 as uuidV5 } from 'uuid';
interface ApiResponse<T> {
code: number; // code from server 0
message: string;
data: T;
}
const clefApiBuilder = <Params extends object | void, Resp>(
path: string,
options?: {
// default to GET
method: 'GET' | 'POST';
// default to 'app'
prefix: 'api' | 'app' | 'api.dev' | 'app.dev';
},
) => {
return async (params: Params): Promise<Resp> => {
const session = await auth();
const email = session?.user?.email;
if (!email || !email.endsWith('@landing.ai')) {
throw new Response('Unauthorized', {
status: 401,
});
}
const sessionUser = {
id: uuidV5(email, uuidV5.URL),
orgId: '-1024',
email: email,
username: email.split('@')[0],
userRole: 'adminPortal',
bucket: 'fake_bucket',
};
const prefix = options?.prefix ?? 'app';
const baseURL = `https://${prefix}.landing.ai/${path}`;
const method = options?.method ?? 'GET';
// Create a URL object with query params
const url = new URL(baseURL);
if (method === 'GET') {
Object.entries(params ?? {}).forEach(([key, value]) =>
url.searchParams.append(key, value),
);
}
const fetchParams: RequestInit = {
method: options?.method ?? 'GET',
headers: {
sessionuser: JSON.stringify(sessionUser), // faked production user
// apikey: 'land_sk_DKeoYtaZZrYqJ9TMMiXe4BIQgJcZ0s3XAoB0JT3jv73FFqnr6k', // dev key
apikey: 'land_sk_Z0AWhSGURwC8UVTjyZDH7VMsYod6jfTK79fC2RTGD85NkV6hwO', // prod key
'X-ROUTE': 'mingruizhang-landing',
},
};
if (method === 'POST' && params instanceof Object) {
const formData = new FormData();
for (const [key, value] of Object.entries(params)) {
formData.append(key, value);
}
fetchParams.body = formData;
}
const res = await fetch(url.toString(), fetchParams);
if (!res.ok) {
console.error('ERROR: fetch data failure', res.status, res.statusText);
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data');
}
const { data }: ApiResponse<Resp> = await res.json();
return data;
};
};
export type ProjectBaseInfo = {
id: number;
name: string;
created_at: Date;
label_type: string;
orgName: string;
orgId: number;
subscription: string;
};
/**
* Fetch recent projects from all organizations from past 30 days, excluding
* 1. test organization such as bdd, cypress
* 2. internal organization such as landing, landing-ai, orgId=1
* 3. projects not containing media or only contain sample media
* @author https://github.com/landing-ai/landing-platform/blob/mingrui-04-08-meaningful-project/packages/server-clef/src/main_app/controllers/admin/get_admin_meaningful_project_controller.ts
*/
export const fetchRecentProjectList = clefApiBuilder<void, ProjectBaseInfo[]>(
'api/admin/vision-agent/projects/recent',
);
export type MediaDetails = {
id: number;
name: string;
path: string;
url: string;
projectId: number;
thumbnails: string[];
properties: {
width: number;
height: number;
format: string;
orientation: number;
};
};
/**
* Randomly fetch 10 media from a given project
* @author https://github.com/landing-ai/landing-platform/blob/mingrui-04-08-meaningful-project/packages/server-clef/src/main_app/controllers/admin/get_admin_meaningful_project_controller.ts
*/
export const fetchProjectMedia = clefApiBuilder<
{ projectId: number },
MediaDetails[]
>('api/admin/vision-agent/project/media');
export type ClassDetails = {
id: number;
name: string;
descriptionText?: string | null;
orgId: number;
projectId: number;
createdAt: string;
updatedAt: string | null;
color?: string | null;
};
/**
* Fetch all active classes of a given project
* @author https://github.com/landing-ai/landing-platform/blob/mingrui-04-08-meaningful-project/packages/server-clef/src/main_app/controllers/admin/get_admin_meaningful_project_controller.ts
*/
export const fetchProjectClass = clefApiBuilder<
{ projectId: number },
ClassDetails[]
>('api/admin/vision-agent/project/class');