Skip to content

feat(crm): add tenant-wide alias resolver#2109

Open
fredcamaral wants to merge 5 commits into
developfrom
feat/crm-search-filters
Open

feat(crm): add tenant-wide alias resolver#2109
fredcamaral wants to merge 5 commits into
developfrom
feat/crm-search-filters

Conversation

@fredcamaral
Copy link
Copy Markdown
Member

Summary

  • add tenant-wide CRM alias resolver endpoints for bank account and account ID lookups
  • add transactional alias_bank_account_index maintenance with tenant-wide uniqueness
  • add CRM resolver backfill endpoint and no-PII reporting
  • add org-scoped alias filters for banking_details_bank_id and banking_details_type
  • regenerate CRM OpenAPI/Swagger docs

Validation

  • git diff --check
  • go test ./pkg/net/http ./components/crm/internal/adapters/mongodb/alias ./components/crm/internal/services ./components/crm/internal/adapters/http/in
  • go test -tags=integration ./components/crm/internal/adapters/mongodb/alias -run 'TestIntegration_AliasRepo_(Update_NonIdentityBankingPatch|Create_|Resolve|Update_|Backfill|FindAll_FilterByBankIDAndType)' -count=1\n- go test ./components/crm/...\n- go test ./...\n- golangci-lint run ./components/crm/...\n\n## Notes\n- resolver routes use dedicated aliases:resolve permission\n- backfill route uses dedicated aliases:backfill permission\n- Mongo integration testcontainer now starts as a single-node replica set to exercise transactions\n- unrelated ledger formatter-only changes remain unstaged and are not included in this PR

@fredcamaral fredcamaral requested a review from a team as a code owner May 18, 2026 02:50
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4d91607e-8d19-4ea2-b19c-aedbe858be28

📥 Commits

Reviewing files that changed from the base of the PR and between c557c3b and 43ea821.

📒 Files selected for processing (7)
  • components/ledger/internal/adapters/http/in/transaction_overdraft_enrichment_test.go
  • components/ledger/internal/adapters/postgres/organization/organization.postgresql_property_test.go
  • components/ledger/internal/adapters/postgres/transaction/transaction.postgresql_property_test.go
  • components/ledger/internal/adapters/redis/transaction/consumer.redis_atomic_state_test.go
  • components/ledger/internal/adapters/redis/transaction/consumer.redis_settings_update_test.go
  • components/ledger/internal/bootstrap/backward_compat_test.go
  • components/ledger/internal/bootstrap/config.rabbitmq.go
💤 Files with no reviewable changes (3)
  • components/ledger/internal/adapters/postgres/organization/organization.postgresql_property_test.go
  • components/ledger/internal/adapters/redis/transaction/consumer.redis_atomic_state_test.go
  • components/ledger/internal/adapters/postgres/transaction/transaction.postgresql_property_test.go

Walkthrough

Adds tenant-wide alias resolution endpoints and a bank-account identity index with backfill; updates OpenAPI/Swagger and domain models; adds HTTP handlers, validation, service use-cases, transactional MongoDB persistence, index maintenance, mocks, and extensive tests plus replica-set test infra.

Changes

Alias Resolution and Bank Account Index Backfill

Layer / File(s) Summary
API Contracts and Domain Models
components/crm/api/openapi.yaml, components/crm/api/swagger.json, components/crm/api/swagger.yaml, components/crm/api/docs.go, pkg/mmodel/alias.go, pkg/constant/entity.go
Adds POST endpoints /v1/aliases/backfill-bank-account-index, /v1/aliases/resolve-account, /v1/aliases/resolve-bank-account; extends GET /v1/aliases query filters with banking_details_bank_id and banking_details_type; adds AliasResponse.organizationId and new request/response/backfill schemas.
HTTP Handlers & Query Parsing
components/crm/internal/adapters/http/in/*.go, pkg/net/http/httputils.go, tests
Adds handlers ResolveBankAccount, ResolveAccount, BackfillBankAccountIndex; extends QueryHeader to parse banking filters; adds handler error classification for business vs system errors; includes handler tests.
Route Registration
components/crm/internal/adapters/http/in/routes.go
Registers three new authenticated POST routes under /v1/aliases with appropriate authorization scopes and body binding.
Banking Identity Validation
components/crm/internal/services/validate-banking-details.go, create/update hooks and tests
Introduces validation enforcing all-or-nothing banking identity fields; integrated into CreateAlias and UpdateAliasByID flows and tested.
Alias Resolution & Backfill Services
components/crm/internal/services/resolve-alias.go, tests
Implements UseCase.ResolveBankAccount, ResolveAccount, BackfillBankAccountIndex with tracing, validation, singular-match enforcement, and mapping to ResolveAliasResponse. Unit tests cover success and error paths.
Bank Account Index Model
components/crm/internal/adapters/mongodb/alias/bank_account_index.go, tests
Adds BankAccountIndexModel with canonical branch logic, encryption/hashing of sensitive fields, timestamps, ToAlias conversion and model tests.
MongoDB Bank Account Index Repository
components/crm/internal/adapters/mongodb/alias/bank_account_index.mongodb.go
Implements index creation (unique compound with partial filter), upsert/replace with duplicate-key -> business error mapping, preflight conflict checks, ResolveBankAccount/ResolveAccount reads, and BackfillBankAccountIndex with dry-run duplicate detection and PII-safe reporting.
Repository Transactional Integration
components/crm/internal/adapters/mongodb/alias/alias.mongodb.go, alias.mongodb_mock.go
Alias repository wraps create/update/delete in transactions to keep alias documents and bank-account index consistent; adds Repository methods for resolution/backfill; mocks regenerated with new methods.
Query Filtering & Index Maintenance
components/crm/internal/adapters/mongodb/alias/alias_query.mongodb.go, alias_maintenance.mongodb.go, tests
FindAll now reports and filters by banking-details bank_id/type; index creation memoized per collection and new indexes added for banking fields with partial filter excluding soft-deleted rows.
Tests & Test Infrastructure
components/crm/internal/adapters/mongodb/alias/*_test.go, tests/utils/mongodb/container.go
Adds extensive unit and integration tests for model, repo, services, handlers, and backfill; MongoDB test container configured as replica set and waits for primary to support transactions.

Comment @coderabbitai help to get the list of available commands and usage tips.

@lerian-studio
Copy link
Copy Markdown
Contributor

lerian-studio commented May 18, 2026

📊 Unit Test Coverage Report: midaz-crm

Metric Value
Overall Coverage 86.1% ✅ PASS
Threshold 85%

Coverage by Package

Package Coverage
github.com/LerianStudio/midaz/v3/components/crm/internal/adapters/http/in 81.0%
github.com/LerianStudio/midaz/v3/components/crm/internal/adapters/mongodb/alias 93.3%
github.com/LerianStudio/midaz/v3/components/crm/internal/adapters/mongodb/holder 87.1%
github.com/LerianStudio/midaz/v3/components/crm/internal/services 88.8%

Generated by Go PR Analysis workflow

@lerian-studio
Copy link
Copy Markdown
Contributor

lerian-studio commented May 18, 2026

🔒 Security Scan Results — crm

Trivy

Filesystem Scan

✅ No vulnerabilities or secrets found.

Docker Image Scan

✅ No vulnerabilities found.


Docker Hub Health Score Compliance

✅ Policies — 4/4 met

Policy Status
Default non-root user ✅ Passed
No fixable critical/high CVEs ✅ Passed
No high-profile vulnerabilities ✅ Passed
No AGPL v3 licenses ✅ Passed

Pre-release Version Check

✅ No unstable version pins found.


🔍 View full scan logs

@lerian-studio
Copy link
Copy Markdown
Contributor

lerian-studio commented May 18, 2026

🔒 Security Scan Results — ledger

Trivy

Filesystem Scan

✅ No vulnerabilities or secrets found.

Docker Image Scan

✅ No vulnerabilities found.


Docker Hub Health Score Compliance

✅ Policies — 4/4 met

Policy Status
Default non-root user ✅ Passed
No fixable critical/high CVEs ✅ Passed
No high-profile vulnerabilities ✅ Passed
No AGPL v3 licenses ✅ Passed

Pre-release Version Check

✅ No unstable version pins found.


🔍 View full scan logs

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/crm/internal/adapters/http/in/alias.go`:
- Around line 375-489: The file contains multiple handler operations
(ResolveBankAccount, ResolveAccount, BackfillBankAccountIndex) in the same
source which violates the guideline "one handler/operation per file"; split each
handler into its own file (e.g., create separate files for ResolveBankAccount,
ResolveAccount, and BackfillBankAccountIndex) preserving the AliasHandler
methods, imports, tracer/log setup and associated comments/Swagger annotations,
and update package-level imports and build (if any) so each new file compiles
standalone within the adapters/http/in package.

In
`@components/crm/internal/adapters/mongodb/alias/alias.mongodb_integration_test.go`:
- Line 371: The test currently creates closingDate using time.Now() (closingDate
:= mmodel.Date{Time: time.Now().UTC().Add(24 * time.Hour)}), which makes the
test time-dependent; replace this with a fixed instant (e.g., construct a
deterministic time via time.Date(...) or the project's fixed-time test utility)
and seed mmodel.Date from that fixed instant so closingDate is deterministic
across runs.

In `@components/crm/internal/adapters/mongodb/alias/alias.mongodb.go`:
- Around line 89-100: The withTransaction method on MongoDBRepository should
short-circuit when the provided context is already canceled: before calling
db.Client().StartSession() check ctx.Err() and immediately return that error if
non-nil so you don't open a session for canceled requests; update the function
to perform this ctx.Err() guard at the top of withTransaction and keep the
existing session.StartSession/WithTransaction flow unchanged otherwise.

In `@components/crm/internal/adapters/mongodb/alias/bank_account_index_test.go`:
- Line 86: Replace the nondeterministic now := time.Now() in
bank_account_index_test.go with a fixed timestamp (e.g., time.Date(...)) and use
that fixed value for any CreatedAt/UpdatedAt fields in the test setup (the
variable currently named "now" and any structs that set CreatedAt/UpdatedAt) so
the test is deterministic; update any assertions expecting those timestamps to
use the same fixed value.

In
`@components/crm/internal/adapters/mongodb/alias/bank_account_index.mongodb.go`:
- Around line 315-357: Add explicit context cancellation checks (ctx.Err()) in
BackfillBankAccountIndex and backfillAliasCollection: before starting any
DB‑intensive operation (e.g., before db.ListCollectionNames, before calling
am.backfillAliasCollection, and before any heavy query/aggregation) and inside
long-running loops such as the cursor iteration in backfillAliasCollection; if
ctx.Err() != nil return early with the context error (or wrap it) so
cancellation/timeout stops work promptly and resources (cursors/span) are
cleaned up. Ensure the same pattern is applied to the later related flow (the
functions covering lines 360-448) and keep context as the first parameter in
those helper calls.

In `@components/crm/internal/services/resolve-alias.go`:
- Around line 21-49: Add an early context-cancellation short-circuit in
ResolveBankAccount by checking ctx.Err() immediately after starting the span and
before any expensive repo calls; if ctx.Err() != nil return nil, ctx.Err().
Specifically, insert the check before calling uc.AliasRepo.ResolveBankAccount
and before calling resolveOneAlias to avoid performing DB work for canceled
contexts; apply the same pattern to the other resolver methods referenced (the
methods around lines 51-83 and 166-186) so each method checks ctx.Err() right
after tracer.Start(...) and before any repository or heavy work.

In `@components/crm/internal/services/validate-banking-details.go`:
- Around line 65-73: The validation function is creating a child span for pure
in-memory validation: remove the tracer.Start(...) / defer span.End() lines and
stop calling libOpenTelemetry.HandleSpanBusinessErrorEvent from this validator;
instead keep NewTrackingFromContext(...) and only emit the logger.Log(...)
warning with the constructed error (err) so span emission remains at the
caller’s I/O boundary (refer to tracer.Start, span.End, and
libOpenTelemetry.HandleSpanBusinessErrorEvent in this file).

In `@pkg/mmodel/alias.go`:
- Line 81: Change the ID fields from plain strings to UUID types: replace
OrganizationID *string with *uuid.UUID, change any resolver ID fields and
backfill alias ID lists from string/[]string to uuid.UUID/*uuid.UUID and
[]uuid.UUID respectively, and update their struct definitions (e.g., the alias
DTO where OrganizationID is defined plus the other affected DTOs referenced in
the review) so JSON marshalling still uses the same tags; also add/import the
uuid package (github.com/google/uuid or your project's preferred uuid package)
where these structs are declared.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 439856a4-036c-4749-8434-315977ca6771

📥 Commits

Reviewing files that changed from the base of the PR and between 04fce3a and 5a12196.

📒 Files selected for processing (28)
  • components/crm/api/docs.go
  • components/crm/api/openapi.yaml
  • components/crm/api/swagger.json
  • components/crm/api/swagger.yaml
  • components/crm/internal/adapters/http/in/alias.go
  • components/crm/internal/adapters/http/in/alias_test.go
  • components/crm/internal/adapters/http/in/routes.go
  • components/crm/internal/adapters/mongodb/alias/alias.mongodb.go
  • components/crm/internal/adapters/mongodb/alias/alias.mongodb_integration_test.go
  • components/crm/internal/adapters/mongodb/alias/alias.mongodb_mock.go
  • components/crm/internal/adapters/mongodb/alias/alias.mongodb_test.go
  • components/crm/internal/adapters/mongodb/alias/alias_maintenance.mongodb.go
  • components/crm/internal/adapters/mongodb/alias/alias_query.mongodb.go
  • components/crm/internal/adapters/mongodb/alias/bank_account_index.go
  • components/crm/internal/adapters/mongodb/alias/bank_account_index.mongodb.go
  • components/crm/internal/adapters/mongodb/alias/bank_account_index_test.go
  • components/crm/internal/services/create-alias.go
  • components/crm/internal/services/create-alias_test.go
  • components/crm/internal/services/resolve-alias.go
  • components/crm/internal/services/resolve-alias_test.go
  • components/crm/internal/services/update-alias.go
  • components/crm/internal/services/update-alias_test.go
  • components/crm/internal/services/validate-banking-details.go
  • pkg/constant/entity.go
  • pkg/mmodel/alias.go
  • pkg/net/http/httputils.go
  • pkg/net/http/httputils_alias_bank_filters_test.go
  • tests/utils/mongodb/container.go

Comment thread components/crm/internal/adapters/http/in/alias.go Outdated
Comment thread components/crm/internal/adapters/mongodb/alias/alias.mongodb_integration_test.go Outdated
Comment thread components/crm/internal/adapters/mongodb/alias/alias.mongodb.go
Comment thread components/crm/internal/adapters/mongodb/alias/bank_account_index_test.go Outdated
Comment thread components/crm/internal/services/resolve-alias.go
Comment thread components/crm/internal/services/validate-banking-details.go
Comment thread pkg/mmodel/alias.go Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/crm/internal/adapters/mongodb/alias/alias.mongodb.go`:
- Around line 550-589: mergeAliasForBankAccountIndex currently only clears the
whole banking_details object but must also clear identity fields removed by
PATCH; update mergeAliasForBankAccountIndex to inspect fieldsToRemove for
"document"/"document", "account_id"/"accountId", "holder_id"/"holderId" and
nested banking fields like "banking_details.account", "bankingDetails.account",
"banking_details.bank", "bankingDetails.bank", "banking_details.iban", etc., and
when present set merged.Document = nil, merged.AccountID = nil, merged.HolderID
= nil, and clear the corresponding fields on merged.BankingDetails (or set
BankingDetails = nil if all its identity subfields are removed); handle both
snake_case and camelCase variants and perform these clears after merging (near
the existing loop over fieldsToRemove) so the candidate used by
preflightBankAccountIdentityConflict/replaceBankAccountIndex no longer contains
stale identity values.

In `@components/crm/internal/adapters/mongodb/alias/bank_account_index.go`:
- Around line 130-137: The code only validates organization_id with
parseRequiredUUIDString but leaves ledger_id and account_id unparsed; add
explicit parseRequiredUUIDString calls for model.LedgerID and model.AccountID
(after organizationID parsing) and return errors.New("malformed bank account
index row: invalid ledger_id") and errors.New("malformed bank account index row:
invalid account_id") on parse errors, keeping the existing zero-UUID check
(isZeroUUIDString) intact; reference the functions isZeroUUIDString and
parseRequiredUUIDString and the model fields LedgerID and AccountID to locate
where to insert the checks.

In `@components/crm/internal/services/resolve-alias.go`:
- Around line 117-121: The child span created for duplicate matches should be
removed and the business-error event should be emitted on the existing parent
span parameter instead; replace the tracer.Start/duplicateSpan creation and
duplicateSpan.End() with a direct call to
libOpenTelemetry.HandleSpanBusinessErrorEvent(span, "Duplicate active alias
resolver matches", err) after creating err via
pkg.ValidateBusinessError(cn.ErrAccountAlreadyAssociated, cn.EntityAlias),
mirroring the approach used in the case 0 branch and avoiding
libCommons.NewTrackingFromContext/tracer usage here.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ac5d63cb-f43f-44a3-b919-c91d36a1e078

📥 Commits

Reviewing files that changed from the base of the PR and between 5a12196 and de0f456.

📒 Files selected for processing (14)
  • components/crm/internal/adapters/http/in/alias.go
  • components/crm/internal/adapters/http/in/alias_test.go
  • components/crm/internal/adapters/http/in/backfill_bank_account_index.go
  • components/crm/internal/adapters/http/in/resolve_account.go
  • components/crm/internal/adapters/http/in/resolve_bank_account.go
  • components/crm/internal/adapters/mongodb/alias/alias.mongodb.go
  • components/crm/internal/adapters/mongodb/alias/alias.mongodb_integration_test.go
  • components/crm/internal/adapters/mongodb/alias/bank_account_index.go
  • components/crm/internal/adapters/mongodb/alias/bank_account_index.mongodb.go
  • components/crm/internal/adapters/mongodb/alias/bank_account_index_test.go
  • components/crm/internal/services/resolve-alias.go
  • components/crm/internal/services/resolve-alias_test.go
  • components/crm/internal/services/validate-banking-details.go
  • pkg/mmodel/alias.go

Comment thread components/crm/internal/adapters/mongodb/alias/alias.mongodb.go
Comment thread components/crm/internal/services/resolve-alias.go Outdated
@fredcamaral fredcamaral requested a review from a team as a code owner May 18, 2026 12:21
@lerian-studio
Copy link
Copy Markdown
Contributor

lerian-studio commented May 18, 2026

📊 Unit Test Coverage Report: midaz-ledger

Metric Value
Overall Coverage 85.4% ✅ PASS
Threshold 85%

Coverage by Package

Package Coverage
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/http/in 85.8%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/mongodb/onboarding 66.7%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/mongodb/transaction 66.7%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/account 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/accounttype 66.7%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/asset 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/assetrate 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/balance 97.5%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/ledger 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/operation 89.9%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/operationroute 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/organization 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/portfolio 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/segment 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/transaction 94.9%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/postgres/transactionroute 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/rabbitmq 91.5%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/redis/transaction/balance 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/services/command 86.9%
github.com/LerianStudio/midaz/v3/components/ledger/internal/services/query 93.1%
github.com/LerianStudio/midaz/v3/components/ledger/internal/services 0.0%

Generated by Go PR Analysis workflow

@fredcamaral
Copy link
Copy Markdown
Member Author

Fixes Applied Successfully

Fixed 5 file(s) based on 3 CodeRabbit feedback item(s).

Files modified:

  • components/crm/internal/adapters/mongodb/alias/alias.mongodb.go
  • components/crm/internal/adapters/mongodb/alias/alias.mongodb_test.go
  • components/crm/internal/adapters/mongodb/alias/bank_account_index.go
  • components/crm/internal/adapters/mongodb/alias/bank_account_index_test.go
  • components/crm/internal/services/resolve-alias.go

Commit: c557c3be3d7e322dc7b96c371356f04f7739ae28

The latest autofix changes are on the feat/crm-search-filters branch.

Format struct initializations, remove extraneous blank lines, and realign
map keys and comments across several test and configuration files in the
ledger component. This ensures compliance with standard Go formatting
conventions and improves code structure and readability.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants