arch: restructure monorepo into domain-driven packages#48
arch: restructure monorepo into domain-driven packages#48
Conversation
Add the following packages as part of a domain-driven monorepo restructure: - packages/domain (@financialadvisor/domain): Standalone core types and utilities (types.ts, utils.ts from shared). No internal dependencies. - packages/ledger (@financialadvisor/ledger): Account integration types, the AccountIntegrationService class, and savings/goal planning tools. Depends on domain. The createAccountIntegrationService factory (which depends on concrete file importers) is moved to ingestion to avoid circular dependencies. - packages/ingestion (@financialadvisor/ingestion): CSV and OFX/QFX file importers plus the createAccountIntegrationService factory that wires them together. Depends on domain and ledger. - packages/resolution (@financialadvisor/resolution): Transaction categorization and analysis. Depends on domain. - packages/analytics (@financialadvisor/analytics): Budget analysis, investment portfolio tools, and predictive analytics. Depends on domain. - packages/advice (@financialadvisor/advice): Stub package for future financial advice capabilities. Depends on domain and analytics. - packages/ai-providers (@financialadvisor/ai-providers): AI provider implementations (OpenAI, Ollama, Copilot), provider manager, accuracy enhancer, performance optimizer, production monitor, and financial planning agent. Depends on domain. Uses axios ^1.13.5 (patched for CVE-2025 SSRF and DoS vulnerabilities vs. 1.7.2). All packages use "type": "module", ESM exports, and composite TypeScript project references. Internal @financialadvisor/* imports updated from @financialadvisor/shared to @financialadvisor/domain. Relative imports within each package preserved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: kayodebristol <3579196+kayodebristol@users.noreply.github.com> Agent-Logs-Url: https://github.com/plures/FinancialAdvisor/sessions/f232932e-67fb-4a53-b94e-f79f8e3e2b2c
|
@copilot CI is failing on this PR. Please implement fixes for failing checks and push updates. |
1 similar comment
|
@copilot CI is failing on this PR. Please implement fixes for failing checks and push updates. |
Co-authored-by: kayodebristol <3579196+kayodebristol@users.noreply.github.com> Agent-Logs-Url: https://github.com/plures/FinancialAdvisor/sessions/10316fe7-4948-46fa-88b0-c67ac5f93c71
Fixed in commit |
|
@copilot CI is failing on this PR. Please implement fixes for failing checks and push updates. |
…ironment Co-authored-by: kayodebristol <3579196+kayodebristol@users.noreply.github.com> Agent-Logs-Url: https://github.com/plures/FinancialAdvisor/sessions/cd58a11b-759a-4988-81a1-4ff51ffbb6c9
Fixed in commit |
|
@copilot CI is failing on this PR. Please implement fixes for failing checks and push updates. |
|
@copilot CI is failing on this PR. Please implement fixes for failing checks and push updates. |
All CI checks are now passing on commit |
Co-authored-by: kayodebristol <3579196+kayodebristol@users.noreply.github.com> Agent-Logs-Url: https://github.com/plures/FinancialAdvisor/sessions/dd4a9d3e-8b3b-4e44-9020-6102c036dd56
|
@copilot CI is failing on this PR. Please implement fixes for failing checks and push updates. |
Co-authored-by: kayodebristol <3579196+kayodebristol@users.noreply.github.com> Agent-Logs-Url: https://github.com/plures/FinancialAdvisor/sessions/dd4a9d3e-8b3b-4e44-9020-6102c036dd56
|
@copilot CI is failing on this PR. Please implement fixes for failing checks and push updates. |
1 similar comment
|
@copilot CI is failing on this PR. Please implement fixes for failing checks and push updates. |
Fixed in commit
All CI checks now pass: CI/CD Pipeline ✅, Security Scanning ✅, CI Feedback Loop ✅. |
All CI checks are passing on the current HEAD |
There was a problem hiding this comment.
Pull request overview
Restructures the TypeScript monorepo into domain-driven packages (domain, ledger, ingestion, resolution, analytics, advice, ai-providers) and migrates consumers/tests to the new package boundaries while keeping legacy packages as deprecated re-export stubs.
Changes:
- Introduce new domain-driven packages with their own
tsconfig.json, exports, and package manifests. - Convert
shared,financial-tools, andai-integrationinto deprecated compatibility stubs and update imports across tests,mcp-server, and the VS Code extension. - Update root build/test/coverage scripts and add a workflow intended to auto-approve Copilot-triggered workflow runs.
Reviewed changes
Copilot reviewed 65 out of 66 changed files in this pull request and generated 18 comments.
Show a summary per file
| File | Description |
|---|---|
| test/unit/predictive-analytics.test.ts | Update imports to analytics + domain packages. |
| test/unit/ai-accuracy-enhancer.test.ts | Update imports to ai-providers + domain. |
| test/integration/ai-providers.test.ts | Update imports to ai-providers + domain. |
| packages/vscode-extension/tsconfig.json | Update project references to new packages. |
| packages/vscode-extension/src/views/dashboardView.ts | Switch extension import to @financialadvisor/ai-providers. |
| packages/vscode-extension/src/providers/financialAdvisorProvider.ts | Switch extension import to @financialadvisor/domain. |
| packages/vscode-extension/src/extension.ts | Switch extension import to @financialadvisor/ai-providers. |
| packages/vscode-extension/package.json | Update deps to domain, analytics, ai-providers. |
| packages/shared/tsconfig.json | Add references to new packages (deprecated stub). |
| packages/shared/src/index.ts | Convert shared to deprecated re-export stub. |
| packages/shared/package.json | Mark deprecated and add deps on new packages. |
| packages/resolution/tsconfig.json | New package config for resolution. |
| packages/resolution/src/index.ts | Export categorization. |
| packages/resolution/src/categorization.ts | Add TransactionAnalyzer + categorization/insights logic. |
| packages/resolution/package.json | New package manifest for resolution. |
| packages/mcp-server/tsconfig.json | Update references to domain + resolution. |
| packages/mcp-server/src/storage.ts | Update domain type import to @financialadvisor/domain. |
| packages/mcp-server/src/server.ts | Switch to TransactionAnalyzer from @financialadvisor/resolution + domain imports. |
| packages/mcp-server/package.json | Update deps to domain + resolution. |
| packages/ledger/tsconfig.json | New package config for ledger. |
| packages/ledger/src/savings.ts | Add SavingsPlanner calculations/recommendations. |
| packages/ledger/src/index.ts | Export ledger public surface. |
| packages/ledger/src/account-integration-types.ts | Add account integration types/errors/interfaces. |
| packages/ledger/src/account-integration-service.ts | Add account integration service skeleton. |
| packages/ledger/package.json | New package manifest for ledger. |
| packages/ingestion/tsconfig.json | New package config for ingestion. |
| packages/ingestion/src/ofx-importer.ts | Add OFX/QFX importer implementation. |
| packages/ingestion/src/index.ts | Export importers + factory to build integration service. |
| packages/ingestion/src/csv-importer.ts | Add CSV importer implementation + templates. |
| packages/ingestion/package.json | New package manifest for ingestion. |
| packages/financial-tools/tsconfig.json | Add references to new packages (deprecated stub). |
| packages/financial-tools/src/index.ts | Convert financial-tools to deprecated re-export stub. |
| packages/financial-tools/package.json | Mark deprecated and depend on new packages. |
| packages/domain/tsconfig.json | New package config for domain. |
| packages/domain/src/utils.ts | Add shared domain utilities. |
| packages/domain/src/types.ts | Add core domain types/enums. |
| packages/domain/src/index.ts | Export domain types + utils. |
| packages/domain/package.json | New package manifest for domain. |
| packages/analytics/tsconfig.json | New package config for analytics. |
| packages/analytics/src/predictive-analytics.ts | Add predictive analytics engine. |
| packages/analytics/src/investment.ts | Add investment/portfolio calculator. |
| packages/analytics/src/index.ts | Export analytics modules. |
| packages/analytics/src/budget.ts | Add budget calculator/analysis. |
| packages/analytics/package.json | New package manifest for analytics. |
| packages/ai-providers/tsconfig.json | New package config for ai-providers. |
| packages/ai-providers/src/provider-manager.ts | Add provider factory + registry/manager. |
| packages/ai-providers/src/production-monitor.ts | Add monitoring/health-check utilities. |
| packages/ai-providers/src/performance-optimizer.ts | Add batching/rate-limit/cache helpers. |
| packages/ai-providers/src/openai-provider.ts | Add OpenAI provider implementation. |
| packages/ai-providers/src/ollama-provider.ts | Add Ollama provider implementation. |
| packages/ai-providers/src/index.ts | Export ai-providers public surface. |
| packages/ai-providers/src/copilot-provider.ts | Add Copilot provider stub (unimplemented). |
| packages/ai-providers/src/base-provider.ts | Add base provider API/types. |
| packages/ai-providers/src/ai-accuracy-enhancer.ts | Add response validation/confidence/caching helpers. |
| packages/ai-providers/src/agents/index.ts | Export agents surface. |
| packages/ai-providers/src/agents/financial-planning-agent.ts | Add financial planning agent logic. |
| packages/ai-providers/package.json | New package manifest for ai-providers. |
| packages/ai-integration/tsconfig.json | Point deprecated stub package at ai-providers. |
| packages/ai-integration/src/index.ts | Convert ai-integration to deprecated re-export stub. |
| packages/ai-integration/package.json | Mark deprecated and depend on ai-providers. |
| packages/advice/tsconfig.json | New package config for advice. |
| packages/advice/src/index.ts | Add AdviceService stub. |
| packages/advice/package.json | New package manifest for advice. |
| package.json | Update build/test/coverage scripts and add @financialadvisor/domain dep. |
| .github/workflows/auto-approve-copilot-runs.yml | Add workflow intended to auto-approve Copilot workflow runs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const needed = progress.goal.targetAmount - progress.goal.currentAmount; | ||
| const allocation_amount = Math.min(needed, remainingAmount); | ||
|
|
||
| if (allocation_amount > 0) { | ||
| allocation[progress.goal.id] = allocation_amount; | ||
| remainingAmount -= allocation_amount; |
There was a problem hiding this comment.
allocation_amount is snake_case, which is inconsistent with the surrounding camelCase style used throughout these packages. Please rename to allocationAmount to match the codebase’s naming conventions.
| "dependencies": { | ||
| "@financialadvisor/shared": "file:../shared", | ||
| "@financialadvisor/ai-providers": "file:../ai-providers", | ||
| "axios": "^1.6.0" |
There was a problem hiding this comment.
@financialadvisor/ai-integration is now a re-export stub, but the package still publishes dist/**/*. If dist continues to include legacy modules that import @financialadvisor/shared, removing @financialadvisor/shared from dependencies will break consumers who deep-import those files. Either (a) restrict compilation/publication to just the stub entrypoint, or (b) keep required legacy dependencies to preserve backward compatibility for deep imports.
| export class TransactionAnalyzer { | ||
| // Common spending categories for auto-categorization | ||
| private static readonly CATEGORY_KEYWORDS = { | ||
| 'Food & Dining': ['restaurant', 'cafe', 'pizza', 'burger', 'taco', 'starbucks', 'mcdonalds', 'subway', 'chipotle'], | ||
| 'Groceries': ['grocery', 'supermarket', 'whole foods', 'trader joes', 'safeway', 'kroger', 'walmart'], | ||
| 'Transportation': ['gas', 'fuel', 'uber', 'lyft', 'taxi', 'metro', 'parking', 'toll'], | ||
| 'Shopping': ['amazon', 'target', 'costco', 'mall', 'store', 'retail'], |
There was a problem hiding this comment.
TransactionAnalyzer introduces core categorization/insights logic (keyword matching, recurring detection, outlier detection) but there are no unit tests validating behavior across representative transaction sets. Please add unit tests for categorization, summaries, recurring-pattern detection, and unusual-transaction thresholds.
| export class SavingsPlanner { | ||
| /** | ||
| * Analyze progress towards a specific goal | ||
| */ | ||
| static analyzeGoalProgress( | ||
| goal: Goal, | ||
| savingsTransactions: Transaction[], | ||
| currentDate: Date = new Date() | ||
| ): GoalProgress { | ||
| const monthlyContributions = this.calculateMonthlyContributions(savingsTransactions, goal.id); |
There was a problem hiding this comment.
SavingsPlanner adds goal progress calculations, recommendations, and allocation logic but currently has no unit tests. Please add unit tests for key scenarios (on-track vs off-track goals, zero/negative income, different priorities, emergency-fund multiplier logic) to ensure stable financial calculations.
| import { OpenAIProvider } from '../../packages/ai-providers/dist/openai-provider.js'; | ||
| import { CopilotProvider } from '../../packages/ai-providers/dist/copilot-provider.js'; | ||
| import { AIProviderFactory, AIProviderManager } from '../../packages/ai-providers/dist/provider-manager.js'; |
There was a problem hiding this comment.
These integration tests make real OpenAI API calls. The repo’s testing guideline is to mock external services and avoid real API calls in tests (to keep CI reliable, fast, and non-billing-dependent). Consider using HTTP mocking (e.g., nock/msw) around the OpenAI client, and keep a separate, manually-invoked smoke test outside the default test suite if needed.
| const records = parse(content, { | ||
| delimiter, | ||
| skip_empty_lines: true, | ||
| relax_column_count: true, | ||
| from_line: template?.skipRows ? template.skipRows + 1 : 1, | ||
| columns: template?.headerRow !== undefined ? true : false, | ||
| }); |
There was a problem hiding this comment.
CSV parsing is configured with columns: true whenever headerRow is set, but several default templates use numeric column indices. With columns: true, csv-parse yields objects (not arrays), so numeric index lookups will return empty strings and all rows will be skipped. Please align columns/from_line behavior with the template: use columns: true only for string column names, or keep columns: false and skip the header row when numeric indices are used.
| const monthsToCompletion = remaining / averageMonthlyContribution; | ||
| projectedCompletionDate = new Date(currentDate); | ||
| projectedCompletionDate.setMonth(projectedCompletionDate.getMonth() + monthsToCompletion); | ||
| } else { |
There was a problem hiding this comment.
setMonth(getMonth() + monthsToCompletion) uses a non-integer month offset (monthsToCompletion can be fractional), which gets coerced and can produce surprising projected dates. Consider rounding (e.g., Math.ceil) or converting fractional months into days to make the projection deterministic.
| "include": ["src/**/*"], | ||
| "exclude": ["dist", "node_modules"], | ||
| "references": [ | ||
| { "path": "../shared" } | ||
| { "path": "../ai-providers" } | ||
| ] |
There was a problem hiding this comment.
This project reference change makes ai-integration depend on ai-providers, but tsconfig.json still includes src/**/* which will compile legacy modules as well. If the intent is a pure re-export stub, consider limiting include to src/index.ts (or excluding legacy files) so the project reference graph and published output match the intended deprecation model.
|
|
||
| on: | ||
| workflow_run: | ||
| workflows: ["*"] |
There was a problem hiding this comment.
workflow_run.workflows: ["*"] does not match all workflows (it only matches a workflow literally named "*"). If the intent is to approve runs from specific workflows, list them explicitly; otherwise remove the filter and add a different guard (e.g., check workflow_run.name in the if:) so the job reliably triggers.
| workflows: ["*"] |
| sourceConfigId: options.accountId || 'unknown', | ||
| fileName: filePath.split('/').pop(), | ||
| transactionsImported: 0, | ||
| transactionsSkipped: 0, | ||
| transactionsFailed: 0, |
There was a problem hiding this comment.
fileName: filePath.split('/').pop() is not cross-platform (Windows paths use \). Prefer path.basename(filePath) (and import node:path) to ensure consistent behavior on all supported OSes.
packages/domain— pure types and value objectspackages/ledger— accounts, balances, savingspackages/ingestion— CSV/OFX importerspackages/resolution— merchant categorizationpackages/analytics— budget/investment/predictive analysispackages/advice— plan generation stubpackages/ai-providers— LLM provider abstractionmcp-server,vscode-extensionto use new packagespackage.jsonbuild scripts and test scriptspackage-lock.jsonwith npm 10 to match CI's Node 22 environment (picomatch@4.0.3 now hoisted correctly)auto-approve-copilot-runs.yml(was causing workflow parse failure)Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.