Computers For Schools Manitoba • Shipped 2020
Operations Platform
Replaced an aging Microsoft Access database with one Laravel app for donations, inventory, warehousing, orders, RMAs, and recycling. Over 100,000 inventory records, thousands of orders, and still running the organization today.
- Role
- Sole developer, built from scratch
- Timeline
- Built Aug 2020 – Jun 2022, supported on contract to Aug 2024, still in use today
- Team
- Solo, with the Executive Director and warehouse, refurbishment, and admin staff
- Stack
- Laravel 8, MySQL, mPDF
Context
Computers For Schools Manitoba takes in donated computers, refurbishes them, and gets them into schools and community organizations. When I started in 2020, all of that ran through an old Microsoft Access database that could hardly be updated anymore.
This was my first real project. I started with a plain PHP app to replace it, but after learning so much about application security I had realized I need a proper framework, which gave me my first taste of Laravel. The Executive Director saw what it could do, and it grew into a full Laravel app used across every Manitoba location.

Problem
Ten operational areas, each with its own workflow and its own people.
- Donation intake and donor records
- Asset tracking for donated equipment, with custom material attributes and subtypes
- Stock transfers between locations, with a full history for chain of custody
- Client records, orders, tax and payment handling, and order assignment
- RMAs and returns
- Received shipments and recycling loads, with regulatory reporting
The people doing the work needed to see just their part. Leadership needed reporting across all of it.
Approach
- Laravel 8
- MySQL
- Blade
- mPDF
Built with the people using it. I got requirements straight from the Executive Director and the warehouse, refurb, and admin staff. Each department's workflow was modelled with the people who actually did that work, and then I kept adjusting as they used it.
Asset tracking. Every piece of donated equipment has custom attributes and subtypes. Stock transfers and a full audit trail give a chain of custody for each item.


Orders. Client records, tax and payments, order assignment, file attachments, CSV bulk import, and PDF invoices with mPDF.

Access. A role and permission layer I wrote from scratch, so admins, supervisors, and floor staff each only see the modules that matter to them.
RMAs and recycling. Returns go through their own RMA flow. Received shipments get logged as a whole, then broken down item by item, so one shipment of recycled equipment can have hundreds of entries and still trace back to where it came from.

Reporting and feedback. Quarterly and annual dashboards, plus an in-app issue reporter so staff could flag problems without leaving the system.
Hosting. It ran on a Windows Server on site. I wrote batch scripts to back up MySQL every day and pull new versions whenever I pushed them.
Scale
The last time I had to dig into the backend, this is roughly what it was holding.
| Inventory records | 100,000+ |
| Orders, RMAs, and received shipments | Thousands |
| Recycled equipment entries per shipment | Hundreds |
| Database tables | 46 |
| Controllers | 41 |
| Views | 100+ |
| Operational areas | 10 |
| Commits | 471 |
Outcome
It became the system the organization runs on for donations, inventory, warehousing, orders, returns, and recycling, and it passed 100,000 records while I was there. After I moved to my next job I kept supporting it on contract until August 2024, shipping new reports and dashboard tweaks whenever they needed them. It's still what they run on today.