> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cfosilvia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Vault transaction upload

# Vault Transaction Upload Documentation

## Overview

The Vault Transaction Upload feature allows users to upload CSV files containing transaction data directly from the Document Vault interface. This provides a unified experience where users can manage both their documents and financial transactions from a single location.

## Architecture

### Component Structure

The transaction upload functionality is built using a reusable approach that leverages existing transaction CSV processing logic:

```
app/vault/components/upload-transactions-vault.tsx
├── Dialog UI wrapper
├── CSV file upload interface
├── Column mapping step
├── Review and preview step
└── Import confirmation

Reuses logic from:
├── app/transactions/unified-page.tsx (CSV parsing)
├── hooks/mutations/use-import-transactions.ts (import logic)
└── lib/unified-transaction-helpers.ts (helper functions)
```

### Key Design Decisions

1. **Component Reusability**: Rather than duplicating CSV processing logic, the component reuses the same parsing and validation functions used in the main transactions page
2. **Separation of Concerns**: Document uploads and transaction uploads are kept as separate dialogs for clarity
3. **User Experience**: The upload process provides immediate feedback and clear progress indicators
4. **No Folder Dependency**: Transaction uploads don't require folder selection, simplifying the workflow

## User Flow

### Step 1: Initiate Upload

* User clicks "Upload Transactions" button in the Vault page header
* Button is always enabled (unlike document upload which requires folder selection)
* PostHog analytics event `vault_transactions_upload_clicked` is tracked

### Step 2: File Upload

* User selects a CSV file containing transaction data
* File validation ensures only CSV files are accepted
* Supported CSV formats:
  * Standard bank export formats
  * Custom formats with manual column mapping

### Step 3: Column Mapping

* System attempts to auto-detect columns:
  * Date
  * Description/Merchant
  * Amount
  * Category (optional)
* User can manually map columns if auto-detection fails
* Preview of first few rows displayed for verification

### Step 4: Category Mapping

* Automatic category assignment using:
  1. Exact match against existing transaction categories
  2. AI-powered categorization for unmatched transactions
* User can review and modify suggested categories
* Unknown categories are flagged for manual review

### Step 5: Preview and Confirmation

* Display summary of transactions to be imported
* Show count and total amount
* Allow final review before import

### Step 6: Import Execution

* Transactions are imported to the database
* Progress indicator shows import status
* Success toast notification displayed
* User redirected or prompted to view transactions

## Component Implementation

### Main Component: UploadTransactionsVault

Located at: `app/vault/components/upload-transactions-vault.tsx`

#### Key Features

```typescript theme={null}
interface UploadTransactionsVaultProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  onSuccess: () => void
}

export function UploadTransactionsVault({
  open,
  onOpenChange,
  onSuccess,
}: UploadTransactionsVaultProps)
```

#### State Management

```typescript theme={null}
const [step, setStep] = useState<'upload' | 'mapping' | 'preview'>('upload')
const [selectedFile, setSelectedFile] = useState<File | null>(null)
const [parsedData, setParsedData] = useState<any[]>([])
const [columnMapping, setColumnMapping] = useState<ColumnMapping>({})
const [isProcessing, setIsProcessing] = useState(false)
```

#### CSV Processing

The component leverages existing CSV parsing logic:

```typescript theme={null}
import { parseCSV, detectColumns, mapTransactions } from '@/lib/csv-helpers'

// Parse uploaded CSV file
const data = await parseCSV(selectedFile)

// Auto-detect column mappings
const detectedColumns = detectColumns(data[0])

// Map CSV rows to transaction objects
const transactions = mapTransactions(data, columnMapping)
```

### Integration with Vault Page

Located at: `app/vault/page.tsx`

```typescript theme={null}
const [isTransactionsUploadOpen, setIsTransactionsUploadOpen] = useState(false)

// Button in header
<Button
  onClick={() => {
    setIsTransactionsUploadOpen(true);
    posthog.capture('vault_transactions_upload_clicked', {
      timestamp: new Date().toISOString()
    });
  }}
  size='sm'
  variant='outline'
>
  <Upload className='h-4 w-4' />
  Upload Transactions
</Button>

// Dialog component
<UploadTransactionsVault
  open={isTransactionsUploadOpen}
  onOpenChange={setIsTransactionsUploadOpen}
  onSuccess={() => {
    toast({
      title: 'Success',
      description: 'Transactions uploaded successfully.',
    })
  }}
/>
```

## API Integration

### Endpoints Used

1. **Parse CSV**: Client-side parsing using Papa Parse library
2. **Import Transactions**: `/api/transactions/import` (existing endpoint)
3. **AI Categorization**: `/api/transactions/categorize` (existing endpoint)

### Data Flow

```
User uploads CSV
    ↓
Parse CSV client-side
    ↓
Detect/Map columns
    ↓
Preview transactions
    ↓
Call import API
    ↓
Save to database
    ↓
Success notification
```

## Comparison: Vault Upload vs. Transactions Page Upload

### Similarities

* Both use the same CSV parsing logic
* Both support automatic category mapping with AI
* Both provide preview before import
* Both handle the same transaction data formats

### Differences

| Feature | Vault Upload | Transactions Page Upload |
| - | - | - |
| **Location** | Document Vault | Transactions Page |
| **Context** | Document management focused | Transaction management focused |
| **Button Text** | "Upload Transactions" | "Import CSV" or "Add Manual Transaction" |
| **User Intent** | Bulk import from vault | Direct transaction management |
| **Post-Import** | Stay in vault with toast | Navigate to transactions view |
| **Analytics Event** | `vault_transactions_upload_clicked` | `transactions_csv_import_clicked` |

## Error Handling

### Common Errors and Solutions

1. **Invalid CSV Format**
   * Error: "Invalid CSV file format"
   * Solution: Ensure file is properly formatted CSV with headers
   * Recovery: User can re-upload a corrected file

2. **Missing Required Columns**
   * Error: "Required columns not found: Date, Amount"
   * Solution: Manual column mapping interface
   * Recovery: User maps columns explicitly

3. **Invalid Date Format**
   * Error: "Unable to parse dates in column"
   * Solution: Suggest common date formats
   * Recovery: User selects correct date format

4. **Duplicate Transactions**
   * Warning: "X transactions appear to be duplicates"
   * Solution: Show duplicate detection with option to skip
   * Recovery: User can review and deselect duplicates

5. **Import Failure**
   * Error: "Failed to import transactions"
   * Solution: Log detailed error and show user-friendly message
   * Recovery: User can retry import or contact support

## Analytics Tracking

### Events Tracked

```typescript theme={null}
// Button click
posthog.capture('vault_transactions_upload_clicked', {
  timestamp: new Date().toISOString()
})

// File selected
posthog.capture('vault_transactions_file_selected', {
  file_size: file.size,
  file_type: file.type,
  timestamp: new Date().toISOString()
})

// Columns mapped
posthog.capture('vault_transactions_columns_mapped', {
  auto_detected: isAutoDetected,
  manual_mapping_required: requiresManualMapping,
  timestamp: new Date().toISOString()
})

// Import initiated
posthog.capture('vault_transactions_import_started', {
  transaction_count: transactions.length,
  total_amount: totalAmount,
  timestamp: new Date().toISOString()
})

// Import completed
posthog.capture('vault_transactions_import_completed', {
  transaction_count: importedCount,
  success_count: successCount,
  error_count: errorCount,
  duration_ms: duration,
  timestamp: new Date().toISOString()
})

// Import failed
posthog.capture('vault_transactions_import_failed', {
  error_message: error.message,
  transaction_count: transactions.length,
  timestamp: new Date().toISOString()
})
```

## Future Enhancements

### Planned Features

1. **Template Support**
   * Save column mappings as templates
   * Quick import with saved templates
   * Share templates across organization

2. **Batch Processing**
   * Import multiple CSV files at once
   * Progress tracking for large imports
   * Background processing for very large files

3. **Advanced Validation**
   * Balance reconciliation checks
   * Duplicate detection across files
   * Spending pattern anomaly detection

4. **Integration with Document Vault**
   * Link imported transactions to source documents
   * Attach receipts or invoices to transactions
   * Track document-to-transaction relationships

5. **Export Capabilities**
   * Export filtered transactions back to CSV
   * Generate reports from imported data
   * Format conversions (QFX, OFX, etc.)

## Best Practices

### For Developers

1. **Component Reusability**: Always check if existing logic can be reused before implementing new parsing/validation
2. **Error Handling**: Provide clear, actionable error messages
3. **Analytics**: Track key user actions for product insights
4. **Testing**: Test with various CSV formats and edge cases
5. **Documentation**: Keep this doc updated with any changes

### For Users

1. **CSV Format**: Ensure CSV has clear headers for Date, Description, and Amount
2. **Data Review**: Always review the preview before importing
3. **Category Mapping**: Review AI-suggested categories for accuracy
4. **Backup**: Keep original CSV files as backup
5. **Regular Imports**: Import transactions regularly to maintain accurate records

## Troubleshooting

### Debug Mode

Enable debug logging for troubleshooting:

```typescript theme={null}
const DEBUG = process.env.NODE_ENV === 'development'

if (DEBUG) {
  console.log('[CSV Upload] Parsed data:', parsedData)
  console.log('[CSV Upload] Column mapping:', columnMapping)
  console.log('[CSV Upload] Mapped transactions:', transactions)
}
```

### Common Issues

1. **Component Not Showing**
   * Check if dialog state is properly managed
   * Verify button onClick handler
   * Check for z-index conflicts

2. **CSV Not Parsing**
   * Verify file type is CSV
   * Check for encoding issues (UTF-8 recommended)
   * Inspect Papa Parse configuration

3. **Import Failing Silently**
   * Check browser console for errors
   * Verify API endpoint is accessible
   * Check authentication tokens

## Conclusion

The Vault Transaction Upload feature provides a seamless way for users to import financial data while managing their documents. By reusing existing CSV processing logic and providing clear user feedback, the feature enhances the overall vault experience without adding unnecessary complexity.

For questions or issues, refer to the main vault documentation at `docs/vault-architecture.md` or the transaction processing documentation.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.