This commit is contained in:
Stephan D
2026-03-10 12:31:09 +01:00
parent d87e709f43
commit e77d1ab793
287 changed files with 2089 additions and 1550 deletions

View File

@@ -22,7 +22,7 @@ const amountInputHint = "*Amount format*\nEnter amount as a decimal number using
type SendTextFunc func(ctx context.Context, chatID string, text string) error
type ScheduleTracker interface {
TrackScheduled(record *storagemodel.TreasuryRequest)
TrackScheduled(ctx context.Context, record *storagemodel.TreasuryRequest)
Untrack(requestID string)
}
@@ -128,6 +128,11 @@ func (r *Router) HandleUpdate(ctx context.Context, update *model.TelegramWebhook
binding, err := r.users.ResolveUserBinding(ctx, userID)
if err != nil {
if errors.Is(err, merrors.ErrNoData) {
r.logUnauthorized(update)
_ = r.sendText(ctx, chatID, unauthorizedMessage)
return true
}
if r.logger != nil {
r.logger.Warn("Failed to resolve treasury user binding",
zap.Error(err),
@@ -224,7 +229,7 @@ func (r *Router) HandleUpdate(ctx context.Context, update *model.TelegramWebhook
func (r *Router) startAmountDialog(ctx context.Context, userID, accountID, chatID string, operation storagemodel.TreasuryOperationType) {
active, err := r.service.GetActiveRequestForAccount(ctx, accountID)
if err != nil {
if err != nil && !errors.Is(err, merrors.ErrNoData) {
if r.logger != nil {
r.logger.Warn("Failed to check active treasury request", zap.Error(err), zap.String("telegram_user_id", userID), zap.String("ledger_account_id", accountID))
}
@@ -267,7 +272,8 @@ func (r *Router) captureAmount(ctx context.Context, userID, accountID, chatID st
})
return
}
if typed, ok := err.(limitError); ok {
var typed limitError
if errors.As(err, &typed) {
switch typed.LimitKind() {
case "per_operation":
_ = r.sendText(ctx, chatID, "*Amount exceeds allowed limit*\n\n*Max per operation:* "+markdownCode(typed.LimitMax())+"\n\nEnter another amount or "+markdownCommand(CommandCancel)+".")
@@ -316,7 +322,7 @@ func (r *Router) confirm(ctx context.Context, userID string, accountID string, c
return
}
if r.tracker != nil {
r.tracker.TrackScheduled(record)
r.tracker.TrackScheduled(ctx, record)
}
r.dialogs.Clear(userID)
delay := int64(r.service.ExecutionDelay().Seconds())
@@ -487,7 +493,7 @@ func (r *Router) resolveAccountProfile(ctx context.Context, ledgerAccountID stri
}
profile, err := r.service.GetAccountProfile(ctx, ledgerAccountID)
if err != nil {
if r.logger != nil {
if r.logger != nil && !errors.Is(err, merrors.ErrNoData) {
r.logger.Warn("Failed to resolve treasury account profile",
zap.Error(err),
zap.String("ledger_account_id", strings.TrimSpace(ledgerAccountID)))

View File

@@ -22,6 +22,7 @@ func (f fakeUserBindingResolver) ResolveUserBinding(_ context.Context, telegramU
return nil, f.err
}
if f.bindings == nil {
//nolint:nilnil // Test stub uses nil, nil to represent missing binding.
return nil, nil
}
return f.bindings[telegramUserID], nil
@@ -36,6 +37,7 @@ func (fakeService) MaxPerOperationLimit() string {
}
func (fakeService) GetActiveRequestForAccount(context.Context, string) (*storagemodel.TreasuryRequest, error) {
//nolint:nilnil // Test stub uses nil, nil to represent no active request.
return nil, nil
}
@@ -48,14 +50,17 @@ func (fakeService) GetAccountProfile(_ context.Context, ledgerAccountID string)
}
func (fakeService) CreateRequest(context.Context, CreateRequestInput) (*storagemodel.TreasuryRequest, error) {
//nolint:nilnil // Test stub uses nil, nil to represent no created request.
return nil, nil
}
func (fakeService) ConfirmRequest(context.Context, string, string) (*storagemodel.TreasuryRequest, error) {
//nolint:nilnil // Test stub uses nil, nil to represent no confirmed request.
return nil, nil
}
func (fakeService) CancelRequest(context.Context, string, string) (*storagemodel.TreasuryRequest, error) {
//nolint:nilnil // Test stub uses nil, nil to represent no cancelled request.
return nil, nil
}