Why Cost Profiles Are Named Rules — Not a Rate on the User - MinuteShark

Engineering

Why Cost Profiles Are Named Rules — Not a Rate on the User

Cost profiles for time tracking look like a settings afterthought until Friday. Someone wants a billable rate. The obvious schema is a number on the user: Alex is $150. Save. Invoice. That model survives a demo. It dies the first week a freelancer invoices two clients at two rates, pays a helper a different internal cost, and still needs last month’s PDF to reprint with the old numbers.

MinuteShark stores named financial rules instead. A cost profile is a document you can pick: billable rate and internal cost per user and/or team, a currency you type as a symbol or code, used by invoices and by project trackers. If both a user rate and a team rate exist, the user wins. Admin configures it. The timer never has to know. This post is why we refused the column on the user record — not a tour of every invoice field.

The product bet: a rate that lives on a person is a nickname. A named profile is a rule you can reuse, compare, and leave alone when the week is messy. Invoices and trackers should point at the same rule.

Why a rate-on-user field lies on day three

Independent work is not one price. A strategy retainer is not a same-day production rescue. A subcontracted designer is not you. If the only place a dollar amount can live is “this user,” you get one of three hacks, all of them bad.

  • Overwrite the user. Alex becomes $185 for Client B, then you forget to put $150 back. Client A’s next invoice is a gift you did not mean to give.
  • Clone the user. “Alex — Acme” and “Alex — Northwind” as fake people so the rate can differ. Reports’ Who dimension becomes a costume party. Disable-user billing rules stop making sense.
  • Type the rate on the invoice and nowhere else. Trackers that watch budget against cost have nothing honest to consume. You have a PDF and a vibes-based burn rate.

We already argue, on the consultant side, that your sticker rate is not your real hourly rate. Engineering has a sibling problem: the database should not pretend there is only one sticker. Internal cost and billable rate are different numbers on purpose. A profile can hold both. A user column usually holds whichever you typed last.

Subcontracting made the lie obvious. Two rate cards in one week — what you bill, what you pay — cannot share a single user field without lying to either the client or yourself. We wrote the commercial version of that split; the schema version is this article.

What a cost profile actually is in the app

On the client, MinuteShark is an Ionic + Angular 16 app. Capacitor 7 wraps the same workspace on iOS and Android. The catalog and the time entries live in Firebase (Auth, Firestore, Functions). Stripe is for subscription billing on the web, which is a different money object: who pays ElementPragma for seats, not what a client owes you. Mixing those in one “rate” field is how products accidentally invoice a freelancer’s SaaS bill to their customer.

A cost profile is a named record in the workspace: rates keyed by user and/or team, plus a currency that is free text. We did not ship an ISO-4217 dropdown that refuses “CAD $” or “US$” because a solo consultant’s PDF is a communication device, not a banking network. Admin-only configuration is load-bearing. Regular Users should not discover they can quietly change the rule that last month’s invoices assumed. Permissions already separate MANAGE_BILLING from locking a task or managing clients. Cost profiles sit with billing, not with the play button.

Why invoices and trackers share the same pointer

If invoices used a typed-in rate and trackers used a field on the project, you would get two truths. Generate Invoice already starts from a report (What × Who × When) and then asks you to pick a cost profile — or enter rates manually for the one-off. Trackers monitor one project or one task against an estimate, a budget, or a revenue goal, and they also ask which profile to use. Same rule, two moments: Friday’s document and Wednesday’s “you are at 50% of cost.”

That is why we generate files with the boring libraries — jsPDF, docx, xlsx — off the invoice you built, not off a second pricing engine. A freelancer invoice should be a document. The document argument is the UX. The profile is the number that document is allowed to trust. The billable rates guide is the customer map of this path.

Manual rates on an invoice still exist because reality includes a one-time rescue you do not want to immortalize as a profile. The named rule is the default. The escape hatch is labeled. Silent AI rewrite of either is not a feature: MinuteShark AI does not invent a cost profile while you chat, and it does not change entries until you confirm a card.

What we left out on purpose

No native QuickBooks “mark paid” loop. No marketplace that syncs a Jira hourly field into our profile. Fewer integrations than enterprise tools is honest; custom development exists when a specialized consulting workflow needs a bridge. We do not claim a public developer API as a self-serve Standard checkbox. Enterprise can include application customization and custom branding — that is a conversation, not a hidden rate column.

We also did not design cost profiles as departmental chargeback theatre. Primary ICP is freelancers, solo consultants, and tiny teams. If you need five nested legal entities and SSO-as-default before you can type $150, you are outside the design center. Workspaces stay isolated: profiles do not leak into another office’s client pool. Cloud sync (Firebase) means the same profile is available wherever you generate the invoice — web, iOS, Android — while subscription management itself stays on the web.

SOC2 Type II, ISO27001, encryption, backups: the profile is still just money rules for people you already invited. It is not a reason to screenshot anyone’s desktop. It is not idle detection. It is the opposite of a surveillance product pretending to be payroll.

How we tell if the model is working

  • Can a consultant keep last year’s rate as a profile named “2025 card” without cloning themselves?
  • Can a two-person practice set a team rate and still override one user who bills higher?
  • Does a tracker at 50% of cost use the same numbers the invoice will multiply?
  • Does reprinting a week still make sense if you pick the profile you actually used, not whoever the user record currently claims to be?

If the answer depends on remembering to edit Alex before you hit Generate, we shipped a nickname. Named rules are slower to type on day one and faster every Friday after that. Time data should help you think. A rate that keeps mutating under the person is not thinking. It is archaeology.

Previous Post Back to Blog Next Post