PropertyOS
A multi-tenant rental management SaaS — built solo, end to end, from the access model to the deploy pipeline.
ReactRTK QueryNode.jsExpressPostgreSQLRedisAwilixZodVitest
- Three separate actor domains — platform operator, landlord, landlord admin — each with its own JWT secret, middleware chain and blast radius.
- No public registration endpoint anywhere: every account is provisioned from the inside, which makes the access model the security model.
- Sessions built to survive a reload and a breach: hashed refresh tokens, rotated on every use, in httpOnly cookies, mirrored into Redis so they can be revoked server-side.
- TOTP multi-factor auth with mfa-pending token gating, password expiry policy and double-submit CSRF protection.
- Support impersonation designed as a reusable pattern — a generic target_type/target_id audit trail, so adding a second impersonation target is additive rather than a rewrite.
- Tenant isolation enforced at the query layer: a cross-tenant read returns 404, never 403, so probing IDs reveals nothing about what exists.
- Unit schemas defined as data by the operator, not hardcoded per property type — new property types onboard without a migration or a new form component.
- Repository → Service → Controller under Awilix dependency injection, 24 versioned migrations, and a GitHub Actions pipeline running Vitest and Supertest against a fresh database.
Written about this project
- Architecture · 1 minWhy I added dependency injection to a project only I would ever touch
- Architecture · Part 1 · 6 minThe SaaS platform with no sign-up form
- Security · Part 2 · 5 minThe property list that returns 404 instead of 403
- Security · Part 3 · 9 minBorrowing an identity safely: how HQLead impersonation works
- Security · Part 4 · 8 minThe bugs that only show up under load
- Architecture · Part 5 · 5 minA form that doesn't know what it's asking
- Security · Part 6 · 6 minThe session that a reload used to erase