# Multi-Table Detection Review

**Date:** 2025-11-27
**Reviewer:** Amp (AI Assistant)
**Scope:** Review of `src/extraction/table_detector.py` for multi-table detection capabilities (FR10).

## Executive Summary

The current `TableDetector` implementation **successfully supports detecting multiple tables** within a single Excel sheet, but with specific constraints. It uses a heuristic state machine that scans rows sequentially to identify distinct table blocks separated by blank rows.

**Status:** ✅ Supported (Vertically Stacked Tables) / ⚠️ Unsupported (Side-by-Side Tables)

## Detailed Analysis

### 1. Vertical Detection (Supported)
The logic in `_detect_boundaries_in_sheet` iterates through the sheet row by row.
- **Mechanism:**
  - Starts a table when a **Header Row** is detected (`_is_header_row`).
  - Ends a table when **2+ consecutive blank rows** are encountered.
  - Resets state (`current_table = None`) and continues scanning for the next header.
- **Result:** Tables stacked vertically (Table A above Table B) are correctly identified as separate `TableBoundary` objects.
- **Code Evidence:**
  ```python
  if current_table and blank_row_count >= 2:
      # Ends current table, saves it to list
      boundaries.append(current_table)
      current_table = None
      # Loop continues to find next table...
  ```

### 2. Horizontal Detection (Limitation)
The current logic **does not** support tables placed side-by-side (e.g., Table A in cols A-C, Table B in cols F-H on the same rows).
- **Mechanism:**
  - `_get_first_populated_col` finds the leftmost populated cell (e.g., "A").
  - `_get_last_populated_col` finds the rightmost populated cell (e.g., "H").
  - It treats the entire range (A:H) as a single table.
- **Impact:** Side-by-side tables will be merged into a single large table, potentially causing header misalignment or "garbage" columns (D-E) being included.

### 3. Integration with Pipeline
The `ExtractionPipeline` in `src/extraction/pipeline.py` correctly handles the output of the detector:
- It accepts a **list** of boundaries: `boundaries = self.table_detector._detect_boundaries_in_sheet(sheet)`
- It iterates through every detected table: `for table_idx, boundary in enumerate(boundaries, start=1):`
- Each table is processed independently for header extraction and record building.

## Conclusion

The system satisfies **FR10: System handles multiple tables per sheet** for the most common case (vertical stacking).

**Recommendations:**
1.  **Keep as is for MVP:** Vertical stacking is the standard convention for machine-readable Excel files.
2.  **Documentation:** Explicitly document that "Side-by-side tables are treated as a single table" to set user expectations.
3.  **Future Improvement:** If side-by-side support is needed, the `_is_header_row` logic would need to detect "gaps" of empty columns within a single row to split boundaries horizontally.
