RaspberryPiFoundation / editor-api

Code Editor backend
https://editor.raspberrypi.org
GNU Affero General Public License v3.0
22 stars 4 forks source link

Add teacher invitation API endpoints #336

Closed floehopper closed 1 week ago

floehopper commented 2 weeks ago

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:

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:

The response to the #accept action can be any of the above, but also:

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:

https://github.com/RaspberryPiFoundation/editor-api/blob/8cf738702ffc5b3644a3d21c76eebb1a927b67f2/app/models/invitation.rb#L10-L12

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.