브라우저가 공개 키로 테이블을 직접 읽고 쓰던 구조를 없앤다.
- api/db.js: 정해진 작업만 서비스 키로 실행 (임의 쿼리·열 지정 불가)
- api/_origin.js: 서버 함수 공용 출처 검사, 공개 배포에서는 404
- src/lib/db.ts: 화면용 호출 함수, 반환 형태 { data, error } 유지
- 빌드 큐에 바로 넣던 예전 진단 신청 모달 삭제
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
32 lines
1.3 KiB
TypeScript
32 lines
1.3 KiB
TypeScript
/**
|
|
* 데이터베이스 조회·쓰기. 브라우저는 테이블에 직접 접근하지 않고 서버 함수(api/db.js)의 정해진 작업만 부른다.
|
|
* 공개 키로 테이블을 읽고 쓰던 구조를 없애기 위한 것이다 (2026-10-07). 반환 형태는 Supabase 클라이언트와 같은 { data, error }.
|
|
*/
|
|
|
|
export type DbOp =
|
|
| 'report.byId' | 'report.status'
|
|
| 'run.clinicId' | 'clinic.byId' | 'plan.active' | 'plan.updateEntry'
|
|
| 'perf.latest' | 'adjustments.list'
|
|
| 'builds.latest' | 'builds.queue' | 'inputs.list' | 'inputs.add';
|
|
|
|
export interface DbResult<T> {
|
|
data: T | null;
|
|
error: { message: string; code?: string | null } | null;
|
|
}
|
|
|
|
export async function db<T = unknown>(op: DbOp, params: Record<string, unknown> = {}): Promise<DbResult<T>> {
|
|
try {
|
|
const res = await fetch('/api/db', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ op, params }),
|
|
});
|
|
const body = (await res.json().catch(() => null)) as DbResult<T> | null;
|
|
if (!body) return { data: null, error: { message: `서버 응답 오류 (${res.status})` } };
|
|
return body;
|
|
} catch (e) {
|
|
console.error(`[db] ${op} 연결 실패`, e);
|
|
return { data: null, error: { message: '서버에 연결할 수 없습니다' } };
|
|
}
|
|
}
|