Release: develop -> main - #207
Open
github-actions[bot] wants to merge 15 commits into
Open
Conversation
…unt (#204) * feat(core,react): let the buy invoice call target the collection account PUT buy/paymentInfos/:id/invoice accepts an optional collectionAccount query switch: when set, the API issues the invoice against the shared DFX collection account instead of the personal virtual IBAN stored on the request (DFXswiss/backend#4686). The switch lives in BuyUrl.invoice, the single place that owns the URL shape, and is passed through by both callers — BuyApi.getInvoice and useBuy().invoiceFor. Putting it in either caller would have placed the query form next to the other one instead of inside it. The parameter is omitted rather than sent as false, because the API maps any present value to true (Util.mapBooleanQuery). It is optional, so every existing caller stays source-compatible: this is additive. Consumer: DFXswiss/app#1270, which currently hand-builds this URL through useApi() because the SDK does not carry the switch. * refactor(core,react): build the collection-account query the way the repo does Review found the first commit hand-rolled the query inside the URL builder. That is the construct commit c6c0411 ("Improve @dfx.swiss/core package quality", #152) removed across the package: definitions/*Url carries the path, the core client builds its query with Utils.buildQuery, and the react hook builds it inline. The exact twin is the optional includeTx switch — SwapApi.ts:14 and SellApi.ts:14 on the client side, swap.hook.ts:23 and sell.hook.ts:20 in the hooks. So BuyUrl.invoice is back to its develop state, BuyApi.getInvoice follows SwapApi.createPaymentInfo, and useBuy().invoiceFor follows swap.hook.ts. The resulting URLs are unchanged. Also drops the comment attributing the design to Util.mapBooleanQuery. That attribution was wrong: this endpoint compares the query against the literal 'true' (DFXswiss/backend#4686) and deliberately does not use presence semantics. Omitting the parameter on false stays correct; only the stated reason was. The three getInvoice tests now assert the returned document as well. Without that, an implementation returning a wrong object passed all of them and tsc -b too, while both sibling specs in the same directory already assert it. * refactor(react): narrow the change to exactly the requested hook edit The review on DFXswiss/app#1270 asked for one thing: give useBuy().invoiceFor an optional collectionAccount parameter so the app stops hand-building the request. It supplied the code and called it a two-line change in buy.hook.ts. The previous two commits went further — they widened BuyApi.getInvoice and added a core test file. Both are reverted here. BuyApi.getInvoice has no caller in this monorepo or in services and was reachable only through DfxApiClient.buy, so widening it was not required to unblock the consumer, and carrying it made this PR larger than what was asked for. What remains is the reviewer's own code, verbatim: the optional parameter on the interface, and the ternary inline in the call. Every existing caller stays source-compatible. Consequence, stated rather than hidden: the switch ships with no test. @dfx.swiss/react defines no test script — per CONTRIBUTING only core and bip322-multisig do — and this PR does not add test infrastructure to react. The same is true today for the includeTx switch in swap.hook.ts and sell.hook.ts. * test(core): cover the collection-account switch on the buy client The hook edit alone shipped the switch untested: @dfx.swiss/react has no test runner, so nothing in this repo would have noticed if the parameter stopped being forwarded. BuyApi.getInvoice calls the same endpoint and lives in the one package that does run tests, so the switch is covered there. It follows the pattern the package already uses for optional boolean queries — Utils.buildQuery with `value || undefined`, exactly as SwapApi.createPaymentInfo and SellApi.createPaymentInfo handle includeTx. BuyUrl.invoice stays path-only. The hook keeps the form the review asked for; core and hook build the query differently, which is the same split swap.hook.ts/SwapApi.ts and sell.hook.ts/SellApi.ts already have. Both produce identical URLs for every value the type permits. Three tests, each asserting the full request options and the returned document. Verified by mutation: dropping `|| undefined` fails 2 of 3, not appending the query fails 1 of 3, returning a wrong document fails 3 of 3.
…e be sent again (#210) * fix(react): keep the support chat sync alive and settle messages by id The 5-second sync was a chain, not a loop: each run scheduled the next only because it changed state, so a single failed request ended it for good and the chat silently stopped receiving messages. - run the sync on a real interval, reading current state through refs - settle optimistic messages by id instead of index, so parallel uploads and a message at position 0 land correctly - anchor the delta on the highest settled id, falling back to a full sync - drop the optimistic entry when a sync already delivered the settled message - replace state instead of mutating it, so StrictMode no longer duplicates - add a jest setup for the package, which lerna previously skipped * feat(react): let a failed message be sent again A send that fails keeps its negative placeholder id and lives only in this context, so the text was unreachable: nothing could retry it and nothing could remove it. The next loadSupportIssue rebuilt the state from the server and the customer's message was gone. retryMessage claims the entry in place, puts it back to Sent and runs the same path as the first attempt. Unknown or already-sent ids are a no-op, so a double click cannot send twice. * fix(react): drop a sync response that belongs to a different ticket The five-second sync reads the open issue from a ref, asks the API for it, and merges whatever comes back into whatever is open by then. Nothing compared the two. Switching tickets while a getIssue is in flight therefore merged the old ticket's messages into the new one -- foreign conversation inside an open support chat. The ref lags the state by an effect tick, which widens the window, and keeping the sync alive after an error widens it further. Compare the uid and discard a response that does not belong to the issue on screen. The comparison lives with the other pure message helpers so it is covered by their tests.
* Add the Yapeal member to the PersonalIbanProvider enum The API accepts 'Yapeal' as an explicit personalIbanProvider selector on the buy payment-info request: it returns the customer's existing active legacy Yapeal personal IBAN, fail-closed, and never issues a new one. The frontend needs the member to build the provider switch next to the payment details. The enum string values are wire format, so a test pins them. * test(core): prove the personalIbanProvider wire transport The enum-value pin compared the member to its own literal - a tautology that stays green if BuyApi stops forwarding the field. The new case calls createPaymentInfo against the mocked HTTP client and asserts the raw 'Yapeal' string on the forwarded request data. * feat(core,react): serve the personal-IBAN row list through the SDK The buy flow needs the customer's personal-IBAN rows (now carrying the issuing bank) to decide whether a legacy Yapeal row exists before choosing the default provider. GET buy/personalIban joins the SDK as BuyApi.getPersonalIbans and useBuy().getPersonalIbans with the VirtualIban type, so the frontend consumes the endpoint through the SDK instead of a hand-built call. A transport test pins the request shape. * style(react): annotate getPersonalIbans with its promise return type Every other callback in the package spells the return type; the new getter was the single exception.
…#224) * Scope develop PR CI to changed packages and honour ci:full Lerna lint, format, build and test run with --since on develop PRs. The ci:full label, main, workflow_dispatch, infrastructure changes and deletions under packages/ force the full workspace run. * Fail-closed on unknown scope mode and name every full-run trigger Root eslint/prettier configs force a full Lerna run. Task steps reject an unknown mode. CONTRIBUTING lists the exact triggers. * Match CONTRIBUTING and the infra comment to the full-run list Spell out the safe path set and name eslint/prettier in the infrastructure comment. Local Lerna commands always cover every package.
…lop (#225) * Reject pull requests into main that are not from develop GitHub cannot restrict the source branch natively. This required check allows only this repository's develop branch to target main. * chore(ci): fail closed when pull_request head metadata is empty Empty strings pass set -u. Without this check a missing repo name plus head ref develop would accept the pull request.
Add a unit spec for every public method and for the private filter query builder via exportCsv and getHistory.
Historical closes-links must keep resolving after the new api repo exists. Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automatic Release PR
This PR was automatically created after changes were pushed to develop.
Commits: 3 new commit(s)
Checklist