294 lines
16 KiB
Markdown
294 lines
16 KiB
Markdown
# Graph Report - /Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup (2026-04-22)
|
|
|
|
## Corpus Check
|
|
- 57 files · ~13,245 words
|
|
- Verdict: corpus is large enough that graph structure adds value.
|
|
|
|
## Summary
|
|
- 354 nodes · 497 edges · 40 communities detected
|
|
- Extraction: 73% EXTRACTED · 27% INFERRED · 0% AMBIGUOUS · INFERRED: 132 edges (avg confidence: 0.76)
|
|
- Token cost: 0 input · 0 output
|
|
|
|
## Community Hubs (Navigation)
|
|
- [[_COMMUNITY_Community 0|Community 0]]
|
|
- [[_COMMUNITY_Community 1|Community 1]]
|
|
- [[_COMMUNITY_Community 2|Community 2]]
|
|
- [[_COMMUNITY_Community 3|Community 3]]
|
|
- [[_COMMUNITY_Community 4|Community 4]]
|
|
- [[_COMMUNITY_Community 5|Community 5]]
|
|
- [[_COMMUNITY_Community 6|Community 6]]
|
|
- [[_COMMUNITY_Community 7|Community 7]]
|
|
- [[_COMMUNITY_Community 8|Community 8]]
|
|
- [[_COMMUNITY_Community 9|Community 9]]
|
|
- [[_COMMUNITY_Community 10|Community 10]]
|
|
- [[_COMMUNITY_Community 11|Community 11]]
|
|
- [[_COMMUNITY_Community 12|Community 12]]
|
|
- [[_COMMUNITY_Community 13|Community 13]]
|
|
- [[_COMMUNITY_Community 14|Community 14]]
|
|
- [[_COMMUNITY_Community 15|Community 15]]
|
|
- [[_COMMUNITY_Community 16|Community 16]]
|
|
- [[_COMMUNITY_Community 17|Community 17]]
|
|
- [[_COMMUNITY_Community 18|Community 18]]
|
|
- [[_COMMUNITY_Community 19|Community 19]]
|
|
- [[_COMMUNITY_Community 20|Community 20]]
|
|
- [[_COMMUNITY_Community 21|Community 21]]
|
|
- [[_COMMUNITY_Community 22|Community 22]]
|
|
- [[_COMMUNITY_Community 23|Community 23]]
|
|
- [[_COMMUNITY_Community 24|Community 24]]
|
|
- [[_COMMUNITY_Community 25|Community 25]]
|
|
- [[_COMMUNITY_Community 26|Community 26]]
|
|
- [[_COMMUNITY_Community 27|Community 27]]
|
|
- [[_COMMUNITY_Community 28|Community 28]]
|
|
- [[_COMMUNITY_Community 29|Community 29]]
|
|
- [[_COMMUNITY_Community 30|Community 30]]
|
|
- [[_COMMUNITY_Community 31|Community 31]]
|
|
- [[_COMMUNITY_Community 32|Community 32]]
|
|
- [[_COMMUNITY_Community 33|Community 33]]
|
|
- [[_COMMUNITY_Community 34|Community 34]]
|
|
- [[_COMMUNITY_Community 35|Community 35]]
|
|
- [[_COMMUNITY_Community 36|Community 36]]
|
|
- [[_COMMUNITY_Community 37|Community 37]]
|
|
- [[_COMMUNITY_Community 38|Community 38]]
|
|
- [[_COMMUNITY_Community 39|Community 39]]
|
|
|
|
## God Nodes (most connected - your core abstractions)
|
|
1. `send_followup_email()` - 22 edges
|
|
2. `compute_aging()` - 21 edges
|
|
3. `FollowupLevelSpec` - 20 edges
|
|
4. `get_overdue_for_partner()` - 13 edges
|
|
5. `compute_followup_level()` - 12 edges
|
|
6. `generate_followup_text()` - 12 edges
|
|
7. `TestFusionFollowupEngine` - 11 edges
|
|
8. `select_tone()` - 11 edges
|
|
9. `TestFollowupController` - 10 edges
|
|
10. `TestLevelResolver` - 10 edges
|
|
|
|
## Surprising Connections (you probably didn't know these)
|
|
- `test_buckets_sum_equals_total()` --calls--> `compute_aging()` [INFERRED]
|
|
/Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup/tests/test_engine_property.py → /Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup/services/overdue_aging.py
|
|
- `test_overdue_amount_excludes_current()` --calls--> `compute_aging()` [INFERRED]
|
|
/Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup/tests/test_engine_property.py → /Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup/services/overdue_aging.py
|
|
- `test_risk_score_in_range()` --calls--> `score_partner()` [INFERRED]
|
|
/Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup/tests/test_engine_property.py → /Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup/services/risk_scorer.py
|
|
- `The follow-up engine — orchestrator for customer follow-ups. 7-method public AP` --uses--> `FollowupLevelSpec` [INFERRED]
|
|
/Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup/models/fusion_followup_engine.py → /Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup/services/level_resolver.py
|
|
- `Cache lookup + LLM fallback.` --uses--> `FollowupLevelSpec` [INFERRED]
|
|
/Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup/models/fusion_followup_engine.py → /Users/gurpreet/Github/Odoo-Modules/fusion_accounting_followup/services/level_resolver.py
|
|
|
|
## Communities
|
|
|
|
### Community 0 - "Community 0"
|
|
Cohesion: 0.07
|
|
Nodes (22): FusionFollowupController, get_partner_detail(), list_overdue(), _parse_date(), pause(), HTTP controller: 6 JSON-RPC endpoints for the OWL follow-up dashboard. All endp, reset(), send_followup() (+14 more)
|
|
|
|
### Community 1 - "Community 1"
|
|
Cohesion: 0.11
|
|
Nodes (13): _max_days_overdue(), Level resolver: which follow-up level should fire for this partner? Pure-Python, Pick the highest-sequence level whose delay_days has been crossed by the mos, Return the actual max days-overdue tracked on the report, falling back to th, resolve_level(), AgingBucket, AgingReport, compute_aging() (+5 more)
|
|
|
|
### Community 2 - "Community 2"
|
|
Cohesion: 0.07
|
|
Nodes (14): Both new fields are declared on account.move.line., We can write the new fields onto an existing move line., Verify follow-up tracking fields are added to account.move.line., TestAccountMoveLineFollowup, Coexistence tests: fusion_accounting_followup menu only visible when Enterprise, TestFollowupCoexistence, Property-based invariants for follow-up services., test_buckets_sum_equals_total() (+6 more)
|
|
|
|
### Community 3 - "Community 3"
|
|
Cohesion: 0.11
|
|
Nodes (14): generate_text(), FusionFollowupEngine, Force the next-higher level than the partner's current last_level., Pause follow-ups for a partner until a date (default 30 days)., Reset partner's follow-up state to no_action., Return audit history for a partner., Fetch posted, unreconciled receivable lines for a partner., Compute risk score from partner's payment history. (+6 more)
|
|
|
|
### Community 4 - "Community 4"
|
|
Cohesion: 0.15
|
|
Nodes (2): FollowupDashboard, FollowupService
|
|
|
|
### Community 5 - "Community 5"
|
|
Cohesion: 0.13
|
|
Nodes (10): generate_followup_text(), _get_provider(), AI-generated follow-up text with templated fallback., Look up provider for 'followup_text' feature., Generate follow-up text via LLM, with templated fallback. Returns: {subject, _templated_fallback(), build_prompt(), LLM prompt for AI-generated follow-up text. Output contract: { "subject": str (+2 more)
|
|
|
|
### Community 6 - "Community 6"
|
|
Cohesion: 0.13
|
|
Nodes (7): HttpCase, Python wrappers for OWL tours via HttpCase.start_tour., TestFollowupTours, _percentile(), Performance benchmarks tagged 'benchmark'., TestControllerBenchmarks, TestEngineBenchmarks
|
|
|
|
### Community 7 - "Community 7"
|
|
Cohesion: 0.21
|
|
Nodes (6): Cache lookup + LLM fallback., compute_fingerprint(), FusionFollowupTextCache, lookup(), Cache of AI-generated follow-up text to avoid LLM cost on repeats., TestFusionFollowupTextCache
|
|
|
|
### Community 8 - "Community 8"
|
|
Cohesion: 0.19
|
|
Nodes (6): FusionMigrationWizard, Followup-specific migration step. Backfills fusion.followup.level from Enterpri, Backfill fusion.followup.level from account_followup.followup.line., Migration step: copy Enterprise account_followup per-partner state onto, Verify the partner-state migration step runs without error., TestFollowupMigrationRoundTrip
|
|
|
|
### Community 9 - "Community 9"
|
|
Cohesion: 0.24
|
|
Nodes (5): PartnerRiskScore, Payment-history risk scorer. Pure-Python: takes payment history (list of paymen, Compute a 0-100 risk score from payment-history primitives. Heuristic weigh, score_partner(), TestRiskScorer
|
|
|
|
### Community 10 - "Community 10"
|
|
Cohesion: 0.22
|
|
Nodes (5): test_tone_always_in_valid_set(), TestToneSelector, Tone selector: pick gentle/firm/legal based on follow-up level + risk score., Default tone follows level sequence; high risk can escalate., select_tone()
|
|
|
|
### Community 11 - "Community 11"
|
|
Cohesion: 0.18
|
|
Nodes (3): FusionFollowupRun, Audit record of one follow-up execution (per partner per level)., TestFusionFollowupRun
|
|
|
|
### Community 12 - "Community 12"
|
|
Cohesion: 0.2
|
|
Nodes (6): _cron_daily_scan(), _cron_risk_refresh(), FusionFollowupCron, Cron handlers for fusion_accounting_followup. Two scheduled jobs: - Daily scan:, Smoke tests for the fusion follow-up cron handlers., TestFollowupCron
|
|
|
|
### Community 13 - "Community 13"
|
|
Cohesion: 0.29
|
|
Nodes (2): HttpCase tests for the 6 follow-up JSON-RPC endpoints., TestFollowupController
|
|
|
|
### Community 14 - "Community 14"
|
|
Cohesion: 0.2
|
|
Nodes (3): Inherit res.partner: add follow-up state fields., ResPartner, TestResPartnerFollowup
|
|
|
|
### Community 15 - "Community 15"
|
|
Cohesion: 0.22
|
|
Nodes (3): FusionBatchFollowupWizard, Batch send follow-ups to selected partners (or all overdue)., TestBatchFollowupWizard
|
|
|
|
### Community 16 - "Community 16"
|
|
Cohesion: 0.25
|
|
Nodes (2): AI tool dispatch tests for fusion follow-up tools., TestFusionFollowupTools
|
|
|
|
### Community 17 - "Community 17"
|
|
Cohesion: 0.25
|
|
Nodes (2): FollowupAdapter wiring tests — engine paths., TestFollowupAdapter
|
|
|
|
### Community 18 - "Community 18"
|
|
Cohesion: 0.38
|
|
Nodes (4): _detect_local_llm(), Local LLM compat test for followup_text_generator. Auto-detects LM Studio (:123, _server_reachable(), TestLocalLLMFollowupText
|
|
|
|
### Community 19 - "Community 19"
|
|
Cohesion: 0.67
|
|
Nodes (2): AccountMoveLine, Inherit account.move.line: track last follow-up level.
|
|
|
|
### Community 20 - "Community 20"
|
|
Cohesion: 0.67
|
|
Nodes (2): FusionFollowupLevel, Follow-up level definition (e.g. Reminder at 7 days, Warning at 30, Legal at 60)
|
|
|
|
### Community 21 - "Community 21"
|
|
Cohesion: 0.67
|
|
Nodes (1): FollowupHistoryTable
|
|
|
|
### Community 22 - "Community 22"
|
|
Cohesion: 0.67
|
|
Nodes (1): AgingBucketStrip
|
|
|
|
### Community 23 - "Community 23"
|
|
Cohesion: 1.0
|
|
Nodes (1): RiskBadge
|
|
|
|
### Community 24 - "Community 24"
|
|
Cohesion: 1.0
|
|
Nodes (1): PartnerCard
|
|
|
|
### Community 25 - "Community 25"
|
|
Cohesion: 1.0
|
|
Nodes (1): AiTextPanel
|
|
|
|
### Community 26 - "Community 26"
|
|
Cohesion: 1.0
|
|
Nodes (0):
|
|
|
|
### Community 27 - "Community 27"
|
|
Cohesion: 1.0
|
|
Nodes (0):
|
|
|
|
### Community 28 - "Community 28"
|
|
Cohesion: 1.0
|
|
Nodes (0):
|
|
|
|
### Community 29 - "Community 29"
|
|
Cohesion: 1.0
|
|
Nodes (0):
|
|
|
|
### Community 30 - "Community 30"
|
|
Cohesion: 1.0
|
|
Nodes (0):
|
|
|
|
### Community 31 - "Community 31"
|
|
Cohesion: 1.0
|
|
Nodes (0):
|
|
|
|
### Community 32 - "Community 32"
|
|
Cohesion: 1.0
|
|
Nodes (0):
|
|
|
|
### Community 33 - "Community 33"
|
|
Cohesion: 1.0
|
|
Nodes (1): Stable hash of the inputs that determine the generated text.
|
|
|
|
### Community 34 - "Community 34"
|
|
Cohesion: 1.0
|
|
Nodes (1): Find a cached entry matching these inputs, or empty recordset.
|
|
|
|
### Community 35 - "Community 35"
|
|
Cohesion: 1.0
|
|
Nodes (1): Scan every partner with overdue and send follow-ups when due.
|
|
|
|
### Community 36 - "Community 36"
|
|
Cohesion: 1.0
|
|
Nodes (1): Refresh fusion_followup_risk_score on every partner with overdue.
|
|
|
|
### Community 37 - "Community 37"
|
|
Cohesion: 1.0
|
|
Nodes (0):
|
|
|
|
### Community 38 - "Community 38"
|
|
Cohesion: 1.0
|
|
Nodes (0):
|
|
|
|
### Community 39 - "Community 39"
|
|
Cohesion: 1.0
|
|
Nodes (0):
|
|
|
|
## Knowledge Gaps
|
|
- **58 isolated node(s):** `Property-based invariants for follow-up services.`, `AI tool dispatch tests for fusion follow-up tools.`, `Local LLM compat test for followup_text_generator. Auto-detects LM Studio (:123`, `Verify follow-up tracking fields are added to account.move.line.`, `Both new fields are declared on account.move.line.` (+53 more)
|
|
These have ≤1 connection - possible missing edges or undocumented components.
|
|
- **Thin community `Community 23`** (2 nodes): `RiskBadge`, `risk_badge.js`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 24`** (2 nodes): `PartnerCard`, `partner_card.js`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 25`** (2 nodes): `AiTextPanel`, `ai_text_panel.js`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 26`** (1 nodes): `__init__.py`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 27`** (1 nodes): `__init__.py`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 28`** (1 nodes): `__init__.py`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 29`** (1 nodes): `__init__.py`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 30`** (1 nodes): `__init__.py`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 31`** (1 nodes): `__init__.py`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 32`** (1 nodes): `__manifest__.py`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 33`** (1 nodes): `Stable hash of the inputs that determine the generated text.`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 34`** (1 nodes): `Find a cached entry matching these inputs, or empty recordset.`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 35`** (1 nodes): `Scan every partner with overdue and send follow-ups when due.`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 36`** (1 nodes): `Refresh fusion_followup_risk_score on every partner with overdue.`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 37`** (1 nodes): `followup_tours.js`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 38`** (1 nodes): `followup_dashboard_view.js`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
- **Thin community `Community 39`** (1 nodes): `__init__.py`
|
|
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
|
|
|
## Suggested Questions
|
|
_Questions this graph is uniquely positioned to answer:_
|
|
|
|
- **Why does `TestEngineBenchmarks` connect `Community 6` to `Community 2`?**
|
|
_High betweenness centrality (0.099) - this node is a cross-community bridge._
|
|
- **Why does `send_followup_email()` connect `Community 0` to `Community 3`, `Community 6`, `Community 7`, `Community 10`, `Community 12`, `Community 15`?**
|
|
_High betweenness centrality (0.089) - this node is a cross-community bridge._
|
|
- **Are the 14 inferred relationships involving `send_followup_email()` (e.g. with `.test_send_no_overdue_returns_no_action()` and `.test_send_followup_p95()`) actually correct?**
|
|
_`send_followup_email()` has 14 INFERRED edges - model-reasoned connections that need verification._
|
|
- **Are the 16 inferred relationships involving `compute_aging()` (e.g. with `test_buckets_sum_equals_total()` and `test_overdue_amount_excludes_current()`) actually correct?**
|
|
_`compute_aging()` has 16 INFERRED edges - model-reasoned connections that need verification._
|
|
- **Are the 18 inferred relationships involving `FollowupLevelSpec` (e.g. with `TestLevelResolver` and `FusionFollowupEngine`) actually correct?**
|
|
_`FollowupLevelSpec` has 18 INFERRED edges - model-reasoned connections that need verification._
|
|
- **Are the 9 inferred relationships involving `get_overdue_for_partner()` (e.g. with `.test_get_overdue_returns_dict()` and `.test_get_overdue_p95()`) actually correct?**
|
|
_`get_overdue_for_partner()` has 9 INFERRED edges - model-reasoned connections that need verification._
|
|
- **What connects `Property-based invariants for follow-up services.`, `AI tool dispatch tests for fusion follow-up tools.`, `Local LLM compat test for followup_text_generator. Auto-detects LM Studio (:123` to the rest of the system?**
|
|
_58 weakly-connected nodes found - possible documentation gaps or missing edges._ |