Insert row
This commit is contained in:
@@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
* Netlify Function (Node runtime).
|
||||||
|
*
|
||||||
|
* Inserts a row into the Supabase `funder_data_submissions` table
|
||||||
|
* when the user submits the funder discovery form. Runs in parallel
|
||||||
|
* with the Anthropic agent stream and is intentionally independent of
|
||||||
|
* it — a Supabase failure must never block (or be observed by) the
|
||||||
|
* streaming brief.
|
||||||
|
*
|
||||||
|
* Environment variables (set in .env.local for local `netlify dev`,
|
||||||
|
* and in the Netlify UI for production):
|
||||||
|
* - SUPABASE_URL e.g. https://<project>.supabase.co
|
||||||
|
* - SUPABASE_SERVICE_ROLE_KEY service role key (server-side only)
|
||||||
|
*
|
||||||
|
* The service role key bypasses RLS, so this function must only be
|
||||||
|
* called from trusted server-side code (which it is — this endpoint
|
||||||
|
* is the only caller). Do NOT expose this key to the browser.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const handler = async (event) => {
|
||||||
|
if (event.httpMethod !== 'POST') {
|
||||||
|
return {
|
||||||
|
statusCode: 405,
|
||||||
|
body: JSON.stringify({ error: 'Method not allowed' }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const SUPABASE_URL = process.env.SUPABASE_URL
|
||||||
|
const SUPABASE_SERVICE_ROLE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY
|
||||||
|
|
||||||
|
if (!SUPABASE_URL || !SUPABASE_SERVICE_ROLE_KEY) {
|
||||||
|
return {
|
||||||
|
statusCode: 500,
|
||||||
|
body: JSON.stringify({
|
||||||
|
error: 'Server is missing SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY',
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let payload
|
||||||
|
try {
|
||||||
|
payload = JSON.parse(event.body || '{}')
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
statusCode: 400,
|
||||||
|
body: JSON.stringify({ error: 'Invalid JSON body' }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const row = {
|
||||||
|
name: payload.userName ?? null,
|
||||||
|
email: payload.userEmail ?? null,
|
||||||
|
station_name: payload.stationName ?? null,
|
||||||
|
station_location: payload.stationLocation ?? null,
|
||||||
|
station_website: payload.stationWebsite ?? null,
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(
|
||||||
|
`${SUPABASE_URL.replace(/\/$/, '')}/rest/v1/funder_data_submissions`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
apikey: SUPABASE_SERVICE_ROLE_KEY,
|
||||||
|
Authorization: `Bearer ${SUPABASE_SERVICE_ROLE_KEY}`,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Prefer: 'return=minimal',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(row),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
const text = await res.text()
|
||||||
|
console.error('Supabase insert failed', res.status, text)
|
||||||
|
return {
|
||||||
|
statusCode: 502,
|
||||||
|
body: JSON.stringify({
|
||||||
|
error: `Supabase insert failed: ${res.status} ${text}`,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 204,
|
||||||
|
body: '',
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Supabase request errored', err)
|
||||||
|
return {
|
||||||
|
statusCode: 500,
|
||||||
|
body: JSON.stringify({
|
||||||
|
error: `Supabase request errored: ${err?.message || String(err)}`,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -174,6 +174,17 @@ export default function App() {
|
|||||||
setIsThinking(true)
|
setIsThinking(true)
|
||||||
setIsStreaming(false)
|
setIsStreaming(false)
|
||||||
|
|
||||||
|
// Fire-and-forget: save the submission to Supabase in parallel
|
||||||
|
// with the Anthropic agent stream. Any failure is logged but must
|
||||||
|
// never block or surface in the streaming UX.
|
||||||
|
fetch('/.netlify/functions/save-submission', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(form),
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error('Failed to save submission to Supabase', err)
|
||||||
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let resume = null
|
let resume = null
|
||||||
// Loop across segments. Each iteration is one HTTP request;
|
// Loop across segments. Each iteration is one HTTP request;
|
||||||
|
|||||||
Reference in New Issue
Block a user