Deeve Technologies
Client workWeb Application

LedgerLine, Laravel Accounting App

A web-based accounting system built for a US CPA firm, developed in Laravel with Livewire for reactive interfaces and Google OAuth sign-in. Built to handle a professional accounting practice's bookkeeping and client financials.

ClientUnited States accounting firm
RoleFull-stack developer
Year2026
TypeWeb Application
Updated23 Sep 2026
Ledger
Overview

LedgerLine is a financial reporting system built for a single United States accounting firm, running in production against real client data.

It takes a tax client from a secure intake form, through accountant review, to a signed Profit and Loss, Balance Sheet or 1120S Trial Balance delivered as PDF or Excel.

Built with
Google OAuthLaravelLivewireMySQLVite
The problem

What was in the way

A small CPA firm collects the same figures from every client each year, and the collection is the slow part. Spreadsheets get emailed back and forth, attachments go missing, and nobody can say with confidence which version a report was built from. The reporting itself is mechanical. The intake, the chasing and the audit trail are where the hours go.

The firm needed the intake to be something a client could complete once, without an account, and the resulting report to be traceable back to exactly what the client submitted and signed.

What I built

Four parts, each with a reason

Signed-link intake, with no account for the client

A client receives a signed URL and fills in the form. No registration, no password, no support call about a forgotten login. The link carries its own authorisation and expires, so the form cannot be shared or replayed. Submissions save as drafts, so a client can leave halfway through and come back.

The form collects per-section line items, add-ons, attachments and disclosures, then captures a signature. That signature is what makes the resulting report defensible: the firm can show what the client stated and when.

Report generation in three formats

Profit and Loss, Balance Sheet and the US 1120S Trial Balance generate as HTML for review, PDF for delivery and Excel for the accountant who wants to keep working with the numbers. PDF rendering runs through headless Chrome rather than a PHP PDF library, so the printed output matches the reviewed HTML exactly instead of approximating it.

Finished reports are delivered on their own signed links, so a client can retrieve a report without an account either.

Operational plumbing

Scheduled and manual backups, per-user notification preferences across in-app, email and SMS, and a dynamic settings layer cached in Redis so configuration changes do not need a deploy. The public intake form is protected by Cloudflare Turnstile, because a public form with no login is a public form.

Roles, two-factor and an audit trail

Access is role based. Accountants, reviewers and administrators see different things. Two-factor authentication uses TOTP, and Google sign-in is available but gated: a Google account does not grant access on its own, it still has to be approved.

Every meaningful action is written to an activity log. Combined with soft deletes and encrypted casts on sensitive columns, the firm can answer who changed what, and when, which is the question that matters when a filing is challenged.

How it was built

The engineering underneath

Laravel 11PHP 8.2 with MySQL 8.4, Blade with Livewire 3 and Alpine.js, Tailwind CSS for styling
7 contextsIdentity, clients, intake, reports, notifications, audit and backup, and settings
LayeredControllers handle HTTP only, domain logic sits in a service layer that knows nothing about requests

The application is layered deliberately. Controllers and Livewire components handle HTTP only. Domain logic lives in a service layer that knows nothing about requests. Eloquent models handle persistence, with encrypted casts on the fields that need it and soft deletes throughout.

Seven bounded contexts keep the codebase navigable as it grows: identity, clients, intake, reports, notifications, audit and backup, and settings. That separation is why a new report type is a contained piece of work rather than a change that ripples through the whole application.

Documentation ships with the code, including a records retention policy, a written information security plan and a secrets rotation procedure. For a system holding tax data, those are part of the deliverable rather than an afterthought.

Laravel 11 on PHP 8.2 with MySQL 8.4. Blade with Livewire 3 and Alpine.js for the interactive pieces, Tailwind CSS for styling. Spatie Browsershot drives PDF rendering through headless Chrome, and Maatwebsite Excel handles the spreadsheet exports.

Spatie Permission provides role based access control, Spatie Activitylog the audit trail, and Spatie Backup the scheduled snapshots. Laravel Fortify supplies TOTP two-factor, Socialite the Google OAuth path. Brevo sends transactional email, Twilio sends SMS, and Cloudflare Turnstile guards the public form. Static analysis runs through Larastan, formatting through Pint.

Livewire earns its place here specifically. The intake form has conditional sections and running totals, which is exactly the kind of interactivity that would otherwise justify a separate front-end application and a second deployment target for no real gain.

Google OAuthLaravelLivewireMySQLVite
More work

Projects like this

All projects
Why it matters for your project

I build software, and I measure whether it works.

The same questions I research are the ones I ask on client builds: is it reliable, is it fast, is it easy to use, and is it secure. Those four drove satisfaction in my ICT portal study, and they shape how I scope and test every project.