Skip to content
Changelog This Week in Miru

This Week in Miru: Safer Team Offboarding, Smarter Reminders, and Invoice Workflow Cleanup

From April 13 to April 22, we shipped 116 non-merge commits across reminders, invoicing, team management, calendars, i18n, and auth hardening.

Vipul A M Vipul A M · · 3 min read
Billing
Miru invoicing screen with invoice status and totals
This article is currently written in English. Navigation, dates, and calls to action follow your selected language.

This week: reliability — fewer billing mistakes, fewer accidental removals, fewer surprises.

Between April 13 and April 22, we shipped 116 non-merge commits in miru-web, touching reminders, invoicing, team flows, calendar behavior, localization, and deployment resilience.

This Week in Miru summary card with commit metrics and key focus areas

1) Team Offboarding Is Now Risk-Aware

Removing a team member used to be a blind action.

Old flow:

DELETE /api/team/:id

New flow:

GET /api/team/:id/removal_impact
DELETE /api/team/:id

The new removalImpact payload includes practical risk signals:

  • projectAssignmentsCount
  • projectNames
  • unbilledEntriesCount
  • unbilledMinutes
  • uninvoicedAmount
  • invoicedEntriesCount
  • hasRisk

What changed in practice:

  • API now returns removal risk before delete
  • UI can show a one-line warning when hasRisk is true
  • Managers can see project impact and uninvoiced amount before final action

Suggested warning copy:

Removing this member will orphan X minutes across Y projects and leave $Z uninvoiced.

This is a small API change with a high operational payoff.

Miru team management view

2) Weekly Missed-Entry Reminders Stopped Crying Wolf

We fixed a class of false weekly reminder emails by tightening duration heuristics and hour-vs-minute detection.

Old logic leaned on entry counts and broad thresholds. New logic inspects real duration characteristics and guards against minute-granularity misreads.

Old shape:

entries_count <= working_days + 2 &&
  timesheet_entries.all? { |entry| entry.duration.to_f <= 24 } &&
  total <= company.working_hours.to_f * 1.5

New shape:

return false if max_duration > 24
return false if total > company.working_hours.to_f * 2
return false if minute_granularity_durations?(durations)

durations.any? { |duration| (duration % 1).positive? } || max_duration <= 12

Result: fewer false reminders, better trust in automation.

Miru time tracking view used in reminder and missed-entry workflows

3) Invoice and Payment Flows Got Tighter

We made the invoice experience less fragile and more obvious:

  • Added waive-off invoice action in the modern invoice UI
  • Moved invoice summary stats above the table
  • Added sort indicator on issue date column
  • Polished invoice editor + print flow
  • Fixed manual line item name usability
  • Normalized invoice date/calendar classes
  • Improved mark-as-paid modal behavior and styling

This is not glamorous work. It is the work that prevents month-end billing drama.

Miru invoices view

Miru payments view for month-end collection workflows

4) Calendar and Date Picker Bugs Were Systematically Removed

Date/time components were causing inconsistent behavior across leaves, invoices, and time tracking.

We shipped a concentrated pass across:

  • calendar.tsx
  • date picker and date range picker components
  • leave calendar navigation/selection styling
  • holiday calendar layout and sorting

If you felt “calendar weirdness” last week, that was real. It is better now.

5) Team and Client Data Flows Are More Defensive

A few fixes worth calling out:

  • Team index now includes hours + project metrics consistently
  • Team status mapping now tolerates boolean/string compatibility (status + statusText paths)
  • Client create no longer allows blank-email flows to throw a 500
  • Add-client form now marks required fields clearly

These are small changes in code and big changes in operational confidence.

6) i18n, Auth Recovery, and Docs Delivery Improved Together

We continued the localization sweep across settings, reports, clients, and payments, while also hardening deploy/session behavior and profile/auth flows.

Highlights:

  • Translation backfill across supported locales
  • Session recovery across deploy-time asset mismatches
  • Bootstrap session recovery hardening
  • Avatar upload validation and UX cleanup
  • Docs pipeline moved to a more resilient hosted flow (/docs route alignment + gh-pages deploy support)

By The Numbers (Apr 13 → Apr 22)

  • 116 non-merge commits
  • 84 fix commits
  • 3 feature commits
  • 4 refactors
  • 5 test-focused commits
  • 542 unique files touched

If you want the raw diffs:

That is the week.

Watchlist for Next Week

  • Add e2e coverage for removal_impact warning paths
  • Track reminder false-positive reports after heuristic changes
  • Monitor invoice print and waive-off flows for month-end regressions
Share:
Vipul A M

Vipul A M

Co-founder at Saeloun. Building Miru. Rails contributor. Shipping from Pune, India.

Put it to work

Run one cleaner billing cycle in Miru.

If this article is about tracking time, billing clients, comparing tools, or automating work, Miru is the product version of that idea. Start free, invite the team, and send the next invoice from tracked work.

What you get

  • Time tracking, invoices, expenses, and payments in one place.
  • Free for up to 5 users. Pro is $1/member/month.
  • Open source, with CLI, API, MCP, and self-hosting paths.
See Miru

The article is the argument. Miru is the workflow.

Track the work, approve the hours, send the invoice, and get paid without bolting together three separate tools.

Billing
Miru invoicing screen with invoice status and totals
Invoicing Miru