Problem: While the current myMilton website provides a portal for easy access to a variety of student data, the platform proves difficult to navigate on mobile devices. As students rely more and more on their phones, creating a stable mobile app to access data on myMilton will prove increasingly important to the fast-paced flow of the school.
Solution: Create a mobile app as a standin for myMilton where students can access schedules, attendance records, and announcements (as next year the schedule will not include assembly).
UI: We used flutter for the UI and developed it using the BLoC pattern architecture to create a sustainable, scalable multiplatform program that others could use. The interface provided intuitive color codes and animation to present to the user easily digestible information. We went for a vibrant color scheme to give the application a more modern feel. On the left, we have a demonstration of the different main screens of our design. Currently, we don't have access to every student's data, so in the video you will see only Aaron Lockhart existing. Note: the colorspace on mobile differs from the colorspace on computers, so some colors may look pasty or weird here.
Infrastructure: We wanted to ensure our deployment infrastructure was robust and horizontally scalable. In order to accomplish this, we used Docker and AWS. Docker allows our backend to be hosted and provisioned on any hardware in seconds, and AWS provides the high availability and performance characteristics necessary for a capable production environment.
Within AWS we utilized several services to speed up and automate the deployment process. We created CloudFormation templates so that our application's infrastructure can be deployed to any AWS environment in minutes, automating the creation of networking services like VPCs and ALBs along with their necessary networks and gateways, as well as our deployment pipeline, which utilizes ECR, CodePipeline, and CodeBuild to monitor for changes on the production branch of our GitHub repository (origin/master), rebuild our app's Docker image and upload it to the Elastic Container Registry, convert our app's docker-compose file to a separate CloudFormation template consisting of the necessary ECS containers provisioned by Fargate, and deploy this template in the form of a Change Set, which can be manually reviewed or automatically deployed to a sub-stack of our main CloudFormation, ultimately spawning the necessary containers and merging them with our existing network infrastructure across two availability zones. Though it may sound complicated, this process greatly simplifies the portability of our application while decreasing downtime and streamlining deployment.
Development: Another one of our goals for this project was to maintain clean, organized code, while adhering to as many best practices as we could.
The first step we took to ensure code cleanliness and development efficiency was to establish a GitHub branch structure. The master branch (GitHub's default branch) is our stable branch, designed to hold thoroughly tested code read for deployment into production. The dev branch is our main working branch. This is where sub-branches used for development, feature branches and bug-fix branches, are branched from and merged into. Each feature branch is assigned to a specific feature, while each bug-fix branch is assigned to a specific bug. Bug-fix branches usually last a single deployment cycle, while feature branches may span multiple. Hotfix branches are branched from and merged into master, as they are assigned issues that must be immediately addressed, else the production environment be left in an undesirable state.
The second step we took is to ensure that clear application structure is upheld. We split the backend into multiple parts, each represented by a subfolder under ./src: services, models, controllers, middlewares, and routers.
Services handle connections to external applications, commonly databases or identity providers. Models directly interact with data sources. They are often between the controllers and the database.
Models provide a level of abstraction that insures homogenous, organized data; in TypeScript, they define both the database schema and the TypeScript interface.
Controllers ultimately handle the request, and should definitively return the appropriate response status. Controllers handle data flow to and from the resource to which it is assigned. There is generally one controller for each endpoint.
Middlewares are useful for executing tasks external to the request's primary objective. They often handle things anywhere from authentication and authorization to logging to external sources to push notifications. Whereas controllers are often assigned only to a single route, middlewares are often used multiple times, as they generally perform non-request-specific actions. Middlewares are often shared between endpoints, as they usually perform general, user-oriented tasks.
Routers define the ExpressJS endpoints, as well as their middlewares and controllers.
Next Steps: We hope to continue developing this app. In the limited time for senior projects we had, we aimed for quality over quantity. We wanted to establish a robust deployment and development infrastructure and to code with best practices and cleanliness in mind over hastily throwing together a large number of raw features. We believe this decision is both the most educational for us in terms of preparing us for the real world and the best way to assist the future Milton students who we hope will continue to develop this app. This does, however, leave features somewhat basic for now. Realtime communication, customizable push notifications and alerts, and automatic scheduling between students are all features we found infeasible to implement in the allotted time frame. We have established a sturdy structure, from which we can branch and grow. Our goal was to leave an app that could be improved and expanded upon even after our time at Milton by new students interested in computer science, and we hope others will come up with newer, better ideas for features that would increase the apps functionality and usability. Most importantly, we still have to work with ATS to figure out streamlining the student data of all students to our backend so that we can integrate the project with student profiles from the whole school.