# Logging Policy

## ✅ Console Statement Prevention (P0 #2)

**Status**: Enforced via ESLint  
**Severity**: Critical - Security & Information Leakage

---

## The Problem

Console statements in production code cause:
- **Information leakage**: Sensitive data exposed in browser console
- **Performance overhead**: Console operations are expensive
- **Unprofessional UX**: Users see debug output
- **No structured logging**: Can't filter, search, or analyze logs effectively

**128 console statements** were found during the security audit.

---

## The Solution

### ✅ Use handleError() for Application Errors

**CRITICAL: All application errors MUST be logged to the Admin Panel Error Log** (`/admin/error-monitoring`)

```typescript
import { handleError } from '@/lib/errorHandler';

// ❌ DON'T use console or raw toast for errors
try {
  await fetchData();
} catch (error) {
  console.error('Failed:', error); // ❌ No admin logging
  toast.error('Failed to load data'); // ❌ Not tracked
}

// ✅ DO use handleError() for application errors
try {
  await fetchData();
} catch (error) {
  handleError(error, {
    action: 'Load Data',
    userId: user?.id,
    metadata: { entityId, context: 'DataLoader' }
  });
  throw error; // Re-throw for parent error boundaries
}
```

### ✅ Use the Structured Logger for Non-Error Logging

```typescript
import { logger } from '@/lib/logger';

// ❌ DON'T use console
console.log('User logged in:', userId);

// ✅ DO use structured logger
logger.info('User logged in', { userId });
logger.debug('Auth state changed', { state, userId });
```

### Error Handling Method

```typescript
// Application errors (REQUIRED for errors that need admin visibility)
handleError(
  error: unknown,
  context: {
    action: string;           // What operation failed
    userId?: string;          // Who was affected
    metadata?: Record<string, unknown>; // Additional context
  }
): string // Returns error reference ID
```

**What handleError() does:**
1. Logs error to `request_metadata` table (Admin Panel visibility)
2. Shows user-friendly toast with reference ID
3. Captures breadcrumbs and environment context
4. Makes errors searchable in `/admin/error-monitoring`
5. Returns error reference ID for tracking

### Logger Methods (for non-error logging)

```typescript
// Information (development only)
logger.info(message: string, context?: Record<string, unknown>);

// Warnings (development + production)
logger.warn(message: string, context?: Record<string, unknown>);

// Errors (development + production, but prefer handleError() for app errors)
logger.error(message: string, context?: Record<string, unknown>);

// Debug (very verbose, development only)
logger.debug(message: string, context?: Record<string, unknown>);
```

### Benefits of Structured Error Handling & Logging

1. **Admin visibility**: All errors logged to Admin Panel (`/admin/error-monitoring`)
2. **User-friendly**: Shows toast with reference ID for support tickets
3. **Context preservation**: Rich metadata for debugging
4. **Searchable**: Filter by user, action, date, error type
5. **Trackable**: Each error gets unique reference ID
6. **Automatic filtering**: Development logs show everything, production shows warnings/errors
7. **Security**: Prevents accidental PII exposure

---

## ESLint Enforcement

The `no-console` rule is enforced in `eslint.config.js`:

```javascript
"no-console": "error" // Blocks ALL console statements
```

This rule will:
- ❌ **Block**: `console.log()`, `console.debug()`, `console.info()`, `console.warn()`, `console.error()`
- ✅ **Use instead**: `logger.*` for logging, `handleError()` for error handling

### Running Lint

```bash
# Check for violations
npm run lint

# Auto-fix where possible
npm run lint -- --fix
```

---

## Migration Guide

### 1. Replace console.error in catch blocks with handleError()

```typescript
// Before
try {
  await saveData();
} catch (error) {
  console.error('Save failed:', error);
  toast.error('Failed to save');
}

// After
try {
  await saveData();
} catch (error) {
  handleError(error, {
    action: 'Save Data',
    userId: user?.id,
    metadata: { entityId, entityType }
  });
  throw error; // Re-throw for parent components
}
```

### 2. Replace console.log with logger.info

```typescript
// Before
console.log('[ModerationQueue] Fetching submissions');

// After
logger.info('Fetching submissions', { component: 'ModerationQueue' });
```

### 3. Replace console.debug with logger.debug

```typescript
// Before
console.log('[DEBUG] Auth state:', authState);

// After
logger.debug('Auth state', { authState });
```

### 4. Replace console.warn with logger.warn

```typescript
// Before
console.warn('localStorage error:', error);

// After
logger.warn('localStorage error', { error });
```

---

## Examples

### Good: Error Handling with Admin Logging

```typescript
import { handleError } from '@/lib/errorHandler';
import { logger } from '@/lib/logger';

const handleSubmit = async () => {
  logger.info('Starting submission', { 
    entityType, 
    entityId, 
    userId 
  });

  try {
    const result = await submitData();
    logger.info('Submission successful', { 
      submissionId: result.id,
      processingTime: Date.now() - startTime 
    });
    toast.success('Submission created successfully');
  } catch (error) {
    // handleError logs to admin panel + shows toast
    const errorId = handleError(error, { 
      action: 'Submit Data',
      userId,
      metadata: { entityType, entityId }
    });
    throw error; // Re-throw for parent error boundaries
  }
};
```

### Bad: Console Logging

```typescript
const handleSubmit = async () => {
  console.log('Submitting...'); // ❌ Will fail ESLint

  try {
    const result = await submitData();
    console.log('Success:', result); // ❌ Will fail ESLint
  } catch (error) {
    console.error(error); // ❌ Will fail ESLint
    toast.error('Failed'); // ❌ Not logged to admin panel
  }
};
```

---

## When to Use What

### Use `handleError()` for:
- ✅ Database errors (fetch, insert, update, delete)
- ✅ API call failures
- ✅ Form submission errors
- ✅ Authentication errors
- ✅ Any error that users should report to support
- ✅ Any error that needs admin investigation

### Use `logger.*` for:
- ✅ Debug information (development only)
- ✅ Performance tracking
- ✅ Component lifecycle events
- ✅ Non-error warnings (localStorage issues, etc.)

### Use `toast.*` (without handleError) for:
- ✅ Success messages
- ✅ Info messages
- ✅ User-facing validation errors (no admin logging needed)

### NEVER use `console.*`:
- ❌ All console statements are blocked by ESLint
- ❌ Use `handleError()` or `logger.*` instead

---

## Environment-Aware Logging

The logger automatically adjusts based on environment:

```typescript
// Development: All logs shown
logger.debug('Verbose details'); // ✅ Visible
logger.info('Operation started'); // ✅ Visible
logger.warn('Potential issue'); // ✅ Visible
logger.error('Critical error'); // ✅ Visible

// Production: Only warnings and errors
logger.debug('Verbose details'); // ❌ Hidden
logger.info('Operation started'); // ❌ Hidden
logger.warn('Potential issue'); // ✅ Visible
logger.error('Critical error'); // ✅ Visible + Sent to monitoring
```

---

## Testing with Logger

```typescript
import { logger } from '@/lib/logger';

// Mock logger in tests
jest.mock('@/lib/logger', () => ({
  logger: {
    info: jest.fn(),
    warn: jest.fn(),
    error: jest.fn(),
    debug: jest.fn(),
  }
}));

test('logs error on failure', async () => {
  await failingOperation();
  
  expect(logger.error).toHaveBeenCalledWith(
    'Operation failed',
    expect.objectContaining({ error: expect.any(String) })
  );
});
```

---

## Monitoring Integration (Future)

The logger is designed to integrate with:
- **Sentry**: Automatic error tracking
- **LogRocket**: Session replay with logs
- **Datadog**: Log aggregation and analysis
- **Custom dashboards**: Structured JSON logs

```typescript
// Future: Logs will automatically flow to monitoring services
logger.error('Payment failed', { 
  userId, 
  amount, 
  paymentProvider 
});
// → Automatically sent to Sentry with full context
// → Triggers alert if error rate exceeds threshold
```

---

## Edge Function Logging

### Using `edgeLogger` in Edge Functions

Edge functions use the `edgeLogger` utility from `_shared/logger.ts`:

```typescript
import { edgeLogger, startRequest, endRequest } from "../_shared/logger.ts";

const handler = async (req: Request): Promise<Response> => {
  const tracking = startRequest('function-name');
  
  try {
    edgeLogger.info('Processing request', {
      requestId: tracking.requestId,
      // ... context
    });
    
    // ... your code
    
    const duration = endRequest(tracking);
    edgeLogger.info('Request completed', { requestId: tracking.requestId, duration });
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    const duration = endRequest(tracking);
    edgeLogger.error('Request failed', {
      error: errorMessage,
      requestId: tracking.requestId,
      duration
    });
  }
};
```

### Logger Methods for Edge Functions
- `edgeLogger.info()` - General information logging
- `edgeLogger.warn()` - Warning conditions
- `edgeLogger.error()` - Error conditions
- `edgeLogger.debug()` - Detailed debugging (dev only)

All logs are visible in the Supabase Edge Function Logs dashboard.

**CRITICAL**: Never use `console.*` in edge functions. Always use `edgeLogger.*` instead.

---

## Summary

**Use `handleError()` for application errors** → Logs to Admin Panel + user-friendly toast  
**Use `logger.*` for general logging (client-side)** → Environment-aware console output  
**Use `edgeLogger.*` for edge function logging** → Structured logs visible in Supabase dashboard  
**Never use `console.*`** → Blocked by ESLint

This approach ensures:
- ✅ Production builds are clean (no console noise)
- ✅ All errors are tracked and actionable in Admin Panel
- ✅ Users get helpful error messages with reference IDs
- ✅ Development remains productive with detailed logs
- ✅ Edge functions have structured, searchable logs

## Admin Panel Error Monitoring

All errors logged via `handleError()` are visible in the Admin Panel at:

**Path**: `/admin/error-monitoring`

**Features**:
- Search and filter errors by action, user, date range
- View error context (metadata, breadcrumbs, environment)
- Track error frequency and patterns
- One-click copy of error details for debugging

**Access**: Admin role required

---

**Updated**: 2025-11-03  
**Status**: ✅ Enforced via ESLint (Frontend + Edge Functions)

---

**See Also:**
- `src/lib/errorHandler.ts` - Error handling utilities
- `src/lib/logger.ts` - Logger implementation
- `eslint.config.js` - Enforcement configuration
- `docs/JSONB_ELIMINATION.md` - Related improvements
