Paul

Software Developer and Consultant

Scavenger Hunt Administration App

I was contacted by Midnight Illusions Ltd. of Guelph, Ontario, to build an administration interface for the Dux Augmented Reality Scavenger Hunt Android / iOS App they developed for the City of Guelph, Ontario.


The Scavenger Hunt Administration App provides Dux users with the ability to log in and create new scavenger hunts with four locations in the city and four clues. Once published, the scavenger hunt is available to users of the Dux App.


Login Page
Project Requirements
Build an administration interface to allow the Scavenger Hunt Creator to upload an image that will be divided into four puzzle pieces placed onto a Google Map of the city. The Hunt Creator will enter the address of each location as well as details for the participants. Participants will then use the Dux Augmented Reality app to access the hunt and travel to each location to find clues about the whereabouts of the next puzzle piece.

To satisfy the requirements of my client, I had to source and integrate several different backend and frontend technologies.


Back-end Tech Talk


For the backend, I used Laravel, a very popular and well-known PHP platform. While programming the backend, I made a special effort to conform to SOLID Design Principles and encapsulated important image manipulation functions in their own service files. For example, an `ImageSpiceService` was created in the backend, so when a user uploaded an image for the scavenger hunt, it would be automatically cut into four pieces via the service I programmed and served to the frontend as clues, which would be placed on the map.


Hunt Step 1

Front-end Tech Talk


Several frontend JavaScript libraries and custom coding were used to provide the necessary administration interface and Scavenger Hunt Builder. To build the administration interface, I used Backpack for Laravel and utilized Laravel's Blade templating engine for the multi-step forms.


Form Validation


All frontend form validation was achieved using jQuery Validation. This jQuery plugin makes simple client-side form validation easy, while still offering plenty of customization options. It was a good choice since we were building the Scavenger Hunt App from scratch.


Image Cropping and Uploading


The image cropping functionality was a crucial part of the Scavenger Hunt App. After exploring several options, I chose to use Croppie.js for its flexibility and speed. Croppie.js is a powerful JavaScript component that allows users to crop images with ease. When a user uploads an image, it's displayed in a modal where Croppie is instantiated to provide the cropping interface.


Hotel Demo App

The app also incorporates Dropzone.js for handling image uploads. Dropzone is a JavaScript library that makes it simple to drag and drop files onto an upload area or select them through a file dialog. This functionality is encapsulated in a custom Blade component called `x-dropzone-image-upload`. When an image is dropped or selected, it gets uploaded to the server, and Croppie is used to crop the image within a modal. The cropped image data is then saved in a hidden field and submitted to the server when the form is saved.


Other Frontend Technologies Used


The front end of the Scavenger Hunt module uses several JavaScript and CSS libraries to achieve the desired behavior. Some of the key libraries used are:


One of the key functions is `createDropzone`, which provides functionality for the 'browse' button in the Dropzone image upload component. When an image is uploaded, it is displayed in a modal where Croppie is instantiated to provide cropping functionality. Once the user crops the image, the cropped data is stored in a hidden field and submitted when the form is saved.


API Endpoints


As well as providing an administration interface for the Scavenger Hunt, I also had to serve the data to my client's iPhone and Android App. This required the construction of several API endpoints which his app could connect with to retrieve the Scavenger Hunt data. I had previously accumulated 1800 hours in backend Laravel development while working at Vista Projects Ltd., so this was not an issue. Postman was used to manually test each endpoint, as well as automated unit tests which I also created.


Testing the App


Testing was an integral part of the development process. I used Postman to manually test the API endpoints and ensure that they were working correctly and returning the expected data. This helped in catching any errors early in the development phase.


In addition to manual testing, I implemented backend unit tests. A unit test is a type of software testing where individual units or components of the software are tested in isolation. The purpose of a unit test is to validate that each unit of the software performs as expected. By writing unit tests for key functionalities, I was able to verify the correctness of the code and prevent regressions as new features were added or existing ones were modified.


These unit tests, alongside the manual tests with Postman, ensured the reliability and stability of the application before it was deployed.


Server Setup and Version Control


To deploy the Scavenger Hunt App, I used an Ubuntu server accessed through SSH. The app was hosted on an Apache2 web server, which was configured to serve the app in a subfolder of the main domain.

I used symbolic links to set up the app directory so that it could be accessed seamlessly from a subfolder. This approach allows the Scavenger Hunt app Administration Interface to operate under a sub-directory of the main site, making it easily accessible while keeping the URL structure organized.

For version control, I used Git to manage the code repository. Git is a distributed version control system that allows multiple developers to work on a project simultaneously, track changes, and collaborate efficiently.


Development Workflow


I followed a structured development workflow using Git branches to ensure code quality and maintainability:

  • Main Branch (typically called main or master):
    • This is the primary branch where the source code is always in a deployable state.
    • Only thoroughly tested and stable code is merged into this branch.
    • Releases are typically tagged in this branch.
  • Staging Branch (also known as develop):
    • This branch acts as an integration branch for features and is used to accumulate code that will eventually go into the main branch.
    • New features, bug fixes, and other updates are merged into this branch from their respective feature branches.
    • Before merging into the main branch, the code in the staging branch is typically tested in a staging environment to ensure stability.
  • Feature Branches:
    • These are short-lived branches created from the staging branch.
    • Each feature branch is dedicated to developing a specific feature or fix.
    • Once a feature is complete, it is merged back into the staging branch, where it undergoes integration testing.
    • Feature branches are usually named descriptively, such as feature/xyz-feature, bugfix/xyz-bug, etc.

Workflow:

  • Developers create a new feature branch from the staging branch.
  • They work on the feature in isolation, committing changes as they go.
  • Once the feature is complete and tested, it's merged back into the staging branch.
  • The staging branch is tested, and if everything is stable, it’s then merged into the main branch for deployment.


Benefits:

  • Isolation of Features: Features are developed independently, which helps avoid conflicts and makes it easier to manage different pieces of work.
  • Controlled Releases: The main branch is always stable and ready for release, while the staging branch allows for integration and testing of features before they reach production.
  • Collaborative Development: Multiple developers can work on different features simultaneously without interfering with each other's work.


This strategy is very effective in environments where multiple features or bug fixes are being developed simultaneously and where the stability of the main branch is critical.