fix(eventstore): use decimal, correct mirror (#9914)

# Eventstore fixes

- `event.Position` used float64 before which can lead to [precision
loss](https://github.com/golang/go/issues/47300). The type got replaced
by [a type without precision
loss](https://github.com/jackc/pgx-shopspring-decimal)
- the handler reported the wrong error if the current state was updated
and therefore took longer to retry failed events.

# Mirror fixes

- max age of auth requests can be configured to speed up copying data
from `auth.auth_requests` table. Auth requests last updated before the
set age will be ignored. Default is 1 month
- notification projections are skipped because notifications should be
sent by the source system. The projections are set to the latest
position
- ensure that mirror can be executed multiple times

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
Silvan
2025-05-28 23:54:18 +02:00
committed by GitHub
parent 046b165db8
commit 131f70db34
51 changed files with 436 additions and 236 deletions

View File

@@ -3,6 +3,8 @@ package repository
import (
"database/sql"
"github.com/shopspring/decimal"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/zerrors"
@@ -57,6 +59,8 @@ const (
// OperationNotIn checks if a stored value does not match one of the passed value list
OperationNotIn
OperationGreaterOrEquals
operationCount
)
@@ -250,10 +254,10 @@ func instanceIDsFilter(builder *eventstore.SearchQueryBuilder, query *SearchQuer
}
func positionAfterFilter(builder *eventstore.SearchQueryBuilder, query *SearchQuery) *Filter {
if builder.GetPositionAfter() == 0 {
if builder.GetPositionAtLeast().IsZero() {
return nil
}
query.Position = NewFilter(FieldPosition, builder.GetPositionAfter(), OperationGreater)
query.Position = NewFilter(FieldPosition, builder.GetPositionAtLeast(), OperationGreaterOrEquals)
return query.Position
}
@@ -295,7 +299,7 @@ func eventDataFilter(query *eventstore.SearchQuery) *Filter {
}
func eventPositionAfterFilter(query *eventstore.SearchQuery) *Filter {
if pos := query.GetPositionAfter(); pos != 0 {
if pos := query.GetPositionAfter(); !pos.Equal(decimal.Decimal{}) {
return NewFilter(FieldPosition, pos, OperationGreater)
}
return nil