improved tgsettle messages + storage fixes

This commit is contained in:
Stephan D
2026-03-05 11:54:07 +01:00
parent 801f349aa8
commit 5e59fea7e5
16 changed files with 537 additions and 172 deletions

View File

@@ -27,6 +27,12 @@ type CreateRequestInput struct {
Amount string
}
type AccountProfile struct {
AccountID string
AccountCode string
Currency string
}
type ExecutionResult struct {
Request *storagemodel.TreasuryRequest
NewBalance *ledger.Balance
@@ -103,6 +109,29 @@ func (s *Service) GetRequest(ctx context.Context, requestID string) (*storagemod
return s.repo.FindByRequestID(ctx, requestID)
}
func (s *Service) GetAccountProfile(ctx context.Context, ledgerAccountID string) (*AccountProfile, error) {
if s == nil || s.ledger == nil {
return nil, merrors.Internal("treasury service unavailable")
}
ledgerAccountID = strings.TrimSpace(ledgerAccountID)
if ledgerAccountID == "" {
return nil, merrors.InvalidArgument("ledger_account_id is required", "ledger_account_id")
}
account, err := s.ledger.GetAccount(ctx, ledgerAccountID)
if err != nil {
return nil, err
}
if account == nil {
return nil, merrors.NoData("ledger account not found")
}
return &AccountProfile{
AccountID: ledgerAccountID,
AccountCode: resolveAccountCode(account, ledgerAccountID),
Currency: strings.ToUpper(strings.TrimSpace(account.Currency)),
}, nil
}
func (s *Service) CreateRequest(ctx context.Context, input CreateRequestInput) (*storagemodel.TreasuryRequest, error) {
if s == nil || s.repo == nil || s.ledger == nil || s.validator == nil {
return nil, merrors.Internal("treasury service unavailable")
@@ -156,17 +185,18 @@ func (s *Service) CreateRequest(ctx context.Context, input CreateRequestInput) (
requestID := newRequestID()
record := &storagemodel.TreasuryRequest{
RequestID: requestID,
OperationType: input.OperationType,
TelegramUserID: input.TelegramUserID,
LedgerAccountID: input.LedgerAccountID,
OrganizationRef: account.OrganizationRef,
ChatID: input.ChatID,
Amount: normalizedAmount,
Currency: strings.ToUpper(strings.TrimSpace(account.Currency)),
Status: storagemodel.TreasuryRequestStatusCreated,
IdempotencyKey: fmt.Sprintf("tgsettle:%s", requestID),
Active: true,
RequestID: requestID,
OperationType: input.OperationType,
TelegramUserID: input.TelegramUserID,
LedgerAccountID: input.LedgerAccountID,
LedgerAccountCode: resolveAccountCode(account, input.LedgerAccountID),
OrganizationRef: account.OrganizationRef,
ChatID: input.ChatID,
Amount: normalizedAmount,
Currency: strings.ToUpper(strings.TrimSpace(account.Currency)),
Status: storagemodel.TreasuryRequestStatusCreated,
IdempotencyKey: fmt.Sprintf("tgsettle:%s", requestID),
Active: true,
}
if err := s.repo.Create(ctx, record); err != nil {
if errors.Is(err, storage.ErrDuplicate) {
@@ -364,14 +394,14 @@ func (s *Service) executeClaimed(ctx context.Context, record *storagemodel.Treas
}, nil
}
func (s *Service) DueRequests(ctx context.Context, statuses []storagemodel.TreasuryRequestStatus, now time.Time, limit int64) ([]*storagemodel.TreasuryRequest, error) {
func (s *Service) DueRequests(ctx context.Context, statuses []storagemodel.TreasuryRequestStatus, now time.Time, limit int64) ([]storagemodel.TreasuryRequest, error) {
if s == nil || s.repo == nil {
return nil, merrors.Internal("treasury service unavailable")
}
return s.repo.FindDueByStatus(ctx, statuses, now, limit)
}
func (s *Service) ScheduledRequests(ctx context.Context, limit int64) ([]*storagemodel.TreasuryRequest, error) {
func (s *Service) ScheduledRequests(ctx context.Context, limit int64) ([]storagemodel.TreasuryRequest, error) {
if s == nil || s.repo == nil {
return nil, merrors.Internal("treasury service unavailable")
}
@@ -395,10 +425,14 @@ func (s *Service) logRequest(record *storagemodel.TreasuryRequest, status string
zap.String("request_id", strings.TrimSpace(record.RequestID)),
zap.String("telegram_user_id", strings.TrimSpace(record.TelegramUserID)),
zap.String("ledger_account_id", strings.TrimSpace(record.LedgerAccountID)),
zap.String("ledger_account_code", strings.TrimSpace(record.LedgerAccountCode)),
zap.String("chat_id", strings.TrimSpace(record.ChatID)),
zap.String("operation_type", strings.TrimSpace(string(record.OperationType))),
zap.String("amount", strings.TrimSpace(record.Amount)),
zap.String("currency", strings.TrimSpace(record.Currency)),
zap.String("status", status),
zap.String("ledger_reference", strings.TrimSpace(record.LedgerReference)),
zap.String("error_message", strings.TrimSpace(record.ErrorMessage)),
}
if err != nil {
fields = append(fields, zap.Error(err))
@@ -409,3 +443,15 @@ func (s *Service) logRequest(record *storagemodel.TreasuryRequest, status string
func newRequestID() string {
return "TGSETTLE-" + strings.ToUpper(bson.NewObjectID().Hex()[:8])
}
func resolveAccountCode(account *ledger.Account, fallbackAccountID string) string {
if account != nil {
if code := strings.TrimSpace(account.AccountCode); code != "" {
return code
}
if code := strings.TrimSpace(account.AccountID); code != "" {
return code
}
}
return strings.TrimSpace(fallbackAccountID)
}