Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

636 forms api backend #722

Merged
merged 8 commits into from
Aug 13, 2024
Merged

636 forms api backend #722

merged 8 commits into from
Aug 13, 2024

Conversation

Joshua-Douglas
Copy link
Member

Closes #636

Apologies for the delay! Please let me know if you'd like any modifications before submitting, or if you need any other endpoints for the frontend.

What changes did you make?

This PR introduces a basic forms API, with four main endpoints:

  • POST /forms -> Create a new form.
  • GET /forms/{form_id} -> Get the form definition
  • GET /responses/{form_id} -> Get the user's responses for a given form
  • PUT /responses/{form_id} -> Add user responses for a form. Overwrite any existing values if previous responses are available.

The /forms endpoints do not rely on user data, but I did require authentication. We could enforce role-based access by simply checking the user role if we want to restrict new form creation to admins, for example.

The basic form scheme is enforced by the OpenAPI schema and the Marshmallow data model schema. A a form contains a title, description, and array of of field groups. Each field group contains a title, description, and array of fields. Each field contains a human-readable reference name, field properties and field validations. The field properties contain the field descriptions, the valid field choices (if applicable) and the field type. The field validations indicate whether a form value is required, and optionally specifies a max_length.

You can easily add forms and responses by interacting with the SwaggerUI.

The supported field types are listed in the API schema, and include date, dropdown, multiple_choice, email, file_upload, group, long_text, number, short_text, yes_no. At this point the answer_text is accepted as-is. We could add field-type specific validation in the update_responses controller, or we can delegate this validation to the frontend.

Rationale behind the changes?

These endpoints give us the basic building blocks to store and retrieve any form containing user-specific responses.

I have not added any form, but I'd be happy to update the database to include the intake form if you have one available. This can be done by seeding the database during startup, or by modifying the existing alembic script to include the form.

Testing done for these changes

  • api/tests/test_forms_repo.py
  • api/tests/test_forms_schema.py

Other Changes

  • While manually testing the endpoints I noticed that the mocking configuration did not support loading user data across multiple development sessions. The data was properly stored in the database, but the existing user accounts were not loaded into the mock AWS userpool, so they weren't accessible. I fixed this in 6802a27 by populating the mock userpool with all the existing users, using a dummy password.

Updated Data Model

classDiagram
class alembic_version{
   *VARCHAR<32> version_num NOT NULL
}
class field_groups{
   *INTEGER group_id NOT NULL
   TEXT description
   INTEGER form_id NOT NULL
   VARCHAR<255> title NOT NULL
}
class forms{
   *INTEGER form_id NOT NULL
   DATETIME created_at
   TEXT description
   VARCHAR<255> title NOT NULL
}
class field_properties{
   *INTEGER properties_id NOT NULL
   JSON choices
   TEXT description
   VARCHAR<50> field_type NOT NULL
}
class field_validations{
   *INTEGER validations_id NOT NULL
   INTEGER max_length
   BOOLEAN required NOT NULL
}
class fields{
   *INTEGER field_id NOT NULL
   INTEGER group_id
   INTEGER properties_id NOT NULL
   VARCHAR<255> ref NOT NULL
   INTEGER validations_id NOT NULL
}
class housing_program{
   *INTEGER id NOT NULL
   VARCHAR program_name NOT NULL
   INTEGER service_provider NOT NULL
}
class housing_program_service_provider{
   *INTEGER id NOT NULL
   VARCHAR provider_name NOT NULL
}
class responses{
   *INTEGER answer_id NOT NULL
   TEXT answer_text
   VARCHAR<255> field_id NOT NULL
   INTEGER user_id NOT NULL
}
class user{
   *INTEGER id NOT NULL
   VARCHAR email NOT NULL
   VARCHAR<255> firstName NOT NULL
   VARCHAR<255> lastName
   VARCHAR<255> middleName
   INTEGER role_id NOT NULL
}
class role{
   *INTEGER id NOT NULL
   VARCHAR name NOT NULL
}
forms "1" -- "0..n" field_groups
field_groups "0..1" -- "0..n" fields
field_validations "1" -- "0..n" fields
field_properties "1" -- "0..n" fields
housing_program_service_provider "1" -- "0..n" housing_program
fields "1" -- "0..n" responses
user "1" -- "0..n" responses
role "1" -- "0..n" user
Loading

@tylerthome tylerthome merged commit 43bce95 into main Aug 13, 2024
4 of 6 checks passed
@tylerthome tylerthome deleted the 636-forms-api-backend branch August 13, 2024 02:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement Forms API
2 participants