diff --git a/apps/simplex-store-service/src/StoreService/Store/Postgres/Migrations.hs b/apps/simplex-store-service/src/StoreService/Store/Postgres/Migrations.hs index cd805f2fd7..1a8b6e7dc1 100644 --- a/apps/simplex-store-service/src/StoreService/Store/Postgres/Migrations.hs +++ b/apps/simplex-store-service/src/StoreService/Store/Postgres/Migrations.hs @@ -22,7 +22,8 @@ schemaMigrations = ("20261010_names", m20261010_names, Just down_m20261010_names), ("20261022_drop_taken_codes", m20261022_drop_taken_codes, Just down_m20261022_drop_taken_codes), ("20261022_name_balances", m20261022_name_balances, Just down_m20261022_name_balances), - ("20261022_name_late_wait", m20261022_name_late_wait, Just down_m20261022_name_late_wait) + ("20261022_name_late_wait", m20261022_name_late_wait, Just down_m20261022_name_late_wait), + ("20261023_name_terms", m20261023_name_terms, Just down_m20261023_name_terms) ] -- | The client tables share this database, so the service tables are the same names behind a prefix. @@ -459,6 +460,23 @@ down_m20261022_name_late_wait = ALTER TABLE @name_invoices DROP COLUMN late_support; |] +-- The terms an order signed; '' for an order stored before orders signed them. +m20261023_name_terms :: Text +m20261023_name_terms = + withPrefix + servicePrefix + [r| +ALTER TABLE @name_registrations ADD COLUMN agreed_terms TEXT NOT NULL DEFAULT ''; +|] + +down_m20261023_name_terms :: Text +down_m20261023_name_terms = + withPrefix + servicePrefix + [r| +ALTER TABLE @name_registrations DROP COLUMN agreed_terms; +|] + {- TODO [badges] deferred with the draft in M20260915_user_badges, service only. ALTER TABLE @payments ADD COLUMN receipt_hash BYTEA; diff --git a/apps/simplex-store-service/src/StoreService/Store/SQLite/Migrations.hs b/apps/simplex-store-service/src/StoreService/Store/SQLite/Migrations.hs index 5c432c0458..78f81be422 100644 --- a/apps/simplex-store-service/src/StoreService/Store/SQLite/Migrations.hs +++ b/apps/simplex-store-service/src/StoreService/Store/SQLite/Migrations.hs @@ -23,7 +23,8 @@ schemaMigrations = ("20261010_names", m20261010_names, Just down_m20261010_names), ("20261022_drop_taken_codes", m20261022_drop_taken_codes, Just down_m20261022_drop_taken_codes), ("20261022_name_balances", m20261022_name_balances, Just down_m20261022_name_balances), - ("20261022_name_late_wait", m20261022_name_late_wait, Just down_m20261022_name_late_wait) + ("20261022_name_late_wait", m20261022_name_late_wait, Just down_m20261022_name_late_wait), + ("20261023_name_terms", m20261023_name_terms, Just down_m20261023_name_terms) ] -- | The client tables share this database, so the service tables are the same names behind a prefix. @@ -461,6 +462,23 @@ down_m20261022_name_late_wait = ALTER TABLE @name_invoices DROP COLUMN late_support; |] +-- The terms an order signed; '' for an order stored before orders signed them. +m20261023_name_terms :: Query +m20261023_name_terms = + withPrefix + servicePrefix + [sql| +ALTER TABLE @name_registrations ADD COLUMN agreed_terms TEXT NOT NULL DEFAULT ''; +|] + +down_m20261023_name_terms :: Query +down_m20261023_name_terms = + withPrefix + servicePrefix + [sql| +ALTER TABLE @name_registrations DROP COLUMN agreed_terms; +|] + {- TODO [badges] deferred with the draft in M20260915_user_badges, service only. ALTER TABLE @payments ADD COLUMN receipt_hash BLOB; diff --git a/tests/Bots/StoreService/NamesStoreTests.hs b/tests/Bots/StoreService/NamesStoreTests.hs index f04baa5c27..985f3438c4 100644 --- a/tests/Bots/StoreService/NamesStoreTests.hs +++ b/tests/Bots/StoreService/NamesStoreTests.hs @@ -47,6 +47,7 @@ namesStoreTests = describe "StoreService names: store" $ do it "rolls back and re-applies only the names migrations, with rows in them, leaving the badge tables and paid invoices as they were" testNamesDownUp it "turns a code_issued order taken at price 0 and not live at its next version, dropping issued_code_id with its index and foreign key, which the down migration restores" testDropTakenCodes it "makes taken orders not live and gives a taken paid order a balance of its price, none to a code order or a price of 0, and rolls back the balance tables and columns" testNameBalancesMigration + it "gives the orders stored before it empty agreed terms, and rolls the column back keeping them" testNameTermsMigration describe "order hash" $ do it "is equal for the same order fields, and differs when any one field differs" testOrderHashFields it "keeps field boundaries, so moving a byte between two fields changes it" testOrderHashBoundaries @@ -181,7 +182,7 @@ testNamesColumns = withServiceStore $ \st -> do [ "registration_id", "label_hash", "length", "label", "secret", "contact_link", "channel_link", "intent_nonce", "intent_deadline", "intent_signature", "sealed", "owner", "commitment", "phase", "commit_tx", "commit_block", "register_tx", "register_block", "reveal_after", "reveal_before", "years", "duration", "expires_at", "price", "name_prepaid_code_id", "registered_at", "failed_at", "error", "created_at", - "updated_at", "version", "live", "order_hash", "method", "moves", "links_refused_at", "balance_source", "balance_used" + "updated_at", "version", "live", "order_hash", "method", "moves", "links_refused_at", "balance_source", "balance_used", "agreed_terms" ] has "sx_badge_service_name_invoices" ["invoice_id", "registration_id", "provider_ref", "late_alerted_at", "late_alerted_units", "late_support"] has "sx_badge_service_name_balances" ["registration_id", "amount", "credited", "refunded", "reserved_by", "refunded_at", "created_at", "updated_at"] @@ -194,7 +195,7 @@ testNamesDownUp :: IO () testNamesDownUp = withServiceStore $ \st -> do let names = dropWhile ((/= "20261010_names") . name) storeServiceSchemaMigrations badgeColumns = mapM (fmap sort . columnsOf st) badgeTables - map name names `shouldBe` ["20261010_names", "20261022_drop_taken_codes", "20261022_name_balances", "20261022_name_late_wait"] + map name names `shouldBe` ["20261010_names", "20261022_drop_taken_codes", "20261022_name_balances", "20261022_name_late_wait", "20261023_name_terms"] badgeBefore <- badgeColumns code <- issue st 1 usable placeCode st "r1" ownerA (order "alicebakery" 1) code `shouldReturn` Right () @@ -267,6 +268,31 @@ testNameBalancesMigration = withServiceStore $ \st -> do runMigrations st $ MTRUp balances balanceOf "paid" `shouldReturn` Just (price, price, 0, Nothing) +testNameTermsMigration :: IO () +testNameTermsMigration = withServiceStore $ \st -> do + let terms = [m | m@Migration {name = "20261023_name_terms"} <- storeServiceSchemaMigrations] + applied :: IO Bool + applied = elem "agreed_terms" <$> columnsOf st "sx_badge_service_name_registrations" + agreedTerms :: IO [(Text, Text)] + agreedTerms = withTransaction st $ \db -> DB.query_ db "SELECT registration_id, agreed_terms FROM sx_badge_service_name_registrations" + kept :: IO [(Text, Text, Int)] + kept = withTransaction st $ \db -> DB.query_ db "SELECT registration_id, phase, price FROM sx_badge_service_name_registrations" + length terms `shouldBe` 1 + runMigrations st $ MTRDown (mapMaybe toDownMigration terms) + applied `shouldReturn` False + withTransaction st $ \db -> do + insertInvoiceRow db "inv-paid" (at 60) "open" + insertOldRegistration db "paid" 1 "unpaid" price Nothing (Just "inv-paid") + kept `shouldReturn` [("paid", "unpaid", price)] + runMigrations st $ MTRUp terms + applied `shouldReturn` True + agreedTerms `shouldReturn` [("paid", "")] + runMigrations st $ MTRDown (mapMaybe toDownMigration terms) + applied `shouldReturn` False + kept `shouldReturn` [("paid", "unpaid", price)] + runMigrations st $ MTRUp terms + agreedTerms `shouldReturn` [("paid", "")] + -- | A registration row as the code before the balances wrote it, paid by the invoice or the code given. insertOldRegistration :: DB.Connection -> Text -> Word8 -> Text -> Int -> Maybe Int64 -> Maybe Text -> IO () insertOldRegistration db rid n phase cents codeId invId = do