Allmine API

Reports — mobil RTK Query migration

~5 dkMobil / WebKararlı

Reports modülü React Native RTK Query entegrasyonu

Reports Modülü - React Native RTK Query Migration Rehberi

Migration rehberi

Yapılandırma sırası için Migration şablonu. Yeni düzenlemelerde Amaç → Önkoşullar → Endpoint → Request/Response → Hata kodları → Client adımları → İlgili sayfalar bölümlerini tercih edin.

Kapsam

Bu doküman, reports modülü için React Native tarafında RTK Query migrasyonunu anlatır. Odak nokta: liveStreamId alaninin opsiyonel olarak create ve list endpointlerinde desteklenmesi.

  • Base path: /api/v1/reports
  • Auth: Authorization: Bearer <JWT>
  • Response modeli: BaseResponseDto<T> (veri data içinden okunur)

Backend Contract (Güncel)

1) Report oluşturma

  • POST /api/v1/reports

Body:

  • reportedUser: string (zorunlu, MongoId)
  • type: ReportType (zorunlu)
  • description: string (zorunlu, max 500)
  • liveStreamId?: string (opsiyonel, MongoId)

2) Kendi reportlarim

  • GET /api/v1/reports/my-reports

Query:

  • status?: ReportStatus
  • type?: ReportType
  • page?: number (default: 1)
  • limit?: number (default: 20)
  • liveStreamId?: string (opsiyonel)

3) Tüm reportlar (Admin)

  • GET /api/v1/reports

Query:

  • status?: ReportStatus
  • type?: ReportType
  • reportedBy?: string
  • reportedUser?: string
  • liveStreamId?: string (opsiyonel)
  • page?: number (default: 1)
  • limit?: number (default: 20)

Migration Adimlari

1. Type tanimlarini guncelle

export type ReportType =
  | 'rude_or_abusive_behavior'
  | 'underage'
  | 'identity_based_hate'
  | 'fake_profile';

export type ReportStatus = 'pending' | 'under_review' | 'resolved' | 'rejected';

export type CreateReportRequest = {
  reportedUser: string;
  type: ReportType;
  description: string;
  liveStreamId?: string; // yeni: optional
};

export type ReportListQuery = {
  status?: ReportStatus;
  type?: ReportType;
  page?: number;
  limit?: number;
  reportedBy?: string;
  reportedUser?: string;
  liveStreamId?: string; // yeni: optional filter
};

2. API slice endpointlerini guncelle

import { baseApi } from '../store/baseApi';

type BaseResponseDto<T> = {
  isSuccess: boolean;
  statusCode: number;
  data: T;
  errors?: string[];
  timestamp: string;
};

const unwrap = <T>(response: BaseResponseDto<T> | T): T => {
  if (
    response &&
    typeof response === 'object' &&
    'data' in (response as Record<string, unknown>)
  ) {
    return (response as BaseResponseDto<T>).data;
  }
  return response as T;
};

const cleanUndefined = <T extends Record<string, unknown>>(obj: T): Partial<T> =>
  Object.fromEntries(
    Object.entries(obj).filter(([, value]) => value !== undefined),
  ) as Partial<T>;

export const reportsApi = baseApi.injectEndpoints({
  endpoints: (builder) => ({
    createReport: builder.mutation<any, CreateReportRequest>({
      query: (body) => ({
        url: '/v1/reports',
        method: 'POST',
        body: cleanUndefined(body),
      }),
      transformResponse: (response: BaseResponseDto<any> | any) => unwrap(response),
      invalidatesTags: ['UserReports', 'AdminReports'],
    }),

    getMyReports: builder.query<any, ReportListQuery | void>({
      query: (params) => ({
        url: '/v1/reports/my-reports',
        params: params ? cleanUndefined(params) : undefined,
      }),
      transformResponse: (response: BaseResponseDto<any> | any) => unwrap(response),
      providesTags: ['UserReports'],
    }),

    getAllReports: builder.query<any, ReportListQuery | void>({
      query: (params) => ({
        url: '/v1/reports',
        params: params ? cleanUndefined(params) : undefined,
      }),
      transformResponse: (response: BaseResponseDto<any> | any) => unwrap(response),
      providesTags: ['AdminReports'],
    }),
  }),
});

export const {
  useCreateReportMutation,
  useGetMyReportsQuery,
  useGetAllReportsQuery,
} = reportsApi;

3. Form submit tarafini guncelle

liveStreamId her report'ta zorunlu değil. Yalnizca ilgili bir yayin için report aciliyorsa gönder.

const [createReport] = useCreateReportMutation();

await createReport({
  reportedUser,
  type,
  description,
  liveStreamId: selectedLiveStreamId || undefined,
}).unwrap();

4. Liste filtrelerinde opsiyonel parametre kullan

const { data, isFetching } = useGetAllReportsQuery({
  page,
  limit,
  status,
  type,
  liveStreamId: filterLiveStreamId || undefined,
});

5. Eski koddan RTK Query'ye gecis stratejisi

  1. Once GET endpointlerini RTK Query'ye tasi.
  2. Sonra POST/PATCH endpointlerini tasi.
  3. Ekran bazli rollout yap (feature flag varsa kullan).
  4. Eski service fonksiyonlarini son asamada kaldir.

Cache ve Invalidation Notlari

  • Liste ekranlari için providesTags: UserReports, AdminReports
  • createReport ve admin update/archive islemleri için invalidatesTags
  • Bu sayede create/islem sonrasi liste otomatik yenilenir.

Hata Yonetimi

  • Mutasyonlarda unwrap() kullan.
  • Backend 400 validation.invalid-id dönerse liveStreamId MongoId formatini kontrol et.
  • liveStreamId bos string ('') gönderme; undefined gönder.

Test Checklist

  • liveStreamId olmadan create calisiyor.
  • liveStreamId ile create calisiyor.
  • my-reports?liveStreamId=... filtreli sonuc donuyor.
  • admin reports?liveStreamId=... filtreli sonuc donuyor.
  • Create sonrasi ilgili listeler otomatik yenileniyor.

Sık Yapilan Hatalar

  • liveStreamId: '' göndermek (validation hatasi uretebilir).
  • Query param temizligi yapmadan undefined/null göndermek.
  • invalidatesTags unutup stale liste gormek.

On this page