Final Project


Team Contract


Project Pitch


MIT Munchies

Problem Definition

In terms of MIT Munchies’ problem definition, I agree that fast fashion is an important and pressing issue to fix in our world. I also agree with the fact that fast fashion has serious environmental and social consequences. However, I wonder whether MIT Munchies could be more specific in the fast fashion problem they are trying to solve. For example, there are currently many sustainable brands available out there (one can just Google “sustainable brands”), so why aren’t consumers using them? Perhaps there’s a problem with cost accessibility in sustainable fashion that hints at an important, underlying problem. Another direction the problem definition could go is how to best help and uplift workers in the fast fashion industry. For example, what kind of autonomy and protections do these workers have? How could you create something that both empowers them to speak against injustice while protecting their identities? One last suggestion could be about reducing the environmental impact of fast fashion: is there anything out there that creates a profitable and more sustainable solution to this waste?

Advertised Marketplace

For this first idea, the overall operational principle and purpose seem easy to understand. One thing I wasn’t clear on was the “save stores” and the relationship to “my closet”: are these saved stores saved because a user bought items in that specific category from that store, or is it just a way of helping the user organize sustainable brand stores by category? If it’s the later category, why not just organize sustainable brand stores by category on the marketplace?

I’m a bit worried how this concept is meant to differentiate itself from Depop, SimpleSwitch, Wearwell, and other sustainable online clothing marketplaces that aim to sell new or used clothing, as well as provide users with filters such as price, sustainable impact, item, brand, etc.

Perhaps, something cool that you could do with this idea is think about how a platform like this could break down cost accessibility issues for users dependant on fast fashion, such as a clothing swap platform.

Shoppers Take Action

For this second idea, I again believe the overall operational principle and purpose seem easy to understand. I really liked the concept of a “learn” page – I think its hard for users to get into and understand sustainability, so I love the idea of educating them on better practices. On another note, I wonder how this app distinguishes itself from Change.org, which allows users to also create and browse petitions. I do see unlike Change.org, Shoppers Take Action has a post concept, but I’m not sure how posts would benefit this app in comparison to petitions, which can contain the same information as a post.

Perhaps, something cool that you could do with this idea is think about how the platform might change (and perhaps be more impactful) if it aimed to uplift factory workers (workers take action?), who have first hand experience on the working conditions and environmental impacts fast fashion factories have.

Donation Coordination

For this third idea, I again believe the overall operational principle and purpose seem easy to understand. I really liked the way this platform coordinates donators and donation receivers. On that note, it might be important to flesh out the difference between a donator and donation receiver – how would the platform look for these two kinds of entities? How will you verify accounts that qualify as donation receivers (or risk random people creating donation drives for their own personal gain)? Also, to incentivize users to donate on the platform, it might be cool to automate the process of receiving tax writeoffs from donating to organizations.

Final Thoughts

I think MIT Munchies’ overall goal to addressing the fast fashion problem is a refreshing and unique idea amongst all the other project groups. I’m excited to see what’s to come!


Final Project Pitch

At Health Portrait, we want to help you in your healthy aging journey.

Keep all your insurance information, important medical contacts, and prescriptions in one place on our app, so you never have to worry about them being misplaced. Take note of how you’re feeling day to day - whether you’re developing an odd pain in your joint, starting a new medication, or actually just having a great time. Our data visualizations also help you get a clear sense of how your health is performing, so you can keep a record of developing trends and let your caregivers or doctors know if something deserves more attention.

Our easy-to-use interface provides an intuitive way for you to maintain a portrait of your health. However, if you need a little help getting started, let people who care about you help you stay healthy! With the shared accounts system on Health Portrait, your loved ones or other caregivers can easily upload important information for you to set up your account, or even help you record how you’re doing when you want a day off from all the technology.

Start maintaining your Health Portrait today and let our app aid you in aging healthily.

Conceptual Design


    concept shared-account
    purpose allow multiple principals to access the same account data
    state
        name: Account -> one String
        account: Credential -> one Account
        username: Credential -> one String
        password: Credential -> one String
        session: Credential -> lone Session
    actions
        registerAccount(n: String, u: String, p: String): one Session
            new a: Account
            a.name = n
            addCredential(u, p)
            return login(u, p)
        getAccount(s: Session): one Account
            return s.~session.account
        changeName(s: Session, n: String)
            a: Account = s.~session.account
            a.name = n
        deleteAccount(s: Session)
            a: Account = s.~session.account
            delete a.~account
            delete a
        addCredential(s: Session, u: String, p: String)
            when u.~username == null
            new c: Credential
            c.account = s.~session.account
            c.username = u
            c.password = p
        changePassword(s: Session, p: String)
            c: Credential = s.~session
            c.password = p
        removeCredential(s: Session, u: String)
            c: Credential = u.~username
            when c.account == s.~session.account
            delete c
        login(u: String, p: String): one Session
            c: Credential = u.~username
            when c.password == p and c.session == null
            new s: Session
            c.session = s
            return s
        logout(s: Session)
            c: Credential = s.~session
            c.session = null
    operational principle
        after registerAccount(n, u, p) -> s
            and addCredential(s, u', p')
            and login(u', p') -> s'
            and addCredentials(s', u'', p'')
            and login(u'', p'') -> s''
        then s.~account == s'.~account == s''.~account
        after registerAccount(n, u, p) -> s
            and addCredential(s, u', p')
            and login(u', p') -> s'
            and addCredentials(s', u'', p'')
            and removeCredentials(s, u'', p'')
        then login(u'', p'') fails

    concept insurance-card [User]
    purpose track information about personal medical insurance
    state
        owner: Card -> one User
        subscriber_name: Card -> one String
        member_id: Card -> one String
        group_number: Card -> one String
        plan_number: Card -> one String
        plan_type: Card -> one String
        purpose: Card -> one String
        notes: Card -> one String
    actions
        addCard(u: User, sn: String, mi: String, gn: String, pn: String, pt: String, p: String, ns: String): one Card
            new c: Card
            c.owner = u
            c.subscriber_name = sn
            c.member_id = mi
            c.group_number = gn
            c.plan_number = pn
            c.plan_type = pt
            c.purpose = p
            c.notes = ns
            return c
        getUserCards(u: User): set Card
            return u.~owner
        setSubscriberName(c: Card, sn: String)
            c.subscriber_name = sn
        setMemberId(c: Card, mi: String)
            c.member_id = mi
        setGroupNumber(c: Card, gn: String)
            c.group_number = gn
        setPlanType(c: Card, pn: String)
            c.plan_number = pn
        setPlanType(c: Card, pt: String)
            c.plan_type = pt
        setPurpose(c: Card, p: String)
            c.purpose = p
        setNotes(c: Card, ns: String)
            c.notes = ns
        removeCard(c: Card)
            delete c
    operational principle
        after addCard(u, sn, mi, gn, pn, pt, p, ns) -> c
            and never removeCard(c)
        then c ∈ getUserCards(u)
        after addCard(u, sn, mi, gn, pn, pt, p, ns) -> c
            and removeCard(c)
        then c ∉ getUserCards(u)

    concept medical-contact [User]
    purpose track contact information for personal doctors and nurses
    state
        owner: Contact -> one User
        active: Contact -> one Boolean
        title: Contact -> one String
        first_name: Contact -> one String
        last_name: Contact -> one String
        hospital: Contact -> one String
        specialty: Contact -> one String
        phone_number: Contact -> one String
        notes: Contact -> one String
    actions
        addContact(u: User, t: String, fn: String, ln: String, h: String, s: String, pn: String, ns: String): one Contact
            new c: Contact
            c.owner = u
            c.active = true
            c.title = t
            c.first_name = fn
            c.last_name = ln
            c.hospital = h
            c.specialty = s
            c.phone_number = pn
            c.notes = ns
            return c
        getUserContacts(u: User): set Contact
            return {c ∈ u.~owner | c.active}
        setTitle(c: Contact, t: String)
            when c.active
            c.title = t
        setFirstName(c: Contact, fn: String)
            when c.active
            c.first_name = fn
        setLastName(c: Contact, ln: String)
            when c.active
            c.last_name = ln
        setHospital(c: Contact, h: String)
            when c.active
            c.hospital = h
        setSpecialty(c: Contact, s: String)
            when c.active
            c.specialty = s
        setPhoneNumber(c: Contact, pn: String)
            when c.active
            c.phone_number = pn
        setNotes(c: Contact, ns: String)
            when c.active
            c.notes = ns
        removeContact(c: Contact)
            when c.active
            c.active = false
    operational principle
        after addContact(u, sn, mi, gn, pn, pt, p, ns) -> c
            and never removeContact(c)
        then c ∈ getUserContacts(u)
        after addContact(u, sn, mi, gn, pn, pt, p, ns) -> c
            and removeContact(c)
        then c ∉ getUserContacts(u)

    concept medication [User]
    purpose track personal medication details
    state
        owner: Medication -> one User
        active: Medication -> one Boolean
        name: Medication -> one String
        generic_name: Medication -> one String
        dose: Medication -> one String
        notes: Medication -> one String
    actions
        addMedication(u: User, n: String, gn: String, d: String, n: String): one Medication
            new m: Contact
            m.owner = u
            m.active = true
            m.name = n
            m.generic_name = gn
            m.dose = d
            m.notes = n
            return m
        getUserMedications(u: User): set Medication
            return {m ∈ u.~owner | m.active}
        setName(m: Medication, n: String)
            when m.active
            m.title = t
        setGenericName(m: Medication, gn: String)
            when m.active
            m.generic_name = gn
        setDose(m: Medication, d: String)
            when m.active
            m.dose = d
        setNotes(m: Medication, n: String)
            when m.active
            m.notes = n
        removeMedication(m: Medication)
            when m.active
            m.active = false
    operational principle
        after addMedication(u, n, gn, d, n) -> m
            and never removeMedication(m)
        then m ∈ getUserMedications(u)
        after addMedication(u, n, gn, d, n) -> m
            and removeMedication(m)
        then m ∉ getUserMedications(u)

    concept photo [Item]
    purpose associate images with an item
    state
        item: Photo -> one Item
        filename: Photo -> one String
        data: Photo -> one Binary
    actions
        uploadPhoto(i: Item, f: String, d: Binary): one Photo
            new p: Photo
            p.item = i
            p.filename = f
            p.data = d
            return p
        getAttachedPhotos(i: Item): set Photo
            return i.~item
        renamePhoto(p: Photo, f: String)
            p.filename = f
        deletePhoto(p: Photo)
            delete p
    operational principle
        after uploadPhoto(i, f, d) -> p
            and never deletePhoto(p)
        then p ∈ getAttachedPhotos(i)
        after uploadPhoto(i, f, d) -> p
            and deletePhoto(p)
        then p ∉ getAttachedPhotos(i)

    concept log-entry [User, Type, Detail]
    purpose log state at a particular point in time
    state
        owner: Entry -> one User
        type: Entry -> one Type
        detail: Entry -> one Detail
        notes: Entry -> one String
        date: Entry -> one Date
    actions
        addEntry(u: User, t: Type, d: Detail, n: String, date: Date): one Entry
            new e: Entry
            e.owner = u
            e.type = t
            e.detail = d
            e.notes = n
            e.date = date
            return e
        getUserEntries(u: User): set Entry
            return u.~owner
        getUserEntriesByType(u: User, t: Type): set Entry
            return {e ∈ u.~owner | e.type == t}
        getUserEntriesByDetail(u: User, t: Type, d: Detail): set Entry
            return {e ∈ u.~owner | e.type == t and e.detail = d}
        setDetail(e: Entry, t: Type, d: Detail)
            e.type = t
            e.detail = d
        setNotes(e: Entry, n: String)
            e.notes = n
        setDate(e: Entry, d: Date)
            e.date = d
        removeEntry(e: Entry)
            delete e
    operational principle
        after addEntry(u, t, d, n) -> e
            and never removeEntry(c)
        then e ∈ getUserEntries(u)
        after addEntry(u, t, d, n) -> e
            and removeEntry(c)
        then e ∉ getUserEntries(u)

    concept condition [User]
    purpose personalize what experiences can be tracked by a user
    state
        owner: Condition -> one User
        active: Condition -> one Boolean
        name: Condition -> one String
    actions
        addCondition(u: User, n: String): one Condition
            new c: Condition
            c.owner = u
            c.active = true
            c.name = n
        getUserConditions(u: User): set Condition
            return {c ∈ u.~owner | c.active}
        renameCondition(c: Condition, n: String)
            when c.active
            c.name = n
        removeCondition(c: Condition)
            when c.active
            c.active = false
    operational principle
        after addCondition(u, n) -> c
            and never removeCondition(c)
        then c ∈ getUserConditions(u)
        after addCondition(u, n) -> c
            and removeCondition(c)
        then c ∉ getUserConditions(u)

    concept trend [Item, Label, Value]
    purpose quantify experiences to observe trends over time
    state
        item: Point -> one Item
        label: Point -> one Label
        date: Point -> one Date
        value: Point -> one Value
    actions
        addPoint(i: Item, l: Label, d: Date, v: Value): one Point
            new p: Point
            p.item = i
            p.label = l
            p.date = d
            p.value = v
            return p
        getItemPoints(i: Item): set Point
            return i.~item
        getTrend(is: set Item, l: Label, b: Date, e: Date): set Point
            when b ≤ e
            return {p ∈ is.~item | p.label == l and p.date ≥ b and p.date ≤ e}
        setLabel(p: Point, l: Label)
            p.label = l
        setDate(p: Point, d: Date)
            p.date = d
        setValue(p: Point, v: Value)
            p.value = v
        removePoint(p: Point)
            delete p
    operational principle
        let u ≠ u, l ≠ l', d0 < d1 < d < d2 < d3
        after addPoint(u, i, l, d, v) -> p
            and never removePoint(p)
        then p ∈ getTrend(u, l, d1, d2)
            and p ∉ getTrend(u', l, d1, d2)
            and p ∉ getTrend(u, l', d1, d2)
            and p ∉ getTrend(u, l, d0, d1)
            and p ∉ getTrend(u, l, d2, d3)
        after addPoint(u, i, l, d, v) -> p
            and removePoint(p)
        then p ∉ getTrend(u, l, d1, d2)

    app health-portrait-beta
    include
        shared-account
        insurance-card [shared-account.Account]
        medical-contact [shared-account.Account]
        medication [shared-account.Account]
        log-entry [shared-account.Account, {"medication", "appointment", "procedure", "other"}, String]
        trend [medical-entry.Entry, {"pain", "happiness", "cognition"}, {1, 2, 3, 4, 5}]

    // auth syncs are omitted for brevity -- for all actions, only the account owning a resource is authorized to take action against it

    sync shared-account.deleteAccount(s)
        let a = shared-account.getAccount(s)
        ∀ c ∈ insurance-card.getUserCards(a) : insurance-card.removeCard(c)
        ∀ c ∈ medical-contact.getUserContacts(a) : medical-contact.removeContact(c)
        ∀ m ∈ medication.getUserMedications(a) : medication.removeMedication(m)
        ∀ e ∈ log-entry.getUserEntries(a) : log-entry.removeEntry(e)
        ∀ c ∈ condition.getUserConditions(a) : condition.removeCondition(c)

    sync log-entry.setDate(e, d)
        ∀ p ∈ trend.getItemPoints(e) : trend.setDate(p, d)

    sync log-entry.removeEntry(e)
        ∀ p ∈ trend.getItemPoints(e) : trend.removePoint(p)

    app health-portrait
    include
        shared-account
        insurance-card [shared-account.Account]
        medical-contact [shared-account.Account]
        medication [shared-account.Account]
        photo [insurance-card.Card]
        photo [medication.Medication]
        log-entry [shared-account.Account, {"medication"}, medication.Medication]
        log-entry [shared-account.Account, {"appointment"}, medical-contact.Contact]
        log-entry [shared-account.Account, {"procedure"}, String]
        log-entry [shared-account.Account, {"other"}, String]
        condition [shared-account.Account]
        trend [medical-entry.Entry, condition.Condition, {1, 2, 3, 4, 5}]

    // auth syncs are omitted for brevity -- for all actions, only the account owning a resource is authorized to take action against it

    sync shared-account.registerAccount(n, u, p) -> s
        let a = shared-account.getAccount(s)
        condition.addCondition(a, "pain")
        condition.addCondition(a, "happiness")
        condition.addCondition(a, "cognition")

    sync shared-account.deleteAccount(s)
        let a = shared-account.getAccount(s)
        ∀ c ∈ insurance-card.getUserCards(a) : insurance-card.removeCard(c)
        ∀ c ∈ medical-contact.getUserContacts(a) : medical-contact.removeContact(c)
        ∀ m ∈ medication.getUserMedications(a) : medication.removeMedication(m)
        ∀ e ∈ log-entry.getUserEntries(a) : log-entry.removeEntry(e)
        ∀ c ∈ condition.getUserConditions(a) : condition.removeCondition(c)

    sync insurance-card.removeCard(c)
        ∀ p ∈ photo.getAttachedPhotos(c) : photo.deletePhoto(p)

    sync medication.removeMedication(m)
        ∀ p ∈ photo.getAttachedPhotos(m) : photo.deletePhoto(p)

    sync log-entry.addEntry(u, t, d, n, date)
        when t == "medication" and d ∉ medication.getUserMedications(u)
            abort addEntry
        when t == "appointment" and d ∉ medical-contact.getUserContacts(u)
            abort addEntry

    sync log-entry.setDetail(e, t, d)
        when t == "medication" and d ∉ medication.getUserMedications(u)
            abort setDetail
        when t == "appointment" and d ∉ medical-contact.getUserContacts(u)
            abort setDetail

    sync log-entry.setDate(e, d)
        ∀ p ∈ trend.getItemPoints(e) : trend.setDate(p, d)

    sync log-entry.removeEntry(e)
        ∀ p ∈ trend.getItemPoints(e) : trend.removePoint(p)

    sync trend.addPoint(i, l, d, v)
        when l ∉ condition.getUserConditions(i.owner)
            abort addPoint

Wireframes

A picture of a wireframe for your personal profile The user’s contacts page. Here they can create and manage medical contacts digitally. The user is also able to edit existing contacts.

A picture of a wireframe for your personal profile The user’s insurance page. The insurance view is condensed to make it easier to process the information as well as help the user find a specific insurance.

A picture of a wireframe for your personal profile The user’s insurance page. This is the uncondensed view for insurances.

A picture of a wireframe for your personal profile The user’s logs page. A user can see different logs depending on whether they were logs about procedures, medications, or appointments.

A picture of a wireframe for your personal profile The user’s trend page. A user can see visualizations of their logs to see overall trends.

VSD Analysis

Direct Stakeholders

The primary direct stakeholders of Health Portrait are its users, which consists of senior citizens and their teams of caregivers.

By 2050, older adults above the age of 65 will number to an estimate of 1.6 billion people, more than double the count today. With an increasing population of elder citizens, there is a greater need for targeted healthcare platforms that address their needs. By maintaining Health Portrait records of important health information, we can reduce the cognitive workload of older adults in navigating the complicated landscape of healthcare systems. In addition, journals of day-to-day fluctuations in health allow them to keep a clear record of trends in their wellbeing, facilitating better communication with caregivers and medical professionals about their health. This can lead towards more targeted care, which in turn generates better health outcomes. With a platform designed to be intuitive to use, senior citizens can do all this independently, providing them with more dignity and autonomy.

In addition to the elderly, our app can also support their caregivers. Informal caregiving has an estimated yearly cost of $500 billion in the US alone. Making it easier for senior citizens to take control of their own health can reduce the workload of caregivers as well, so they can worry less about misplaced health records or how to instruct the senior citizen in seeking better healthcare. Additionally, a reduced workload gives caregivers the extra time and capacity to invest into other tasks of higher importance to support their cared ones.

Non-Targeted Use

The goal of Health Portrait is to make health data more accessible to elderly patients and enable relatives to provide support remotely, but this remote access also gives rise to potential vectors of malfeasance. For example, a caretaking relative could modify or delete the patient’s log entries to gaslight them into believing that a symptom was not as severe as they claimed. One way to limit the risk of this behavior in a future version of this app would be to expand the shared-account concept into a couple of separate concepts which could collectively allow for access restrictions at the principal granularity (further discussion in tradeoffs section below). Even if these controls were implemented, since elderly users are generally less technologically literate and more susceptible to phishing attacks, the privacy of their personal medical data could be at elevated risk even if we were to enforce encryption at-rest and in-transit. Since the MVP version of this app is targeted specifically at patients and their family members as opposed to medical professionals, another form of non-targeted use would be if doctors started requiring patients to use this platform or requesting to be added as caregivers themselves. This could be an interesting future direction of the app, but it would also necessitate HIPAA compliance and further rigorous scrutiny into the security characteristics of the platform.

Adaptation

Our goal in implementing HealthPortrait is to encourage positive lifestyle changes based on long-term symptom data. When patients (or their caregivers, on behalf of the patient) log symptoms resulting from medications, procedures, or new habits (physical therapy exercises, etc.), they have the option to rate various conditions (for our first implementations, either “happiness,” “cognition,” or “pain,” and for our final implementations, these may be customized to whatever the user desires) on a scale of 1-5. These scales will then be collected for data visualization, which allows users to clearly see long-term effects of treatments, etc. For example, a user may log how much pain they feel each day for a month. A graph of this data may reveal to the user that each time they take a specific medication, their pain decreases, so the user can then begin taking this medication regularly to better manage their pain.

On a similar note, having users regularly log their physical and mental condition can promote better awareness overall of their health. Users may realize that they’ve been logging a “5” in pain nearly each day of the week, and once they’re aware there’s a problem, they can then start taking steps to determine the root cause and become healthier. Unfortunately, users may also abuse the system. Patients/caretakers may use the logger to track exceptionally high pain levels in an attempt to be prescribed more medication (opioids, valiums, etc.).

Widespread Use

One synergistic benefit of Health Portrait becoming widespread is the possibility of integration with current healthcare systems. Currently, most healthcare systems are disjoint, functioning completely separate from each other. This has caused significant issues for elderly patients, as studies have found patients are subjected to unnecessary medical tests and procedures due to lack of coordinated  health care services. With Health Portrait, both patients and doctors could have a centralized place to access and upload records, improving elderly patient care. Another synergistic benefit of Health Portrait is creating a large database of the everyday symptoms of chronic diseases. With widespread use of Health Portrait, medical researchers could have access to a large, diverse medical symptom database which they could anonymize and then research to develop treatments or cures of long-term diseases. Lastly, a synergistic benefit from the widespread use of Health Portrait could be a healthier elderly population with longer life-spans. Research has shown the benefits of long-term symptom logging such as extended life-spans, more effective patient-doctor interactions, and an increased awareness of one’s personal health. With Health Portrait’s ease of use and ability to share accounts with a patient’s caregivers, the elderly population could be more incentivized to more involved with their long-term health.

One potential breakdown from the widespread use of Health Portrait is the negative effects on those who choose not to use/do not have access to Health Portrait. If medical systems begin to depend on Health Portrait as the sole way to access and upload medical information, patients who do not have access to digital systems or choose not to use digital systems may be left behind. Another potential breakdown from the widespread use of Health Portrait is data privacy issues leading to higher life insurance costs. There already concerns about how genetic testing results could be used by life insurance companies to hike-up premiums, and something similar could happen with the medical information tracked by Health Portrait.

Tradeoffs

Bells and Thistles

→ Customization vs. Usability

As stated previously, the main purpose of our app is to help senior citizens easily manage and interact with their health data, so having an accessible, easy-to-use interface is key. Too many fun features or “bells and whistles” could easily discourage elderly users (who often have limited motor/cognitive functionality and/or are non-technologically-inclined) to use our application. So, we focused on making our interface very simple (limited color schemes, limited call-to-action items, etc.) to ensure majority of users could easily navigate.

Too Many Cooks in the Kitchen

→ One Account, One Login vs. One Patient, Many Accounts vs. One Account, Many Logins

For a while, we debated what definition of “user” would best suit our app’s functionality:

One Account, One Login would allow many users to access the same patient data with the same username and password. In other words, each user would use the same set of credentials to log into the same account. This would be easy to implement, but it would then be difficult to know which party (patient vs. caregiver) posted which logs, and we would not be able to support multiple sessions. So this was not a good option.

One Patient, Many Accounts would allow many users with different usernames and passwords to access a “Patient” object. In other words, each user would use a different set of credentials to log into different accounts, and they could then join a type of “community,” which we’re calling a “Patient,” where they could then view and edit data regarding a specific user. It’s similar to a Facebook Group, but instead of users getting together to discuss town events or their best Thanksgiving recipes, it’s users creating logs about a central patient, most likely an elderly family member. Some version of this concept would be valuable in this app, but it adds a significant amount of complexity, and in order to implement it fully in the available time we would have had to sacrifice multiple other concepts which we think are more critical to the overall vision of the app.

One Account, Many Logins would allow many users to access the same patient data with different usernames and passwords. In other words, each user would use a different set of credentials to log into the same account. This version strikes a nice middle-ground between the others and is the option we ultimately decided to implement. Having multiple sets of credentials solves the conflicting sessions issue from our first One Account, One Login idea, and this solution is much simpler than our second One Patient, Many Accounts idea.

Another aspect of this user concept that we considered was autonomy vs. appropriate support. Some patients may feel ashamed of asking for help, and feel embarrassed or ashamed about sharing their health information. For example, in the One Patient, Many Accounts implementation, we considered a case in which the elderly user was the admin of their own patient “group.” They could refuse help by removing their caretakers’ accounts from their group. On the other hand, this same scenario could occur if a patient’s cognitive function is limited, and they may delete other users unintentionally or unknowingly. By implementing One Account, Many Logins, we thought we had found a good balance between giving the patient enough power and autonomy so they can keep their dignity and confidence throughout their health journey, but the caretakers also have enough power to step in and administrate if needed.

Mind Your Own Business

→ Integrating Medical Professionals vs. Storing Data Locally

An issue that often came up was how our app could comply with the laws set by the Health Insurance Portability and Accountability Act of 1996 (HIPAA). As explained earlier, according to our research, unless a website is being used to share patient health information with a HIPPA Covered Entity, it does not need to be HIPAA compliant. Thus, since our website is only meant to be access by patients and their relatives, we don’t need to worry about adhering to HIPAA compliance. If we were to integrate services where medical professionals could independently view and interact with this data, however, we would most likely need to make adjustments to the design of the app to adhere to HIPAA’s rules and regulations. This would be a valuable feature in a future version of the app, but the additional complexity of this compliance requirement wouldn’t be a worthwhile tradeoff given our very limited timeframe, so we decided to avoid sharing the patient’s information with any parties other than their approved caregiver(s).

Project Plan

GitHub Repo

https://github.com/jrdegreeff/health-portrait

Beta Design Revision