Skip to content

DistrictVolumeProcessor

Paulo Gomes da Cruz Junior edited this page Jun 17, 2026 · 1 revision

DistrictVolumeProcessor Service

Type: Component (Service) — FileProcessor<TableData> implementation Domain: District Volume Import Status: Complete (Issue #905) Last updated: 2026-06-17

Overview

DistrictVolumeProcessor is the top-level orchestrator of the spreadsheet import pipeline. It implements FileProcessor<TableData> and coordinates the full processing chain: file loading, format detection (Interior vs Coast), matrix parsing, and domain mapping.

It is consumed by FileUploadInput which calls processor.load(file) when a user drops or selects a file.

Public Interface

Class: DistrictVolumeProcessor implements FileProcessor<TableData>

No constructor parameters.

load(file: File): Promise<ProcessorResult<TableData>>

Processes a district volume spreadsheet file.

Parameter Type Required Description
file File yes Browser File (.xlsx)

Returns: ProcessorResult<TableData>

  • Success: { success: true, data: [InteriorData | CoastData] }
  • Failure: { success: false, errors: string[] }

Pipeline

file
  │
  ▼
1. detectVariant(reader, file)
   └─ listSheets → check for "Interior" or "Coast" (case-insensitive)
   └─ on failure → return { success: false, errors: [...] }
  │
  ▼
2. reader.read(file, config.sheetName)
   └─ on failure → return { success: false, errors: [...] }
  │
  ▼
3. MatrixParser.parse(worksheet, config)
   └─ errors found → return { success: false, errors: [...] }
   └─ no data rows → return { success: false, errors: [...] }
  │
  ▼
4. mapInteriorSpreadsheet(data)  OR  mapCoastSpreadsheet(data)
  │
  ▼
{ success: true, data: [TableData] }

Detection Heuristic

Uses ExcelReader.listSheets() to check if any sheet name starts with "Interior" or "Coast" (case-insensitive, trimmed). The first match determines the variant and selects the corresponding MatrixConfig (interiorMatrixConfig or coastMatrixConfig).

Design Principles

Single Processor, Dual Format

Rather than two separate processors, a single processor auto-detects the format. This simplifies the FileUploadInput contract — it only needs one processor instance.

Procedural Error Handling

Each pipeline step catches its own errors and returns a user-friendly message. The processor never throws — it always returns a ProcessorResult, satisfying the FileProcessor contract.

Zero UI Dependencies

No React, Zod, or Carbon imports. The processor works with browser File objects and returns plain domain data.

Dependencies

Dependency Purpose
ExcelReader File loading and sheet access
MatrixParser Two-row merged-header parsing
interiorMatrixConfig / coastMatrixConfig Layout configuration
mapInteriorSpreadsheet / mapCoastSpreadsheet Domain object mapping
FileProcessor / ProcessorResult Contract types

Code Location

Artifact Path
Service frontend/src/services/districtvolumes/processors/districtVolumeProcessor.ts
Tests frontend/src/services/districtvolumes/processors/districtVolumeProcessor.unit.test.ts

Test Coverage

4 integration tests covering: valid Interior spreadsheet, valid Coast spreadsheet, corrupt file, and unsupported format.

Consumers

Consumer Location
DistrictVolumeUploadPage src/pages/DistrictVolumeUpload/

Usage Example

import { DistrictVolumeProcessor } from '@/services/districtvolumes/processors/districtVolumeProcessor';

const processor = new DistrictVolumeProcessor();
const result = await processor.load(file);

if (result.success) {
  const [data] = result.data;
  // data.type === 'INTERIOR' | 'COASTAL'
}

References

Reference Link
GitHub Issue #905
Related page ExcelReader
Related page MatrixParser
Related page SpreadsheetValidator

Waste Plus Wiki

Home

Architecture

Codes

Decisions

Knowledge Base

Development

Changes

Clone this wiki locally