Software Development
InfraxDev helped stabilize and progressively modernize an established analytics platform through architectural refactoring, resilient data imports, cloud-storage integrations, background processing, and fixes across dashboards, charts, filters, and document exports.
Client: Confidential Analytics Platform
Industry: Business Intelligence and Analytics
An established data-visualization platform was already deployed and serving customers when the engagement began. InfraxDev was engaged to modernize a mixed-generation codebase while resolving production defects reported through real customer workflows.
The platform is an established data-visualization platform that turns complex datasets into interactive dashboards, configurable charts, reports, and presentation-ready exports. By the time the engagement began, the product was already deployed and supporting active customers.
This changed the nature of the engineering work. New capabilities had to be introduced without disrupting existing dashboards, imports, or reporting workflows. At the same time, issues reported by customers needed to be reproduced, traced through a large mixed-generation codebase, and corrected with a limited blast radius.
Across a multi-year engagement, InfraxDev combined production support with incremental modernization: stabilizing customer-facing behavior while progressively improving the internal structure of the application.
The platform covered far more than chart rendering. It included dataset ingestion, data preparation, dashboard configuration, filtering, exports, scheduled jobs, cloud-storage connections, localization, and tenant-aware project management.
Several constraints made changes demanding:
The objective was therefore not a one-time rewrite. It was to make the live platform more reliable and maintainable through controlled, reviewable improvements.
The platform used amCharts 4 and amCharts 5 as its visualization foundations, then extended them with application-specific builders, templates, and configuration logic. The result was not a catalog of fixed charts: users could map different datasets and choose from more than 50 data and presentation settings covering series, metrics, filters, groupings, axes, legends, labels, colors, benchmarks, timelines, and layout behavior.
Each rendering path therefore had to translate changing user selections into a consistent chart definition while preserving compatibility with dashboards, filters, and exports.
A major chart-settings component had accumulated responsibilities for layout, colors, groups, benchmarks, timelines, and advanced options. This made routine changes risky because unrelated settings shared the same large component.
The component was decomposed into smaller, focused Vue modules with shared helper functions. Each settings area became easier to reason about and modify independently. The work also removed unused code and clarified the boundary between the main settings interface and specialized configuration panels.
This incremental approach preserved the existing user experience while reducing the cost and risk of future chart-related changes.
Backend responsibilities were progressively moved away from oversized controllers and legacy models. Data-table logic was extracted into dedicated services and repositories, project-related persistence was moved into repository classes, and reusable behavior was consolidated into helpers.
These changes created clearer boundaries between HTTP handling, domain operations, data access, and presentation. They also provided safer places for fixes and new features, reducing the need to modify unrelated parts of the application.
The result was a gradual modernization path that respected the realities of a mature production codebase.
Data ingestion was a core workflow, but large files and long-running transformations were not well suited to synchronous requests. Import processing was moved into queued background jobs so uploads could be handled without tying their success to a browser connection.
The import workflow was expanded to support:
Importer behavior was organized around reusable base services, allowing different data sources to share validation and processing logic rather than duplicating it.
The platform gained managed import flows for Dropbox and Google Drive. The work covered provider-specific adapters, account configuration, authorization flows, access-token renewal, scheduled import commands, webhook handling, and background jobs.
A common importer abstraction was introduced for the cloud providers. This kept provider-specific API handling separate from the platform's core ingestion process and made the workflow easier to extend.
The integration was designed around operational realities: credentials expire, network calls fail, and imports may need to run without an administrator keeping a browser session open.
A substantial part of the engagement involved investigating defects that appeared only with particular datasets, chart types, filters, or dashboard configurations.
Fixes covered areas including:
These issues required tracing behavior across server-rendered templates, frontend state, chart libraries, and generated data structures. The goal was not merely to suppress visible symptoms, but to correct the underlying state or transformation logic while protecting other chart configurations.
Document exports represented a second rendering environment with failure modes different from the browser. Dashboards could contain text charts, charts hidden by minimum-case rules, missing images, or combinations that only failed during screenshot and document generation.
The export pipeline was hardened across PDF, PowerPoint, Excel, and image generation. Corrections included allowing exports to continue when an individual chart was intentionally unavailable, resolving chart-image paths, handling text-chart rendering, and fixing dashboard screenshot edge cases.
These changes improved the resilience of a workflow that customers relied on to distribute and present analytical results outside the platform.
Alongside the larger architectural work, many smaller corrections protected day-to-day usability. These included media uploads, email configuration, translations, chart-menu behavior, dynamic creation of questions and filters, and compatibility between older and newer parts of the interface.
German localization was expanded across application and chart terminology. Dependencies and configuration were also updated where necessary to keep operational services functioning.
This combination of deep refactoring and detailed maintenance is typical of long-lived SaaS engineering: architectural progress matters, but so does resolving the specific issue blocking a customer today.
The engagement left the platform with clearer frontend components, stronger service and repository boundaries, more capable import workflows, reusable cloud-storage integrations, and a more fault-tolerant export pipeline.
Just as importantly, modernization took place without requiring a disruptive rewrite. Production defects were addressed alongside structural improvements, allowing the product to continue serving existing customers while becoming easier to maintain and extend.
The case demonstrates how a mature data product can be improved safely: understand the behavior customers already depend on, isolate responsibilities progressively, move expensive work into resilient background processing, and treat every production fix as an opportunity to strengthen the surrounding design.