Skip to content
Notifications
Clear all

Just built a budget tracker integrated with our PM tool using the API.

1 Posts
1 Users
0 Reactions
0 Views
(@infra_architect_rebel_2)
Reputable Member
Joined: 5 months ago
Posts: 198
Topic starter   [#24189]

So you've all seen the endless parade of "integrations" and "marketplace apps" for project management tools. They promise to connect your tasks to your budget, your time tracking to your revenue, and your left-pinky finger movements to your sprint velocity. Most are either eye-wateringly expensive monthly subscriptions for what amounts to a few API calls, or they're so over-engineered they require a dedicated platform team to maintain.

I found myself in the familiar, tiresome position of being asked to provide "real-time project financials" in our PM tool, with the usual constraints: no new SaaS subscriptions, no sending data to third-party processors, and it needed to be done last quarter. Instead of embarking on a six-month vendor evaluation and proof-of-concept odyssey, I spent a weekend building a simple budget tracker that hooks directly into our PM tool's API. The result is a cron job and a few hundred lines of Python that would make any enterprise integration vendor blush with shame at their own pricing sheet.

The core of it is embarrassingly straightforward. It polls for completed tasks (with specific cost-centric labels or custom fields we use for "engineering hours," "cloud spend," etc.), aggregates them against a predefined project budget stored in a simple PostgreSQL table, and then updates a custom field or a pinned comment in the project's overview. The entire state is managed in our own database, which means we own the historical data and aren't subject to some external service's data retention limits or API changes.

Here's the gist of the aggregation logic and the API update:

```python
# Simplified core logic - runs nightly
def update_project_burn(project_id):
# Get budget from our own control plane DB
budget = db.query("SELECT allocated, managed_code FROM project_budgets WHERE pm_project_id = %s", project_id).first()

# Fetch completed cost-items from PM tool API in last period
completed_items = pm_api.get_tasks(
project=project_id,
completed_since=last_run,
fields=['custom_cost_amount', 'custom_cost_code']
)

# Aggregate spend by our internal cost code
burn_aggregate = {}
for item in completed_items:
code = item['custom_cost_code']
burn_aggregate[code] = burn_aggregate.get(code, 0) + float(item['custom_cost_amount'])

# Update a custom "Current Burn" field in the PM tool project
# Format: "ENG: $12,340 | CLOUD: $5,678 | REMAINING: $32,098"
summary_text = build_summary_string(budget.allocated, burn_aggregate)
pm_api.update_project_custom_field(
project_id,
field_id=os.getenv('BURN_FIELD_ID'),
value=summary_text
)

# Log everything locally for reporting and audit
db.insert('burn_snapshots', {
'project_id': project_id,
'snapshot_date': datetime.now(),
'burn_data': json.dumps(burn_aggregate),
'summary_text': summary_text
})
```

The key architectural decisions that kept this from becoming yet another microservices nightmare:

* **It's a monolith in a cron job:** No message queues, no serverless functions, no Kubernetes pods. A single script in a container scheduled via cron in a single VM. The complexity is linear and entirely contained.
* **Idempotent and fault-tolerant:** It can run multiple times a day without double-counting because it queries for items completed *since the last successful run*, which we track. If the PM tool API is down, it fails and tries again next cycle.
* **Own your data:** The PM tool is treated as a presentation layer. All the authoritative data lives in our database. This means we can change PM tools someday without losing our historical financial tracking.
* **Cost:** The entire thing runs on a single, modest instance. The operational cost is negligible compared to the $20/user/month "financial integration" platforms we evaluated.

The pushback I received internally was predictably focused on "scaling" and "maintainability." To which I say: scaling to what? We're tracking budgets for dozens of projects, not millions of real-time transactions. As for maintainability, the entire system is so simple that any engineer on the team can read and modify the code in an afternoon. Compare that to the "low-code" integration platform that required a certified consultant to tweak a workflow.

This approach isn't for everyone, of course. If your company has a policy of buying over building, or if you lack the basic in-house skills to run a script and a database, then by all means, pay the premium. But for those of us tired of the SaaS sprawl and the endless vendor lock-in, sometimes the most elegant, cost-effective, and reliable solution is the one you build yourself against a decent API. It's just a bit of glue code, not a platform.


monoliths are not evil


   
Quote