Skip to content

refactor: Improve TasksManager maintainability - quick wins #2752

@baderdean

Description

@baderdean

Problem

The TasksManager class (723 lines) is difficult to maintain due to:

  • Inline PubSub handler in constructor (~50 mixed concerns)
  • Deeply nested conditionals in hasCompleted() (8 levels)
  • createTask() at 320+ lines doing too much
  • Loose type casting hiding potential errors

These hurt debugging and onboarding when things break at 3am.

Plan

1. Extract inline PubSub handler (~1-2 hrs)

Current: Lines 56-108 in constructor - JSON parsing, validation, state updates all together.

Refactor:

  • Create TaskProgressHandler class
  • Move JSON parsing and validation there
  • Keep state updates in TasksManager

Why: Easier to debug when PubSub fails, testable in isolation.

2. Break up `hasCompleted()` method (~2-3 hrs)

Current: 562-650 - 8 levels of nested conditionals, impossible to trace which process stops when.

Refactor:

// From:
if (!fetch.stoppedAt && fetch.status === TaskStatus.Done) { ... }
if (!signature.stoppedAt && ...) { ... }

// To:
private checkAndStopFetch(task: MiningTask): Promise<void>
private checkAndStopSignature(task: MiningTask): Promise<void>
private checkAndStopExtract(task: MiningTask): Promise<void>
private checkAndStopClean(task: MiningTask): Promise<void>

Why: When a fetch task doesn't stop as expected, you can debug one method instead of unwinding 8 levels.

3. Split `createTask()` method (~2-3 hrs)

Current: 320+ lines doing: ID generation, task building, DB creation, API calls, Redis subscription.

Refactor:

  • initiateMiningId() - generates IDs and stream names
  • buildTaskObject() - constructs the MiningTask with processes
  • createDbRecords() - creates Supabase task records
  • startFetchJob() - calls email fetcher API

Why: When fetch fails mid-method, you hunt through 300 lines to find where.

4. Type-safe progress updates (~1 hr)

Current: Line 544 uses as Record<string, number> casting - hides type errors.

Refactor:

// From:
const taskProgress = process[taskProperty].details.progress as Record<string, number>;

// To:
const progressTypes: Record<TaskProgressType, keyof TaskProgress> = {
  fetched: 'fetched',
  extracted: 'extracted',
  // ...
};
// Use with type guard

Why: Catches bugs at compile time, not runtime.

Files to Modify

  • backend/src/services/tasks-manager/TasksManager.ts

Files to Add

  • backend/src/services/tasks-manager/TaskProgressHandler.ts (new)

Files to Test

  • backend/test/unit/taskManager.test.ts - May need updates for extracted classes

Not in Scope

Success Criteria

  • TasksManager under 500 lines
  • hasCompleted() uses flat method calls
  • createTask() broken into 4 clear steps
  • No `as` casting on progress updates

Metadata

Metadata

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions