Skip to content

feat: release candidate of balance overdraft feature (v3.7.0)#2088

Merged
ClaraTersi merged 125 commits into
mainfrom
release-candidate
Apr 30, 2026
Merged

feat: release candidate of balance overdraft feature (v3.7.0)#2088
ClaraTersi merged 125 commits into
mainfrom
release-candidate

Conversation

@ClaraTersi
Copy link
Copy Markdown
Member

Summary

  • Adds balance overdraft support, including direction-aware balances, overdraft limits, repayment handling, companion operations, operation snapshots, and related migrations.
  • Adds /readyz readiness implementations for Ledger and CRM with TLS detection, health checks, metrics, and lifecycle handling.
  • Expands onboarding list filters, status validation, indexes, API docs, and integration coverage.
  • Updates CI/shared workflows, security documentation, dependencies, and test container tooling.

Operational Notes

  • Includes new Ledger migrations for onboarding filters, balance overdraft fields, unique balance keys, and operation snapshots.
  • Updates API documentation and Postman collection artifacts.

ClaraTersi and others added 30 commits April 14, 2026 10:46
chore: sync main to develop [skip ci]
chore: sync main to develop [skip ci]
Adopt the org-wide SECURITY.md template with:

- GitHub Security Advisory as preferred reporting channel
- Response timeline table (24h ack → 90d resolution)
- Clear scope (in/out) with dependency nuance
- Supported versions table
- Secrets management guidance for dev and production
- Standardized contact section

Part of the SECURITY.md standardization initiative across all
LerianStudio public repositories.

Requested-by: @jota-music
…cluding status, legal document, name, and alias ✨
…tion errors for ledgers and organizations 🔨
chore: sync main to develop [skip ci]
…tion errors for accounts in PostgreSQL repository 🔨
…lters-1

feat: implement onboarding list endpoint filters
- bump remaining @v1.26.1 refs (s3-upload, api-dog-e2e-tests) to v1.26.3
- add top-level permissions block for pr-security-scan caller
…s-v1.26.3

chore(workflows): bump shared-workflows to v1.26.3
…, entity ID, blocked status, and parent account ID ✨
…tion and implement new status filtering for portfolios 🔨
… services and update validation error messages 🔨
feat(ledger): add  readyz implementation and related tests
@ClaraTersi ClaraTersi requested review from a team as code owners April 30, 2026 13:04
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

Walkthrough

This pull request upgrades the lib-commons dependency from v4 to v5 across CRM and ledger components, updates GitHub Actions workflows to use v1.27.5, transitions the project license from Apache 2.0 to Elastic License 2.0, introduces comprehensive overdraft support with transaction enrichment, implements a new readiness health-check endpoint with dependency validators and TLS enforcement policies, and updates API documentation to reflect new filtering capabilities and schema changes.

Changes

Cohort / File(s) Summary
GitHub Actions Workflows
.github/workflows/build.yml, go-combined-analysis.yml, gptchangelog.yml, pr-security-scan.yml, pr-validation.yml, release-notification.yml, release.yml
Updated all reusable workflow references from v1.26.1 to v1.27.5. Added explicit permissions block to pr-security-scan.yml. Updated Go toolchain version from 1.25.8 to 1.25.9 in go-combined-analysis.yml and removed shared_paths input.
License and Documentation
README.md, SECURITY.md
Transitioned license from Apache 2.0 to Elastic License 2.0 with updated badge, product terminology to "source-available," and comprehensive security policy documentation including vulnerability reporting procedures, supported versions, and deployment-specific guidance.
CRM Environment and Version
components/crm/.env.example, components/crm/api/crm_docs.go, components/crm/api/crm_swagger.*, components/crm/cmd/app/main.go
Bumped CRM version to v3.7.0, added DEPLOYMENT_MODE environment variable (supporting local/saas/byoc modes), updated Swagger/OpenAPI API version metadata from 1.0.0 to v3.7.0.
CRM Bootstrap and Readiness
components/crm/internal/bootstrap/readyz.go, readyz_checkers.go, readyz_*_test.go, tls_detection.go, tls_detection_test.go, config.go, server.go
Introduced new readiness endpoint (/readyz) with dependency health checkers (MongoChecker, NAChecker), TLS enforcement/validation for deployment modes, server lifecycle state management (ready/draining), and comprehensive test coverage. Added TLS detection from MongoDB URIs with deployment mode handling.
CRM HTTP Handlers and Routes
components/crm/internal/adapters/http/in/alias.go, alias_test.go, holder.go, routes.go, swagger.go
Updated route parameter naming from :id to :alias_id, added ReadyzHandler interface and integration into router, updated Fiber locals extraction for alias UUID retrieval.
CRM lib-commons Dependency Upgrades
components/crm/internal/adapters/.../*.go, components/crm/internal/bootstrap/.../*.go, components/crm/internal/services/.../*.go
Bulk upgrade of lib-commons imports from v4 to v5 across all MongoDB adapters, HTTP handlers, service layer, and bootstrap modules.
Ledger Environment and Version
components/ledger/.env.example, Dockerfile, cmd/app/main.go
Bumped ledger version to v3.7.0, added DEPLOYMENT_MODE and RabbitMQ overdraft event configuration variables (RABBITMQ_OVERDRAFT_EVENTS_ENABLED, RABBITMQ_OVERDRAFT_EVENTS_EXCHANGE), updated Swagger documentation to reflect Elastic License 2.0.
Ledger API Documentation
components/ledger/api/docs.go, openapi.yaml, swagger.json
Updated API version to v3.7.0, added comprehensive query filtering for organizations, ledgers, account types, accounts, and portfolios; introduced per-balance overdraft settings; standardized path parameter naming (id → resource-specific IDs); added balance-level overdraft and direction fields; new mmodel.BalanceSettings schema.
Ledger HTTP Handlers - Account/Ledger/Organization
components/ledger/internal/adapters/http/in/account.go, account_test.go, ledger.go, ledger_test.go, organization.go, organization_test.go, accounttype.go, accounttype_test.go
Updated route parameters to be resource-specific (e.g., :account_id, :ledger_id, :organization_id), added status validation for account/ledger/organization filtering with HTTP 400 error handling, replaced reflect.TypeOf() with constants for entity identification.
Ledger HTTP Handlers - Transaction Overdraft
components/ledger/internal/adapters/http/in/transaction_create.go, transaction_overdraft_enrichment.go, transaction_overdraft_enrichment_test.go, transaction_*_test.go, operation_route.go, operation_route_overdraft_*_test.go
Introduced overdraft enrichment logic with companion balance operations, snapshot tracking, effective operation amount calculation, refund/cancellation handling, and comprehensive test coverage. Extended accounting validation to support overdraft scenario with mandatory debit/credit checks.
Ledger PostgreSQL Repositories - General
components/ledger/internal/adapters/postgres/account/account.postgresql.go, ledger.postgresql.go, organization.postgresql.go, portfolio.postgresql.go, accounttype.postgresql.go
Refactored FindAll repository methods to accept http.QueryHeader instead of separate pagination and filter parameters, added entity ID filtering, status/legal document filtering, name/alias prefix searching with wildcard protection.
Ledger PostgreSQL Models - Balance Overdraft
components/ledger/internal/adapters/postgres/balance/balance.go, balance.postgresql.go, balance_overdraft_*_test.go
Added persistence for direction, overdraft_used, and settings JSONB columns, implemented round-trip serialization/deserialization for balance settings, added batch update support for overdraft used values.
Ledger PostgreSQL Models - Operation Snapshot
components/ledger/internal/adapters/postgres/operation/operation.go, operation.postgresql.go, operation_*_snapshot_*.go, operation_balance_overdraft_used_test.go
Added snapshot JSONB column storing overdraft usage before/after operation, implemented typed decimal field population from snapshot strings with defensive zero-filling, comprehensive snapshot round-trip and migration path testing.
Ledger PostgreSQL Mock Updates
components/ledger/internal/adapters/postgres/.../...postgresql_mock.go
Updated mock signatures to match repository interface changes (pagination parameter types, removed extra arguments), regenerated with updated mockgen directives.
RabbitMQ and Infrastructure
components/infra/rabbitmq/etc/definitions.json
Added new durable topic exchange transaction.overdraft_events.exchange for overdraft event publishing.
All Components - lib-commons v4→v5
Across ledger/crm service layers, adapters, and tests
Systematic upgrade of all github.com/LerianStudio/lib-commons import paths from /v4/ to /v5/ affecting commons utilities, logging, OpenTelemetry, tenant-manager, PostgreSQL, MongoDB, and RabbitMQ client integrations.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Handler as Transaction Handler
    participant Enricher as Overdraft Enricher
    participant CompLoader as Companion Loader
    participant TxCore as Transaction Core
    participant DB as Database

    Client->>Handler: POST /transactions (with overdraft debit)
    Handler->>Handler: Validate input & load balances
    Handler->>Enricher: enrichOverdraftOperations()
    Enricher->>Enricher: Detect debit overflow on<br/>credit balance
    Enricher->>CompLoader: Load overdraft companion<br/>balance
    CompLoader-->>Enricher: Companion balance
    Enricher->>Enricher: Create synthetic overdraft<br/>operation (debit direction)
    Enricher-->>Handler: companionFromTos list
    Handler->>TxCore: BuildOperations with<br/>companion operations
    TxCore->>TxCore: Calculate snapshots &<br/>overdraft used per-op
    TxCore-->>Handler: Operations including<br/>companion operations
    Handler->>DB: Persist transaction &<br/>all operations
    DB-->>Handler: Success
    Handler-->>Client: 201 Created with<br/>source/destination filtered
Loading
sequenceDiagram
    participant Client
    participant Readyz as Readyz Handler
    participant Checkers as Dependency Checkers
    participant Mongo as MongoDB
    participant Metrics as Metrics Registry

    Client->>Readyz: GET /readyz
    Readyz->>Readyz: Check server lifecycle<br/>(ready/draining)
    alt Not ready or draining
        Readyz-->>Client: 503 Unavailable
    else Ready
        Readyz->>Checkers: Run all checks with<br/>timeout
        Checkers->>Mongo: Ping()
        Mongo-->>Checkers: Latency & status
        Checkers-->>Readyz: DependencyCheck[]
        Readyz->>Metrics: Record check duration<br/>& status per checker
        Readyz->>Readyz: Aggregate status<br/>(all up vs unhealthy)
        alt All up
            Readyz-->>Client: 200 OK, status=healthy
        else Any down
            Readyz-->>Client: 503 Unavailable,<br/>status=unhealthy
        end
    end
Loading

@lerian-studio
Copy link
Copy Markdown
Contributor

lerian-studio commented Apr 30, 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 Apr 30, 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

@lerian-studio
Copy link
Copy Markdown
Contributor

lerian-studio commented Apr 30, 2026

📊 Unit Test Coverage Report: midaz-crm

Metric Value
Overall Coverage 87.7% ✅ PASS
Threshold 85%

Coverage by Package

Package Coverage
github.com/LerianStudio/midaz/v3/components/crm/internal/adapters/http/in 86.2%
github.com/LerianStudio/midaz/v3/components/crm/internal/adapters/mongodb/alias 92.1%
github.com/LerianStudio/midaz/v3/components/crm/internal/adapters/mongodb/holder 87.1%
github.com/LerianStudio/midaz/v3/components/crm/internal/services 95.2%

Generated by Go PR Analysis workflow

@lerian-studio
Copy link
Copy Markdown
Contributor

lerian-studio commented Apr 30, 2026

📊 Unit Test Coverage Report: midaz-ledger

Metric Value
Overall Coverage 85.3% ✅ PASS
Threshold 85%

Coverage by Package

Package Coverage
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/http/in 85.7%
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 90.6%
github.com/LerianStudio/midaz/v3/components/ledger/internal/adapters/redis/transaction/balance 100.0%
github.com/LerianStudio/midaz/v3/components/ledger/internal/services/command 87.0%
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

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: 22

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (11)
components/ledger/internal/adapters/postgres/ledger/ledger.postgresql_integration_test.go (1)

143-150: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use a fixed timestamp in defaultQueryHeader.

This helper now makes every FindAll test depend on wall-clock time. Please anchor the range to a fixed instant so the suite stays deterministic and aligned with the repo’s test rules.

Suggested fix
+var fixedQueryTime = time.Date(2026, 4, 30, 12, 0, 0, 0, time.UTC)
+
 // defaultQueryHeader returns a QueryHeader with valid date range for tests.
 func defaultQueryHeader(page, limit int) http.QueryHeader {
 	return http.QueryHeader{
 		Page:      page,
 		Limit:     limit,
-		StartDate: time.Now().AddDate(-1, 0, 0), // 1 year ago
-		EndDate:   time.Now().AddDate(0, 0, 1),  // tomorrow
+		StartDate: fixedQueryTime.AddDate(-1, 0, 0),
+		EndDate:   fixedQueryTime.AddDate(0, 0, 1),
 	}
 }

As per coding guidelines "Do not use time.Now() in tests; use fixed time utilities instead".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@components/ledger/internal/adapters/postgres/ledger/ledger.postgresql_integration_test.go`
around lines 143 - 150, The helper defaultQueryHeader currently uses time.Now(),
making tests time-dependent; change defaultQueryHeader to use a fixed,
deterministic timestamp (e.g., a package-level constant or a call to a test time
helper) for StartDate and EndDate so FindAll tests are stable—update
defaultQueryHeader (and add a fixed time constant or use the repo's fixed time
utility) to return StartDate and EndDate based on that fixed instant rather than
time.Now().
components/crm/internal/services/create-holder.go (1)

35-35: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Use structured log fields instead of fmt.Sprintf in error logs.
Line 35 and Line 59 should log err via structured fields to preserve machine-parsable logs.

Proposed fix
 import (
 	"context"
-	"fmt"
 	"time"
@@
-		logger.Log(ctx, libLog.LevelError, fmt.Sprintf("Failed to generate holder id: %v", err))
+		logger.Log(ctx, libLog.LevelError, "Failed to generate holder id", libLog.Err(err))
@@
-		logger.Log(ctx, libLog.LevelError, fmt.Sprintf("Failed to create holder: %v", err))
+		logger.Log(ctx, libLog.LevelError, "Failed to create holder", libLog.Err(err))

As per coding guidelines "Use structured logging with libLog.Err(), libLog.String(), libLog.Int() instead of fmt.Sprintf inside log calls".

Also applies to: 59-59

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/crm/internal/services/create-holder.go` at line 35, Replace the
fmt.Sprintf-style error messages in the logger.Log calls with structured log
fields: pass libLog.Err(err) plus a short string field (e.g.,
libLog.String("msg","Failed to generate holder id")) and any relevant context
(e.g., libLog.String("holder", holderID) or libLog.Int(...) as applicable) to
logger.Log(ctx, libLog.LevelError, ...). Do this for the call that currently
uses fmt.Sprintf("Failed to generate holder id: %v", err) and the other
occurrence around the same area (the logger.Log call at the second spot) so both
use libLog.Err(err) and appropriate libLog.String()/libLog.Int() fields instead
of fmt.Sprintf.
components/ledger/internal/adapters/postgres/portfolio/portfolio.postgresql_integration_test.go (1)

358-390: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use fixed timestamps in integration test filters.

These query windows are time-dependent and can drift between runs. Replace time.Now() with a fixed test timestamp fixture to keep pagination/date-range assertions deterministic.

Suggested deterministic fixture update
+var fixedQueryTime = time.Date(2026, time.January, 15, 12, 0, 0, 0, time.UTC)
+
 page1Filter := http.QueryHeader{
   Limit:     2,
   Page:      1,
   SortOrder: "DESC",
-  StartDate: time.Now().AddDate(-1, 0, 0),
-  EndDate:   time.Now().AddDate(0, 0, 1),
+  StartDate: fixedQueryTime.AddDate(-1, 0, 0),
+  EndDate:   fixedQueryTime.AddDate(0, 0, 1),
 }
 
 func defaultQueryHeader() http.QueryHeader {
   return http.QueryHeader{
     Limit:     10,
     Page:      1,
     SortOrder: "DESC",
-    StartDate: time.Now().AddDate(-1, 0, 0),
-    EndDate:   time.Now().AddDate(0, 0, 1),
+    StartDate: fixedQueryTime.AddDate(-1, 0, 0),
+    EndDate:   fixedQueryTime.AddDate(0, 0, 1),
   }
 }

As per coding guidelines: **/*test.go: Do NOT use time.Now() in tests; use fixed time utilities instead.

Also applies to: 652-659

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@components/ledger/internal/adapters/postgres/portfolio/portfolio.postgresql_integration_test.go`
around lines 358 - 390, The test uses time.Now() inside the
pagination/date-range filters (page1Filter, page2Filter, page3Filter passed to
repo.FindAll) which makes assertions flaky; replace those calls with a fixed
test timestamp fixture (e.g., a package-level testTime or a fixture like
fixtures.FixedTime) and use deterministic offsets from that fixture
(testTime.AddDate(...)) for StartDate/EndDate throughout the file (also update
the other occurrences referenced in the comment) so the pagination/date-range
assertions are stable across runs.
components/ledger/internal/adapters/postgres/accounttype/accounttype.postgresql_integration_test.go (1)

427-445: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace dynamic clock usage in test query windows.

time.Now() in these QueryHeader filters can make boundary-sensitive assertions flaky. Use a fixed test timestamp fixture.

Suggested deterministic fixture update
+var fixedQueryTime = time.Date(2026, time.January, 15, 12, 0, 0, 0, time.UTC)
+
 limitFilter := http.QueryHeader{
   Limit:     2,
   SortOrder: "DESC",
-  StartDate: time.Now().AddDate(-1, 0, 0),
-  EndDate:   time.Now().AddDate(0, 0, 1),
+  StartDate: fixedQueryTime.AddDate(-1, 0, 0),
+  EndDate:   fixedQueryTime.AddDate(0, 0, 1),
 }
 
 func defaultQueryHeader() http.QueryHeader {
   return http.QueryHeader{
     Limit:     10,
     SortOrder: "DESC",
-    StartDate: time.Now().AddDate(-1, 0, 0),
-    EndDate:   time.Now().AddDate(0, 0, 1),
+    StartDate: fixedQueryTime.AddDate(-1, 0, 0),
+    EndDate:   fixedQueryTime.AddDate(0, 0, 1),
   }
 }

As per coding guidelines: **/*test.go: Do NOT use time.Now() in tests; use fixed time utilities instead.

Also applies to: 471-487, 704-710

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@components/ledger/internal/adapters/postgres/accounttype/accounttype.postgresql_integration_test.go`
around lines 427 - 445, Tests use time.Now() in QueryHeader filters
(limitFilter, allFilter passed to repo.FindAll), which makes boundary assertions
flaky; replace dynamic clock usage with a fixed test timestamp fixture (e.g., a
package-level or helper const like testNow or fixedTime from your test fixtures)
and compute StartDate/EndDate relative to that fixed timestamp. Update all
occurrences noted (including the other blocks around lines referenced) so
http.QueryHeader uses the deterministic fixture instead of time.Now(), keeping
SortOrder/Limit values unchanged.
components/ledger/internal/adapters/postgres/organization/organization.postgresql_integration_test.go (1)

447-454: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use a fixed timestamp in the test query helper.

defaultQueryHeader now bakes time.Now() into every FindAll test, which makes the new date-filter coverage time-dependent. Please switch this helper to a fixed instant so pagination/filter failures are reproducible.

Suggested change
+var fixedQueryNow = time.Date(2026, 1, 15, 12, 0, 0, 0, time.UTC)
+
 // defaultQueryHeader returns a QueryHeader with valid date range for tests.
 func defaultQueryHeader(page, limit int) http.QueryHeader {
 	return http.QueryHeader{
 		Page:      page,
 		Limit:     limit,
-		StartDate: time.Now().AddDate(-1, 0, 0), // 1 year ago
-		EndDate:   time.Now().AddDate(0, 0, 1),  // tomorrow
+		StartDate: fixedQueryNow.AddDate(-1, 0, 0),
+		EndDate:   fixedQueryNow.AddDate(0, 0, 1),
 	}
 }

As per coding guidelines **/*test.go: Do NOT use time.Now() in tests; use fixed time utilities instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@components/ledger/internal/adapters/postgres/organization/organization.postgresql_integration_test.go`
around lines 447 - 454, The test helper defaultQueryHeader embeds time.Now(),
making FindAll tests time-dependent; change defaultQueryHeader to return a
QueryHeader with fixed StartDate and EndDate (use a deterministic time.Date
value or a shared fixedClock constant used across tests) instead of time.Now(),
so all pagination/filter tests are reproducible; update any tests that rely on
the current helper to use the fixed instant or adjust expectations accordingly
(refer to defaultQueryHeader and any FindAll test callers to locate changes).
components/ledger/internal/adapters/postgres/account/account.postgresql_integration_test.go (1)

377-383: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use fixed timestamps in integration tests instead of time.Now().

Line 381 and Line 382 (and repeated new filter setups in this file) use wall-clock time. Replace with fixed test timestamps so filter tests remain fully deterministic.

As per coding guidelines **/*test.go: Do not use time.Now() in tests; use fixed time utilities instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@components/ledger/internal/adapters/postgres/account/account.postgresql_integration_test.go`
around lines 377 - 383, The test uses wall-clock times when constructing the
filter variable (http.QueryHeader named "filter") via time.Now().Add(...);
replace these with fixed deterministic timestamps (e.g., time.Date(...,
time.UTC) or your test fixed-time helper) for StartDate and EndDate so the
filter setup and any repeated filter constructions in this file are
deterministic; update every occurrence that uses time.Now().Add(...) in the test
to use the chosen fixed timestamp values (and keep them in UTC to avoid timezone
flakiness).
components/ledger/internal/adapters/postgres/account/account.postgresql.go (1)

233-314: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Cyclomatic complexity is elevated but acceptable.

Static analysis flags this method with complexity 22 (threshold 18). The complexity stems from the many optional filter conditions, each following an identical and readable pattern. While the metric exceeds the threshold, the code remains maintainable because each filter block is self-contained and uniform. If additional filters are added in the future, consider extracting filter application into a helper function or builder pattern to keep complexity manageable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/ledger/internal/adapters/postgres/account/account.postgresql.go`
around lines 233 - 314, The FindAll method in AccountPostgreSQLRepository has
elevated cyclomatic complexity due to many inline optional filter blocks;
refactor by extracting the repeated filter-application logic into a helper
(e.g., buildAccountFilters or applyAccountFilters) that accepts the
squirrel.SelectBuilder, the http.QueryHeader filter and returns the updated
builder; move all blocks that add WHERE clauses (EntityIDs, Status, Type,
AssetCode, EntityID, Blocked, ParentAccountID, Name, Alias, date range,
sort/limit/offset) into that helper and call it from FindAll to keep FindAll
focused on setup/teardown and reduce complexity.
components/ledger/api/openapi.yaml (1)

7332-7339: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove the non-negative constraint from overdraft-capable available fields.

These schemas still declare available.minimum: 0, but allowOverdraft now explicitly allows transactions to drive available below zero. Any SDK/runtime validator generated from this spec will treat valid overdraft balances as invalid.

Also applies to: 7426-7433, 10209-10216, 10323-10329

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/ledger/api/openapi.yaml` around lines 7332 - 7339, The OpenAPI
schemas declare available.minimum: 0 even for overdraft-capable balances, which
conflicts with allowOverdraft allowing negative available; remove the
non-negative constraint by deleting the minimum: 0 (and any duplicate
minimum/type mismatch entries) from the affected available field definitions so
the available property can be negative when allowOverdraft is true; search for
the schema property named available and the flag allowOverdraft to locate each
occurrence (including the additional occurrences noted in the comment) and
remove the minimum: 0 constraint there.
components/ledger/api/docs.go (1)

8360-8402: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

refund is documented in prose but missing from the schema.

AccountingEntries now says it supports refund, but this definition only exposes cancel, commit, direct, hold, overdraft, and revert. That leaves the generated contract internally inconsistent and any generated client will miss refund entirely. Please update the OpenAPI source/annotations so the description and properties match, then regenerate this file.

Based on learnings, components/*/api/docs.go is auto-generated Swagger/OpenAPI output; apply the fix in the source spec/annotations and regenerate rather than editing docs.go manually.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/ledger/api/docs.go` around lines 8360 - 8402, The OpenAPI schema
for AccountingEntries is missing the refund property even though the prose
mentions it; update the source OpenAPI/spec or code annotations that define
AccountingEntries to add a "refund" property with the same allOf/$ref to
AccountingEntry (matching cancel/commit/direct/hold/revert/overdraft), then
regenerate the Swagger artifacts so components/ledger/api/docs.go includes
refund in the properties; ensure the change is applied to the original
spec/annotations (not docs.go) and run the project’s OpenAPI generator to
produce the updated docs file.
components/ledger/api/swagger.json (2)

8336-8378: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add the missing refund entry to AccountingEntries.

The description now says this object covers refund, but the schema never defines a refund property. That leaves the contract inconsistent and prevents generated clients from expressing the new refund accounting entry.

Suggested fix
         "overdraft": {
           "description": "The accounting entry for the overdraft lifecycle. Debit rubric classifies\noverdraft usage (deficit grows); credit rubric classifies overdraft\nrepayment (deficit shrinks). Both rubrics are REQUIRED when this entry\nis present.",
           "allOf": [
             {
               "$ref": "#/definitions/AccountingEntry"
             }
           ]
         },
+        "refund": {
+          "description": "The accounting entry for the refund action.",
+          "allOf": [
+            {
+              "$ref": "#/definitions/AccountingEntry"
+            }
+          ]
+        },
         "revert": {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/ledger/api/swagger.json` around lines 8336 - 8378, The
AccountingEntries schema lists refund in its description but lacks a refund
property; add a "refund" property to the AccountingEntries object (alongside
cancel/commit/direct/hold/overdraft) with a description like "The accounting
entry for the refund action." and an allOf reference to
"#/definitions/AccountingEntry" so generated clients can represent the refund
accounting entry; mirror the pattern used by the other entries (e.g., "direct"
or "commit") when adding the refund property.

8894-8929: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don’t expose internal-only balance settings in public request schemas.

CreateAdditionalBalance and UpdateBalance both reuse mmodel.BalanceSettings, whose contract explicitly allows balanceScope: "internal", and the create schema still permits the reserved balance key overdraft. That means the OpenAPI spec allows requests the runtime guards already reject.

Please split request/response balance-settings schemas, or otherwise constrain the request-side contract so public input cannot send balanceScope: "internal" and cannot create key: "overdraft". Based on learnings: Balance API requests must prevent clients from setting balanceScope to "internal" and must forbid using the reserved balance key "overdraft". This is already enforced by runtime guards; ensure the API contract/docs (e.g., OpenAPI/Swagger schemas such as in swagger.json) also disallow these values so client code can’t legally send them and reviews don’t miss schema/contract mismatches.

Also applies to: 10613-10620, 11013-11038

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/ledger/api/swagger.json` around lines 8894 - 8929, The
CreateAdditionalBalance and UpdateBalance request schemas currently reuse
mmodel.BalanceSettings which permits balanceScope: "internal" and also allow the
reserved key "overdraft"; update the OpenAPI schemas so client-facing request
contracts cannot set those internal-only values: create separate request-side
schema(s) (e.g., BalanceSettingsRequest) or add validation constraints/enums to
the existing request properties to forbid balanceScope = "internal" and add a
pattern/enum or forbidden-value rule for the key property to disallow
"overdraft"; ensure these changes are applied to the CreateAdditionalBalance and
UpdateBalance definitions (and the other occurrences mentioned) so the public
spec no longer permits internal-only settings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/build.yml:
- Line 16: Replace the mutable tag ref in the uses entry
"LerianStudio/github-actions-shared-workflows/.github/workflows/build.yml@v1.27.5"
with the immutable commit SHA "268d75a43e5339819131d1309d0f39862a8cb7af" (keep
the human-readable tag as a trailing comment if desired), and apply the same
replacement pattern for all other workflow uses refs that point to the same
shared repo (e.g., the occurrences referenced in release.yml,
release-notification.yml, pr-validation.yml, pr-security-scan.yml,
gptchangelog.yml, go-combined-analysis.yml) so CI pins to an immutable commit
SHA rather than a mutable tag.

In `@components/crm/internal/bootstrap/readyz_checkers.go`:
- Around line 66-77: MongoChecker.Check currently calls c.client.Ping(ctx)
without verifying the context; add a fast pre-check for ctx.Err() at the start
of Check to short-circuit and return a DependencyCheck with StatusFailed (or
appropriate status) and the ctx error as Reason when the context is canceled or
deadline exceeded, before performing any I/O; update the logic around
c.client.Ping(ctx), latencyMs calculation, and returned DependencyCheck so the
function returns immediately on ctx.Err() and only measures ping latency when
the context is valid.
- Around line 79-84: The readiness checker currently returns the raw driver
error in DependencyCheck.Error (the err value) which can leak infra details;
change the returned Error to a sanitized message (e.g., "ping failed") while
emitting the full err to internal logs/telemetry instead. Update the code around
the return that builds DependencyCheck (the block using StatusDown, latencyMs,
Error) to set Error to a generic string and call the existing logger (or
standard logger if none) to log fmt.Errorf("mongo ping failed: %v", err) or
similar for internal diagnostics; keep latencyMs and StatusDown as-is. Ensure
you reference the same err variable and DependencyCheck construction so only the
response payload is sanitized.

In `@components/ledger/api/docs.go`:
- Around line 2716-2718: The OpenAPI 404 response for the POST
/accounts/{account_id}/balances endpoint is incorrect in the generated file
(components/.../api/docs.go) — it should reflect a missing parent resource
(account/ledger/organization) instead of "Balance not found"; update the source
OpenAPI annotations/spec for the handler that creates balances (the POST
accounts/{account_id}/balances operation) to change the 404 description to
something like "Account not found" or "Parent resource not found" and ensure the
404 is tied to the account/ledger/org lookup, then regenerate the
Swagger/OpenAPI output so components/*/api/docs.go is updated (do not edit
docs.go directly).
- Around line 11046-11049: The schema for balanceScope is currently a free-form
string; update the OpenAPI source/annotations that define the balance scope enum
(the balanceScope property in the balance/account schema) to declare an enum
with values ["transactional","internal"], set the default to "transactional"
(and document the empty-string backward-compatibility in description if
desired), then regenerate the OpenAPI/Swagger artifacts rather than editing the
generated components/*/api/docs.go; ensure the generated schema shows type:
string, enum: [...], and default: "transactional".

In `@components/ledger/api/openapi.yaml`:
- Around line 3826-3846: The operation-route detail endpoint is missing some
standard error responses; restore the dropped 403 on DELETE
/operation-routes/{operation_route_id} and add the same error response set for
GET /operation-routes/{operation_route_id} so it matches other resource-by-id
routes: include 401, 403, 404, and 500 with application/json content referring
to the existing components/schemas/Error for each response code (use the same
response shape as other id endpoints).
- Around line 5045-5053: The PATCH requestBody for the ledger-settings endpoint
is currently typed as a generic object; change the OpenAPI schema to a typed
object with an "accounting" property that is an object containing boolean
properties "validateAccountType" and "validateRoutes", and set
additionalProperties: false so unknown fields are rejected; because
components/*/api/openapi.yaml is generated by Swaggo, make this change by
updating the source Swaggo annotations or the model/struct that defines ledger
settings (or add a deterministic post-generation transformer) so the generated
schema for the ledger-settings PATCH accurately documents
accounting.validateAccountType and accounting.validateRoutes as booleans and
disallows unknown fields.
- Around line 87-91: The OpenAPI query parameter "status" is currently an
unconstrained string and must be replaced with an enum listing the exact allowed
values for that endpoint's entity; consult the canonical lists in
components/ledger/internal/adapters/http/in/status_validation.go and replace the
generic schema (type: string) with schema.enum containing the per-entity allowed
statuses for the "status" query param used at the shown location and the other
occurrences noted (lines 485-489, 1321-1325, 4024-4028). Ensure each endpoint's
"status" parameter uses the matching enum from status_validation.go so the spec
and adapter validation stay in sync.

In `@components/ledger/api/swagger.json`:
- Around line 6063-6110: The PATCH operation for ledger settings currently uses
a loose "type: object" for the body parameter named "settings" (the "patch"
operation); replace that with a concrete schema that models the allowed, closed
fields: define "settings" as an object with an optional "accounting" object that
has two boolean properties "validateAccountType" and "validateRoutes", set
additionalProperties: false on both the root settings object and the accounting
object to reject unknown fields, and ensure the boolean types are explicit so
generated SDKs and docs match the server's 0147/0148 validation behavior.

In `@components/ledger/internal/adapters/http/in/account.go`:
- Around line 248-255: The handlers GetAccountByID, UpdateAccount, and
DeleteAccountByID are still retrieving the UUID using http.GetUUIDFromLocals(c,
"id") while the route annotations and locals were renamed to "account_id";
update each handler to read http.GetUUIDFromLocals(c, "account_id") (and any
other occurrences noted around the blocks at ~273, ~413-422, ~441, ~484-491,
~510) so the implementation matches the documented route local, and update
corresponding tests/routes to use the "account_id" local key as well.

In
`@components/ledger/internal/adapters/http/in/operation_route_validation_test.go`:
- Line 821: Remove the redundant loop-variable rebinding by deleting the
unnecessary "tt := tt" inside the test's range loop; locate the table-driven
test where the variable named "tt" is used (the inner closure using tt) and
simply use the loop-provided tt directly so each iteration's closure captures
the iteration copy without the extra reassignment.

In `@components/ledger/internal/adapters/http/in/portfolio_test.go`:
- Around line 641-643: The test currently uses gomock.Any() for the 4th argument
of PortfolioRepo.FindAll which lets the call pass without verifying
metadata-derived IDs are included; replace those gomock.Any() matchers (the
expectation around PortfolioRepo.FindAll and the similar one at 718-720) with a
concrete matcher that asserts the filter contains the expected IDs (e.g., build
an expected filter value with the metadata-derived IDs and use
gomock.Eq(expectedFilter) or a custom gomock.Matches function to check the IDs
are present) so the mock verifies the repository receives the filtered IDs from
metadata.

In `@components/ledger/internal/adapters/http/in/segment.go`:
- Around line 196-202: Swagger comments for the three endpoints reference
{segment_id} but the actual routes and handlers use :id and extract via
GetUUIDFromLocals(c, "id"); update the Swagger annotations in the segment.go
comments for GetSegmentByID, UpdateSegment, and DeleteSegmentByID to use {id}
(instead of {segment_id}) so they match the route parameter name and the handler
extraction, keeping the route registrations and handler code unchanged.

In
`@components/ledger/internal/adapters/http/in/transaction_create_snapshot_test.go`:
- Around line 287-306: The test is reimplementing the adapter/writeback bridge
instead of using the production path; replace the inline loop that builds
snapshotAdapters and calls propagateSnapshotToCompanions with a call to the
production bridge (e.g., invoke BuildOperations so it performs the same wiring)
or extract the bridge logic into a shared helper used by both BuildOperations
and the test (the helper should encapsulate the operationForSnapshot assembly
and propagateSnapshotToCompanions invocation) and have both the production code
and tests call that helper so the test no longer duplicates the wiring; apply
the same change to the other occurrence around lines 377-389.

In
`@components/ledger/internal/adapters/http/in/transaction_overdraft_enrichment.go`:
- Around line 823-854: The code currently reuses usageByAlias[alias] for every
cancelled RELEASE/CREDIT leg, allowing sum of overdraft repayments to exceed the
outstanding; change the logic so each time you apply an overdraft to a balance
operation (inside the loop over balanceOps in
transaction_overdraft_enrichment.go), compute applied := min(usage, the
cancelable amount for that balance op), set balanceOps[i].Amount.OverdraftAmount
= applied, then decrement usageByAlias[alias] = usage.Sub(applied) (or remove
the map entry when zero) so subsequent legs consume the remaining outstanding;
reference pendingOverdraftUsageByAlias, balanceOps[i].Amount,
accountAliasFromOperationAlias and collectOverdraftCancelSplits when
implementing the min/apply-and-decrement behavior.

In
`@components/ledger/internal/adapters/postgres/balance/balance_overdraft_integration_test.go`:
- Line 36: Replace uses of time.Now().Truncate(time.Microsecond) in the test
(occurrences in balance_overdraft_integration_test.go around the variable named
now used in the test setup and assertions) with a deterministic fixed time
value: define a package-level variable like testFixedTime (e.g., a specific
time.Date value) and use testFixedTime.Truncate(time.Microsecond) wherever now
is currently set (including the instances used at lines noted in the review).
Update any comparisons or expectations that rely on now to use this
testFixedTime so the tests are deterministic.

In `@components/ledger/internal/adapters/postgres/balance/balance.go`:
- Around line 63-69: The current code swallows json.Marshal errors for
Balance.Settings (setting b.Settings = nil on failure), which incorrectly treats
malformed internal balances as non-internal; change the logic so
json.Marshal(balance.Settings) errors are not ignored: call
json.Marshal(balance.Settings) and if it returns an error, propagate/return a
technical error from the enclosing function instead of setting b.Settings to
nil, and only assign b.Settings when marshal succeeds; apply the same fix to the
duplicate marshal block later that also marshals balance.Settings.

In `@components/ledger/internal/adapters/postgres/balance/balance.postgresql.go`:
- Around line 54-56: The timestamp-based read path in this file still returns a
legacy projection missing the Settings field resulting in historical balances
having Settings == nil; update the timestamp-based read query/projection to
include "settings" alongside "direction" and "overdraft_used" so historical rows
populate mmodel.Balance.Settings, and ensure downstream interpretation follows
the rule "use mmodel.Balance.Settings as the canonical indicator" (i.e., treat a
nil Balance.Settings as NOT internal). Locate the timestamp-based read
function/projection in this file (the code that constructs the
historical/at-timestamp balance object) and add the settings field to the
returned shape and/or mapping logic, and verify any mapping code sets
mmodel.Balance.Settings to nil only when no settings exist so downstream logic
treats nil as non-internal.
- Around line 1531-1541: The current code in balance.postgresql.go parses
balance.OverdraftUsed into overdraftUsed and, on parse error, calls log.Printf
with the sensitive OverdraftUsed value; replace that global logger call with the
request-scoped structured logger (libLog) and do not include the malformed
financial value. Specifically, remove the log.Printf(...) and instead emit a
structured warning via libLog (e.g., libLog.Warn or libLog.With(...).Warn) that
includes the balance ID (ids[i]) and the parseErr message only, omitting
balance.OverdraftUsed, then continue as before so the sync skips the row. Ensure
the change targets the block around overdraftUsed, parseErr and replaces only
the logging call.

In `@components/ledger/internal/adapters/postgres/ledger/ledger.postgresql.go`:
- Around line 283-295: The ORDER BY clause currently interpolates
pagination.SortOrder directly (see the pagination variable and the OrderBy("id "
+ strings.ToUpper(pagination.SortOrder)) call); whitelist and normalize this
value to a safe enum before building the Squirrel query: accept only "ASC" or
"DESC" (e.g., strings.ToUpper and switch or map), default to a safe choice
(e.g., "ASC") or return an error for invalid input, then pass that validated
token into OrderBy (e.g., OrderBy("id " + safeSortOrder)); do not permit
arbitrary strings to be concatenated into the SQL fragment.

In
`@components/ledger/internal/adapters/postgres/operationroute/operationroute_overdraft_test.go`:
- Around line 52-53: Replace the non-deterministic time.Now() usage in the test
setup for CreatedAt and UpdatedAt with a fixed test timestamp (e.g., a shared
test constant or test utility like a FixedTime/TestClock); locate the places
setting CreatedAt and UpdatedAt in the operationroute_overdraft_test.go setup
and assign them the fixed time value so the tests are deterministic and comply
with the test guidelines.

In `@components/ledger/internal/adapters/postgres/transaction/transaction.go`:
- Around line 300-316: The current companion lookup uses fromByAlias/toByAlias
keyed only by account alias which is ambiguous when BalanceKey is preserved;
change the index maps to use a stable composite key (e.g., alias + ":" +
BalanceKey or a small struct key) when populating and when looking up in
addCompanionAmount so each entry is disambiguated by both AccountAlias and
BalanceKey; update the map creation code that fills fromByAlias/toByAlias and
the addCompanionAmount function (and the analogous logic around lines 345-380)
to use that composite key for both storing idx and performing the lookup.

---

Outside diff comments:
In `@components/crm/internal/services/create-holder.go`:
- Line 35: Replace the fmt.Sprintf-style error messages in the logger.Log calls
with structured log fields: pass libLog.Err(err) plus a short string field
(e.g., libLog.String("msg","Failed to generate holder id")) and any relevant
context (e.g., libLog.String("holder", holderID) or libLog.Int(...) as
applicable) to logger.Log(ctx, libLog.LevelError, ...). Do this for the call
that currently uses fmt.Sprintf("Failed to generate holder id: %v", err) and the
other occurrence around the same area (the logger.Log call at the second spot)
so both use libLog.Err(err) and appropriate libLog.String()/libLog.Int() fields
instead of fmt.Sprintf.

In `@components/ledger/api/docs.go`:
- Around line 8360-8402: The OpenAPI schema for AccountingEntries is missing the
refund property even though the prose mentions it; update the source
OpenAPI/spec or code annotations that define AccountingEntries to add a "refund"
property with the same allOf/$ref to AccountingEntry (matching
cancel/commit/direct/hold/revert/overdraft), then regenerate the Swagger
artifacts so components/ledger/api/docs.go includes refund in the properties;
ensure the change is applied to the original spec/annotations (not docs.go) and
run the project’s OpenAPI generator to produce the updated docs file.

In `@components/ledger/api/openapi.yaml`:
- Around line 7332-7339: The OpenAPI schemas declare available.minimum: 0 even
for overdraft-capable balances, which conflicts with allowOverdraft allowing
negative available; remove the non-negative constraint by deleting the minimum:
0 (and any duplicate minimum/type mismatch entries) from the affected available
field definitions so the available property can be negative when allowOverdraft
is true; search for the schema property named available and the flag
allowOverdraft to locate each occurrence (including the additional occurrences
noted in the comment) and remove the minimum: 0 constraint there.

In `@components/ledger/api/swagger.json`:
- Around line 8336-8378: The AccountingEntries schema lists refund in its
description but lacks a refund property; add a "refund" property to the
AccountingEntries object (alongside cancel/commit/direct/hold/overdraft) with a
description like "The accounting entry for the refund action." and an allOf
reference to "#/definitions/AccountingEntry" so generated clients can represent
the refund accounting entry; mirror the pattern used by the other entries (e.g.,
"direct" or "commit") when adding the refund property.
- Around line 8894-8929: The CreateAdditionalBalance and UpdateBalance request
schemas currently reuse mmodel.BalanceSettings which permits balanceScope:
"internal" and also allow the reserved key "overdraft"; update the OpenAPI
schemas so client-facing request contracts cannot set those internal-only
values: create separate request-side schema(s) (e.g., BalanceSettingsRequest) or
add validation constraints/enums to the existing request properties to forbid
balanceScope = "internal" and add a pattern/enum or forbidden-value rule for the
key property to disallow "overdraft"; ensure these changes are applied to the
CreateAdditionalBalance and UpdateBalance definitions (and the other occurrences
mentioned) so the public spec no longer permits internal-only settings.

In
`@components/ledger/internal/adapters/postgres/account/account.postgresql_integration_test.go`:
- Around line 377-383: The test uses wall-clock times when constructing the
filter variable (http.QueryHeader named "filter") via time.Now().Add(...);
replace these with fixed deterministic timestamps (e.g., time.Date(...,
time.UTC) or your test fixed-time helper) for StartDate and EndDate so the
filter setup and any repeated filter constructions in this file are
deterministic; update every occurrence that uses time.Now().Add(...) in the test
to use the chosen fixed timestamp values (and keep them in UTC to avoid timezone
flakiness).

In `@components/ledger/internal/adapters/postgres/account/account.postgresql.go`:
- Around line 233-314: The FindAll method in AccountPostgreSQLRepository has
elevated cyclomatic complexity due to many inline optional filter blocks;
refactor by extracting the repeated filter-application logic into a helper
(e.g., buildAccountFilters or applyAccountFilters) that accepts the
squirrel.SelectBuilder, the http.QueryHeader filter and returns the updated
builder; move all blocks that add WHERE clauses (EntityIDs, Status, Type,
AssetCode, EntityID, Blocked, ParentAccountID, Name, Alias, date range,
sort/limit/offset) into that helper and call it from FindAll to keep FindAll
focused on setup/teardown and reduce complexity.

In
`@components/ledger/internal/adapters/postgres/accounttype/accounttype.postgresql_integration_test.go`:
- Around line 427-445: Tests use time.Now() in QueryHeader filters (limitFilter,
allFilter passed to repo.FindAll), which makes boundary assertions flaky;
replace dynamic clock usage with a fixed test timestamp fixture (e.g., a
package-level or helper const like testNow or fixedTime from your test fixtures)
and compute StartDate/EndDate relative to that fixed timestamp. Update all
occurrences noted (including the other blocks around lines referenced) so
http.QueryHeader uses the deterministic fixture instead of time.Now(), keeping
SortOrder/Limit values unchanged.

In
`@components/ledger/internal/adapters/postgres/ledger/ledger.postgresql_integration_test.go`:
- Around line 143-150: The helper defaultQueryHeader currently uses time.Now(),
making tests time-dependent; change defaultQueryHeader to use a fixed,
deterministic timestamp (e.g., a package-level constant or a call to a test time
helper) for StartDate and EndDate so FindAll tests are stable—update
defaultQueryHeader (and add a fixed time constant or use the repo's fixed time
utility) to return StartDate and EndDate based on that fixed instant rather than
time.Now().

In
`@components/ledger/internal/adapters/postgres/organization/organization.postgresql_integration_test.go`:
- Around line 447-454: The test helper defaultQueryHeader embeds time.Now(),
making FindAll tests time-dependent; change defaultQueryHeader to return a
QueryHeader with fixed StartDate and EndDate (use a deterministic time.Date
value or a shared fixedClock constant used across tests) instead of time.Now(),
so all pagination/filter tests are reproducible; update any tests that rely on
the current helper to use the fixed instant or adjust expectations accordingly
(refer to defaultQueryHeader and any FindAll test callers to locate changes).

In
`@components/ledger/internal/adapters/postgres/portfolio/portfolio.postgresql_integration_test.go`:
- Around line 358-390: The test uses time.Now() inside the pagination/date-range
filters (page1Filter, page2Filter, page3Filter passed to repo.FindAll) which
makes assertions flaky; replace those calls with a fixed test timestamp fixture
(e.g., a package-level testTime or a fixture like fixtures.FixedTime) and use
deterministic offsets from that fixture (testTime.AddDate(...)) for
StartDate/EndDate throughout the file (also update the other occurrences
referenced in the comment) so the pagination/date-range assertions are stable
across runs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

Comment thread .github/workflows/build.yml
Comment thread components/crm/internal/bootstrap/readyz_checkers.go
Comment thread components/crm/internal/bootstrap/readyz_checkers.go
Comment thread components/ledger/api/docs.go
Comment thread components/ledger/api/docs.go
gandalf-at-lerian and others added 3 commits April 30, 2026 11:59
The comment in the snapshot migration contained a semicolon inside a
SQL comment line. Migration runners that split statements on semicolons
(e.g. golang-migrate with x-multi-statement) would incorrectly split
the comment, producing an invalid statement starting with 'if future
queries need filtering by...'.

This caused migration failures on AWS RDS environments while working
on self-hosted PostgreSQL where the full file is sent as a single
execution.

Requested-by: @ClaraTersi
…-comment

fix: remove semicolon from SQL comment in migration 000033
chore: promote develop to release-candidate
@ClaraTersi ClaraTersi merged commit 318e556 into main Apr 30, 2026
38 checks passed
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.

5 participants