- Problem
- A building permit is a chain of custody: an applicant submits, a ward verifies, an engineer reviews, a municipality approves — each step binding, each step contestable later. The software has to prove who did what, hold up against the Government Enterprise Architecture 2.0 review, and exchange data with systems built by other vendors.
- What I owned
- Application features and backend services inside the engineering team: data models, Laravel services, RESTful APIs consumed by internal and external systems, SQL and query performance work, and defect triage on live municipal deployments. name the specific modules — permit intake? plan approval? reporting?
- How it works
- Every application is a state machine rather than a status column, so an approval can only follow a verification. Role-based access is checked at the service layer, state transitions are written with the record in one transaction, and the integration surface is a versioned REST contract rather than direct database access by other vendors.
- Tradeoffs
- Modelling permits as explicit state machines cost more up front than a status field and made ad-hoc change requests slower to land. It paid for itself the first time somebody asked who approved a permit eleven months earlier.
- Outcome
- Systems running in municipal use. add the number you can defend: municipalities or wards live, permits processed, or “passed GEA 2.0 review”
- Laravel
- PHP
- PostgreSQL
- MySQL
- REST
- RBAC
- GEA 2.0
Government deployments — not publicly linkable. Happy to walk through the architecture in a call.