Skip to content

Commit 2668a93

Browse files
Claudeclaude
authored andcommitted
feat: wire contribute_feedback remote submission to Supabase
Replace placeholder remote endpoint with real PostgREST INSERT using the public anon key. Feedback is POSTed directly to community_feedback table with RLS restricting anon to INSERT-only. New file: src/services/feedback-remote.ts — lightweight POST with hardcoded anon key (public by Supabase design, safe to ship in npm). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 348dc07 commit 2668a93

2 files changed

Lines changed: 57 additions & 11 deletions

File tree

src/services/feedback-remote.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Remote feedback submission via Supabase anon key.
3+
*
4+
* This uses the PUBLIC anon key (designed to be shipped in client apps).
5+
* RLS restricts anon to INSERT-only on community_feedback.
6+
* Separate from supabase-client.ts because it uses the anon key, not service role.
7+
*/
8+
9+
const FEEDBACK_URL = "https://cjptxyezuxdiinufgrrm.supabase.co/rest/v1/community_feedback";
10+
const FEEDBACK_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNqcHR4eWV6dXhkaWludWZncnJtIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjYxODY3MDMsImV4cCI6MjA4MTc2MjcwM30.L0oZy3LYCMikmZ15IUU5DnfJmucM37DJ14nUkM3AreY";
11+
12+
export interface FeedbackPayload {
13+
feedback_id: string;
14+
type: string;
15+
tool: string;
16+
description: string;
17+
severity: string;
18+
suggested_fix?: string;
19+
context?: string;
20+
gitmem_version: string;
21+
agent_identity?: string;
22+
install_id?: string | null;
23+
client_timestamp: string;
24+
}
25+
26+
export async function submitFeedbackRemote(payload: FeedbackPayload): Promise<void> {
27+
const response = await fetch(FEEDBACK_URL, {
28+
method: "POST",
29+
headers: {
30+
"apikey": FEEDBACK_ANON_KEY,
31+
"Authorization": `Bearer ${FEEDBACK_ANON_KEY}`,
32+
"Content-Type": "application/json",
33+
"Content-Profile": "public",
34+
"Prefer": "return=minimal",
35+
},
36+
body: JSON.stringify(payload),
37+
});
38+
39+
if (!response.ok) {
40+
const text = await response.text();
41+
throw new Error(`Feedback submit failed: ${response.status} - ${text.slice(0, 200)}`);
42+
}
43+
}

src/tools/contribute-feedback.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { isFeedbackEnabled, getInstallId } from "../services/gitmem-dir.js";
2121
import { getAgentIdentity } from "../services/agent-detection.js";
2222
import { sanitizeFeedbackText } from "../services/feedback-sanitizer.js";
2323
import { getEffectTracker } from "../services/effect-tracker.js";
24+
import { submitFeedbackRemote } from "../services/feedback-remote.js";
2425
import { wrapDisplay } from "../services/display-protocol.js";
2526
import { Timer } from "../services/metrics.js";
2627
import type { ContributeFeedbackParams } from "../schemas/contribute-feedback.js";
@@ -118,17 +119,19 @@ export async function contributeFeedback(params: ContributeFeedbackParams): Prom
118119
"feedback",
119120
"remote-submit",
120121
async () => {
121-
// Remote endpoint — POST to Supabase Edge Function or similar
122-
// For now, this is a placeholder that logs the intent.
123-
// The actual endpoint will be configured when the backend is ready.
124-
console.error(`[contribute-feedback] Remote feedback queued: ${id} (${params.type})`);
125-
// When endpoint is available:
126-
// const response = await fetch(FEEDBACK_ENDPOINT, {
127-
// method: "POST",
128-
// headers: { "Content-Type": "application/json" },
129-
// body: JSON.stringify(remotePayload),
130-
// });
131-
// if (!response.ok) throw new Error(`HTTP ${response.status}`);
122+
await submitFeedbackRemote({
123+
feedback_id: id,
124+
type: params.type,
125+
tool: params.tool,
126+
description: sanitizedDescription,
127+
severity: params.severity,
128+
suggested_fix: sanitizedFix,
129+
context: sanitizedContext,
130+
gitmem_version: pkg.version,
131+
agent_identity: getAgentIdentity(),
132+
install_id: installId,
133+
client_timestamp: now.toISOString(),
134+
});
132135
return remotePayload;
133136
},
134137
);

0 commit comments

Comments
 (0)