Cityfarm Manager
Context
In my second year at university, we were split into teams of five and assigned real projects from real clients to work on over six months. This came complete with real requirements, real client meetings, and a real handover. During this project I learned a lot about working in a team towards a deadline and on a project where the client was someone other than myself.
The Brief
Windmill Hill City Farm is a charity-run city farm and as such does not have the budget or the requirements of a larger scale commercial farm. The farm manager approached the uni needing a system to keep track of their animals, enclosures, and the tasks associated with them.
The System
You can use a demo installation of the system here.
The system uses a pretty simple tech stack:
- React/Typescript on the front end
- Java/Spring on the back end
- MongoDB
What I worked on
Backend
I wrote most of the backend, which consisted of a pretty standard CRUD REST API. I got it up to a point where it met all of our initial requirements pretty quickly and moved over to the front-end.
Frontend
When I moved over to help the rest of the team on the front-end I realised that they were using plain Javascript and none of the pages were split into components or had any code re-use between them.
They were also using plain HTML/CSS and some disparate libraries for things like modals and date pickers. I moved everything over to Mui for consistency.
I then moved everything over to Typescript and split out the pages into smaller, more manageable components.
Additionally, I wrote a wrapper library that handled all the API calls to the backend, using custom types for our business logic.
Deployment & CI/CD
I setup a CI pipeline which checked each pull request to ensure that it would compile and pass our tests.
I also setup a CD pipeline which would build Docker containers of each component and deploy them to an Azure Container App. Pretty quickly this reached our $100 budget limit because serverless pricing is currently ridiculous.
So instead I just moved it over to my home-server and wrote my own webhook handler that would re-deploy the Docker Compose stack whenever a pull request was merged.
Problems I faced
Technical Planning
None of my other team members had any experience with any sort of web development. I left them to work on the front end while I did back end which meant that when I moved to front end I had to make a lot of changes.
This obviously wasn’t their fault and I should’ve realised they wouldn’t magically know how to make these decisions themselves and should’ve helped them make these decisions upfront.
Backend Rewrite
Initially, we wrote everything to be very object-oriented. Classes for each type of animal, with specific fields for each of their properties. About half-way through the project I realised this gave the client no ability to add new animal types without someone writing new code (our client was very non-technical so it certainly wouldn’t be him). This meant I had to pretty much completely rewrite the backend.
I designed a new system which used user-definable “Schemas” which could have any number of fields and any associated type. The API could then handle requests for objects of these custom types.
I even wrote a validator to check that the data being sent to the API matched the schema. This was a lot of upfront work but results in amazing flexibility for the client.