hackforla / HomeUniteUs

We're working with community non-profits who have a Host Home or empty bedrooms initiative to develop a workflow management tool to make the process scalable (across all providers), reduce institutional bias, and effectively capture data.
https://homeunite.us/
GNU General Public License v2.0
35 stars 21 forks source link

Generated intake profile fields #672

Open erikguntner opened 1 month ago

erikguntner commented 1 month ago

This PR outlines a basic approach to rendering intake profiles based on objects defined in the database. This isn't a complete example, but I think it allows us to visualize further development of the data model to help fit our needs.

I accidentally created this branch off of the fix-mocking-errors branch, so I apologize for the added noise. If you would like to view only the relative changes use this link since it filters out the other files.

What changes did you make?

As I mentioned there is quite a bit of noise in this PR so I wanted to highlight some of the most relevant files and what they are doing.

Data layer:

View layer:

Rationale behind the changes?

I wanted to explore what was possible when using a data model that describes the intake profile to generate the necessary fields.

Pros:

Cons:

What did you learn or can share that is new?(optional)

Resources

The data model is heavily inspired by Typeform's API with a few tweaks:

Data Model

erDiagram
    INTAKE_PROFILE ||--|{ FIELD_GROUP : contains
    INTAKE_PROFILE {
        string id PK
        string name
    }
    TYPE {
        string id PK
        string type "long_text, short_text, multiple_choice, yes_no, email, phone_number"
    }
    FIELD_GROUP ||--|{ FIELD : has
    FIELD_GROUP {
        string id PK
        string profile_id FK
        int order
        string title
    }
    FIELD ||--|| PROPERTIES : has
    FIELD ||--|| VALIDATIONS : has
    FIELD ||--|| TYPE : has
    FIELD ||--|| ANSWER : has
    FIELD {
        string id PK
        string field_group_id FK
        string type_id FK
        int order
        string title
    }
    PROPERTIES ||--|{ CHOICES : "can contain"
    PROPERTIES {
        string id PK
        string field_id FK
        string description "all"
        boolean randomize "multiple_choice, dropdown"
        boolean alphabetical_order "multiple_choice, dropdown"
        boolean allow_multiple_selection "multiple_choice"
        boolean allow_other_choice "multiple_choice"
    }
    VALIDATIONS {
        string id PK
        string field_id FK
        boolean is_required "all"
        int max_characters "short_text, long_text"
    }
    CHOICES {
        string id PK
        string properties_id FK
        string label
     }

    ANSWER {
        string id PK
        string field_id FK
            int user_id FK
        jsonb value "unsure of the best way to define this type since it needs to cover a many different data types (e.g)"
    }

Something that I believe is worth considering is whether we need to store the INTAKE_PROFILE, FIELD_GROUP, FIELD along with the PROPERTIES, and VALIDATIONS in the database at all. These only describe the intake profile and are not created, updated, or deleted by users. An alternative might be to define the two intake profiles in a more readable file format (like yaml) that could be read and parsed on both ends for their necessary purposes. These files could then act as a source of truth for the shape of the intake profiles and we wouldn't have to go through updating the database if you wanted to change the structure of the profile. Also, since the data model is still very much in flux it would make it easier to make updates to it. I think this would cut down on the complexity of the backend data model and allow to store just the information related to the users.

Example Field Group

{
      id: '7767',
      title: 'Personal Information',
      fields: [
        {
          id: '3029',
          title: 'What is your email?',
          type: 'email',
          properties: {},
          validations: {},
        },
        {
          id: '2584',
          title:
            'What is your work history?',
          type: 'long_text',
          properties: {},
          validations: {},
        },
        {
          id: '3271',
          title:
            'What is your phone number?.',
          type: 'number',
          properties: {},
          validations: {},
        },
      ],
    },
}

Screenshots of Proposed Changes Of The Website (if any, please do not screen shot code changes)

This video shows profiels 1 and 2 being rendered along with validation.

https://github.com/hackforla/HomeUniteUs/assets/27253583/6bb044fe-648b-4687-9802-ade3de1d4ea9