Allmine API

Grouped transaction history — mobil migration

~5 dkMobil / WebKararlı

GET /users/me/transactions/grouped pagination ve entry.id key extractor değişikliği

Grouped transaction history — mobil migration

Breaking change (pagination)

Grouped endpoint artık transaction satırı değil, grouped entry bazında sayfalar. Infinite scroll key extractor entry.id kullanmalıdır.

Amaç

Grouped transaction history endpoint'inde pagination semantiği değişti. Aynı streamId farklı sayfalarda tekrar stream_group olarak dönüyordu; React duplicate key uyarısına yol açıyordu. Mobil istemci grouped listeyi yeni kontrata ve entry.id key'ine göre güncellemelidir.

Etkilenen: iOS / Android (RTK Query veya eşdeğer). Web aynı endpoint'i kullanıyorsa aynı kurallar geçerlidir.

Önkoşullar

  • Backend deploy: group-based pagination aktif
  • Kullanıcı JWT (Authorization: Bearer)
  • Grouped ekran kullanılıyorsa flat endpoint zorunlu değil; flat ekran /users/me/transactions ile çalışmaya devam eder

Endpoint

RolMethodPath
Flat (değişmedi)GET/api/v1/users/me/transactions
Grouped (güncellendi)GET/api/v1/users/me/transactions/grouped
Admin (mobil kullanmaz)GET/api/v1/users/admin/:id/transactions/grouped

Mobil normal kullanıcı akışı yalnızca GET /api/v1/users/me/transactions/grouped kullanmalıdır.

Query: page, limit, types, statuses, direction, dateFrom, dateTo, sortAPI Reference ile doğrulayın.

Request / Response

Başarılı gövde BaseResponse + paginated data:

type UserTransactionHistoryGroupedEntry =
  | {
      id: string; // stream_group:<streamId>
      entryType: 'stream_group';
      streamId: string;
      streamTitle?: string | null;
      thumbnailUrl?: string | null;
      transactions: UserTransactionHistoryItem[];
    }
  | {
      id: string; // transaction:<transaction.id>
      entryType: 'transaction';
      transaction: UserTransactionHistoryItem;
    };

type PaginatedUserGroupedTransactions = {
  list: UserTransactionHistoryGroupedEntry[];
  pagination: {
    currentPage: number;
    totalPages: number;
    totalItems: number; // grouped entry sayısı, transaction satırı değil
    itemsPerPage: number;
    hasNextPage: boolean;
    hasPrevPage: boolean;
  };
};

pagination.totalItems ve itemsPerPage artık grouped entry sayısını ifade eder. Bir stream_group içinde limit'ten fazla transaction olabilir.

Hata kodları

HTTPDurumClient
401Token eksik/geçersizRefresh + tek retry (Authentication Flow)
400Query validationFiltreleri düzelt
403Yetki

Detay: Error Model. Flat endpoint hata davranışı değişmedi.

Client adımları

1. Key extractor

// Eski — duplicate key riski
const keyExtractor = (entry: UserTransactionHistoryGroupedEntry) =>
  entry.entryType === 'stream_group'
    ? `stream_group:${entry.streamId}`
    : `transaction:${entry.transaction.id}`;

// Yeni
const keyExtractor = (entry: UserTransactionHistoryGroupedEntry) => entry.id;

Nested satırlar için transaction.id kullanılmaya devam eder.

2. RTK Query

getMyGroupedTransactions: builder.query<
  PaginatedUserGroupedTransactions,
  { page?: number; limit?: number; /* filtreler */ }
>({
  query: ({ page = 1, limit = 20, types, statuses, ...params }) => ({
    url: '/api/v1/users/me/transactions/grouped',
    method: 'GET',
    params: {
      page,
      limit,
      types: types?.join(','),
      statuses: statuses?.join(','),
      ...params,
    },
  }),
}),

Infinite scroll: append sırasında entry.id ile defensive dedupe önerilir.

3. UI

  • Header: streamTitle || streamId
  • pagination.totalItems kullanıcıya "toplam transaction" olarak gösterilmemeli
  • Filtre değişince appended liste sıfırlanmalı

4. Test checklist

  1. Flat ekran /users/me/transactions ile çalışıyor
  2. Grouped ekranda keyExtractor={(e) => e.id}
  3. limit=1 ile bir stream grubu tek entry olarak geliyor
  4. Sayfa 2'de page 1'deki stream_group tekrar gelmiyor
  5. entryType: 'transaction' tekil render
  6. Filtre değişince liste reset

İlgili sayfalar

On this page