{"results":{"result":{"added-files":{"code-health":9.786405925250707,"old-code-health":0.0,"files":[{"file":"apps/usage_metrics/tests/test_characterisation.py","loc":193,"code-health":10.0},{"file":"apps/usage_metrics/filters.py","loc":71,"code-health":10.0},{"file":"apps/usage_metrics/tests/test_metrics.py","loc":280,"code-health":10.0},{"file":"apps/usage_metrics/dashboard_querysets.py","loc":163,"code-health":8.959659945245399},{"file":"apps/usage_metrics/tests/test_dashboard_querysets.py","loc":183,"code-health":10.0},{"file":"apps/usage_metrics/metrics.py","loc":209,"code-health":9.6882083290695}]},"external-review-url":"https://github.com/dimagi/open-chat-studio/pull/4134","old-code-health":9.773176232618352,"modified-files":{"code-health":9.910429205341444,"old-code-health":9.773176232618352,"files":[{"file":"config/settings.py","loc":840,"old-loc":839,"code-health":9.6882083290695,"old-code-health":9.6882083290695},{"file":"apps/dashboard/services.py","loc":465,"old-loc":569,"code-health":10.0,"old-code-health":9.292536416550487},{"file":"apps/api/v2/usage/services.py","loc":536,"old-loc":552,"code-health":10.0,"old-code-health":10.0},{"file":"apps/cost_tracking/services/reporting.py","loc":519,"old-loc":512,"code-health":10.0,"old-code-health":10.0},{"file":"apps/cost_tracking/tests/test_reporting_filters.py","loc":321,"old-loc":262,"code-health":10.0,"old-code-health":10.0},{"file":"apps/dashboard/tests/test_services.py","loc":243,"old-loc":194,"code-health":10.0,"old-code-health":10.0}]},"removed-files":{"code-health":0.0,"old-code-health":0.0,"files":[]},"external-review-id":"4134","analysis-time":"2026-08-06T18:52:05Z","negative-impact-count":3,"suppressions":{"number-of-types":0,"number-of-files-touched":0,"findings":[]},"affected-hotspots":1,"commits":["3bc4613af08da3d135554810c052d2242d28c782","8e633bf03fb21abe803b6fa00fc967997a2aca88","8fbd6b44ca36b34a19c7ad7380d5a5c505a5cb12","36a544cd5c1f12a75953d6c26ad25e25b8da8bc4","56b633a77df8ffe8494c2ffdafb15b48e6f5e8ae","555d3df06df1eb21d1c68f694f959eb0c8de0600","9656a6fcfe8544b7c59ea64e69179acaab974bc9","a09ca54aee6be847d75432604c807846233be961","a4ab8ba810b6281b61fb2f70822dc5334138f343","445d96b04ea47ee47b9fc77818799780ab40ffc2","48cc1bd4a83a45935aad587b097313d182d57842","b6206e65164e5fb51fae6d7c1919d49a88f75a5c","53b29eea729a1ff38cb867813d9b5a91d3565d1a","f0cce87551500fc621a20769ff99e49bfddb4ebe","d23d2549fcc9639fdb1bd78daa8fe4d73df28a93","ad968730a77dd8e3a0578ee4af20bd97e48efd6b"],"is-negative-review":true,"negative-findings":{"number-of-types":3,"number-of-files-touched":2,"findings":[{"method":"filtered_querysets","why-it-occurs":"Overly long functions make the code harder to read. The recommended maximum function length for the Python language is 80 lines of code. Severity: Brain Method - Complex Method - Long Method.","name":"Large Method","file":"apps/usage_metrics/dashboard_querysets.py","refactoring-examples":null,"change-level":"warning","is-hotspot?":false,"line":33,"what-changed":"filtered_querysets has 138 lines, threshold = 80","how-to-fix":"We recommend to be careful here -- just splitting long functions don't necessarily make the code easier to read. Instead, look for natural chunks inside the functions that expresses a specific task or concern. Often, such concerns are indicated by a Code Comment followed by an if-statement. Use the [EXTRACT FUNCTION](https://refactoring.com/catalog/extractFunction.html) refactoring to encapsulate that concern.","change-type":"introduced"},{"method":"filtered_querysets","why-it-occurs":"Functions with many arguments indicate either a) low cohesion where the function has too many responsibilities, or b) a missing abstraction that encapsulates those arguments.\n\nThe threshold for the Python language is 6 function arguments.","name":"Excess Number of Function Arguments","file":"apps/usage_metrics/dashboard_querysets.py","refactoring-examples":null,"change-level":"warning","is-hotspot?":false,"line":33,"what-changed":"filtered_querysets has 7 arguments, max arguments = 6","how-to-fix":"Start by investigating the responsibilities of the function. Make sure it doesn't do too many things, in which case it should be split into smaller and more cohesive functions. Consider the refactoring [INTRODUCE PARAMETER OBJECT](https://refactoring.com/catalog/introduceParameterObject.html) to encapsulate arguments that refer to the same logical concept.","change-type":"introduced"},{"why-it-occurs":"This code health issue is measured as the average number of function arguments across the whole file. A function with many arguments can be simplified either by a) splitting the function if it has too many responsibilities, or b) by introducing an abstraction (class, record, struct, etc.) which encapsulates the arguments. ","name":"Missing Arguments Abstractions","file":"apps/usage_metrics/metrics.py","refactoring-examples":null,"change-level":"warning","is-hotspot?":false,"what-changed":"The average number of function arguments in this module is 4.11 across 18 functions. The average arguments threshold is 4.00","how-to-fix":"Start by investigating the responsibilities of the function. Make sure it doesn't do too many things, in which case it should be split into smaller and more cohesive functions. Consider the refactoring [INTRODUCE PARAMETER OBJECT](https://refactoring.com/catalog/introduceParameterObject.html) to encapsulate arguments that refer to the same logical concept.","change-type":"introduced"}]},"positive-impact-count":1,"repo":"open-chat-studio","code-health":9.876548622487922,"version":"3.0","authors":["barry47products"],"directives":{"added":[],"removed":[]},"positive-findings":{"number-of-types":1,"number-of-files-touched":1,"findings":[{"method":"DashboardService.get_filtered_queryset_base","why-it-occurs":"Overly long functions make the code harder to read. The recommended maximum function length for the Python language is 80 lines of code. Severity: Brain Method - Complex Method - Long Method.","name":"Large Method","file":"apps/dashboard/services.py","change-level":"improvement","is-hotspot?":false,"line":47,"what-changed":"DashboardService.get_filtered_queryset_base is no longer above the threshold for lines of code","how-to-fix":"We recommend to be careful here -- just splitting long functions don't necessarily make the code easier to read. Instead, look for natural chunks inside the functions that expresses a specific task or concern. Often, such concerns are indicated by a Code Comment followed by an if-statement. Use the [EXTRACT FUNCTION](https://refactoring.com/catalog/extractFunction.html) refactoring to encapsulate that concern.","change-type":"fixed"}]},"notices":{"number-of-types":0,"number-of-files-touched":0,"findings":[]},"external-review-provider":"GitHub"},"analysistime":"2026-08-06T18:52:04.000Z","project-name":"open-chat-studio","repository":"https://github.com/dimagi/open-chat-studio.git"}}