Day 2 of building _SpeakSheet _in public – an AI tool that generates Excel spreadsheets from natural language prompts.
Today was a mix of small UX wins and frustrating technical challenges. Here's what happened.
✅ Shipped: One-Click File Uploads
The Problem:
Users had to select a file AND click an "Upload" button before the backend would process it.
The Fix:
Made the upload trigger automatically when a file is selected.
The Code (simplified):
const handleFileSelect = async (selectedFile) => {
if (!selectedFile) return;
console.log
if (validateFile(selectedFile)) {
setFile(selectedFile);
toast.success(`File "${selectedFile.name}" selected`);
try {
setUploading(true);
// Use selectedFile directly, not file state
const { publicUrl } = await uploadToSupabase(selectedFile, user.id);
setFile(publicUrl);
toast.success("File uploaded successfully!");
} catch (error) {
console.error("File upload failed:", error);
toast.error("File upload failed");
} finally {
setUploading(false);
}
}
};
The Lesson:
Sometimes the best features are the ones you remove. One less click = better UX.
🐛 Challenge #1: Supabase Storage Structure
The Problem:
Files weren't saving to Supabase storage, but no errors were showing in the console.
The Debug Process:
Checked file size limits ✅
Checked bucket permissions ✅
Checked network requests ✅
Re-read the Supabase docs... and found it.
The Issue:
A JSON schema error in my storage bucket configuration.
Error because of this line data[0].schema
The fix:One missing pair of square brackets.
The lesson: JSON schema errors fail silently and waste time. Always validate your config.
Challenge #2: Gemini API Rate Limits
Halfway through testing, I started getting this error:
text
Error: 429 - Resource has been exhausted (e.g. check quota).
First reaction: "Did I break something?"
Reality: I'm hitting rate limits already.
Quick fix:
Swapped to a backup API key
Kept building
Long-term fix (needed):
Add request queueing
Show "High demand, please wait..." to users
Consider upgrading API tier or adding fallback models
The silver lining:
Hitting rate limits this early means I'm actually stress-testing the product. Better to discover this now than during launch.
🧠 What I Learned Today
UX wins come from removing steps
Fewer clicks > fancy features
Test with production-level load earlyHitting rate limits in dev > hitting them in production
JSON schema errors are silent killersAlways validate your configs
Rate limits are validation
Means you're using the product enough to stress-test it
Top comments (0)