-
Notifications
You must be signed in to change notification settings - Fork 21
API Roadmap
This page is used to define and collaborate on strategic improvements to be made to the API. Initially this is focused on v2.0.0 but will evolve to describe the order and scope of incremental enhancements to get to v2.0.0 and beyond.
All APIs are prototyped on the epic/api-2.0.0
branch.
API resources will be as follows:
-
/health
: Health API for the application -
/security
: User authentication (token generation, etc.) -
/roles
: Defines privilege sets within the application -
/users
: Manages users -
/role-grants
: Controls which users have what privileges -
/entity-types
: Manages entity classification -
/entities
: Manages entities (facilities of some sort) -
/contacts
: Manages contacts -
/contact-association-types
: Manages association classification -
/contact-associations
: Manages associations between a contact and one or more entities -
/email
: Manages e-mail functionality ("blast" e-mail, password reset, etc.) -
/email-templates
: Manages e-mail templates -
/events
: Manages event definitions -
/questionnaires
: Manages questionnaires (add/remove questions, support versioning) -
/check-ins
: Allows a contact to "check in" with some level of additional data
The health API will be implemented to match the prototyped API. Additional checks can be added over time as needed.
NOTE: To minimize maintenance, we may want to look into a framework such as @financial-times/health-check or endoscope.
The /security
endpoints are used to obtain a JSON web token (JWT). The token may have the roles associated with the authentication; currently, a valid JWT is sufficient.
The authentication model will need to include verification of the authenticated "user" (either a system user or a contact).
We may need to update the JWT content to omit role information, as roles can be revoked while the JWT is still valid; we should also review the overall JWT content to see what we want to add to the structure and such - there may be a way to handle the non-user access for checkins and such.
JWTs can be generated for system users and by e-mail address (for contacts). The roles granted
Roles are defined as one or more permissions for the application APIs. Each permission specifies an endpoint and one or more HTTP methods for that endpoint (Note: Need to have a concrete way to map endpoints with path parameters - maybe regex?).
Roles are intended to be fine-grained, and limited to specific areas (read user information, administer users, etc.). If possible, we should limit the number of roles using an aggregation-like mechanism, where having the role that allows user administration automatically grants the roles related to read-only user endpoints. This minimizes duplication and allows roles to be more dynamic.
The /roles
endpoint allows the retrieval, creation, modification and deletion of roles, and the addition and removal of permissions from roles.
Users are those API consumers who have their own authentication credentials to the application. They explicitly authenticate, and only have access to the APIs that they are granted. Users are not contacts, and are not associated with entities.
The /users
endpoint allows retrieval, creation, modification and deletion of users.
Any user can have one or more roles granted to them. Those roles allow an authenticated user to access the APIs using the role-specified HTTP methods.
The /role-grants
endpoint allows the granting of roles to and the revocation of roles from a user or contact.
Entity types are ad hoc classifications for entities, such as "assisted living" and "long-term care". Types cannot be changed, and cannot be deleted if in use. Entity types can be used to filter the recipient list for outbound e-mail notifications. Entity types may need to support soft deletion for reporting purposes. This may also change behavior to allow re-creation.
The /entity-types
endpoint allows allows retrieval, creation, modification and deletion of entity types.
An entity represents a real-world location that can be associated with a contact, and which can have check-ins completed. Entities can be used to create the recipient list for outbound e-mail notifications. Entities may need to support soft deletion for reporting purposes. This may also change behavior to allow re-creation.
The /entities
endpoint allows allows retrieval, creation, modification and deletion of entities.
Contacts represent real-world people that are the point of contact for one or more entities. Contacts can have different responsibilities (contact association types) for different entities. Contacts can be used to create the recipient list for outbound e-mail notifications. Contacts may need to support soft deletion for reporting purposes. This may also change behavior to allow re-creation.
Contact association types are ad hoc classifications for contact associations, such as such as "administrator" and "primary support". Types cannot be changed, and cannot be deleted if in use. Contact association types can be used to filter the recipient list for outbound e-mail notifications. Association types may need to support soft deletion for reporting purposes. This may also change behavior to allow re-creation.
The /contact-association-types
endpoint allows allows retrieval, creation, modification and deletion of entity types.
A contact association is a relationship between a contact and an entity. This is a many-to-many relationship, as entities can have multiple contacts, and contacts can be associated with multiple entities. Associations may need to support soft deletion for reporting purposes. This may also change behavior to allow re-creation.
The /contact-associations
endpoint allows the creation or removal of entity associations for contact.
From an implementation perspective, we should look at the transporters for nodemailer
The /email
endpoint allows transmission of e-mail messages for various use cases. The APIs allow selection of the recipients, and will use internally-rendered templates for the message content. Depending on the API, the template may be specific to the invocation, or hard-coded for the use case.
With a more generic system, the ability to create and modify templates is required. Given that the server side uses Nunjucks, the API must be implemented to prevent the injection of potentially insecure content into the templates. We should also look at other templating engines like Handlebars or Mustache.
We'll want to support a variable/placeholder in templates that allows the author to specify that the user should see a self-check in link/button. The template would need to reference a questionnaire and would render with an embedded token in the URL. This will allow functional parity with v1 where the email content/embedded tokens are already supported.
We may need to switch to something like using Markdown for the the templates. We can use Marked as a parser, and render the template into HTML or plain text prior to using the templating engine for substitution. We'd probably still want to use something like DOMPurify for the generated HTML. To save on the performance hit, we can render the Markdown on template creation/modification, and store the render results. Then all that we need to do at "blast" time is to perform the templating/substitution.
Non-Markdown content (like JavaScript or HTML inclusion) must be prohibited.
For variable substitution, we should adopt a JSON-style notation for the substituted fields.
Question: We know SMS texting support is likely coming as a request. Should we make this endpoint a generic messaging solution OR have a separate endpoint for SMS?
The /email-templates
endpoint allows creation, retrieval, modification, and removal of e-mail templates.
Events represent a classification of interactions with the check-in system. Check-ins can be associated with events for classification purposes. Events may need to support soft deletion for reporting purposes. This may also change behavior to allow re-creation.
Note: This is not critical for functional parity with v1, so may be deferred to 2.1.
The /events
endpoint allows creation, retrieval, modification, and removal of event information.
Questionnaires are intended to define a set of render-capable question definitions that can be displayed to an end user. Questionnaires may need to support soft deletion for reporting purposes. Modifications should also allow versioning and visibility control of versions.
Question body text can be up to 1024 characters in length. Answers can be of one of the following forms:
- Short text: Free-form text up to 80 characters (should be rendered as a single text input)
- Long text: Free-form text from 80 to 1024 characters (should be rendered as multi-line text input)
- Checkbox List: Provides multiple fixed options; multiple options may be selected
- Option List: Provides multiple fixed options; only a single option may be selected
- Yes/No: Provides a simple choice rendered as a single checkbox
Questionnaires also need to be able to provide optional guidance/explanations for the overall content, and for each question.
All question types can be flagged as "required"; the flag defaults to false
.
Checkbox and option lists also support a flag to enable an "Other" choice; the flag defaults to false
. If a question enables this flag, rendering will include an additional "Other" option. If the user chooses that option, an additional short-text field will be enabled for text input that will be included in the answer.
Thought: We may want to consider a way to defined static text in a questionnaire that is just providing info or guidance to the respondent. I'd propose that we have a new type of question, that does not allow responses.
TBD: How are questionnaires associated with events?
The /questionnaires
endpoint allows creation, retrieval, modification, and removal of questionnaire information.
A check-in is the process of a contact indicating that they have acknowledged the state of their associated entity. Check-ins may be associated with events or questionnaires. Check-ins are always in the context of a contact association.
Thought: We should think through the use case where a Questionnaire is NOT associated with a check-in. This is NOT the typical use case for the current usage by the City of Baltimore. Is this needed to handle the case where an entity could proactively provide unprompted input about their status? Is this to support unstructured data gathering before or instead of pre-defining a structured data need in the form of a Questionnaire. One alternate approach could be to default to a one long-text question Questionnaire to capture any response without an explicit Questionnaire cited. This would allow us the ability to assume this relationship always exists without implying the burden of Questionnaire mgmt.
Thought: In the case where there is a relationship tot a Questionnaire, should we validate the input? E.g. reject the answer “blue” to a True/False question.
The /check-ins
endpoint allows creation and retrieval of check-in information. Reporting may be a separate API as well.
Need to add REST validation (for example, using express-openapi-validate; see this article for more details)
Add an API that tracks metrics such as:
- Total requests
- Average response times
- Breakdown by resource/path
- Memory & performance characteristics
Feedback: This is great. Could make v2.1 since this is not currently supported. Thinking v2.0 should be the minimum needed to get to feature parity with v1. This will allow us to transition to v2 in PROD sooner.
This is something that would probably be best as a third-party tool we include, rather than writing it from scratch.
ToDo: We need to nail down how API version will be exposed to the caller. Suggestion is to use route versioning for major versions. All endpoints described above would include "/v2/" in their route. Additionally, we should align on how to align the swagger docs. If we have v1 and v2 supported concurrently in any fashion I'd suggest that we have separate swagger docs/contracts, one for each version.
ToDo: Thinking it’ll be a good idea to deliver a script, postman collection or other resource that can boot-strap with a recommended starter set of roles and permissions.
There is a potential need for a revision history for the following resources:
- Contacts
- Users
- Events
- Entities
- Questionnaires
- Roles
- Role Grants
Revision history will tentatively include:
- Modifying user
- Modification timestamp
- Modification status (created, deleted, modified)
- Modified fields (only for modifications; contains field name, original value and modified value)
The schema and content needs to be determined for the various types of CSV extracts. There should also be some sort of restriction mechanism to prevent all data being exported by unauthorized users (data leaks).
Feedback: We should prioritize this for v2.0 or 2.0.1 specifically for the retrieval of check in data in a way that genetically maps question responses to columns in the CSV.
As the intent is to create a more generic CMS, we should evaluate how much internationalization / localization we want to support. Potential areas of impact include:
- Application messages
- Input filtering/validation
- Database design/implementation (field layout, collation, etc.)
Feedback: This is not urgent and can be post 2.0.0