Skip to content
Ercan Labs
← Notes

Moderation is not a status field

Rejecting a listing is one line. "Why was it rejected, who decided, was it appealed" is a data model question.

· 4 min

The first version had a status field: active, inactive, rejected. The moderation decision was written into it. Three months later the question came: "Why was this listing pulled last week?"

There was no answer. The field held the last value, not the previous one, the person who decided, or the reason. A deleted row does not come back.

Turning the decision into an event

A moderation decision is no longer a field on the listing but its own record: who, when, which reason code, which outcome. Listing visibility is derived from those records.

  • The question became a single query: the decision history of a listing.
  • The same listing can be decided again; the earlier record stays.
  • An appeal is a new record attached to a decision; no separate table was needed.

The cost

Query count went up. "Should this appear in the list" now reads three tables instead of one field. I balanced it with indexes and a cached visibility state, but the cost is real: more complex reads.

In return the system is accountable. When someone asks "who closed this" a month later, the answer is one click away.

The general rule

If a field holds something that changes over time and will be questioned later, it should be a record, not a field. Balance, stock, publication state, approval — same pattern. A field knows only the last value; a record knows the history.

RELATED CASE

Real Estate Platform

Multi-role property platform: listing lifecycle, agency management, subscriptions and moderation.

MORE NOTES