Skip to main content
Archive, Delete, and Restore Flow.
This file explains how archiving, soft delete, and restore currently work in the project.

Table of Contents

  1. Overview
  2. The Two Different States
  3. User Archive Flow
  4. User Delete Flow
  5. User Restore Flow
  6. Self Delete Flow
  7. Role of the Archivable Trait
  8. Important Testing Notes

1. Overview

This project uses two separate mechanisms:
  1. custom archive state through archived_at
  2. Laravel soft delete through deleted_at
These are not the same thing.

2. The Two Different States

Archive State

  • controlled by the custom Archivable trait
  • stored in archived_at
  • archived records are hidden by the trait’s global scope
  • archived records can be brought back with unarchive()

Soft Delete State

  • controlled by Laravel SoftDeletes
  • stored in deleted_at
  • soft-deleted records are not physically removed from the database
  • soft-deleted records can be restored with Laravel restore()

3. User Archive Flow

Endpoint:
Controller:

Success Response

What happens internally:
  • the controller finds the user
  • it calls $user->archive()
  • the Archivable trait sets archived_at = now()
To fetch archived users, the project supports:

4. User Delete Flow

Endpoint:
Controller:

Success Response

Important note:
  • despite the response message, the controller calls:
That means:
  • this is a Laravel soft delete
  • the row is not hard-deleted from the database
  • it can still be restored later
Also note:
  • this endpoint only works on users fetched from User::onlyArchived()
  • so the intended flow is usually:
  1. archive the user first
  2. then call delete

5. User Restore Flow

There are two different restore behaviors in the project.

Unarchive Archived User

Endpoint:
Controller:

Success Response

This only clears:
  • archived_at
It does not restore a Laravel soft-deleted row.

Restore Soft-Deleted User

Endpoint:
Controller:

Success Response

This restores:
  • deleted_at
It does not automatically explain or manage archive state in the response.

6. Self Delete Flow

Endpoint:
Controller:

Request JSON

Success Response

What happens internally:
  • password is verified
  • all current personal access tokens are deleted
  • the user row is soft-deleted with Laravel delete()
Important restriction:
  • admins
  • super-admins
  • instructors
cannot self-delete through this endpoint

7. Role of the Archivable Trait

The custom trait lives in:
Main behavior:
  • adds a global scope that hides archived rows where archived_at is not null
  • provides archive()
  • provides unarchive()
  • provides scopeOnlyArchived()
  • provides scopeWithArchived()
Practical impact:
  • normal queries may hide archived rows automatically
  • onlyArchived() is required when you want archived rows back

8. Important Testing Notes

  • archive and delete are different operations.
  • unarchive and restore are different operations.
  • the message User force deleted successfully. is misleading because the controller performs a soft delete.
  • if you want to test the full admin lifecycle in Postman, a safe order is:
  1. POST /api/user/{id}/archive
  2. POST /api/user/{id}/unarchive
  3. POST /api/user/{id}/archive
  4. DELETE /api/user/{id}/delete
  5. POST /api/users/{userId}/restore