-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Prepared by: Ethan C. Joshua S. Kyler K.
The current world of applied ethics in medicine offers a wide variety of contest on how limited resources should be allocated. Whether it is by the purse of the individual, the amount of dependents, their age and demographic, their likeliness to contribute to society and overall social points, most can agree there isn't a level playing field that makes this choice come easy. That's where Project Alek comes in as a neutral, white-box solution that is random in it's selection.
Project Alek is a mobile app that aims to allow its users to randomly choose individuals from a population, given an amount of limited supply. Built in Flutter and integrated with Firebase as well as a variety of other resources, it allows each allocation run to be verifiable and provable in a reasonably assured manner. It accomplishes all the major goals that were laid out at the start of the project; lightweight, email integration, verifiable results and effectively allocates resources in a random way.
Project Alek was designed with the medical field in mind as Covid-19 has hit the world and scarce amounts of ventilators and other supplies are needed to maintain the health and livelihood of people. This does not mean that it is limited to this application. We designed this application to work under any situation where things need to be distributed in a way where there is no applicable bias. A list is generated with user-inputted names or potentially auto-generated id's. These lists are used to randomly pick an amount of data depending on how much of a resource is available and is then displayed to the user. A PDF with the report data is also automatically generated and sent to whatever email was provided at the start of the application. Firebase is implemented as well and stores a specific hashkey for a run which is displayed to the user at multiple points. This hashkey is unique and insures that a specific run of the data cannot be replicated without having an entirely different hashkey. Local history functionality displays the last runs with the list generated and this hashkey is displayed there as well.
Project arose from the need to fulfill these specifications:
- Lightweight/Mobile
- Random Allocation
- Tamper Evident Results
- Quick to use
- Simple
Given this, we designed an architecture for the process that anonymized the data in the back end, while providing a simple UI to accomplish the single task.
The process starts with a user entering their email, which is saved locally to the device. They can either start a new allocation, look at their history of transactions, change their email in the settings, or look for common questions on the help screen(this function was planned, but not yet implemented).
A transaction takes the amount of supply, the recipients and that's it. Everything else is done in the background. A function request is first sent to the Firebase Functions server, which will respond with a selection list and a timestamp. This timestamp and selection is added to their initial process, and the view will transition to the results screen. The information is then is anonymized with a one-way hash and sent to the database. This information is stored using the provider, and exiting the results screen queues a pdf generator on the local device which will be attached to an email.
The rest of the screens are fairly simple. The history view allows the user to see their previous runs which are stored using the provider. Should they change phones, the data won't transfer, which is why it's important to save those PDFs somewhere safe. The settings screen only changes a single provider variable, so there isn't much to talk about there.
We decided to go with Flutter for this project due to the abilities it provides. Being able to program for the Android, iOS, and experimental Web platforms all at once meant that we could develop an application that could fit any need our sponsor / users would want. This is not without flaws as there are some aspects of it that take away from the personality we could have added if we developed for each separately.
One such issue is the scaling from mobile to web. The web functionality in Flutter is still a bit rough and there was likely a way to customize it to look better, but you can see from this photo that the experience is very stretched out:
Compared to the mobile version shown here:
The plugins used will be explained later, but we essentially used provider states in order to maintain all of the data we needed for this application. The history section of the application uses Shared Preferences to store a list of history models with data from the provider and is then loaded back into the application when the history page is loaded. It is an easy and efficient way to store the data that only goes away when the application is uninstalled. We did things this way because we did not want users to have the ability to delete the history of a run and then run the application again to get different results. The main development challenge of this application is that we wanted to avoid storing as much personal data as possible.
Firebase was an integral tool in this application. We used Firebase Functions to generate a random list derived from set parameters, which allows us to modify it without redeploying the entire app. It also allows us to keep that process off the device, making it more secure from those who would try and alter the results. Anonymous results were then timestamped and sent off to our document based storage with Firestore. We also utilized Firebase configs to store API Keys and other secret information. The client requests these resources before starting their transactions, so an offline use of this application is not possible. Firebase Hosting was also incredibly useful for quick deployment and testing of functionality, when UI was not the most important. It also allowed our sponsor and other users test the Application and find any bugs.
To set up our emailing capability, we used Mailgun as it already had plugin support with Flutter and worked quite well. It's overall usage is quite simple, but does require safe handling of an API key. To be able to send emails to anyone, we were required to provide it with a domain and attach new Hosting documents to it (CNAME, TXT). To do this, we used NameCheap, a popular, cheap and easy to use hosting site. We purchased projalek.com, which currently hosts the web version of the app. This version is generally more up to date since it can be deployed immediately after any changes.
This was the plugin used in order to handle application states. The provider plugin allows us to create a model, a provider, and a state that all work together. A new state is created which contains all of the data for an allocation run. This included the email inserted, the list generated, the history data (loaded and saved from here to the device), and also any data that had to be pulled from Firebase and stored for usage in the history and report. This was used throughout the application to manage stored variables and to update screens so that everything was using the correct state. It is essentially an entire state management tool that works wonderfully for these types of applications.
Joshua, could you add this? Thanks. - Ethan
To use mailgun with flutter, you can use this plugin that greatly simplifies the already existing API options for mailgun.
To encrypt jsons and convert them into a hashkey, we used crypt. It's a neat plugin that does basic functions your computer does for you everyday.
Coming into this, I had no flutter experience, and had only used the Firebase's Firestore in a webapp. I had never attempted to do integrate the amount of resources that we had used in this project before. I felt the best in my role architecting the app and managing the project with zenhub. My flutter abilities have improved from non-existent to doable. I don't know if I can put something together in the same amount of time as Kyle, or make it look half as good, but it'll exist. That was good enough for this application. Using a lot of the lessons learned in professional experience before this course, I was able to set up a strong relationship with our sponsor, answering any questions and being consistent with my updates and expectations. My normal work doesn't deal with a lot of pure development, and I'm glad I got this time to do just that, and do it well.
When we were starting this project I had no experience of how to use any of the applications we decided on. Starting with the language flutter learned quite a bit to be able to code in the language and support our group. I filled in a lot of holes in our group while I may have done less work I believe I grew a lot as a developer. There were many lessons learned through communication and the transfer of knowledge between the team. I was able to learn much from Kyler and Ethan that would have taken much longer. This project taught me a lot of team-based tactics to keep a project moving.
I am currently working as a Software Engineer at a company which is focusing primarily on new Flutter applications. This meant that I had some experience coming into this project and was glad that we decided Flutter would be the best tool for this application. With this in mind, there was a large amount that I did not know and learned through this project.
Firebase was a weakness of mine, and although I was not specifically the person to implement it, I feel as though I now have a better grasp on how the overall structure of it works within Flutter. The same can be said for the PDF service MailGun. I was the one that went through and formatted the send-able PDF in a way that interfaced with the providers that were created and it was the first time I had ever done something like that.
Android deployment is next. The original plan was to release on as many platforms as possible and the app is setup to do so with the exception of a few configuration details for iOS. In the end, we were told that we only really needed to deploy on Android and that is what we did. I have never actually gone through the steps of deployment and this was an absolutely wonderful chance to learn. The application is now available on the Google Play store at the following link:
https://play.google.com/store/apps/details?id=com.projalek.allocation_app
1.2 Avoid Harm The intent and use of this app was set by our sponsor, and so as to avoid harm we stuck to those specifications as closely as possible.
1.4 Be fair and take action not to discriminate. The purpose of our app is purely this. To avoid discrimination, we apply a purely random chance of selection being applied to a pool of individuals selected by the user.
1.6 Respect confidentiality To respect the privacy of our users, we do not take, ask or store any identifiable information, besides an email. This email is only used to send the results to them, and is not stored in our database.
1.7 Honor Confidentiality To honor the privacy of our users, we do not take or store any identifiable information. The contents of their locally saved lists are run through a one-way hash before our database receives them, ensuring that we cannot discern them based on the information.
2.1 Strive to achieve high quality in both the processes and products of professional work. Before changes can be pushed to our end product, we require it to go through a testing phase where another developer must test it locally, and approve it.
2.3 Know and respect existing rules pertaining to professional work. To ensure the progress of our work, we developed with an AGILE mindset in mind. This comes with all it's requirements and rules. While it was strange at first, we quickly adapted and implemented it with great effect.
2.9 Design and implement systems that are robustly and usably secure In consideration of our specifications and needs around privacy, we first designed an architecture that can answer the problems posed; namely we foresaw that allocation results should be verifiable without storing personal information and designed a solution around that.
3.4 Articulate, apply, and support policies and processes that reflect the principles of the Code. At every point of decision we made an effort to prioritize security and confidentiality.
3.5 Create opportunities for members of the organization or group to grow as professionals. Through multiple meetings we set up a strong relationship with our sponsor, ending with a possible extension of future work and consultancies. Beyond the scope of our project we were able gain valuable experience by offering advice on how to search for talent and continuing the work we started.
3.7 Recognize and take special care of systems that become integrated into the infrastructure of society. We understand that the implications this software can have on society, that based on the random allocation some could live and others could die. Our main responsibility was to insure that this system does not promise a solution while being vulnerable to low skill attacks. This necessitated the need for results that are verifiable, traceable and tamper evident, such that a grieving party could know and understand how the choice was made, as cruel as it may be.
Our team has been absolutely wonderful as a whole. There were some sprints that could have gone much better and there were sprints that were absolutely amazing. I believe that everyone was able to work together in a way that benefited everyone and the communication through Discord, Slack, and other means went over very well. We were able to check pull requests and fix issues in a minimal amount of time while keeping a professional standard that we wanted to maintain.
Project Alek has been a wonderful project to work on as a whole. The entirety of the team is coming out of this with more knowledge about a popular programming language than ever before and we feel that we have made something that can be incredibly useful given time. This application was created to fill a gap between randomization and validation. There were many applications out there that provide randomized selections of data but none of them had a way to truly verify that the application was run in a fair and verifiable way. There are many improvements that could still be made but we feel that we have provided the absolute best application we could given the time available to us.
We had some sicknesses / other personal matters that drove our development ability down quite a bit. This was partially countered by the sheer amount of work we all did early but it was still a challenge towards the end of the development cycle.
Another challenge we had was the overall challenge of learning Flutter. Now that we have worked on this application for awhile there are some aspects of the application that definitely could have been done in a way that would have been even better than it already is. This includes things that were coded in an overly complicated way when it really didn't need to be. It caused some issues with widgets resizing properly / aligning with what the design was supposed to be.
- This project has a lot of integrated services that require maintenance to some degree. The current area of biggest concern is that the Firebase rules need to be updated to only allow read and writes of a certain type.
- The Firestore is currently used for write-only. While it possible to search it for transactions, it's increasingly tedious to do so. Some work will be required to either generate a better naming scheme, or make a tool for searching the documents based on their contents.
- Communicate and start early. You can't start early enough. - E.C.
- Plugins plugins plugins. Don't reinvent the wheel. - E.C.
- Break down your tasks into the simplest components. Going to integrate a plugin? Add it to your dependencies, try and run it. Find it's simplest function and try and implement, even if that's not what you were intending to use it for. - E.C.
- If you're not sure how to work with the team, start by doing the things nobody else wants to do. It's not always much, but they'll really appreciate you. This works for things that are not coding too. - E.C.