Skip to content

refactor(config): extract configMapper, unify build paths, DRY gadget escalation#539

Merged
zbigniewsobiecki merged 1 commit intodevfrom
refactor/config-repository-and-gadget-utils
Feb 24, 2026
Merged

refactor(config): extract configMapper, unify build paths, DRY gadget escalation#539
zbigniewsobiecki merged 1 commit intodevfrom
refactor/config-repository-and-gadget-utils

Conversation

@aaight
Copy link
Copy Markdown
Collaborator

@aaight aaight commented Feb 24, 2026

Summary

Refactors two areas of the codebase identified as the top candidates for cleanup:

  1. configRepository.tsconfigMapper.ts extraction — Separates pure transformation logic from DB query concerns by moving all mapping functions, interfaces, and helpers into a new dedicated module. Refactors mapProjectRow to use a structured MapProjectInput object instead of 8 positional parameters, adds a typed ProjectConfigRaw return type, and extracts buildTrelloConfig / buildJiraConfig / buildAgentBackendConfig per-integration helpers. Removes both biome-ignore suppressions.

  2. Unified buildRawConfig helper — Eliminates the duplicated extract→split→map→validate pattern shared between loadConfigFromDb and findProjectConfigFromDb by extracting a buildRawConfig(opts) function both callers use.

  3. DRY file-editing gadget utilities — Moves the identical ESCALATION_HINT constant and withEscalationHint function from FileSearchAndReplace.ts and FileMultiEdit.ts into a new shared module src/gadgets/shared/editEscalation.ts.

New files

  • src/db/repositories/configMapper.ts — extracted mapper with typed interfaces
  • src/gadgets/shared/editEscalation.ts — shared escalation hint utility
  • tests/unit/db/repositories/configMapper.test.ts — 34 unit tests (Trello-only, JIRA-only, mixed, none integration combos)
  • tests/unit/gadgets/shared/editEscalation.test.ts — 6 unit tests for the shared escalation utility

Test plan

  • All 3225 existing tests pass (no regressions)
  • 40 new unit tests cover the extracted mapper and escalation utility
  • TypeScript type check: zero errors (npx tsc --noEmit)
  • Linting: zero errors, 1 pre-existing unrelated warning

Card: https://trello.com/c/U4YWqGN9/111-find-top-candidate-for-refactoring-and-plan-clean-refactoring-of-it-look-for-god-classes-modules-functions-files-code-duplicatio

🤖 Generated with Claude Code

@nhopeatall
Copy link
Copy Markdown
Collaborator

nhopeatall commented Feb 24, 2026

🤖 On it — checking the refactor/config-repository-and-gadget-utils branch


Progress: [███░░░░░░░] 29% (iteration 20/70)

🔍 Code Review Update (1 min)

I've completed reviewing the shared/index.ts re-exports and confirmed the removal of recordEditFailure from FileSearchAndReplace.ts. I've also verified that projectIntegrations includes projectId and that extractIntegrationConfigs is correctly used within configRepository.ts. I'm currently examining the ProjectRow type in configMapper.ts to ensure it aligns with the actual projects.$inferSelect type.

Last updated: iteration 20 · review

Copy link
Copy Markdown
Collaborator

@nhopeatall nhopeatall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — clean extraction refactoring with no behavioral changes.

What I verified:

  1. configMapper.ts extraction: All mapping functions, interfaces, and helpers moved faithfully. The key differences from the original are intentional improvements:

    • IntegrationRow now includes projectId (needed by buildRawConfig's indexing logic, previously accessed on the raw DB row before casting to the narrower type)
    • mapProjectRow returns typed ProjectConfigRaw instead of Record<string, unknown>
    • MapProjectInput replaces 8 positional parameters with a structured object
    • Both biome-ignore suppressions in configRepository.ts are eliminated (one moves to configMapper.ts for GitHubIntegrationConfig, the other for cognitive complexity is no longer needed)
  2. buildRawConfig unification: The duplicated extract→index→map pattern from loadConfigFromDb and findProjectConfigFromDb is correctly unified. The indexing-by-projectId logic that was previously inline in loadConfigFromDb is now inside buildRawConfig, and findProjectConfigFromDb correctly wraps its single-project data into the same structures (single-entry Map for projectAgentConfigsMap, array for projectRows).

  3. editEscalation.ts DRY: Byte-for-byte identical code extracted from both FileSearchAndReplace.ts and FileMultiEdit.ts. Import of recordEditFailure correctly removed from both files' ./shared/index.js imports since it's now consumed internally by editEscalation.ts.

  4. Type compatibility: The manually-defined ProjectRow in configMapper.ts is a structural subset of typeof projects.$inferSelect, so TypeScript correctly accepts the DB rows. DefaultsRow similarly works because BuildRawConfigOpts.defaultsRow is only used for mapping, while the orgId access in loadConfigFromDb happens on the full DB type before passing to buildRawConfig.

  5. Tests: 40 new tests cover the extracted functions thoroughly with appropriate fixtures.

@nhopeatall
Copy link
Copy Markdown
Collaborator

✅ Review complete — approved with no issues found.

Copy link
Copy Markdown
Collaborator

@nhopeatall nhopeatall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — clean extraction refactoring with no behavioral changes. Verified type compatibility, faithful code movement, and proper test coverage.

@zbigniewsobiecki zbigniewsobiecki merged commit 72440d0 into dev Feb 24, 2026
5 checks passed
@zbigniewsobiecki zbigniewsobiecki mentioned this pull request Feb 25, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants