--
-- This file is part of Anastasis
-- Copyright (C) 2026 Anastasis SARL
--
-- ANASTASIS is free software; you can redistribute it and/or modify it under the
-- terms of the GNU General Public License as published by the Free Software
-- Foundation; either version 3, or (at your option) any later version.
--
-- ANASTASIS is distributed in the hope that it will be useful, but WITHOUT ANY
-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License along with
-- ANASTASIS; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
--

-- Everything in one big transaction
BEGIN;

-- Check patch versioning is in place.
SELECT _v.register_patch('stasis-0003', NULL, NULL);

SET search_path TO anastasis;

-- ANASTASIS_DB_get_recdoc_payment() is a singleton select on
-- (user_id, payment_identifier): a second row for the same pair does not make
-- it return the first one, it makes it return a hard error, i.e. the account
-- can no longer use that identifier at all.  Nothing enforced the uniqueness
-- the readers assume, and the backend could be talked into inserting a
-- duplicate by re-using a payment identifier for an order the merchant
-- answers idempotently.  The C side no longer does that; this index is what
-- makes it impossible rather than merely unlikely.
--
-- Duplicates that already exist have to go first, or the index cannot be
-- built.  Of a duplicate group we keep the paid row if there is one (that is
-- the row carrying the account's credit) and otherwise the oldest, which is
-- the one the client was told about; the rest are unpaid leftovers of the
-- situation described above and are exactly what garbage collection would
-- have removed anyway.
DELETE FROM anastasis_recdoc_payment
  WHERE payment_id NOT IN (
    SELECT DISTINCT ON (user_id, payment_identifier) payment_id
      FROM anastasis_recdoc_payment
      ORDER BY user_id
              ,payment_identifier
              ,paid DESC
              ,creation_date ASC
              ,payment_id ASC);

CREATE UNIQUE INDEX anastasis_recdoc_payment_identifier_unique
  ON anastasis_recdoc_payment
  (user_id
  ,payment_identifier);
COMMENT ON INDEX anastasis_recdoc_payment_identifier_unique
  IS 'A payment identifier identifies at most one payment per account; the readers are singleton selects on this pair';

COMMIT;
