
Vikoma
A platform for appointment-based businesses in Ecuador, such as beauty salons, hair salons, nail studios, spas and barbershops. It replaces notebooks, chats and hand-balanced cash. Live in production: its first pilot barbershop has already signed up and set up its business.
Each business gets its own space, with its own team, services and clients. The owner signs in with Google and finishes setup in about 5 minutes, measured with the pilot barbershop. It includes conflict-free scheduling, inventory that drops automatically with each sale, cash flow and revenue reports, WhatsApp confirmations, a waitlist, reference photos with consent under Ecuador's data law, and separate permissions for the owner and the team. The agenda stays readable when the internet drops. I built it solo: money in whole cents, times in UTC and 2,679 automated tests that run in about 16 seconds, with ≈81% line coverage of business logic and repositories.
Problems
- One business could reference another's data. The tursodb engine silently ignored foreign keys.
How I solved them
- I confirmed it with an insert that had to fail and moved production to libSQL. Data goes through a single access point, with tests proving it never mixes. The app refuses to boot if foreign keys are not enforced.
Show 4 more problems and solutionsHide the extra problems and solutions
Problems
- Two clients must never book the same slot, even at the same moment.
- Two simultaneous checkouts could sell sold-out stock or repeat an invoice number.
- The OAuth sign-in check accepted any value. A hex parser read base64url input and returned empty buffers, so everything matched.
- A WhatsApp failure must not block a booking.
How I solved them
- Every booking rechecks the slot inside the database transaction, not just on screen.
- Invoice numbers come from an atomic UPDATE with RETURNING. A test with 25 concurrent requests demands 25 distinct numbers. Stock uses conditional updates and retries lock errors.
- A negative security test caught it. The comparison is now constant-time and hashes both sides first.
- The message is queued with the appointment and sent later, with retries. Without client consent, it never goes out.



