feat: enhance feedback form with image upload, user/project context, and scene graph (#113)

* feat: enhance feedback form with image upload, user/project context, and scene graph

- Add invisible drag-and-drop zone that reveals on hover+drag with dashed border overlay
- Multi-image upload (max 5, max 5MB each) to Supabase Storage feedback-images bucket
- Subtle attach button + thumbnail previews with remove on hover
- Auto-capture authenticated user email/name from Better Auth session
- Pass projectId from editor context
- Snapshot scene graph (nodes + rootNodeIds) on submit
- DB migration adds user_email, user_name, project_id, images (jsonb), scene_graph (jsonb) columns
- Storage bucket + RLS policies for public read / service role write

* refactor: use existing user_id FK instead of denormalized email/name columns

Removed user_email and user_name — the user_id already links to the users table.
Simpler schema, no data duplication.

* fix: guard against undefined in removeImage

* refactor: direct Supabase Storage upload via signed URLs

Bypass Vercel's 4.5MB serverless body-size limit by uploading images
directly from the client to Supabase Storage.

- New createImageUploadUrls server action generates signed upload URLs
- Client PUTs files directly to Supabase (no bytes through Vercel)
- submitFeedback now receives only image paths, not FormData with files
- No migration changes needed (existing RLS policies support signed URLs)

* fix: remove relative class that broke dialog centering

twMerge was replacing the Dialog's fixed positioning with relative,
pushing the dialog to the bottom of the viewport.

---------

Co-authored-by: Anton Pascal <anton-pascal@users.noreply.github.com>
This commit is contained in:
Anton
2026-02-22 23:52:42 -05:00
committed by GitHub
co-authored by Anton Pascal
parent c0a7fd8067
commit c476d30303
5 changed files with 317 additions and 29 deletions
@@ -0,0 +1,20 @@
-- Add image upload, project context, and scene graph to feedback
ALTER TABLE feedback
ADD COLUMN IF NOT EXISTS project_id text,
ADD COLUMN IF NOT EXISTS images jsonb,
ADD COLUMN IF NOT EXISTS scene_graph jsonb;
-- Create feedback-images storage bucket (public read, service-role write)
INSERT INTO storage.buckets (id, name, public)
VALUES ('feedback-images', 'feedback-images', true)
ON CONFLICT (id) DO NOTHING;
-- Allow public read on feedback-images bucket
CREATE POLICY "Public read feedback images"
ON storage.objects FOR SELECT
USING (bucket_id = 'feedback-images');
-- Allow service role (and authenticated users) to upload
CREATE POLICY "Service role upload feedback images"
ON storage.objects FOR INSERT
WITH CHECK (bucket_id = 'feedback-images');