# Submission Flow Logging This document describes the structured logging implemented for tracking submission data through the moderation pipeline. ## Overview The submission flow has structured logging at each critical stage to enable debugging and auditing of data transformations. ## Logging Stages ### 1. Location Selection Stage **Location**: `src/components/admin/ParkForm.tsx` → `LocationSearch.onLocationSelect()` **Log Points**: - Location selected from search (when user picks from dropdown) - Location set in form state (confirmation of setValue) **Log Format**: ```typescript console.info('[ParkForm] Location selected:', { name: string, city: string | undefined, state_province: string | undefined, country: string, latitude: number, longitude: number, display_name: string }); console.info('[ParkForm] Location set in form:', locationObject); ``` ### 2. Form Submission Stage **Location**: `src/components/admin/ParkForm.tsx` → `handleFormSubmit()` **Log Points**: - Form data being submitted (what's being passed to submission helper) **Log Format**: ```typescript console.info('[ParkForm] Submitting park data:', { hasLocation: boolean, hasLocationId: boolean, locationData: object | undefined, parkName: string, isEditing: boolean }); ``` ### 3. Submission Helper Reception Stage **Location**: `src/lib/entitySubmissionHelpers.ts` → `submitParkCreation()` **Log Points**: - Data received by submission helper (what arrived from form) - Data being saved to database (temp_location_data structure) **Log Format**: ```typescript console.info('[submitParkCreation] Received data:', { hasLocation: boolean, hasLocationId: boolean, locationData: object | undefined, parkName: string, hasComposite: boolean }); console.info('[submitParkCreation] Saving to park_submissions:', { name: string, hasLocation: boolean, hasLocationId: boolean, temp_location_data: object | null }); ``` ### 4. Edit Stage **Location**: `src/lib/submissionItemsService.ts` → `updateSubmissionItem()` **Log Points**: - Update item start (when moderator edits) - Saving park data (before database write) - Park data saved successfully (after database write) **Log Format**: ```typescript console.info('[Submission Flow] Update item start', { itemId: string, hasItemData: boolean, statusUpdate: string | undefined, timestamp: ISO string }); console.info('[Submission Flow] Saving park data', { itemId: string, parkSubmissionId: string, hasLocation: boolean, locationData: object | null, fields: string[], timestamp: ISO string }); ``` ### 5. Validation Stage **Location**: `src/hooks/moderation/useModerationActions.ts` → `handleApproveSubmission()` **Log Points**: - Preparing items for validation (after fetching from DB) - Transformed park data (after temp_location_data → location transform) - Starting validation (before schema validation) - Validation completed (after schema validation) - Validation found blocking errors (if errors exist) **Log Format**: ```typescript console.info('[Submission Flow] Transformed park data for validation', { itemId: string, hasLocation: boolean, locationData: object | null, transformedHasLocation: boolean, timestamp: ISO string }); console.warn('[Submission Flow] Validation found blocking errors', { submissionId: string, itemsWithErrors: Array<{ itemId: string, itemType: string, errors: string[] }>, timestamp: ISO string }); ``` ### 6. Approval Stage **Location**: `src/lib/submissionItemsService.ts` → `approveSubmissionItems()` **Log Points**: - Approval process started (beginning of batch approval) - Processing item for approval (for each item) - Entity created successfully (after entity creation) **Log Format**: ```typescript console.info('[Submission Flow] Approval process started', { itemCount: number, itemIds: string[], itemTypes: string[], userId: string, timestamp: ISO string }); console.info('[Submission Flow] Processing item for approval', { itemId: string, itemType: string, isEdit: boolean, hasLocation: boolean, locationData: object | null, timestamp: ISO string }); ``` ## Key Data Transformations Logged ### Park Location Data The most critical transformation logged is the park location data flow: 1. **User Selection** (LocationSearch): OpenStreetMap result → `location` object 2. **Form State** (ParkForm): `setValue('location', location)` 3. **Form Submission** (ParkForm → submitParkCreation): `data.location` passed in submission 4. **Database Storage** (submitParkCreation): `data.location` → `temp_location_data` (JSONB in park_submissions) 5. **Display/Edit**: `temp_location_data` → `location` (transformed for form compatibility) 6. **Validation**: `temp_location_data` → `location` (transformed for schema validation) 7. **Approval**: `location` used to create actual location record **Why this matters**: - If location is NULL in database but user selected one → Check stages 1-4 - If validation fails with "Location is required" → Check stages 5-6 - Location validation errors typically indicate a break in this transformation chain. ## Debugging Workflow ### To debug "Location is required" validation errors: 1. **Check browser console** for `[ParkForm]` and `[Submission Flow]` logs 2. **Verify data at each stage**: ```javascript // Stage 1: Location selection [ParkForm] Location selected: { name: "Farmington, Utah", latitude: 40.98, ... } [ParkForm] Location set in form: { name: "Farmington, Utah", ... } // Stage 2: Form submission [ParkForm] Submitting park data { hasLocation: true, locationData: {...} } // Stage 3: Submission helper receives data [submitParkCreation] Received data { hasLocation: true, locationData: {...} } [submitParkCreation] Saving to park_submissions { temp_location_data: {...} } // Stage 4: Edit stage (if moderator edits later) [Submission Flow] Saving park data { hasLocation: true, locationData: {...} } // Stage 5: Validation stage [Submission Flow] Transformed park data { hasLocation: true, transformedHasLocation: true } // Stage 6: Approval stage [Submission Flow] Processing item { hasLocation: true, locationData: {...} } ``` 3. **Look for missing data**: - If `[ParkForm] Location selected` missing → User didn't select location from dropdown - If `hasLocation: false` in form submission → Location not set in form state (possible React Hook Form issue) - If `hasLocation: true` in submission but NULL in database → Database write failed (check errors) - If `hasLocation: true` but `transformedHasLocation: false` → Transformation failed - If validation logs missing → Check database query/fetch ### To debug NULL location in new submissions: 1. **Open browser console** before creating submission 2. **Select location** and verify `[ParkForm] Location selected` appears 3. **Submit form** and verify `[ParkForm] Submitting park data` shows `hasLocation: true` 4. **Check** `[submitParkCreation] Saving to park_submissions` shows `temp_location_data` is not null 5. **If location was selected but is NULL in database**: - Form state was cleared (page refresh/navigation before submit) - React Hook Form setValue didn't work (check "Location set in form" log) - Database write succeeded but data was lost (check for errors) ## Error Logging Integration Structured errors use the `handleError()` utility from `@/lib/errorHandler`: ```typescript handleError(error, { action: 'Update Park Submission Data', metadata: { itemId, parkSubmissionId, updateFields: Object.keys(updateData) } }); ``` Errors are logged to: - **Database**: `request_metadata` table - **Admin Panel**: `/admin/error-monitoring` - **Console**: Browser developer tools (with reference ID) ## Log Filtering To filter logs in browser console: ```javascript // All submission flow logs localStorage.setItem('logFilter', 'Submission Flow'); // Specific stages localStorage.setItem('logFilter', 'Validation'); localStorage.setItem('logFilter', 'Saving park data'); ``` ## Performance Considerations - Logs use `console.info()` and `console.warn()` which are stripped in production builds - Sensitive data (passwords, tokens) are never logged - Object logging uses shallow copies to avoid memory leaks - Timestamps use ISO format for timezone-aware debugging ## Future Enhancements - [ ] Add edge function logging for backend approval process - [ ] Add real-time log streaming to admin dashboard - [ ] Add log retention policies (30-day automatic cleanup) - [ ] Add performance metrics (time between stages) - [ ] Add user action correlation (who edited what when)