shortform/adr/2023-11-27-shortform-user-model.md

2.1 KiB

ADR 2023-11-27: ShortForm User Model

Table of Contents

Context

ShortForm is a project intended to help facilitate discussion of interesting topics among groups of people. Some person posts a prompt, essay, article, or some other piece of content and others engage in discussion.

This application depends on the concept of a user. ShortForm has users who are allowed to post articles and upload assets, as well as the more-numerous user category which is allowed to post comments on content. Comments are the primary discussion forum of ShortForm.

Decision

Keep scope tight for the initial build of ShortForm.

  • Support two types of users: posters and commenters.
  • Do not support registration - administrators in control of the server must add users by hand.
  • Users have a username and a password.
  • New accounts cannot be used until users supply a password.
  • New accounts receive their initial password via the password reset mechanism.
  • The password reset mechanism for an account must be initiated by an admin.
  • Manage user accounts in the ShortForm database.
  • Use Argon2 for password encryption.

These restrictions allow ShortForm to work as intended while remaining light on features initially, serving a small community that communicates directly outside of ShortForm.

Relational Data Model

Enum Type: user_role

CREATE TYPE user_role AS ENUM ('poster', 'commenter');

Enum Type: user_status

CREATE TYPE user_status AS ENUM ('active', 'locked', 'initializing');

Table: users

CREATE TABLE users(
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    created_at TIMESTAMPTZ NOT NULL,
    username TEXT NOT NULL UNIQUE,
    password TEXT NOT NULL,
    role user_role NOT NULL,
    status user_status NOT NULL
);

Table: password_resets

CREATE TABLE password_resets(
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    created_at TIMESTAMPTZ NOT NULL,
    expires_at TIMESTAMPTZ NOT NULL,
    token TEXT NOT NULL,
    used BOOLEAN NOT NULL
);