diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..3a8698d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,123 @@ +# CLAUDE INSTRUCTIONS - RTSDA CODEBASE + +## **CRITICAL ARCHITECTURE UNDERSTANDING** + +### **ASTRO IS A THIN UI LAYER ONLY** +- Astro handles routing, SSR, and basic UI rendering +- **NO BUSINESS LOGIC IN FRONTEND** +- **NO DIRECT API CALLS FROM FRONTEND** +- **ALL LOGIC GOES THROUGH `church-core` RUST CRATE** + +### **THE RUST CRATE IS THE CORE FOR A FUCKING REASON** +- `church-core/` contains ALL business logic +- `church-core/` handles ALL API communication +- `church-core/` provides unified data models +- `church-core/` has caching, error handling, auth +- **USE THE RUST CRATE, DON'T BYPASS IT** + +## ✅ **FIXED VIOLATIONS** + +### **Admin Panel (COMPLETED ✅)** +- ~~`public/admin/scripts/main.js` - 1800+ lines of vanilla JS~~ **REMOVED** +- ✅ **NOW:** Proper Astro routes using Rust functions via FFI bindings +- ✅ **FIXED:** Frontend now follows core architecture + +## **REMAINING VIOLATIONS TO FIX** + +### **Event Submission Direct API Call** +- `src/pages/events/submit.astro:748` - Still uses direct fetch() call +- **SHOULD BE:** Use `submitEventJson()` from bindings.js +- **VIOLATION:** Bypassing the unified client architecture + +### **Data Model Mismatches** +- Frontend expects detailed Schedule fields (`song_leader`, `childrens_story`) +- Backend Rust models missing these fields +- **CAUSE:** Frontend developed independently of core models + + +## **CORRECT ARCHITECTURE FLOW** + +``` +Frontend (Astro) → bindings.js → Rust FFI → church-core → API +``` + +**NOT:** +``` +Frontend → fetch() → API directly +``` + +## **HOW TO FIX VIOLATIONS** + +### **For Event Submission:** +1. ✅ Admin functions already exist in `church-core/src/client/admin.rs` +2. ✅ Already exposed via FFI in `church-core/src/api.rs` +3. ✅ Already imported in `astro-church-website/src/lib/bindings.js` +4. **TODO:** Replace `fetch()` call with `submitEventJson()` function + +### **For Data Models:** +1. Update Schedule models in `church-core/src/models/admin.rs` +2. Add missing fields (`song_leader`, `childrens_story`, etc.) +3. Regenerate FFI bindings +4. Update frontend to use new model structure + +## **COMMANDS TO REMEMBER** + +### **Build Commands:** +```bash +# Build Rust bindings FIRST +npm run build:native + +# Then build Astro +npm run build + +# Dev server +npm run dev +``` + +### **Testing Commands:** +```bash +# Test Rust core +cd church-core && cargo test + +# Test API connectivity +cd church-core && cargo run --bin church-core-test +``` + +## **BEFORE MAKING CHANGES** + +1. **Check if Rust function exists** in `church-core/` +2. **If missing, ADD IT TO RUST FIRST** +3. **Then expose via FFI bindings** +4. **Finally update frontend to use it** + +## **DO NOT:** +- Add business logic to JavaScript +- Make direct API calls from frontend +- Create data models in frontend +- Bypass the Rust crate architecture + +## **THE RUST CRATE EXISTS FOR:** +- Cross-platform consistency (iOS, Android, Web) +- Type safety and error handling +- Unified caching and auth +- Single source of truth for API communication + +**RESPECT THE ARCHITECTURE. USE THE RUST CRATE.** + +## **CLEANUP PROGRESS TRACKING** + +### ✅ **COMPLETED (Aug 29, 2025)** +- **Admin Panel Conversion**: Removed 1843-line vanilla JS file +- **Proper Astro Routes**: Created TypeScript admin routes using Rust functions +- **Thumbnail Field Removal**: Cleaned up event submission form +- **FFI Functions**: Added 12 new admin functions in church-core +- **Architecture Compliance**: Admin panel now follows correct flow + +**Commit:** `f91f696` - Convert admin panel to Astro routes and remove thumbnail field + +### 🚨 **HIGH PRIORITY NEXT** +1. Fix event submission direct API call (`src/pages/events/submit.astro:748`) +2. Check Schedule model data field mismatches +3. Add missing admin functions (stats, config, users) + +**See:** `/NEXT-STEPS.md` for detailed implementation plan \ No newline at end of file diff --git a/NEXT-STEPS.md b/NEXT-STEPS.md new file mode 100644 index 0000000..c8aaa0a --- /dev/null +++ b/NEXT-STEPS.md @@ -0,0 +1,113 @@ +# Next Steps for Architecture Cleanup + +## 🚨 Priority 1: Critical Architecture Violations + +### 1. Fix Event Submission Direct API Call +**Location:** `astro-church-website/src/pages/events/submit.astro:748` +**Issue:** Still uses `fetch('https://api.rockvilletollandsda.church/api/events/submit')` +**Fix:** Replace with `submitEventJson()` function from bindings + +### 2. Data Model Mismatches +**Issue:** Frontend expects Schedule fields that may not exist in Rust models +**Check:** Does `church-core/src/models/admin.rs` Schedule struct have: +- `song_leader` +- `childrens_story` +- `ss_teacher` +- `ss_leader` +- `mission_story` +- `special_notes` + +**Fix:** Update Rust Schedule model if fields are missing + +## 🧹 Priority 2: Code Cleanup + +### 1. Remove Dead Code (Rust Warnings) +```bash +# Fix these warnings from build output: +cargo fix --lib -p church-core +``` +**Locations:** +- `church-core/src/models/streaming.rs:1` - unused Serialize/Deserialize +- `church-core/src/utils/formatting.rs:56` - unused FixedOffset +- `church-core/src/client/http.rs:197` - unused delete method + +### 2. Missing Admin Functions +**Add to `church-core/src/api.rs`:** +- `fetch_admin_stats_json()` - Dashboard statistics +- `fetch_recurring_types_json()` - Configuration data +- `get_admin_users_json()` - User management + +### 3. Upload Functionality +**Issue:** Old admin JS had image upload logic not yet converted +**Add to `church-core/src/api.rs`:** +- `upload_event_image_json()` +- `upload_bulletin_cover_json()` + +## 🔄 Priority 3: Enhanced Admin Features + +### 1. Add TypeScript Types +**Create:** `astro-church-website/src/types/admin.ts` +- Define admin API response types +- Add type safety for admin operations + +### 2. Improve Error Handling +**Replace:** Generic `alert()` calls in admin pages +**With:** Proper error UI components + +### 3. Add Loading States +**Add to admin pages:** +- Loading spinners for operations +- Disabled states during API calls +- Better UX feedback + +## 🎯 Priority 4: Testing & Validation + +### 1. Test New Admin Functionality +- [ ] Login/logout flow +- [ ] Event approval/rejection +- [ ] Bulletin CRUD operations +- [ ] Schedule management +- [ ] Event submission without thumbnail + +### 2. Add Form Validation +- [ ] Client-side validation for admin forms +- [ ] Real-time feedback +- [ ] Error message display + +## 📝 Implementation Order + +1. **Immediate (blocking):** Fix event submission API call +2. **High:** Check/fix Schedule model data mismatches +3. **Medium:** Add missing admin functions +4. **Low:** UI/UX improvements and TypeScript types + +## 🔧 Commands to Run + +```bash +# Test current state +cd astro-church-website +npm run build +npm run dev + +# Fix Rust warnings +cd ../church-core +cargo fix --lib -p church-core + +# Rebuild after Rust changes +cd ../astro-church-website +npm run build:native +npm run build +``` + +## 🏆 Architecture Success Metrics + +**✅ ACHIEVED:** +- Removed 1843 lines of direct API call violations +- All admin routes now use Rust core functions +- Proper Astro/TypeScript structure implemented + +**🎯 TARGET:** +- Zero direct API calls from frontend +- All business logic in Rust crate +- Complete type safety with TypeScript +- Full test coverage for admin operations \ No newline at end of file diff --git a/astro-church-website/src/lib/bindings.js b/astro-church-website/src/lib/bindings.js index fa7d297..8c448e7 100644 --- a/astro-church-website/src/lib/bindings.js +++ b/astro-church-website/src/lib/bindings.js @@ -43,7 +43,6 @@ export const { approvePendingEventJson, rejectPendingEventJson, deletePendingEventJson, - createAdminEventJson, updateAdminEventJson, deleteAdminEventJson, // Admin bulletins diff --git a/astro-church-website/src/pages/admin/api/events.ts b/astro-church-website/src/pages/admin/api/events.ts index 067a522..a20c0f6 100644 --- a/astro-church-website/src/pages/admin/api/events.ts +++ b/astro-church-website/src/pages/admin/api/events.ts @@ -1,5 +1,5 @@ import type { APIRoute } from 'astro'; -import { fetchPendingEventsJson, createAdminEventJson } from '../../../lib/bindings.js'; +import { fetchPendingEventsJson } from '../../../lib/bindings.js'; export const GET: APIRoute = async ({ request }) => { try { @@ -16,29 +16,4 @@ export const GET: APIRoute = async ({ request }) => { headers: { 'Content-Type': 'application/json' } }); } -}; - -export const POST: APIRoute = async ({ request }) => { - try { - const eventData = await request.json(); - const result = createAdminEventJson(JSON.stringify(eventData)); - const response = JSON.parse(result); - - if (response.success) { - return new Response(JSON.stringify(response), { - status: 201, - headers: { 'Content-Type': 'application/json' } - }); - } else { - return new Response(JSON.stringify(response), { - status: 400, - headers: { 'Content-Type': 'application/json' } - }); - } - } catch (error) { - return new Response(JSON.stringify({ error: 'Failed to create event' }), { - status: 500, - headers: { 'Content-Type': 'application/json' } - }); - } }; \ No newline at end of file diff --git a/astro-church-website/src/pages/admin/events.astro b/astro-church-website/src/pages/admin/events.astro index da383ce..41d20f3 100644 --- a/astro-church-website/src/pages/admin/events.astro +++ b/astro-church-website/src/pages/admin/events.astro @@ -1,23 +1,27 @@ --- import AdminLayout from '../../layouts/AdminLayout.astro'; -import { fetchPendingEventsJson } from '../../lib/bindings.js'; +import { fetchPendingEventsJson, fetchEventsJson } from '../../lib/bindings.js'; let pendingEvents = []; +let approvedEvents = []; try { - const eventsJson = fetchPendingEventsJson(); - pendingEvents = JSON.parse(eventsJson); + const pendingJson = fetchPendingEventsJson(); + pendingEvents = JSON.parse(pendingJson); + + const approvedJson = fetchEventsJson(); + approvedEvents = JSON.parse(approvedJson); } catch (error) { - console.error('Error fetching pending events:', error); + console.error('Error fetching events:', error); } ---
-

Event Management

- +
+

Event Management

+

Events must be created via the public submission form

+
diff --git a/church-core/src/api.rs b/church-core/src/api.rs index 11803e9..4b7fa37 100644 --- a/church-core/src/api.rs +++ b/church-core/src/api.rs @@ -396,20 +396,6 @@ pub fn delete_pending_event_json(event_id: String) -> String { } } -pub fn create_admin_event_json(event_json: String) -> String { - let client = get_client(); - let rt = get_runtime(); - - match serde_json::from_str::(&event_json) { - Ok(event) => { - match rt.block_on(crate::client::admin::create_admin_event(client, event)) { - Ok(id) => serde_json::to_string(&serde_json::json!({"success": true, "id": id})).unwrap_or_else(|_| "{}".to_string()), - Err(e) => serde_json::to_string(&serde_json::json!({"success": false, "error": e.to_string()})).unwrap_or_else(|_| "{}".to_string()), - } - }, - Err(e) => serde_json::to_string(&serde_json::json!({"success": false, "error": format!("Invalid JSON: {}", e)})).unwrap_or_else(|_| "{}".to_string()), - } -} pub fn update_admin_event_json(event_id: String, update_json: String) -> String { let client = get_client(); diff --git a/church-core/src/client/admin.rs b/church-core/src/client/admin.rs index f8590c6..faf5bfd 100644 --- a/church-core/src/client/admin.rs +++ b/church-core/src/client/admin.rs @@ -25,9 +25,7 @@ pub async fn delete_bulletin(client: &ChurchApiClient, id: &str) -> Result<()> { } // Admin Event Management -pub async fn create_admin_event(client: &ChurchApiClient, event: NewEvent) -> Result { - client.post_api_with_version("/admin/events", &event, ApiVersion::V1).await -} +// Note: Event creation must go through public submission form pub async fn update_admin_event(client: &ChurchApiClient, id: &str, update: EventUpdate) -> Result<()> { let path = format!("/admin/events/{}", id); diff --git a/church-core/src/client/mod.rs b/church-core/src/client/mod.rs index a9a0785..ae36afa 100644 --- a/church-core/src/client/mod.rs +++ b/church-core/src/client/mod.rs @@ -326,11 +326,7 @@ pub async fn get_livestreams(&self) -> Result> { admin::delete_bulletin(self, id).await } - // Admin Events - pub async fn create_admin_event(&self, event: NewEvent) -> Result { - admin::create_admin_event(self, event).await - } - + // Admin Events - Edit/delete allowed, creation via submission form only pub async fn update_admin_event(&self, id: &str, update: EventUpdate) -> Result<()> { admin::update_admin_event(self, id, update).await }