Stylique Studio

Multi-tenant operations platform for salons. Our own product.

Product
43k
Lines of code
200
Test files
8
Ledger migrations
Next.js 16React 19SupabasePostgreSQLRazorpayDexie

The problem

Salon chains run on a spreadsheet, a card machine and a notebook. The software that exists for them handles appointments and stops there. It does not touch inventory, payroll, commission, or the books. The result is that the owner cannot answer what a chair earned last month, and the accountant rebuilds the year from receipts every March. The second problem is quieter and worse: because nothing reconciles, nobody notices when it stops reconciling. A voided bill, a tip paid in cash, a product sold from the shelf and a stylist's commission all move money, and in most salon software none of them meet in a single place where the numbers have to agree.

What we built

  • Double-entry general ledger that auto-posts from bills, expenses, payroll and inventory movements, so trial balance, P&L and balance sheet are generated rather than typed
  • Payroll with payslips, advances, tip payouts and a commission engine
  • Offline-first billing: a counter keeps taking payments through an internet outage and reconciles on reconnect
  • Multi-tenant platform console: tenants, plans, seat and outlet limits, feature flags, subscription state and billing events
  • Inventory with goods receipt notes through to supplier payment
  • CRM depth: segments, campaigns, loyalty tiers, referrals, cohort and leakage reporting
  • Statutory GST reporting and export
  • Memberships and store credit, both posting to the ledger so a prepaid balance is a liability rather than a note in a spreadsheet
  • Staff attendance with automatic clock-out, so an unclosed shift does not silently distort payroll
  • Employee revenue targets and per-stylist performance against them
  • Booking requests, customer segments, campaign sends and templated messaging
  • Expense capture and supplier payment, both posted through the same journal as everything else
  • Bill voiding as a reversing entry with a full audit trail, never a delete
  • Fifty-two database migrations, including a general-ledger backfill that reconstructed history for outlets that predated the accounting module

Decisions worth explaining

A voided bill is reversed, never deleted

Deleting a bill makes the day balance and the history lie. Voiding posts a reversing entry, keeps the original, and records who voided it and when. It costs more to build and it is the difference between a system an accountant will accept and one they will not.

The counter keeps working when the internet does not

Salon internet is unreliable and a counter that stops taking payments is unusable. Billing runs offline-first against a local store and reconciles a full bill on reconnect, including the ledger postings, so an outage delays the sync rather than losing the sale.

Tenant isolation is enforced in the database, not the app

Application-layer checks are one forgotten `where` clause away from a data leak between salons. Isolation is enforced with row-level security and locked-down procedure grants, so a query written incorrectly returns nothing rather than someone else's customers.

Built and owned by the studio, which is why it can be shown in more detail than client work.