The Journey Behind EventSnap

Inspiration

EventSnap was born from a frustrating personal experience at my sister's wedding. As the unofficial photographer, I spent weeks after the event collecting photos from family members through various channels - WhatsApp, email, Google Drive links, and even physical USB drives. This fragmented process made me realize there had to be a better way to collect and organize event photos.

The vision was clear: create a platform where guests could easily share photos while event owners could effortlessly manage them - all without requiring guests to download apps or create accounts.

Learning Process

Building EventSnap pushed me to deepen my understanding in several key areas:

  1. Multi-tenant Architecture: Implementing a secure system where different user roles (admins, event owners, and anonymous guests) could interact with the same platform while maintaining proper access control.

  2. Row Level Security: Learning how to implement database-level security in Supabase, ensuring that users could only access data they were authorized to see.

  3. Anonymous Authentication Flows: Creating a secure yet frictionless experience for guests to upload photos without registration.

  4. File Management at Scale: Handling potentially large volumes of image uploads, validations, and storage efficiently.

Development Approach

I approached the development with a focus on user experience first:

  1. Started with user journey mapping for all three user types (admins, event owners, and guests)
  2. Designed the database schema to support the core functionality while maintaining security
  3. Built the authentication system with role-based access control
  4. Implemented the photo upload and management features
  5. Added QR code generation for easy sharing
  6. Polished the UI/UX with responsive design

Technical Challenges

The journey wasn't without obstacles:

Infinite Recursion in RLS Policies

One of the most challenging issues was an infinite recursion bug in the Row Level Security policies. When checking if a user was an admin, the policy would query the profiles table, which itself had RLS enabled, creating a circular dependency.

The solution required creating a SECURITY DEFINER function called is_admin() that bypassed RLS when checking admin status:

CREATE OR REPLACE FUNCTION is_admin()
RETURNS boolean
LANGUAGE sql
SECURITY DEFINER
SET search_path = public
AS $$
  SELECT EXISTS (
    SELECT 1 FROM profiles 
    WHERE id = auth.uid() AND role = 'admin'
  );
$$;

Anonymous Upload Security

Balancing security with ease of use for anonymous uploads was challenging. I needed to ensure guests could upload photos without authentication while preventing abuse.

The solution combined:

  • Time-limited access through event deadlines
  • File validation on both client and server
  • Storage bucket policies with proper constraints
  • IP tracking for basic abuse prevention

Efficient Photo Management

As events could potentially accumulate hundreds or thousands of photos, efficient management became crucial. I implemented:

  • Lazy loading and pagination for photo galleries
  • Client-side image compression before upload
  • Thumbnail generation for faster gallery loading
  • Bulk download functionality with ZIP compression

Future Directions

This MVP is just the beginning. The architecture was designed with extensibility in mind, allowing for future enhancements like:

  • AI-powered duplicate detection
  • Facial recognition for photo organization
  • Mobile apps for offline uploads
  • Social features like commenting and favorites

What started as a solution to a personal problem has evolved into a platform with potential to transform how we collect and share memories from special events.

Built With

  • autoprefixer
  • date-fns
  • eslint
  • input-validation
  • jszip
  • lucide-react
  • netlify
  • next.js-13.5.1-with-app-router
  • postcss
  • postgresql-database
  • qrcode.react
  • radix-ui-components
  • react-18.2.0
  • react-hook-form-7.53.0-with-zod-validation
  • row-level-security-(rls)
  • sonner-toast-notifications
  • storage)
  • supabase-(authentication
  • tailwind-css-3.3.3
  • typescript-5.2.2
Share this project:

Updates