Skip to content

Latest commit

 

History

History
167 lines (110 loc) · 3.58 KB

File metadata and controls

167 lines (110 loc) · 3.58 KB

SheetBuddy - Technical Debt & Improvements

P0 - Critical (Before Major Scale)

Web Worker for Large File Parsing

Files: lib/csvParser.ts, lib/xlsxParser.ts

CSV/XLSX parsing runs on main thread, blocking UI for large files (10k+ rows).

Solution:

// Create worker file: lib/parseWorker.ts
self.onmessage = async (e) => {
  const { file, type } = e.data;
  // Parse in worker
  const result = type === 'xlsx' ? await parseXLSX(file) : await parseCSV(file);
  self.postMessage(result);
};

Effort: Medium (4-6 hours)


P1 - High Priority

List Virtualization

Files: components/partner/PartnerList.tsx, components/compare/CompareView.tsx

All list items render to DOM. With 1000+ items, causes severe lag.

Solution: Install @tanstack/react-virtual or react-window

npm install @tanstack/react-virtual
import { useVirtualizer } from '@tanstack/react-virtual';

const virtualizer = useVirtualizer({
  count: filtered.length,
  getScrollElement: () => parentRef.current,
  estimateSize: () => 72, // estimated row height
});

Effort: Medium (3-4 hours)


Optimize Duplicate Detection

File: lib/dataTransformer.ts:196-213

Building Sets on every import degrades with database size.

Solution:

  • Cache existing invite keys in IndexedDB index
  • Use bloom filter for quick negative lookups
  • Or lazy-load existing data in chunks

Effort: Medium (2-3 hours)


P2 - Medium Priority

Consolidate ParsedRow Type

Files: lib/csvParser.ts, lib/xlsxParser.ts, lib/dataTransformer.ts

Three identical ParsedRow interface definitions.

Solution: Move to lib/types.ts and import everywhere.

Effort: Low (30 min)


Add Loading State to useTemplates

File: hooks/useTemplates.ts

Hook doesn't expose loading state like usePartners does.

Solution:

const isLoading = templatesQuery === undefined;
return { templates, isLoading, ... };

Effort: Low (15 min)


Zustand Store Slices

File: store/appStore.ts

Single store with 18+ fields. Could split into:

  • uiSlice (modals, view mode)
  • filterSlice (search, sort, status)
  • projectSlice (current project)

Effort: Medium (2 hours)


Extract Column Detection Constants

File: lib/columnDetector.ts

Magic numbers scattered throughout:

if (commaDelimitedRatio > 0.2 || ...)  // Why 0.2?
if (yesNoRatio > 0.7 || ...)           // Why 0.7?

Solution: Create config object with named thresholds.

Effort: Low (30 min)


P3 - Nice to Have

Replace Deprecated execCommand

File: components/partner/PartnerCard.tsx:46-51

Clipboard fallback uses deprecated document.execCommand('copy').

Solution: Remove fallback or use clipboard-polyfill package.

Effort: Low (15 min)


Error Boundaries for File Parsing

File: hooks/useImport.ts

Generic error messages for corrupted files.

Solution: Add specific error types:

class ParseError extends Error {
  constructor(message: string, public row?: number, public column?: string) {
    super(message);
  }
}

Effort: Low (1 hour)


Database Migration Robustness

File: lib/database.ts

No rollback strategy for failed migrations.

Solution: Add version tracking table and rollback handlers.

Effort: High (4+ hours)


Completed

  • CSV formula injection protection (Moved to export-time in lib/utils.ts)
  • Regex error handling in template pattern matching
  • Search input debouncing (300ms)
  • Fix useMemo side effects in CompareView