Nam Nguyen
Back to blog

What I shipped in October 2026

6 min readNam Nguyen

I keep saying I will write one of these every month. This is the first one I actually finished, so treat it as the start of a habit rather than proof of one. October was a month of three distinct phases: a billing module, two weeks of chasing crash reports, and then a blog that did not exist before.

Here is the monthly build recap.

BiBoTracking: billing, then a lot of apologising to Sentry

The first half of the month went into billing. Not payments — the other kind. Small teams that track time usually need to turn that time into an invoice, and until October BiBoTracking just stopped at "here is how many hours someone worked".

So I built the layer underneath it: clients, projects, tasks, rates, time entries and invoices on the backend, then the admin pages on top of them for time, tasks, projects, invoices and rates. The admin pages went out in English only first. Translations came a day later, for both the web admin and the desktop app, along with a tasks screen in the desktop app that has its own timer. That was the right order, I think, but it meant the feature was technically live and practically unusable for anyone not reading English for about a day.

Two smaller things landed around it. The admin sidebar got labelled groups the way the desktop app already had, and it collapses to icons on a narrow screen — the old flat list had stopped being navigable once billing added a dozen pages. And I built a business overview for super admin: daily and monthly actives, retention cohorts, a churn watchlist. I am not going to quote numbers off it here. It has been live for less than three weeks and I do not trust my own dashboard yet.

There was also one bug that was pure self-inflicted: deleting something that was still referenced came back from Postgres as a restrict violation and surfaced as a generic error instead of "this is in use". Fixing it was a one-liner. Finding it took longer, because the error text had nothing to do with the cause.

Ten days of crash fixes

Then the second half, which I did not plan for at all. From around the 23rd to the 25th I did almost nothing but desktop stability.

The pattern was the same each time. Sentry would light up, I would look at the report, and most of them were not bugs. The browser extension reporting that a tab it was told to close no longer exists. Disk and lock errors from machines that are out of space. Benign extension noise from a fork whose reports were landing in my project. All of that was real signal about the user's machine and zero signal about my code, and it was burying the reports that mattered.

So I did two things in parallel. I stopped forwarding the expected failures — closed tabs, environmental disk and lock problems — and gave SQLite a proper busy timeout so lock contention waits instead of erroring. And I fixed the handful that were genuinely mine: screen captures with zero size were being processed instead of skipped, and the WebP encoder panicked on bad dimensions rather than refusing them.

The ugliest part was in the window library the desktop app sits on. It panicked when a repaint re-entered itself, and it choked on stray window messages that arrive after the event loop is already gone. I patched both to warn instead of die. Patching a dependency is a debt I will pay again at the next upgrade, and I took it anyway, because a user watching the app vanish does not care whose code crashed.

My honest read: I shipped a billing module in half a month and spent the other half making the existing product stop falling over. The second half was more valuable.

A blog for BiBoTracking, built in one day

On the 27th I built a blog into the BiBoTracking marketing site. Markdown files with front matter, rendered as an index and post pages, with meta tags and structured data, a nav link, and the post URLs wired into the sitemap. The sitemap needed one fix before it validated — an ordering problem in the generated XML that I had been emitting wrong without noticing.

Then I published four posts. A free-alternative checklist first, as a test of the pipeline, then three real ones: Time tracking that does not destroy team morale, Time Doctor vs BiBoTracking: what you actually pay for, and Hubstaff alternatives for small remote teams in 2026.

Three posts in one day is not a content strategy. It is a backlog being emptied. I have no traffic data to report on them — they are a day old.

This blog

I also shipped the plumbing to publish here through the site's own blog API, instead of editing files by hand, and then used it once: Building BiBoTracking: what one product taught me. It is the longer version of what I keep circling in these recaps — what one product actually taught me, written in one piece instead of in monthly fragments. If you want the earlier one in the same spirit, what delegating product strategy to AI cost me is still the post I would point a friend at first.

One post a month on my own blog is thin. I know.

What I got wrong

Two things.

I shipped the billing admin in English and translated it the next day. For a product whose users are not mostly English speakers, that is the wrong order, and I only did it because English-first felt faster on the day.

And I let Sentry fill with noise for long enough that it took ten days to dig out. Every one of those non-bug reports was a decision I had made earlier — report everything, sort it out later. Later arrived. The lesson is not "filter your errors"; it is that an alert channel you have learned to ignore is worse than no alert channel, because you keep paying attention to it badly.

What is next

The work already in motion:

  • Billing, properly finished. There are staging notes sitting against it and a renumbered ticket waiting. It is deployed, not done.
  • More posts on the BiBoTracking blog. The format exists now and the pipeline works. The expensive part was the first one.
  • Whatever the crash reports say. Now that the noise is gone, the ones left should actually mean something. That is the whole point of the last two weeks, and I have not had enough days of clean data to know if it worked.

Nothing else. I would rather this list be short and true.