Coursework
BINCOL Online Commercial Waste Collection System — Development Lead, Vertex IT Solutions (Team MEL-14)
Final-semester capstone: booking and scheduling for a commercial waste collection service.

Project overview
BINCOL is a commercial waste collection business serving cafés, restaurants, retail stores and light-industrial sites. Its customer base had grown from roughly 40 to over 130 accounts in two years, but bookings were still taken by phone and email, tracked in a shared spreadsheet, and dispatched to drivers as printed run sheets. The result was double-booked trucks, missed pickups, month-end invoicing rebuilt by hand, and no auditable record for a business holding ABNs, site addresses and payment data under the Australian Privacy Act.
Our team delivered a full software requirements specification and working system covering 54 functional and 15 non-functional requirements across eleven modules — customer self-service booking, waste category and bin management, scheduling, driver and truck assignment, route planning, invoicing and payments, notifications, reporting and feedback.
My contribution
I was the Development Lead and Technical Lead on a five-person team. In practice that meant four things: I decided how the system would be built, I originated the ideas that made it more than a digitised paper process, I built and connected the parts everything else depended on, and I assembled four people's work into one running system.
Technical architecture
The system is written in hand-rolled PHP MVC with no framework. That was a deliberate decision I made and defended. A framework would have been faster, but it would have hidden the architecture inside someone else's conventions — and the project had an explicit requirement to demonstrate MVC separation. Building it by hand meant the model, view and controller boundaries were mine to define, visible in the folder structure, and provable to a supervisor. I set the project structure, the naming conventions and the coding standards the other four developers built into.
Originating the system's differentiating features
Every feature that takes this system beyond the original client brief came from me. The client specified 49 requirements describing a booking system. I proposed the five that make it a different product — QR bin scanning, the onboarding service designer, exception-only approval, at-risk account alerts and the missed-collection predictor — along with the governing rule for when automation is allowed to act without a human. These became FR50 to FR54 in the final requirements. They weren't features anyone asked for; they came from reading the client's actual operational problem and asking what the brief had left on the table.
Database design
Twenty entities, fifty relationships, implementation-level ERD in crow's-foot notation with full cardinality and participation constraints. I applied two rules without exception: every many-to-many relationship resolved through a bridge entity, no shortcuts anywhere in the model; and every one of the fifty relationships had to be traceable to a real screen or system action. That second rule was mine, and it was the most useful discipline on the project — it stopped the model growing relationships that felt sensible in the abstract but had nothing behind them.
Connecting the frontend to the database
I built the layer where the interface meets the data — wiring every form, dashboard, table and status view to the models behind them. All database access goes through PDO with prepared statements and transactions, which gives injection protection and transactional integrity in the same design decision. That matters most on the booking → assignment → invoice → payment chain, where a half-completed write would leave a customer billed for a collection that never happened. This was the work that turned a set of static pages and an empty schema into a system that actually did something.
Integrating the team's work into one codebase
Four other developers were building separate modules in parallel, and the project ran without version control. I was responsible for collecting everyone's code, resolving the conflicts between how each person had structured their work, bringing it into line with the project's MVC conventions, and assembling it into a single running application. In practice this meant reconciling inconsistent naming, duplicated logic and mismatched database calls — then making sure the merged result still worked end to end. Doing this without Git meant it had to be done carefully and by hand, enforced by strict file ownership: each member edited only their allocated files, and anything touching another member's area was raised rather than changed silently.
Security implementation
bcrypt password hashing through password_hash(). CSRF tokens, input validation and output sanitisation against injection and XSS. Most importantly, role-scoped queries enforced at the join level rather than the table level — so a customer's query cannot return another customer's branches or invoices even through a join, and a driver sees collection addresses and job notes but never billing data. Payment integration stores only a transaction reference token; no card data enters the application.
Requirement traceability
I maintained the Software Requirements Traceability Matrix mapping each of the 54 requirements to the exact component implementing it, in ClassName::method() format — controller methods for user-triggered actions, model or service methods for system-triggered ones. Component names stayed identical across the requirements tables, every diagram and the matrix, so any requirement could be followed from specification, to the file and method implementing it, to the test case verifying it.
Code review
Nothing entered the build without passing MVC conformity, input validation and query scoping. As the person assembling the final codebase, I was the last check before any teammate's work became part of the system.
Automated testing
End-to-end automation with Playwright across five critical flows: registration and verification, booking creation, staff approval and assignment, driver status update, and invoice payment. I chose five rather than full coverage deliberately — with a fixed deadline, five flows tested properly beat thirty tested badly.
Showcase video
I produced the project's showcase video, scripting and recording a walkthrough of the complete system across all four user roles — customer booking, staff approval and assignment, driver collection, and administrator reporting. Turning a twelve-week build into a few minutes a non-technical viewer can follow is its own problem: it forces you to find the single thread through the system that makes the whole thing make sense, and to cut everything that doesn't serve it.
Features I designed
Most capstone projects stop at putting an existing paper process onto a screen. These five go further, and all five were my proposals.
QR bin scan instant pickup. Each bin carries a QR sticker tied to its storage location. A customer scans it and the booking form opens pre-filled with that site's address, bin type and waste category. It removes the most error-prone step in the whole flow: a customer with six branches picking the wrong one.
Onboarding service designer. A new customer describes their business in plain English, and the system proposes a bin size, waste category and collection frequency. A decision that previously required a phone call with an experienced staff member becomes a self-service step.
Exception-only booking approval. Instead of staff approving every request, routine bookings inside admin-defined thresholds are approved automatically, and only exceptions are queued for human review: unusual volumes, hazardous categories, new accounts, short-notice dates. Staff judgement goes to the small share of requests that need it.
At-risk account alert. A weekly brief flagging accounts with falling volume, unresolved complaints or late payment, so a customer about to leave is identified while something can still be done.
Missed-collection predictor. Next-day jobs scored for failure risk from each site's access history, so a repeatedly inaccessible site is flagged before the truck is dispatched rather than after a wasted trip.
The rule I set for all five: human confirmation is required only for automated outputs that create a record, cost money, or leave the system. A score, flag or suggestion needs no gate — it's information for a person to act on. An invoice, a booking, an outbound email does.
Think of a hospital monitor versus a prescription. The monitor beeping is information; nobody signs for it, and you'd be furious if they had to. The prescription is an action with consequences, so a human name goes on it. Both are useful; only one needs a signature. Writing that line down explicitly is what stops an automated feature from either being buried under pointless approval clicks or quietly doing something expensive and irreversible on its own.
Technical stack
The system is built on a hand-rolled PHP MVC architecture with Composer for dependency management, running on Apache through a XAMPP development environment. Data is stored in MariaDB and accessed exclusively through PDO with prepared statements and transactions, giving injection protection and transactional integrity across the booking-to-invoice chain in a single design decision. The frontend uses Bootstrap 5.3.3 with Bootstrap Icons and the Inter typeface, fully responsive across desktop, tablet and mobile browsers and built to WCAG 2.1 AA accessibility standards. The five intelligent features are powered by [your answer here]. Mapping and route display run on Leaflet with OpenStreetMap, payments through Stripe and PayPal in sandbox mode, and transactional email over SMTP. End-to-end testing is automated with Playwright across the five critical user flows. Interface design was produced in Balsamiq Cloud, with all system diagrams — context, data flow, use case, sequence and ERD — drawn in draw.io.
What I learned
Constraints are design decisions in disguise. No framework, no Git, a fixed twelve weeks, a team with uneven experience. Early on these felt like things working against the project. By the end I understood they were the brief. Hand-rolled MVC, five Playwright flows instead of full coverage, and strict file ownership instead of branching were all answers to those constraints — and each was defensible precisely because it was shaped by them.
A model is only as good as what it can point to. My rule that every relationship must trace to a screen or an action started as a completeness check and became the most valuable thing I did. It's easy to add a foreign key because it seems reasonable. Being forced to name the user action it serves exposed several that served nothing.
Security is a query-shape problem, not a feature. I started thinking of security as things you add — hashing, tokens, validation. What actually mattered was the shape of every query: scoping at the join level so an unscoped result is impossible to write by accident. Protections you bolt on sit at the edges; the protection built into how data is retrieved is the one that holds.
Integration is where a group project is won or lost. Four people writing working code does not produce a working system. Assembling it — reconciling naming, duplicated logic and mismatched database calls by hand, without version control — taught me that conventions set on day one save days in week eleven, and that the person who merges the work needs authority over the standards everyone writes to.
Automation needs a boundary, not an on-switch. The hardest thinking wasn't making a feature work — it was deciding where a human must stand in the loop. The record/money/leaves-the-system rule took several iterations to arrive at, and it's the thinking I'd carry to any future project.
Scope discipline is a technical skill. Learning to say something was out of scope and leave it out — rather than quietly building it because it was interesting — was harder than any code I wrote. Equally, learning that submitted work was locked, so problems found later became forward-looking recommendations rather than retroactive edits.
Get the framework right before the detail. We initially reasoned about privacy using the wrong legal framework and had to rebuild that work around the Australian Privacy Principles and the OAIC. Checking which rules apply costs an hour; discovering it late costs a section.
Skills demonstrated
Full-stack web development · relational database design and normalisation · MVC architecture · frontend-to-database integration · multi-developer code integration · secure coding (OWASP) · API integration · feature ideation and product thinking · automation design with human-in-the-loop safeguards · requirements traceability · automated testing · Agile Scrum delivery · privacy and compliance (Australian Privacy Principles, DPIA) · technical leadership and code review · technical communication and video production