fix(transactions): drop suppressed transactions from the transactions page
The SSR transactions page listed transactions flagged :transaction-approval-status/suppressed, which the GraphQL/CLJS page has always excluded (auto-ap.datomic.transactions, the true branch of its cond->>), as do the ledger queries in auto-ap.ledger. Suppressing a transaction is the user's way of saying 'stop showing me this', so the same transaction stayed visible on the page it was suppressed from. The scan-transactions ion does no status filtering of its own, so nothing downstream was dropping them: for the worst-affected client a five-year range returned 14,736 rows against 3,641 real ones -- the other 11,095 were suppressed. 22,813 suppressed transactions exist db-wide. Filtered inside the query rather than after it so that the row count and the amount total, both derived from fetch-ids, match the rows rendered. Measured 6ms -> 29ms on that worst-case client and range. The three status routes (approved, unapproved, requires-feedback) constrain the status themselves and there is no suppressed route, so no page loses its own rows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -132,7 +132,13 @@
|
|||||||
valid-clients]}
|
valid-clients]}
|
||||||
(cond-> {:query {:find []
|
(cond-> {:query {:find []
|
||||||
:in ['$ '[?clients ?start ?end]]
|
:in ['$ '[?clients ?start ?end]]
|
||||||
:where '[[(iol-ion.query/scan-transactions $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]]}
|
;; Suppressed transactions are never listed -- the GraphQL page has
|
||||||
|
;; always dropped them (auto-ap.datomic.transactions/graphql-results),
|
||||||
|
;; as do the ledger queries. The three status routes (approved,
|
||||||
|
;; unapproved, requires-feedback) constrain the status themselves, and
|
||||||
|
;; there is no suppressed route, so this never hides a page's own rows.
|
||||||
|
:where '[[(iol-ion.query/scan-transactions $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]
|
||||||
|
(not [?e :transaction/approval-status :transaction-approval-status/suppressed])]}
|
||||||
:args [db
|
:args [db
|
||||||
[valid-clients
|
[valid-clients
|
||||||
(some-> (:start-date query-params) coerce/to-date)
|
(some-> (:start-date query-params) coerce/to-date)
|
||||||
|
|||||||
68
test/clj/auto_ap/ssr/transaction/common_test.clj
Normal file
68
test/clj/auto_ap/ssr/transaction/common_test.clj
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
(ns auto-ap.ssr.transaction.common-test
|
||||||
|
(:require
|
||||||
|
[auto-ap.datomic :refer [conn]]
|
||||||
|
[auto-ap.integration.util :refer [setup-test-data test-bank-account test-client
|
||||||
|
test-transaction wrap-setup]]
|
||||||
|
[auto-ap.ssr.transaction.common :as sut]
|
||||||
|
[clojure.test :refer [deftest is testing use-fixtures]]
|
||||||
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
|
(use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
|
(defn- fetch
|
||||||
|
"Runs the transactions page query the way the page does, over a range wide
|
||||||
|
enough to cover the fixture data."
|
||||||
|
[client-id & {:keys [route-params query-params]}]
|
||||||
|
(sut/fetch-ids (dc/db conn)
|
||||||
|
{:clients [client-id]
|
||||||
|
:route-params (or route-params {})
|
||||||
|
:query-params (merge {:start-date "2021-01-01"
|
||||||
|
:end-date "2023-12-31"}
|
||||||
|
query-params)}))
|
||||||
|
|
||||||
|
(deftest fetch-ids-suppressed-test
|
||||||
|
(let [{:strs [suppressed-client kept-tx suppressed-tx]}
|
||||||
|
(setup-test-data
|
||||||
|
[(test-bank-account :db/id "suppressed-bank")
|
||||||
|
(test-client :db/id "suppressed-client"
|
||||||
|
:client/bank-accounts ["suppressed-bank"])
|
||||||
|
(test-transaction :db/id "kept-tx"
|
||||||
|
:transaction/client "suppressed-client"
|
||||||
|
:transaction/bank-account "suppressed-bank"
|
||||||
|
:transaction/date #inst "2022-06-01"
|
||||||
|
:transaction/amount 100.0
|
||||||
|
:transaction/approval-status :transaction-approval-status/approved)
|
||||||
|
(test-transaction :db/id "suppressed-tx"
|
||||||
|
:transaction/client "suppressed-client"
|
||||||
|
:transaction/bank-account "suppressed-bank"
|
||||||
|
:transaction/date #inst "2022-06-02"
|
||||||
|
:transaction/amount 250.0
|
||||||
|
:transaction/approval-status :transaction-approval-status/suppressed)])]
|
||||||
|
|
||||||
|
(testing "Should leave a suppressed transaction out of the transactions page"
|
||||||
|
(let [{:keys [ids all-ids count]} (fetch suppressed-client)]
|
||||||
|
(is (= [kept-tx] (vec ids)))
|
||||||
|
(is (not (contains? (set all-ids) suppressed-tx))
|
||||||
|
"a suppressed transaction must not reach the amount total either")
|
||||||
|
(is (= 1 count)
|
||||||
|
"the row count has to match what the page renders, not the unfiltered scan")))
|
||||||
|
|
||||||
|
(testing "Should still list a transaction on an explicit status route"
|
||||||
|
(let [{:keys [ids]} (fetch suppressed-client
|
||||||
|
:route-params {:status :transaction-approval-status/approved})]
|
||||||
|
(is (= [kept-tx] (vec ids)))))
|
||||||
|
|
||||||
|
(testing "Should return nothing for a client whose transactions are all suppressed"
|
||||||
|
(let [{:strs [empty-client]}
|
||||||
|
(setup-test-data
|
||||||
|
[(test-bank-account :db/id "empty-bank")
|
||||||
|
(test-client :db/id "empty-client"
|
||||||
|
:client/bank-accounts ["empty-bank"])
|
||||||
|
(test-transaction :db/id "only-tx"
|
||||||
|
:transaction/client "empty-client"
|
||||||
|
:transaction/bank-account "empty-bank"
|
||||||
|
:transaction/date #inst "2022-06-03"
|
||||||
|
:transaction/approval-status :transaction-approval-status/suppressed)])
|
||||||
|
{:keys [ids count]} (fetch empty-client)]
|
||||||
|
(is (empty? ids))
|
||||||
|
(is (= 0 count))))))
|
||||||
Reference in New Issue
Block a user