Release: develop -> main#3616
Open
github-actions[bot] wants to merge 17 commits intomainfrom
Open
Conversation
…e + IBAN) (#3615) * feat: include BankTxReturn in compliance name search * feat: include BankTxRepeat in compliance name search and apply to IBAN search
Adds a PR check that fails when an existing migration file in migration/ is modified, renamed or deleted. Forces corrections to be applied as a new follow-up migration instead of editing the original, which would create drift between environments that have already run the old version and those that haven't.
When POST /recall is called without an explicit userId, resolve the user via the BankTx.user getter (transaction → buyCrypto → buyCryptoChargeback → buyFiats). Load the top-level relations so the getter can resolve through the eager transaction.user chain. Backward compatible: callers passing userId explicitly keep their existing behavior.
* feat: include recall info in bank tx support responses Compliance search and user-data detail responses now include an optional recall object on each BankTxSupportInfo. The frontend can render recall status inline without an additional roundtrip. - RecallService.findByBankTxIds batches the lookup for all bankTxs of a response - SupportService maps recalls by bankTx id and hands them to toBankTxDto * rename: findByBankTxIds → getByBankTxIds for naming consistency
* feat: support Sepolia for faucet and use fixed ETH amount Switch faucet blockchain based on environment (Sepolia on DEV/LOC, Ethereum otherwise) and replace CHF-based amount conversion with a fixed native-coin amount (0.0005 ETH). * refactor: align faucet blockchain field with existing pattern Match the readonly field style used in realunit.service.ts for environment-based blockchain selection. * feat: enable faucet by default on DEV and LOC environments Faucet is required for the BitBox RealUnit sell flow on Sepolia (DEV/LOC). Keep the ENV flag as an explicit override for PRD. * chore: remove stale FAUCET_ENABLED from env examples The flag is auto-enabled on DEV and LOC and only relevant on PRD, where it is configured via deployment secrets.
* feat: add report fields to Mros entity Extends the Mros entity with the core goAML SAR report-content fields that every MROS submission needs: - reportCode (default SAR) - reason (Sachverhalt long text) - action (Grund / Unternommen long text) - indicators (JSON-serialised array of goAML indicator codes) reason/action/indicators are nullable for backward compatibility with existing rows; the DTOs mark them optional so the UI can roll the fields out gradually. * style: simplify indicatorCodes setter to match priceStepsObject pattern * revert: remove hand-written migration To be replaced by a TypeORM-generated migration via npm run migration AddMrosReportFields so the DEFAULT/constraint names match TypeORM's deterministic hash naming (learned from PR #3613 / constraint-name drift).
Documents the repo-specific rules that keep biting contributors and AI assistants: - Migrations must be generated via 'npm run migration', not hand- written (constraint-name drift, see PR #3613 / #3614). - Migrations are immutable once merged — CI enforces it. - Canonical JSON-column pattern (getter/setter) from buy-crypto.entity.ts. - Create vs Update DTO conventions (IsOptional vs IsOptionalButNotNull). - Service update pattern with Object.assign + typed setters. - Branch / commit / release-PR workflow.
… stats single query (#3593) * feat: support dashboard counts endpoint, configurable clerks, message stats single query - add GET /support/issue/counts endpoint (single GROUP BY query instead of 3 list calls) - add GET /support/issue/clerks endpoint, reads from supportClerks setting with 'Support' fallback - register supportClerks string[] setting - getMessageStats: collapse 2 queries into 1 via correlated subquery - drop single state filter in favor of states list (comma-separated) - add reusable StringToArray() DTO transform decorator - restore original clerk assignment (last-writer-wins) on message creation * feat: support issue activity endpoint for dashboard message polling * refactor: extract role-department map, use typeorm subquery for message stats
Follow-up to PR #3621 — the entity columns reportCode/reason/action/ indicators were merged without a corresponding migration. Constraint names match TypeORM's auto-generated format (DF_ + sha1('mros_<column>').substring(0, 27)) so a future 'npm run migration' run on this schema doesn't see drift.
…3628) Reality update from PR #3621: contributors / AI assistants without local DB setup couldn't run 'npm run migration', so they skipped the migration entirely (David caught it after merge). The strict ban on hand-writing didn't survive contact with that case. The new policy keeps 'npm run migration' as the preferred path but adds an explicit fallback: hand-written is allowed if the constraint names match TypeORM's deterministic algorithm. Documents the formula (prefix + sha1 substring + length per constraint type) and the many-to-many join-table conventions. Verifiable: every contributor can sanity-check their hashes against existing 'AddMros'-style constraints before pushing.
* feat: compliance pending reviews endpoint Adds /support/pending-reviews and /support/pending-reviews/items endpoints aggregating all kyc_step and bank_data entries in ManualReview or InternalReview, grouped by type and name. Replaces the external NutzerMonitoring Google Sheet for manual compliance tasks. * refactor: simplify pending review list queries
…3629) * feat: throw TfaRequiredException with stable code for 2FA responses Replaces the generic ForbiddenException thrown by checkVerification with a dedicated TfaRequiredException carrying code "2FA_REQUIRED", matching the existing pattern of KycLevelRequiredException and RegistrationRequiredException. Without a stable code, clients had to fall back to a statusCode == 403 heuristic, which conflicts with all other 403 paths (account blocked, country not allowed, permission denied, etc.). With this change, clients can match on code instead and trigger the correct 2FA flow. Includes the optional level field in the response payload so clients can distinguish basic from strict 2FA where relevant. * refactor: tighten TfaRequiredException — TfaLevel type, TFA_REQUIRED code - Use TfaLevel enum (via import type to avoid runtime circular dep) so callers get type-safe level argument instead of arbitrary string. - Switch code to TFA_REQUIRED for consistency with the alphabetic SCREAMING_SNAKE_CASE convention used by KYC_LEVEL_REQUIRED and REGISTRATION_REQUIRED. The Tfa identifier namespace is what the rest of the codebase uses for machine-readable references (TfaService, TfaLevel, TfaType); 2FA stays in user-facing strings. - Hoist level?.toLowerCase() into a local to remove the duplicate call.
Add backend support for the new compliance call-queue feature, exposing five queues based on AML pending transactions and unavailable/suspicious phone-call userData. Endpoints (all guarded by COMPLIANCE role): - GET support/call-queues — counts per queue - GET support/call-queues/clerks — clerk list from setting - GET support/call-queues/:queue/items — items per queue (limit 200) Service layer: - BuyCryptoService.getByAmlReason / countByAmlReason - BuyFiatService.getByAmlReason / countByAmlReason - UserDataService.getByPhoneCallStatuses / countByPhoneCallStatuses All use find() with loadEagerRelations:false (consistent with the pending-review query refactor in #3599). Misc: - Register complianceClerks string[] setting - Extend UserDataComplianceUpdateCols with phoneCallStatus and the four phoneCall*CheckDate fields, so they can be set via the existing admin update endpoint - Resolve usedRef -> refUserName in bulk in UserSupportInfo (one extra query, no N+1) - Drop redundant 'name' field from BankDataService.getPendingReviewSummary return type (unused after #3599) - ParseEnumPipe on the queue param to fail-fast on invalid values
* feat: link transactions to Mros via many-to-many A compliance officer selects which transactions are relevant to an MROS report — goAML XML needs these as structured transaction nodes (t_from_my_client / t_to_my_client) at export time. - Many-to-many relation on Mros.transactions (new join table generated by typeorm via migration) - transactionIds: number[] on create/update DTO; service resolves to Transaction entities via the new TransactionService.getTransactionsByIds - Update loads the existing transactions relation so replacing the selection works cleanly Migration to be generated locally via npm run migration AddMrosTransactionsRelation (per CONTRIBUTING.md). * feat: add migration for mros transactions many-to-many Join table mros_transactions_transaction with composite PK + indices + cascading FKs on both sides. All constraint names computed via TypeORM's DefaultNamingStrategy (sha1(table_name + '_' + column).substring(0, N)) so future 'npm run migration' won't see drift.
davidleomay
previously approved these changes
Apr 28, 2026
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: 1 new commit(s)
Checklist