Clients
Selected Work
Design + Development / Internal Tool
Internal Product / Design Engineering
VRB BusinessOperations
I needed a business tool. So I built my own.
Rather than adapting my workflow to subscription software, I designed and developed a private internal system around the way I actually run my business.
Designer + Developer
Internal Business Tool
Next.js · Node · MongoDB
Active · Personal Business
Private administration dashboard
One place to see the information and tools I regularly need to manage the operational side of my business.
VRB / Dashboard

Operational Overview
Client and financial information is obscured throughout this case study.
Software shaped around my workflow.
I wanted control over the system I relied on to manage my business.
I didn't want another subscription, I wanted my business information to remain under my control, and I knew I could build something more specific to the way I work than an off-the-shelf platform.
The result became a practical internal product that I use regularly, particularly for creating invoices and managing client-related information.
Not a collection of demos. One working system.
Invoices + Payments
Services
Todos
Social Planning
Templates
The user, designer and developer were the same person.
That made the feedback loop unusually direct. I could identify something I needed while running the business, decide how it should fit into the existing workflow, build it and immediately use it in real work.
Why adapt my workflow to someone else's software when I could build software around my workflow?
Information + Data Structure
One Place to Run the Business
Overview first. Context when I need it.
I didn't want to hunt through separate tools every time I needed information about the business or a client.
The system gives me a high-level operational view from the main dashboard, then lets me move into an individual client record when I need the details behind those numbers.
Two levels of information
What needs my attention overall?
The main dashboard surfaces business-wide information such as clients, todos, invoiced totals, payments and outstanding balances alongside shortcuts into the tools I use regularly.
What belongs to this relationship?
Opening a client brings the information connected to that company into one context, including its financial summary, invoices, payments, proposals, todos and meetings.
One client. Connected records.
Instead of treating invoices, payments and tasks as isolated records, the interface keeps the relevant information grouped around the client it belongs to.
VRB / Client

Total invoiced, paid and unpaid amounts are surfaced at the top so I can understand the client's financial state before opening individual records.
Payments, invoices, proposals, todos and meetings remain accessible from the same client workspace.
New payments, proposals, todos and meetings can be created from the context where I am already working.
The UI follows the data relationships.
MongoDB document
clientId
clientId
clientId
clientId
clientId
MongoDB records are connected through IDs, allowing the application to retrieve the information associated with a client and compose it into one useful workspace.
Design Decision
Global when I'm managing the business.Contextual when I'm managing a client.
The same underlying information can serve different purposes depending on where I am in the application. The main dashboard helps me scan the business as a whole, while the client workspace narrows the interface to one relationship.
The database connects the records.The interface turns those relationships into context.
Invoice Workflow
From Service to Document
Build once. Reuse every time.
I didn't want every invoice to start from a blank form.
My services are stored in the database and pulled directly into the invoice builder, where I can select an existing service, customize it for the client, calculate the totals and generate a finished invoice from the same workflow.
Saved data → working document
Saved Service
Pull from MongoDBSelect + Edit
Customize for the clientCalculate
Subtotal · Tax · TotalGenerate
Create stored invoiceThe form and the output stay connected.
The builder combines reusable service data with invoice-specific information, so creating a document is mostly selecting, adjusting and confirming rather than re-entering the same information every time.
VRB / Create Invoice

Existing services are pulled from the database so I can select from the packages and extras I already offer.
A saved service gives me a starting point without locking the invoice to a fixed description or price.
Subtotals, tax and final totals recalculate as the invoice changes.
The service is the starting point. The invoice is the instance.
Name
Default price
Description
Selected service
Adjusted price
Edited description
The stored service reduces repetitive entry while the invoice line item stays flexible enough for project-specific changes.
The finished document is still part of the application.
Creating the invoice saves the data and takes me to a dedicated document view styled specifically for printing.
Browser-rendered document

I wanted the generated invoice to look exactly the way I designed it every time.
The final invoice is a dedicated CSS template rendered from the stored invoice data. Because the document is still HTML and CSS, the content can adjust naturally while the overall layout stays predictable.
I print only the invoice area, save it as a PDF and send that finished document to the client.
Consistent output
Content adjusts naturally
Easy to review before export
No separate PDF layout system
Interface decisions backed by application logic.
Service selection, editable line items, invoice fields and calculated totals.
Sequential invoice numbers, calculations and editable stored invoice data.
Services, clients and invoices are stored and connected through application data.
The stored invoice is transformed into the final printable client document.
Design Decision
Reduce repetitive input. Keep the final document flexible.
Reusing stored services speeds up invoice creation, but each invoice still needs room for client-specific pricing and descriptions. The workflow keeps the reusable data and the one-off document connected without treating them as the same thing.
The goal wasn't to automate everything.It was to remove the parts I shouldn't have to repeat.
Product Evolution + Financial Logic
When the Original Model Changed
Then a real invoice broke my assumptions.
The original invoice workflow was built around services.
That worked until I purchased physical products for a client and needed to mark them up. Suddenly the selling price was only half of the information I needed.
From simple billing to tracked cost
Service → Invoice
Name
Description
Price
Enough for the service-based work I was originally invoicing.
Product → Cost + Markup + Invoice
Supplier Cost
Client Price
Profit
Supplier Payment
The invoice still needed to stay simple for the client while the application tracked the extra business logic privately.
One transaction. Two different views.
The client only needs to see what they are being charged. I still need to know what I paid, what was marked up and what the work actually earned.
VRB / Invoice Builder
The amount I actually paid can be tracked separately from the amount charged to the client.
The application can use both values when calculating the financial result of a physical product sale.
Supplier and margin information stays inside the internal workflow and does not appear on the client-facing invoice.
Same sale. Different information needs.
What the client needs
Line item
Description
Price
Tax
Total
What I need to run the business
Supplier cost
Supplier tax
Selling price
Profit
Payment state
Track the cost without exposing the cost.
Supplier Cost
Markup
Client Price
Internal Profit
Client-facing pricing and private cost information belong to the same transaction, but they do not belong in the same interface.
Design Engineering Decision
Extend the workflow. Don't overload the document.
Adding product cost tracking did not mean adding every new field to the invoice itself. I extended the internal data and calculations while keeping the client-facing document focused on the information the client actually needs.
Real use found the requirement before a roadmap ever could.
I didn't add cost tracking because I thought the application might need it someday. I added it when an actual client purchase exposed a gap in the original model.
That made the change grounded in a real transaction, with real consequences for pricing, margin and record keeping.
The original workflow worked until the business asked something new of it.
Payments + Edge Cases
Designing for Real Transactions
The happy path wasn't enough.
An invoice is rarely just created, paid once and forgotten.
As I used the system for real client work, the financial workflow had to support partial payments, multiple payment records, overpayments, receipts and changes made after an invoice was originally created.
Then real payments happened
Simple state
State changes over time
Created
Partial
Remaining amount
Recorded
Payments belong to the invoice history.
I manually record each payment, including how it was received, and attach it to the relevant invoice. That gives the invoice a payment history instead of reducing everything to a single paid-or-unpaid flag.
The invoice receives a sequential invoice number and begins with its calculated total.
I enter the payment amount and payment method and associate it with the invoice.
The invoice can represent the remaining amount after one or several payments.
Receipt functionality was added later when the workflow needed a client-facing payment record.
Not exceptions anymore. Just part of the system.
One invoice can have more than one payment.
Instead of assuming a payment closes the invoice, the system keeps the transaction open until the remaining balance has actually been resolved.
The balance can move past zero.
A client can pay slightly more than the invoice total. Rather than forcing that amount into a clean paid state, the invoice can preserve the resulting balance.
Created doesn't always mean finished.
Certain invoice details can still be edited after creation, allowing the document to reflect legitimate changes without rebuilding it from scratch.
A later requirement became part of the workflow.
Receipt generation was added after the original version of the application when real use made that output useful.
Automate the math. Keep control of the judgement.
Sequential invoice numbers
Subtotal calculations
Tax calculations
Invoice totals
Balance recalculation
Recording payments
Selecting payment method
Changing invoice status
Reviewing edits
This is a private tool built for one person. I don't need to automate every decision simply because I can. Calculations and repetitive identifiers are good candidates for automation, while status changes and payment entry are areas where I prefer direct control.
The invoice becomes a record over time.
The generated invoice can show its payment history, paid amount and remaining balance, making the final document reflect what has actually happened rather than only its original total.
VRB / Invoice

Individual payment records remain associated with the invoice instead of disappearing into a single status.
The displayed balance reflects what has actually been paid against the invoice.
The same invoice view can continue representing the transaction as its payment state changes.
Design Engineering Decision
Model what happened. Not what should have happened.
The more I used the application, the more important it became to preserve the real state of a transaction. Multiple payments, overpayments and later edits are not errors to hide. They are information the system needs to represent accurately.
Real business data is rarely perfectly tidy. The interface shouldn't require it to be.
Project Wrap-Up
Built to Fit, Not Built to Sell
Useful because it fits the way I work.
This was never meant to become another all-purpose business platform.
It only needed to solve my problems well: keep the information I rely on together, remove repetitive work, handle the financial situations I actually encounter and give me complete control over the system behind it.
One internal tool, several parts of the business
Client Records
Invoices
Payments
Receipts
Services
Todos
Social Calendar
Instagram Checklist
Templates
CSV Export
Design decisions, connected to working systems.
Workflow + Information Design
Turning business operations into interfaces that keep global information, client context and financial data understandable.
Full-Stack Application Logic
Building the interface, calculations, persistent data and workflows behind clients, invoices, payments and operational records.
Connected Data
Structuring related records so the application can move between business-level views and individual client context.
Real-World Adaptation
Extending the tool when actual business needs introduced receipts, supplier costs, physical products and less tidy payment scenarios.
No subscription.No borrowed workflow.No dependency on someone else's product.
Building the application myself gives me control over how it works, how it looks and how it changes. If I need something different, I can change the system instead of changing the way I run the business.
It also means the information remains mine. I am not relying on a subscription continuing forever or another platform deciding which features and data I can access.
The value of this project isn't that I recreated existing business software.It's that I recognized exactly what I needed, designed a system around those needs, engineered it, and now use it to run my business.
Interface · hierarchy · workflows
Next.js · Node · MongoDB · application logic
Used regularly for real business administration
Adapted as new operational needs appeared
I didn't build software and then look for a use for it.
I had a workflow, and built the software it needed.