diff --git a/OBJECT_STORAGE_SETUP.md b/OBJECT_STORAGE_SETUP.md deleted file mode 100644 index ddb4a55..0000000 --- a/OBJECT_STORAGE_SETUP.md +++ /dev/null @@ -1,118 +0,0 @@ -# 🗄️ Object Storage Setup Guide - -## Problem: Images Disappearing After a Few Hours - -Your website was saving uploaded images to the local filesystem (`static/images/`), which is **ephemeral storage** in Replit. This means files get automatically deleted after a few hours. - -## Solution: Replit Object Storage (Persistent Storage) - -I've updated your website to use **Replit Object Storage**, which is built on Google Cloud Storage and provides permanent file storage. - ---- - -## 📋 Setup Instructions (Required) - -### Step 1: Create an Object Storage Bucket - -1. Open the **Tools** panel in your Replit workspace (left sidebar) -2. Click on **Object Storage** -3. Click **"Create a Bucket"** -4. Give it a name (e.g., `ftc-team-images`) -5. Click **Create** - -### Step 2: Set Environment Variable - -1. Go to the **Secrets** tab in your Replit workspace (lock icon in left sidebar) -2. Add a new secret: - - **Key**: `OBJECT_STORAGE_BUCKET` - - **Value**: Your bucket name (e.g., `ftc-team-images`) -3. Click **Add Secret** - -### Step 3: Restart the Server - -1. Stop the Flask server if it's running -2. Start it again (or let it auto-restart) - ---- - -## ✅ How It Works Now - -### Automatic Upload to Persistent Storage - -All file uploads now go to Object Storage instead of local storage: - -- **Member/Mentor Photos** → `members/` folder in your bucket -- **Competition Images** → `competitions/` folder -- **Sponsor Logos** → `sponsors/` folder - -### Full Image URLs - -Images are now stored as **full Google Cloud Storage URLs** like: -``` -https://storage.googleapis.com/ftc-team-images/members/abc123.jpg -``` - -These URLs are: -- ✅ **Permanent** - Never get deleted -- ✅ **Fast** - Served directly from Google's CDN -- ✅ **Public** - Accessible from anywhere on the web -- ✅ **Reliable** - Backed by Google Cloud infrastructure - ---- - -## 🔧 Code Changes Made - -### New Files: -- `object_storage.py` - Object storage service module -- `OBJECT_STORAGE_SETUP.md` - This guide - -### Updated Files: -- `app.py` - All upload routes now use object storage - - `add_member()` - Member/mentor images - - `update_member()` - Member/mentor updates - - `add_competition()` - Competition images - - `edit_competition()` - Competition image updates - - `add_sponsor()` - Sponsor logos - -### Updated Dependencies: -- Added `google-cloud-storage` package - ---- - -## 🚀 Testing - -After setup, test by: - -1. Go to `/admin/login` (password: `techturb123`) -2. Upload a new member photo or competition image -3. Check that the image displays correctly -4. Wait a few hours - the image should still be there! - ---- - -## 🔒 Security Notes - -- Object storage is authenticated automatically via Replit's infrastructure -- All uploaded files are made publicly accessible (required for website images) -- Files are organized into folders for easy management -- Each file gets a unique UUID to prevent naming conflicts - ---- - -## ⚠️ Important: Fallback Mode - -If you haven't set up object storage yet, the website will still work using local storage (ephemeral): -- You'll see a warning in the console: `"Warning: Object Storage not configured"` -- Files will still be saved but **will disappear after a few hours** -- Set up object storage ASAP to make uploads permanent! - ---- - -## 📚 Additional Resources - -- [Replit Object Storage Docs](https://docs.replit.com/hosting/deployments/object-storage) -- [Google Cloud Storage](https://cloud.google.com/storage) - ---- - -**Need Help?** If you have any issues with setup, check the console logs for error messages. diff --git a/replit.md b/replit.md index 9a52bbf..746d070 100644 --- a/replit.md +++ b/replit.md @@ -3,39 +3,28 @@ ## Overview Flask-based website for FTC Team 23344 with a modern dark theme (#000000 pure black background), comprehensive content management system, PostgreSQL database integration, and premium smooth-scrolling animations. -## Recent Changes (November 13, 2025) +## Recent Changes (December 13, 2025) -### Critical Fix: Persistent Object Storage for Uploaded Files -Fixed the issue where uploaded images (members, mentors, competitions, sponsors) were disappearing after a few hours. +### Complete Object Storage Migration +All uploaded images are now stored permanently in Replit Object Storage, preventing the issue where files would disappear after a few hours. -**The Problem:** -- Files were being saved to local filesystem (`static/images/`) -- Local storage in Replit is **ephemeral** and gets cleared periodically -- All uploaded images would vanish after a few hours +**What Was Done:** +1. Installed `replit-object-storage` official Python package +2. Created `object_storage.py` using official Replit SDK +3. Added `/storage/` route to serve files from object storage +4. Added `|image_url` Jinja template filter to handle both local and storage paths +5. Migrated all existing member, mentor, competition, and sponsor images to object storage +6. Updated database paths from `images/filename.jpg` to `/storage/folder/uuid.ext` -**The Solution:** -- Migrated to **Replit Object Storage** (built on Google Cloud Storage) -- All file uploads now go to **persistent, permanent storage** -- Images are served directly from Google's CDN with full URLs +**How It Works:** +- New uploads go directly to object storage via `upload_file_to_storage()` helper +- Database stores paths like `/storage/members/uuid.png` +- Templates use `{{ image_path|image_url }}` filter which handles both formats +- `/storage/` route serves files from object storage bucket +- Background images (hero, team, etc.) remain local as they don't get erased -**Technical Implementation:** -- Created `object_storage.py` module using Google Cloud Storage Python client -- Updated all upload routes to use object storage: - - `add_member()`, `update_member()` - Member/mentor photos - - `add_competition()`, `edit_competition()` - Competition images - - `add_sponsor()` - Sponsor logos -- Intelligent fallback: uses local storage if object storage not configured -- Files organized by type: `members/`, `competitions/`, `sponsors/` folders -- Unique UUIDs prevent filename conflicts -- Public URLs stored in database instead of local paths - -**Setup Required (See OBJECT_STORAGE_SETUP.md):** -1. Create bucket in Object Storage pane -2. Set `OBJECT_STORAGE_BUCKET` environment variable -3. Restart server - -**Dependencies Added:** -- `google-cloud-storage` (v3.5.0) +**Bucket:** `ftc-team-images` +**Package:** `replit-object-storage` (installed via pip) ## Recent Changes (November 12, 2025)