| import { supabase } from './supabase' |
|
|
| |
|
|
| const USE_GO_GATEWAY: Record<string, boolean> = { |
| 'verify-receipt': false, |
| 'nature-letter': false, |
| 'embed-text': false, |
| 'explain-methodology': false, |
| 'mock-vcs': false, |
| } |
|
|
| let GO_GATEWAY_URL = 'http://localhost:8080' |
|
|
| export function setUseGoGateway(functionName: string, use: boolean): void { |
| if (functionName in USE_GO_GATEWAY) { |
| USE_GO_GATEWAY[functionName] = use |
| } |
| } |
|
|
| export function setGoGatewayUrl(url: string): void { |
| GO_GATEWAY_URL = url |
| } |
|
|
| |
|
|
| |
| |
| |
| |
| function assertDataContract(functionName: string, data: any): void { |
| if (!data) { |
| throw new Error(`[apiAdapter] API κ³μ½ κ²μ¦ μ€ν¨: ${functionName} μλ΅μ΄ λΉμ΄μμ΅λλ€.`) |
| } |
|
|
| switch (functionName) { |
| case 'verify-receipt': |
| if (data.success === undefined) { |
| throw new Error(`[apiAdapter] API κ³μ½ κ²μ¦ μ€ν¨: verify-receipt μλ΅μ νμ νλ(success)κ° λλ½λμμ΅λλ€.`) |
| } |
| if (data.co2Reduction === undefined && data.co2_reduction === undefined) { |
| throw new Error(`[apiAdapter] API κ³μ½ κ²μ¦ μ€ν¨: verify-receipt μλ΅μ νμ νλ(co2Reduction)κ° λλ½λμμ΅λλ€.`) |
| } |
| break; |
|
|
| case 'nature-letter': |
| if (!data.body) { |
| throw new Error(`[apiAdapter] API κ³μ½ κ²μ¦ μ€ν¨: nature-letter μλ΅μ νμ νλ(body)κ° λλ½λμμ΅λλ€.`) |
| } |
| break; |
|
|
| case 'embed-text': |
| if (!Array.isArray(data.embedding)) { |
| throw new Error(`[apiAdapter] API κ³μ½ κ²μ¦ μ€ν¨: embed-text μλ΅μ νμ νλ(embedding)κ° λλ½λμμ΅λλ€.`) |
| } |
| break; |
|
|
| case 'explain-methodology': |
| if (data.eligibilityScore === undefined && data.eligibility_score === undefined) { |
| throw new Error(`[apiAdapter] API κ³μ½ κ²μ¦ μ€ν¨: explain-methodology μλ΅μ νμ νλ(eligibilityScore)κ° λλ½λμμ΅λλ€.`) |
| } |
| if (!data.explanation) { |
| throw new Error(`[apiAdapter] API κ³μ½ κ²μ¦ μ€ν¨: explain-methodology μλ΅μ νμ νλ(explanation)κ° λλ½λμμ΅λλ€.`) |
| } |
| break; |
|
|
| case 'mock-vcs': |
| if (data.success === undefined) { |
| throw new Error(`[apiAdapter] API κ³μ½ κ²μ¦ μ€ν¨: mock-vcs μλ΅μ νμ νλ(success)κ° λλ½λμμ΅λλ€.`) |
| } |
| if (!data.externalId && !data.external_id) { |
| throw new Error(`[apiAdapter] API κ³μ½ κ²μ¦ μ€ν¨: mock-vcs μλ΅μ νμ νλ(externalId)κ° λλ½λμμ΅λλ€.`) |
| } |
| break; |
|
|
| default: |
| |
| break; |
| } |
| } |
|
|
| |
|
|
| |
| |
| |
| |
| export async function invokeEdgeFunction<TReq, TRes>( |
| functionName: string, |
| payload: TReq |
| ): Promise<TRes> { |
| const useGo = USE_GO_GATEWAY[functionName] || false |
|
|
| if (useGo) { |
| |
| const targetUrl = `${GO_GATEWAY_URL}/api/v1/${functionName}` |
| const response = await fetch(targetUrl, { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify(payload), |
| }) |
|
|
| if (!response.ok) { |
| const errText = await response.text() |
| throw new Error(`[apiAdapter] Go Gateway API νΈμΆ μ€ν¨ (${response.status}): ${errText}`) |
| } |
|
|
| const resData = await response.json() |
| |
| |
| assertDataContract(functionName, resData) |
| return resData as TRes |
| } else { |
| |
| const { data, error } = await supabase.functions.invoke(functionName, { |
| body: payload as any, |
| }) |
|
|
| if (error) { |
| throw new Error(error.message || String(error)) |
| } |
|
|
| |
| assertDataContract(functionName, data) |
| return data as TRes |
| } |
| } |
|
|