Files
thrilltrack-explorer/docs/logging/SUBMISSION_FLOW_LOGGING.md
2025-11-06 00:11:31 +00:00

8.5 KiB

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.tsxLocationSearch.onLocationSelect()

Log Points:

  • Location selected from search (when user picks from dropdown)
  • Location set in form state (confirmation of setValue)

Log Format:

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.tsxhandleFormSubmit()

Log Points:

  • Form data being submitted (what's being passed to submission helper)

Log Format:

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.tssubmitParkCreation()

Log Points:

  • Data received by submission helper (what arrived from form)
  • Data being saved to database (temp_location_data structure)

Log Format:

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.tsupdateSubmissionItem()

Log Points:

  • Update item start (when moderator edits)
  • Saving park data (before database write)
  • Park data saved successfully (after database write)

Log Format:

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.tshandleApproveSubmission()

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:

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.tsapproveSubmissionItems()

Log Points:

  • Approval process started (beginning of batch approval)
  • Processing item for approval (for each item)
  • Entity created successfully (after entity creation)

Log Format:

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.locationtemp_location_data (JSONB in park_submissions)
  5. Display/Edit: temp_location_datalocation (transformed for form compatibility)
  6. Validation: temp_location_datalocation (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:

    // 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:

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:

// 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)