A refresh token exists for one reason: exchange itself for a new access token, once, and then stop being useful. Everything about a good implementation follows from taking "once" literally. This one does — every refresh token is single-use, and grouped with every other token descended from the same login into a family. Calling POST /auth/refresh with a given token can fail four different ways, and three of them are just bookkeeping. The fourth is the one this post is actually about.
One row per token, one family per login
@Entity()
export class RefreshToken {
@PrimaryGeneratedColumn('uuid')






