Skip to content

[Adapters] lowStock reports digital and soft-deleted products that can never clear #158

Description

@vedanshujain

ReportingStore.lowStock is a bare scan of the inventory table:

selectFrom("inventory").select(["sku","on_hand"]).where("on_hand","<=",threshold)

(packages/store-postgres/src/kysely-reporting-store.ts:148-157). No join to product_commerce,
so there is no deleted_at filter and no product_kind filter. The default threshold is 5
(packages/domain/src/ports/settings-store.ts:39).

Why this is now worse

PR 1a establishes the invariant "a product with a SKU has an inventory row", seeding a row at 0
on both write paths. So every SKU'd product now appears in the low-stock report at 0 until it is
stocked
, where previously only products that had been explicitly seeded appeared at all.

Two categories can never clear:

  • Digital products. They hold no stock by design — nothing ever restocks them — so a digital
    SKU sits in the low-stock report permanently. product_kind lives on product_commerce, which
    this query never joins.
  • Soft-deleted products. softDelete sets deleted_at on product_commerce and retains the
    row; the inventory row is untouched and keeps being reported.

The result is a report that a merchant learns to ignore, which is the failure mode a low-stock
alert can least afford.

Suggested direction

Join product_commerce and filter to deleted_at is null and product_kind = 'physical'. Needs
cases on both dialects and a decision on whether an inventory row with no matching
product_commerce row (possible after a SKU rename — see the SKU-rename stranding issue) should
be reported or hidden.

Deliberately not fixed in PR 1a: it is an [Adapters] + reporting-contract change, and 1a's
scope is the seeding invariant.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions