Twelve modular products under one workspace and one login: peso invoicing with VAT, Asia/Manila time, and a private workspace per organization. Built solo with AI assistance.
Most small businesses in the Philippines already run on several tools that don't talk to each other: a spreadsheet for customers, a separate POS that has no idea what's in stock, a notebook for inventory, staff records in a folder, delivery addresses in a chat thread. Nobody re-enters that on purpose — it just happens, one tool at a time, until the same customer exists in four places with four slightly different spellings of their name.
Bizph starts from a specific belief: these businesses don't need another all-in-one ERP that tries to do everything and does most of it half-well. They need a handful of tools that actually work together, and the option to add one at a time as the business grows. So Bizph isn't one application with a feature list — it's built as independent products. A business can run on a single one, or combine several, and the products it does enable share the same customers, staff and records instead of each keeping a private copy.
Twelve products, grouped the same way the live product groups them. Every one below exists in the application today — Procurement isn't counted separately; it ships as part of Inventory.
Every product also reads and writes a small set of shared records — organizations, users, customers and files — instead of keeping its own copy. That shared layer is what turns twelve separate tools into one workspace rather than twelve unrelated apps that happen to share a login screen.
Take a water-refilling station in Dasmariñas, Cavite — one of Bizph's own example accounts — running POS, Inventory, Dispatch and Cashflow. One order moves through all four without anyone re-entering it.
Building four screens for that isn't the hard part. The hard part is letting POS, Inventory, Dispatch and Cashflow react to one order without being wired directly to each other — so a business that only has POS and Inventory still works on its own, and Dispatch can be switched on later without anyone touching the other three. That's what the transactional outbox in the next section is for.
Bizph is sold as separate products, not one subscription, and that business decision shapes the architecture as much as any technical requirement does:
The platform treats tenant identity and authorization as server-side concerns, connects products through events rather than direct dependencies, and documents its security-sensitive decisions.
The tenant is resolved server-side from the subdomain, and every tenant query is scoped by organization. The browser is never trusted for tenant identity. One login is shared across subdomains.
Authorization comes from the database as permissions plus per-product entitlements, never from hardcoded role names. The frontend only hides things for UX. The server decides.
In practice: organization → enabled product → user permission. A user doesn't gain access just by existing inside an organization.
Product data connects through events using a transactional outbox, processed by a pg-boss background worker. Each cross-product link is optional, so a module works alone and links up when its neighbour is present.
Organization logo upload uses magic-byte sniffing, a server-side re-encode, a private quarantine bucket, rate limits and operator takedown. The design is recorded in an architecture decision record.
Six questions shaped most of the engineering work. Each one turned into a specific decision described below.
Each customer organization gets its own workspace at {name}.bizph.app. No query may ever cross that boundary.
Access depends on what an organization has bought and what a person is allowed to do, not on a fixed list of role names.
CRM, Invoice, Cashflow, HR, Schedule, Tasks, Inventory, Events, Files, Dispatch, Reservations and POS are sold separately, yet they should still connect when a customer has several.
Features such as organization logos accept files from the browser, which cannot be trusted by default.
Peso (₱) invoicing with VAT, Asia/Manila time, and GCash/Maya as accepted payment methods are core behaviour, not settings added later.
About 184k lines of TypeScript across 5 apps and 29 packages had to stay consistent and reviewable.
Bizph is a pnpm and Turborepo monorepo of 5 apps and 29 shared packages, deployed across Vercel, Railway and Supabase. It was built solo with AI assistance.
The public site at bizph.app introduces the product family and the workspace model.
Each organization works at {name}.bizph.app. A custom "operations ledger" design system, built on Ant Design, re-themes the workspace with the organization's brand colour.
A separate internal console for the operator, used for actions such as takedowns.
A GraphQL Yoga API over PostgreSQL through Drizzle ORM (39 migrations), with Supabase for auth, database and storage.
A pg-boss worker processes the transactional outbox for cross-product integration and runs scheduled jobs for expiry, reminders and cleanup.
About 376 test files (254 unit and 122 integration, the integration ones against a real PostgreSQL) and 40 end-to-end specs. A release-gate Playwright suite includes security checks. 12 ADRs and a master architecture document record the decisions.
Tenant identity and authorization are resolved on the server. The frontend only hides things for UX.
Permissions and per-product entitlements live in the database, so access follows what a customer has bought.
Cross-product links are events, and each one is optional, so any module can be sold and used alone.
Decisions are recorded as 12 ADRs, including the logo-upload security design.
Bizph is a solo engineering project. I designed the system, wrote and reviewed the code, and I'm the only person who has worked in the codebase.
AI tools were a development partner throughout — for implementation, exploring approaches, documentation, debugging and iterating quickly on the systems described above. What they didn't do was decide the tenant model, choose what stays isolated versus shared, set the testing strategy, or sign off on what shipped. Those decisions, and the final code that implements them, stayed mine.
Bizph went live at bizph.app on 2026-09-20 and is pre-launch. It has no paying customers yet, so there are no user, revenue or retention figures to report. What exists today is a deployed, tested platform: 12 products, 5 apps and 29 packages behind one login, with wildcard tenant subdomains across Vercel, Railway and Supabase. The repository is private.
The platform side of this is built and tested. The market side hasn't been tested at all — and those are two different kinds of validation. What's still open:
Building this solo meant the architecture decisions had nowhere to hide — whatever shortcut I took, I'd be the one debugging it later. That pushed me toward writing decisions down as ADRs, testing the boundaries that matter most first (tenant isolation, authorization), and keeping products genuinely optional instead of assuming I'd get every dependency right on the first try. The next real test isn't a code review. It's whether a small business picks two products, keeps using them, and asks for a third.