There are two new endpoints which I've agreed with @chrislo:
GET /teacher_invitations/:token # => `Api::TeacherInvitations#show`
PUT /teacher_invitations/:token/accept # => `Api::TeacherInvitations#accept`
The response to the #show action can be any of the following:
Success: 200 OK
User is not logged in: 401 Unauthorized
Token does not exist: 404 Not Found
Token has expired: 403 Forbidden
Invitation email has changed since token was created: 403 Forbidden
Invitation email does not match current user email: 403 Forbidden
This response includes an error message to distinguish it from the other two 403 Forbidden responses
The response to the #accept action can be any of the above, but also:
Role validation error: 422 Unprocessable entity
This response includes the validation error Hash from Role#errors in the "error" key of the JSON in the response body
We contemplated having generic /invitations endpoints to match the generic Invitation model. However, the token for the teacher invitation workflow is already effectively "namespaced" to be specific to the teacher invitation workflow:
As agreed with @chrislo, I've renamed the Invitation model to TeacherInvitation to make things clearer / more idiomatic. We can always extract duplication in the future if/when we end up adding another invitation type, e.g. OwnerInvitation.
It's conceivable that the UI will need to know about validation errors that will occur on accepting the invitation in advance of actually accepting the invitation, but we can tackle that if it comes up.
There seem to be a number of different patterns for implementing and testing API controller actions and none of them seem great, so I've mainly just stuck to the simplest and most idiomatic Rails implementation. This means it should be relatively easy to refactor towards one of the patterns (or a new pattern) if that seems appropriate.
I contemplated wrapping the creation of the role and the updating of Invitation#accepted_at in a transaction like we've done in some API actions, but it seemed like overkill.
This provides the API endpoints for the teacher invitation acceptance workflow which is part of the EPIC: Invite teachers.
There are two new endpoints which I've agreed with @chrislo:
The response to the
#show
action can be any of the following:The response to the
#accept
action can be any of the above, but also:Hash
fromRole#errors
in the "error" key of the JSON in the response bodyWe contemplated having generic
/invitations
endpoints to match the genericInvitation
model. However, the token for the teacher invitation workflow is already effectively "namespaced" to be specific to the teacher invitation workflow:https://github.com/RaspberryPiFoundation/editor-api/blob/8cf738702ffc5b3644a3d21c76eebb1a927b67f2/app/models/invitation.rb#L10-L12
As agreed with @chrislo, I've renamed the
Invitation
model toTeacherInvitation
to make things clearer / more idiomatic. We can always extract duplication in the future if/when we end up adding another invitation type, e.g.OwnerInvitation
.It's conceivable that the UI will need to know about validation errors that will occur on accepting the invitation in advance of actually accepting the invitation, but we can tackle that if it comes up.
There seem to be a number of different patterns for implementing and testing API controller actions and none of them seem great, so I've mainly just stuck to the simplest and most idiomatic Rails implementation. This means it should be relatively easy to refactor towards one of the patterns (or a new pattern) if that seems appropriate.
I contemplated wrapping the creation of the role and the updating of
Invitation#accepted_at
in a transaction like we've done in some API actions, but it seemed like overkill.