Skip to content

feat: inactive account lifecycle (track last login, deactivate, delete) #243

Description

@Angak0k

Summary

Track the last login date for every account and drive a two-stage inactivity lifecycle:

  • 12 months of inactivity → account deactivated
  • 17 months → warning email sent ("your account will be deleted in 30 days")
  • 18 months → account hard-deleted (all packs, inventories, and related data)

Deactivated accounts can self-reactivate by logging in with valid credentials.

Motivation

Without a last-login signal, there is no way to detect dormant accounts, which accumulates stale data and inflates user counts.

Design

Database — migration 000026

  • Add last_login_at TIMESTAMPTZ NULL to account (updated on every successful login; falls back to created_at via COALESCE for accounts that never logged in)
  • Add deletion_warned_at TIMESTAMPTZ NULL to account (stamped when warning email is sent; deletion guard — no account can be hard-deleted without this stamp)
  • Add 'deactivated' to UserStatus enum (distinct from 'inactive' which is reserved for the email-confirmation flow)

Updated enum: pending | inactive | active | deactivated

Login flow changes (pkg/accounts/accounts.go)

  1. On successful login: UPDATE account SET last_login_at = NOW().
  2. New status branch for deactivated accounts: auto-reactivate (set status = 'active', clear deletion_warned_at, update last_login_at) and return tokens. Existing inactive/pending path is unchanged.

Cleanup binary (cmd/cleanup/)

Standalone binary invoked by an external scheduler (K8s CronJob / systemd). Three phases run in order:

Phase Threshold Action
Deactivate 12 months UPDATE account SET status = 'deactivated'
Warn 17 months Send warning email + stamp deletion_warned_at
Delete 18 months + warned DELETE FROM account (cascade)

Business logic lives in pkg/accounts/ for unit testability. New make run-cleanup Makefile target.

Status flow

pending     ──(email confirmed)──► active
inactive    ──(email confirmed)──► active
active      ──(12mo inactivity)──► deactivated
deactivated ──(valid login)    ──► active        ← reactivation
deactivated ──(18mo + warned)  ──► [hard deleted]

Out of scope

  • Admin UI to manually override account status
  • Partial data retention on deletion

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeatureNew fonctionnality or functional improvement of an existing one

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions