Skip to content

Refactor utilities, types, and components for improved organization#37

Merged
kryptodrex merged 34 commits intodevelopfrom
issue/shared-logic-refactor
Mar 14, 2026
Merged

Refactor utilities, types, and components for improved organization#37
kryptodrex merged 34 commits intodevelopfrom
issue/shared-logic-refactor

Conversation

@kryptodrex
Copy link
Copy Markdown
Owner

@kryptodrex kryptodrex commented Mar 14, 2026

Shared Logic Refactor

Goal

Reduce duplication, improve consistency, and lower bug risk by extracting reusable logic into shared utils, services, hooks, and shared UI patterns.

How To Use This File

  • Mark an item complete only when its Done Criteria are fully met.
  • For any task that changes/adds src/services or src/utils, add/update tests in the same task.
  • Keep each item scope-limited; do not bundle multiple large refactors into one PR.

Prioritized Checklist (Most Important -> Least Important)

1. Centralize Financial Calculation Engine

Priority: Critical

  • Implement src/services/budgetCalculations.ts as the single source of truth for paycheck/tax/net/allocation math.
  • Migrate BudgetContext.calculatePaycheckBreakdown to use shared functions.
  • Migrate KeyMetrics and pdfExport to use the same shared functions.
  • Migrate PayBreakdown to use the same shared functions.
  • Add parity tests proving all consumers return identical numbers for the same fixture.

Problem: Core pay/tax/net/leftover math is duplicated across multiple layers.

Current duplication evidence:

  • src/contexts/BudgetContext.tsx (calculatePaycheckBreakdown)
  • src/components/PayBreakdown/PayBreakdown.tsx (yearly/display breakdown math)
  • src/components/KeyMetrics/KeyMetrics.tsx (annual/monthly metric math)
  • src/services/pdfExport.ts (its own gross/tax/net math)

Refactor target:

  • Add src/services/budgetCalculations.ts with pure functions:
    • calculatePayBreakdownPerPaycheck
    • calculateAnnualizedSummary
    • calculateDisplaySummary(displayMode)
    • calculateAllocationTotals

Done Criteria:

  • No component/service performs independent pay/tax/net math outside shared calculator functions.
  • pdfExport values match PayBreakdown/KeyMetrics outputs for test fixtures.
  • New/updated tests exist for budgetCalculations and all touched services/utils.

Why first: This removes the highest bug surface area and guarantees all screens/export use identical numbers.


2. Unified Missing/Moved File Relink Flow

Priority: Critical

  • Extract shared relink state/decision logic to src/hooks/useFileRelinkFlow.ts (or equivalent service + hook).
  • Keep Welcome and PlanDashboard modal UIs, but wire both to the shared flow.
  • Ensure cancel behavior is identical across entry points (clear stale path policy, no stale saves).
  • Add tests for success, cancelled, mismatch, and invalid paths.

Problem: Similar relink state + modal handling exists in multiple components.

Current duplication evidence:

  • src/components/WelcomeScreen/WelcomeScreen.tsx
  • src/components/PlanDashboard/PlanDashboard.tsx
  • Shared behavior depends on FileStorageService.relinkMovedBudgetFile

Refactor target:

  • Add src/hooks/useFileRelinkFlow.ts (or a small service + hook pair)
  • Keep modal visuals local if desired, but centralize decision/state logic:
    • open/cancel/retry
    • invalid/mismatch message handling
    • stale path cleanup policy

Why second: Prevents regressions in file safety logic and keeps save/load behavior consistent.

Done Criteria:

  • Welcome and PlanDashboard use a common relink flow contract.
  • Saving cannot proceed to stale paths from any trigger (button, menu, keyboard shortcut).
  • Shared tests cover all status outcomes.

3. File Path / Plan Name Helpers

Priority: High

  • Create src/utils/filePath.ts for all filename/path parsing.
  • Replace all ad-hoc basename/split logic in BudgetContext and FileStorageService.
  • Add unit tests for separators, extensions, whitespace, and empty input edge cases.

Problem: Path-to-name parsing logic is duplicated in context/service and ad-hoc splits exist.

Current duplication evidence:

  • src/contexts/BudgetContext.tsx (derivePlanNameFromFilePath)
  • src/services/fileStorage.ts (derivePlanNameFromFilePath and repeated basename extraction)

Refactor target:

  • Add src/utils/filePath.ts:
    • getBaseFileName(path)
    • getPlanNameFromPath(path)
    • stripFileExtension(name)

Why third: Low risk and immediately improves consistency.

Done Criteria:

  • Only shared helpers are used for plan-name derivation and basename extraction.
  • No direct split(/[\\/]) basename parsing remains in business logic.

4. Shared Dialog Strategy (Replace scattered alert / confirm)

Priority: High

  • Introduce shared app dialogs (ConfirmDialog, ErrorDialog) and optional useAppDialogs helper.
  • Replace highest-impact alert/confirm calls first (PlanDashboard, Settings, SetupWizard, Welcome).
  • Standardize button wording (Cancel, Confirm, Retry) and error presentation.

Problem: Browser dialogs are still scattered and inconsistent for UX/testing.

Current duplication evidence:

  • PlanDashboard, Settings, WelcomeScreen, SetupWizard, EncryptionSetup, PlanTabs, and manager components.

Refactor target:

  • Add shared modal-based helpers:
    • ConfirmDialog
    • ErrorDialog
    • optional useAppDialogs

Why fourth: Better UX consistency and testability.

Done Criteria:

  • Critical flows no longer rely on native window.alert/window.confirm.
  • Dialog interaction behavior is consistent and keyboard-accessible.

5. Manager CRUD Form Patterns -> Shared Hooks

Priority: High

  • Extract reusable hooks for modal entity editing and field error state.
  • Migrate at least two manager components first (recommended: Bills + Loans), then expand.
  • Preserve existing UX/validation messages while reducing duplicate handlers.

Problem: Bills/Loans/Savings/Benefits managers all implement similar modal-form CRUD state and validation patterns.

Current duplication evidence:

  • Add/edit modal toggles and editingX patterns
  • handleAdd*, handleEdit*, handleSave*, handleDelete* duplication

Refactor target:

  • Add hooks:
    • useModalEntityEditor<T>()
    • useFieldErrors<T>()
    • useDeleteConfirmation()

Why fifth: Large maintainability win, but higher refactor complexity than utility-only changes.

Done Criteria:

  • Repeated handleAdd/Edit/Save/Delete scaffolding is reduced substantially across managers.
  • No behavior regressions in add/edit/delete flows.

6. Display Mode Conversion Utilities

Priority: Medium-High

  • Add src/utils/displayAmounts.ts and migrate manager-level toDisplayAmount/fromDisplayAmount helpers.
  • Keep pay frequency + display mode conversion rules centralized.

Problem: Local toDisplayAmount helpers repeated across managers.

Current duplication evidence:

  • BillsManager, SavingsManager, PayBreakdown, and related components.

Refactor target:

  • Add src/utils/displayAmounts.ts:
    • toDisplayAmount(perPaycheck, paychecksPerYear, mode)
    • fromDisplayAmount(value, paychecksPerYear, mode)

Why now: Reduces small arithmetic drift and simplifies components.

Done Criteria:

  • All display amount conversions route through one shared utility API.

7. Suggested Leftover Logic

Priority: Medium

  • Move suggestion formula to src/utils/paySuggestions.ts.
  • Use it in both SetupWizard and PaySettingsModal.
  • Add tests for rounding/minimum-floor behavior.

Problem: Same suggestion formula exists in setup and pay settings modal.

Current duplication evidence:

  • SetupWizard
  • PaySettingsModal

Refactor target:

  • Add src/utils/paySuggestions.ts:
    Done Criteria:
    • Setup and modal produce identical suggestion values for the same inputs.
    • getSuggestedLeftoverPerPaycheck(grossPerPaycheck)
    • formatSuggestedLeftover(...) if needed

8. Split And Rename auth.ts Types

Priority: Medium

  • Break src/types/auth.ts into smaller domain-focused type files.
  • Replace the misleading auth.ts entry point with a narrow compatibility barrel during migration.
  • Update imports so active app code no longer keeps expanding the old catch-all file.

Problem: src/types/auth.ts has become a catch-all type file for the entire app, and the name no longer matches the domain.

Current duplication / maintenance evidence:

  • Unrelated budget, account, tax, loan, tab, and settings types all live in one file.
  • New shared services and components continue importing from auth.ts, increasing coupling and search noise.
  • The filename suggests authentication concerns even though this app does not have an auth domain.

Refactor target:

  • Split src/types/auth.ts into clearer modules such as:
    • src/types/budget.ts
    • src/types/accounts.ts
    • src/types/payroll.ts
    • src/types/settings.ts
    • src/types/tabs.ts
  • Optionally keep a temporary barrel during migration if needed, but the end state should avoid auth.ts as the main import surface.

Why here: This is foundational cleanup for Phase 2 and later shared-service work, because type sprawl will otherwise keep leaking into every new abstraction.

Done Criteria:

  • New code no longer imports app domain types from src/types/auth.ts.
  • Domain types are grouped into smaller files with clearer names.
  • Any compatibility barrel is temporary and no longer the default import target.

9. Budget Currency Conversion as Service

Priority: Medium

  • Move convertBudgetAmounts + rounding logic from PaySettingsModal to src/services/budgetCurrencyConversion.ts.
  • Add tests covering major numeric fields and excluded percentage fields.

Problem: Deep budget amount conversion currently lives in component-level modal logic.

Current duplication evidence:

  • PaySettingsModal (convertBudgetAmounts)

Refactor target:

  • Add src/services/budgetCurrencyConversion.ts:
    Done Criteria:
    • Component only orchestrates UI; conversion logic lives in service with tests.
    • convertBudgetAmounts(data, rate)
    • roundCurrency helper

10. Account Grouping and Totals Helpers

Priority: Medium

  • Add src/utils/accountGrouping.ts helpers for repeated reducers/grouping.
  • Migrate Bills/Loans/Savings grouping and subtotal logic to shared helpers.

Problem: Multiple account-grouping reducers and subtotal patterns exist in managers.

Current duplication evidence:

  • BillsManager, LoansManager, SavingsManager

Refactor target:

  • Add src/utils/accountGrouping.ts:
    Done Criteria:
    • Manager components use shared grouping functions for account-based list construction.
    • groupByAccountId
    • buildAccountRows
    • sumByFrequency

11. Shared ViewMode Type

Priority: Medium-Low

  • Add src/types/viewMode.ts.
  • Replace local 'paycheck' | 'monthly' | 'yearly' declarations with imported type.

Problem: 'paycheck' | 'monthly' | 'yearly' is redeclared in many places.

Refactor target:

  • Add src/types/viewMode.ts and import everywhere.

Done Criteria:

  • No local re-declarations of ViewMode union remain in components.

12. Encryption Setup Flow Consolidation

Priority: Medium-Low

  • Extract reusable encryption setup/save behavior into service/hook.
  • Remove duplicated key validation/saving code across SetupWizard, EncryptionSetup, PlanDashboard.

Problem: Encryption setup/save behavior is distributed across SetupWizard, EncryptionSetup, and PlanDashboard handlers.

Refactor target:

  • Add src/services/encryptionSetupService.ts or useEncryptionSetupFlow(planId).

Done Criteria:

  • One flow controls key generation, validation, save, and error messaging.

13. Shared Path Display Styling Utility

Priority: Low

  • Create one shared CSS utility/class for relink path/code blocks.
  • Replace duplicated modal path classes in Welcome and PlanDashboard.

Problem: Similar relink modal path styling classes exist in multiple component CSS files.

Refactor target:

  • Add one shared utility class for code/path blocks in a shared stylesheet.

Done Criteria:

  • Path display styling is defined once and reused.

14. Remove/Archive Backup and Unused Artifacts

Priority: Low (Hygiene)

  • Remove or archive *.backup files outside src.
  • Confirm whether BenefitsManager is intentionally unused; either wire it or remove it.
  • Ensure search/indexing and maintenance docs no longer reference stale backups.

Problem: *.backup files and likely unused component artifacts increase confusion.

Current candidates:

  • src/components/BenefitsManager/*.backup
  • src/components/LoansManager/*.backup
  • src/components/_shared/Button/*.backup

Refactor target:

  • Remove from active tree (or move to an archive folder outside src).

Done Criteria:

  • Active source tree has no backup artifacts that can be confused with runtime code.

Phased Execution Plan

Phase 1 (Low Risk, High ROI)

  • Shared file-path utils (filePath.ts)
  • Shared ViewMode type
  • Suggested leftover utility
  • Display amount utility

Phase 2 (Core correctness)

  • budgetCalculations service
  • Migrate PayBreakdown, KeyMetrics, pdfExport, and context calculations to shared engine
  • Add regression tests for parity across all consumers
  • Split and rename src/types/auth.ts into domain type modules

Phase 3 (Workflow consistency)

  • File relink hook/service extraction
  • Dialog strategy (ConfirmDialog/ErrorDialog)
  • Replace high-impact alert/confirm usage

Phase 4 (Form architecture)

  • Manager CRUD hooks
  • Account grouping helpers

Phase 5 (Cleanup)

  • Currency conversion service extraction
  • CSS/path styling utility extraction
  • Remove backup artifacts
  • Rename 'shared' directory under 'components' to '_shared' and adjust imports as necessary
  • Reorganize the components directory to group related components together: tab-driven plan views under tabViews, separate non-plan windows under views, and _shared components into more intuitive subgroups.
  • Extract any reused constants to a new src/constants directory, split out by files that make sense, and update imports

Test Strategy Requirements

  • Any changed existing src/services or src/utils module includes updated tests.
  • Any new src/services/*.ts or src/utils/*.ts module includes a matching *.test.ts.
  • Parity tests added where math is migrated from components/context to shared service.

Success Metrics

  • Reduced duplicated logic blocks in manager/components/services.
  • Financial outputs match across UI and PDF export for the same input data.
  • Fewer direct alert/confirm calls in app components.
  • All new/refactored services/utils covered by unit tests.

Introduce three new utility modules with tests: displayAmounts (wrappers around payPeriod conversions plus monthlyToDisplayAmount), filePath (getBaseFileName, stripFileExtension, getPlanNameFromPath with robust path/extension handling), and paySuggestions (leftover suggestion algorithm with rounding/minimum and currency formatting). Also update payPeriod to import and use the ViewMode type in its conversion and label functions. Tests cover conversion accuracy, edge cases, path normalization, and formatting behavior.
Extract large monolithic src/types/auth.ts into dedicated type modules for better organization and maintainability. Added new files: src/types/accounts.ts, budget.ts, budgetContext.ts, frequencies.ts, obligations.ts, payroll.ts, settings.ts, tabs.ts, viewMode.ts and updated src/types/auth.ts to re-export the new modules. Introduces interfaces and type aliases for accounts, budget data, budget context, frequencies, obligations (bills/loans/savings), payroll (pay settings, deductions, taxes, benefits, retirement), settings, tabs, and view modes to simplify imports and reduce file size of the original auth types.
Introduce budgetCalculations.ts with paycheck/annual/display breakdown helpers (calculatePaycheckBreakdown, calculateAnnualizedPayBreakdown, calculateDisplayPayBreakdown, calculateAnnualizedPaySummary) and accompanying tests. Update pdfExport to consume the shared paycheck breakdown (replacing ad-hoc math) and extend pdfExport.test to assert metrics use the new totals. Also refactor FileStorageService to use getBaseFileName/getPlanNameFromPath utilities when deriving file/plan names.
Replace local derivePlanNameFromFilePath and in-file paycheck calculation with shared utility functions. Import getPlanNameFromPath to derive plan names from file paths and delegate paycheck breakdown to budgetCalculations (calculatePaycheckBreakdown and getEmptyPaycheckBreakdown). This centralizes parsing and payroll logic, reduces duplication, and keeps BudgetContext focused on state management.
Centralize display-mode conversion logic and adopt the shared ViewMode type across multiple components. Replaced local convertToDisplayMode/convertFromDisplayMode helpers with utils/displayAmounts (toDisplayAmount, fromDisplayAmount, monthlyToDisplayAmount), removed duplicate conversion implementations, and updated component props to use ViewMode. Also integrated calculation helpers from services (calculateAnnualizedPaySummary, calculateAnnualizedPayBreakdown) and paySuggestions utilities (getSuggestedLeftoverPerPaycheck, formatSuggestedLeftover) to unify pay/tax/suggestion logic. Updated ViewModeSelector typing and adjusted formatting calls accordingly. Affected files include BenefitsManager, BillsManager, KeyMetrics, LoansManager, PayBreakdown, PaySettingsModal, PlanDashboard, SavingsManager, SetupWizard, TaxBreakdown, and the shared ViewModeSelector.
Move and reorganize TypeScript type imports previously from types/auth into domain-specific modules (types/accounts, types/payroll, types/obligations, types/frequencies, types/tabs, types/budget, types/budgetContext, types/settings). Update import paths across components, contexts, services, and utils to reference the new type files. No runtime logic changes — this is a types-only refactor to improve type organization and clarity.
Fix accounts handling when localStorage contains invalid JSON: on parse failure, create default accounts, persist them via saveAccounts, and return them (removed error logging). Also correct the Account type import path (from ../types/auth to ../types/accounts). Update tests to assert fallback length and that localStorage now contains valid JSON after recovery.
Introduce useFileRelinkFlow hook and tests, wire it into hooks index, and extend FileStorageService for relinking scenarios. The hook manages missing-file prompt state, relink mismatch messages, loading state, and calls FileStorageService.relinkMovedBudgetFile; it invokes an onRelinkSuccess callback on success. Added unit tests for the hook (prompting, mismatch, success) and expanded fileStorage tests to cover relink picker cancelled, mismatch, and successful relink that updates recent-file metadata. Also made addRecentFileForPlan non-private (static) to support recent-file updates during relink handling.
Introduce a shared FileRelinkModal component and styles, and replace duplicated relink modals in PlanDashboard and WelcomeScreen with the new component. Both components were refactored to use the useFileRelinkFlow hook (centralizing relink state/logic), removing duplicated state and handlers and wiring up success/clear callbacks. Minor related updates: export FileRelinkModal from shared index, move relink CSS into the new file and remove the copies, adjust tab rendering/deps (temporarilyVisibleTab handling and tabConfigs dependency), and update save/button disabled checks to use the new missingFile state.
Replace the previous alert+null-return when decryption max attempts are reached with throwing an Error so callers can handle failures programmatically. Adds a unit test that simulates repeated wrong keys for an encrypted plan file and asserts loadBudget rejects with the new error message.
Introduce useAppDialogs to manage confirm and error dialog state (with default labels and callback handling). Add comprehensive tests (mocking React hooks) that verify opening/closing dialogs and invoking confirm/cancel/close callbacks. Export the new hook from hooks index. Also rename a helper in useFileRelinkFlow.test.ts from renderHook to useTestHook for consistency.
Replace native alert() calls with the centralized ErrorDialog managed by useAppDialogs in src/contexts/BudgetContext.tsx. Imports useAppDialogs and ErrorDialog, call openErrorDialog with title/message/actionLabel on save/load/select-save-location errors, add openErrorDialog to relevant dependency arrays, and render the ErrorDialog inside the provider using errorDialog/closeErrorDialog. Console.error remains for logging; UX now uses the app dialog instead of browser alerts.
Add reusable ConfirmDialog and ErrorDialog components (with CSS and index exports) and wire them into the app via the useAppDialogs hook. Replace window.confirm/alert usage with openConfirmDialog/openErrorDialog calls across multiple components (BenefitsManager, BillsManager, LoansManager, SavingsManager, PlanTabs, PlanDashboard, PaySettingsModal, EncryptionSetup, SetupWizard, Settings, WelcomeScreen) to provide consistent, styled modal confirmations and error reporting. Also export the new dialog components from the shared index. This centralizes dialog behavior and improves UX by replacing native alerts/confirms with app modals.
Add two new reusable hooks: useModalEntityEditor (manages modal open/edit state and selected entity) and useFieldErrors (stores and clears per-field validation errors). Add unit tests for both hooks that mock React state/callback behavior. Export the new hooks from src/hooks/index.ts so they're available to consumers.
Replace local modal and error state with shared hooks in BillsManager and LoansManager. Introduces useModalEntityEditor to manage open/edit state for entities and useFieldErrors to centralize validation errors; wires modal isOpen/onClose to the editor, clears errors on open/close, and uses clearFieldError on input changes. Minor form/handler adjustments to call editor.openForCreate/openForEdit and editor.closeEditor. No functional changes intended—refactor reduces duplication and standardizes modal/error handling.
Introduce account grouping utilities and tests. Adds generic helpers: groupByAccountId (groups items by accountId), buildAccountRows (constructs AccountRow entries, excludes empty accounts and sorts by totalMonthly desc), and getAccountNameById (returns account name or 'Unknown Account' fallback). Includes Vitest tests covering grouping, row building/sorting, exclusion of empty accounts, and fallback name behavior.
Replace inline account grouping and row-building logic with shared utilities (groupByAccountId, buildAccountRows, getAccountNameById) to centralize and deduplicate code. Updated BillsManager, LoansManager and SavingsManager to import and use these helpers, simplified mapping and sorting of account rows, and removed a local getAccountName implementation in SavingsManager. No functional behavior changes intended—just refactoring for clarity and reuse.
Move currency conversion and rounding logic out of PaySettingsModal into a new reusable service (src/services/budgetCurrencyConversion.ts) and add unit tests (src/services/budgetCurrencyConversion.test.ts). PaySettingsModal now imports convertBudgetAmounts instead of using an inline implementation and no longer imports BudgetData. Tests cover rounding, conversion of monetary fields, preservation of percentage-based values, and proper handling of loan fields. Exported roundCurrency helper is provided for testing.
Move common mono/path display styles into src/components/shared/sharedPathDisplay.css and import it in EncryptionConfigPanel and FileRelinkModal. Apply the .shared-path-display (and .shared-path-display--primary) classes to code elements, update EncryptionConfigPanel selectors to .encryption-key-code, and remove duplicated styling from the component CSS files to keep display styles consistent and DRY.
Delete stale .backup files for BenefitsManager, LoansManager, and shared Button components, and remove the BenefitsManager index export. Also remove mentions of the BenefitsManager component from src/README.md. This cleans up leftover backup artifacts and outdated README references.
Update src/README.md to match a UI component refactor: move SetupWizard and WelcomeScreen under views/, group per-tab features under tabViews/, consolidate dialog components under modals/, rename shared to _shared/, and add SavingsManager. This keeps the README in sync with the new directory structure and component naming conventions.
Introduce centralized constants for menu events and storage keys and refactor code to use them. Adds src/constants/events.ts and src/constants/storage.ts, replaces hard-coded 'menu:*' channels with MENU_EVENTS + menuChannel (and adds sendMenuEvent helper in electron/main.ts), updates preload and types to use typed MenuEventName, and switches app code (App, PlanDashboard, GlossaryTerm, SettingsModal, ThemeContext) to use APP_CUSTOM_EVENTS for custom DOM events. Also consolidates localStorage key usage in FileStorageService and AccountsService to use STORAGE_KEYS/APP_STORAGE_KEYS, updates related tests, and removes duplicated string literals to improve maintainability.
Add a reusable useEncryptionSetupFlow hook to centralize encryption setup state and persistence (key generation, keychain save/delete, and app settings). Refactor EncryptionSetup, PlanDashboard and SetupWizard to use the hook (removing duplicated FileStorageService/KeychainService logic), wire up new helpers (generateKey, saveSelection, canSaveSelection, goBackToSelection, reset) and update hooks/index export. Include unit tests for the hook (useEncryptionSetupFlow.test.ts) covering key generation, save success/failure and missing-key validation.
Move EncryptionSetup and EncryptionConfigPanel into organized locations and update imports for reuse. EncryptionConfigPanel was relocated to components/_shared/workflows and exported via components/_shared; EncryptionSetup view was moved to components/views/EncryptionSetup with a new index export. Import paths in App.tsx, PlanDashboard, SetupWizard and EncryptionSetup internals were updated accordingly, and CSS/shared path references were adjusted. This refactor centralizes the encryption config panel as a shared workflow and cleans up module resolution.
@github-actions
Copy link
Copy Markdown

Version Update Detected

Version has been correctly bumped from 0.3.1 to 0.3.2

@kryptodrex kryptodrex linked an issue Mar 14, 2026 that may be closed by this pull request
65 tasks
Replace direct ACCOUNTS_KEY reference with STORAGE_KEYS.accounts in AccountsService.hasAccounts to centralize storage keys. Add a BudgetData type import to PaySettingsModal for type coverage. Update sampleBudget in budgetCurrencyConversion tests to include settings.locale ('en-US') to match updated settings shape.
@github-actions
Copy link
Copy Markdown

Version Update Detected

Version has been correctly bumped from 0.3.1 to 0.3.2

@kryptodrex kryptodrex merged commit 97eafe8 into develop Mar 14, 2026
3 checks passed
@kryptodrex kryptodrex deleted the issue/shared-logic-refactor branch March 14, 2026 22:19
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.

Shared Logic/Component Refactor

1 participant