Allmine API
Live Stream

Live Stream reports — RTK Query

Yayın şikayetleri mobil API slice

Live Stream Reports - React Native (RTK Query, Minimal)

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, live-stream-reports backend endpointlerini React Native tarafında RTK Query ile kullanmak için minimal entegrasyon ornegidir.

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

Endpoint Ozeti

User:

  • POST /api/v1/live-stream-reports/:streamId
  • GET /api/v1/live-stream-reports/types
  • GET /api/v1/live-stream-reports/my-reports

Admin:

  • GET /api/v1/live-stream-reports/admin
  • GET /api/v1/live-stream-reports/admin/stats
  • GET /api/v1/live-stream-reports/admin/:id
  • PATCH /api/v1/live-stream-reports/admin/:id
  • PATCH /api/v1/live-stream-reports/admin/:id/archive

RTK Query - Ornek API Slice

import { baseApi } from './baseApi';

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

type Pagination = {
  currentPage: number;
  totalPages: number;
  totalItems: number;
  itemsPerPage: number;
  hasNextPage: boolean;
  hasPrevPage: boolean;
};

type ReportType =
  | 'harassment_or_bullying'
  | 'hate_speech'
  | 'sexual_content_or_nudity'
  | 'violence_or_self_harm'
  | 'spam_or_scam'
  | 'copyright_or_intellectual_property'
  | 'other';

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

type ReportTypeOption = {
  key: ReportType;
  label: string;
  requiresCustomText: boolean;
};

type LiveStreamReport = {
  id: string;
  type: ReportType;
  description?: string | null;
  status: ReportStatus;
  streamStatusAtReport: string;
  createdAt: string;
  updatedAt: string;
};

type ReportListResponse = {
  list: LiveStreamReport[];
  pagination: Pagination;
};

type AdminReportListResponse = ReportListResponse & {
  stats: {
    total: number;
    recent: number;
    byStatus: Array<{ _id: string; count: number }>;
    byType: Array<{ _id: string; count: number }>;
  };
};

type CreateReportBody = {
  type: ReportType;
  description?: string;
};

type UpdateReportBody = {
  status?: ReportStatus;
  adminNotes?: string;
};

type UpdateReportResponse = {
  message: string;
  data: LiveStreamReport;
};

type ArchiveReportResponse = {
  message: string;
};

const unwrap = <T>(r: BaseResponseDto<T> | T): T => {
  if (r && typeof r === 'object' && 'data' in (r as any)) {
    return (r as BaseResponseDto<T>).data;
  }
  return r as T;
};

export const liveStreamReportsApi = baseApi.injectEndpoints({
  endpoints: (builder) => ({
    createLiveStreamReport: builder.mutation<
      LiveStreamReport,
      { streamId: string; body: CreateReportBody }
    >({
      query: ({ streamId, body }) => ({
        url: `/v1/live-stream-reports/${streamId}`,
        method: 'POST',
        body,
      }),
      transformResponse: (r: BaseResponseDto<LiveStreamReport> | LiveStreamReport) =>
        unwrap(r),
      invalidatesTags: [{ type: 'LiveStreamReport', id: 'MY_LIST' }],
    }),

    getLiveStreamReportTypes: builder.query<ReportTypeOption[], void>({
      query: () => ({ url: '/v1/live-stream-reports/types' }),
      transformResponse: (r: BaseResponseDto<ReportTypeOption[]> | ReportTypeOption[]) =>
        unwrap(r),
    }),

    getMyLiveStreamReports: builder.query<
      ReportListResponse,
      { status?: ReportStatus; type?: ReportType; page?: number; limit?: number } | void
    >({
      query: (params) => ({ url: '/v1/live-stream-reports/my-reports', params }),
      transformResponse: (r: BaseResponseDto<ReportListResponse> | ReportListResponse) =>
        unwrap(r),
      providesTags: [{ type: 'LiveStreamReport', id: 'MY_LIST' }],
    }),

    getAdminLiveStreamReports: builder.query<
      AdminReportListResponse,
      {
        status?: ReportStatus;
        type?: ReportType;
        reportedBy?: string;
        liveStreamId?: string;
        streamCreatorId?: string;
        page?: number;
        limit?: number;
      } | void
    >({
      query: (params) => ({ url: '/v1/live-stream-reports/admin', params }),
      transformResponse: (
        r: BaseResponseDto<AdminReportListResponse> | AdminReportListResponse,
      ) => unwrap(r),
      providesTags: [{ type: 'LiveStreamReport', id: 'ADMIN_LIST' }],
    }),

    getAdminLiveStreamReportStats: builder.query<
      AdminReportListResponse['stats'],
      void
    >({
      query: () => ({ url: '/v1/live-stream-reports/admin/stats' }),
      transformResponse: (
        r: BaseResponseDto<AdminReportListResponse['stats']> | AdminReportListResponse['stats'],
      ) => unwrap(r),
    }),

    getAdminLiveStreamReportById: builder.query<LiveStreamReport, { id: string }>({
      query: ({ id }) => ({ url: `/v1/live-stream-reports/admin/${id}` }),
      transformResponse: (r: BaseResponseDto<LiveStreamReport> | LiveStreamReport) =>
        unwrap(r),
      providesTags: (_res, _err, { id }) => [{ type: 'LiveStreamReport', id }],
    }),

    updateAdminLiveStreamReport: builder.mutation<
      UpdateReportResponse,
      { id: string; body: UpdateReportBody }
    >({
      query: ({ id, body }) => ({
        url: `/v1/live-stream-reports/admin/${id}`,
        method: 'PATCH',
        body,
      }),
      transformResponse: (
        r: BaseResponseDto<UpdateReportResponse> | UpdateReportResponse,
      ) => unwrap(r),
      invalidatesTags: (_res, _err, { id }) => [
        { type: 'LiveStreamReport', id },
        { type: 'LiveStreamReport', id: 'ADMIN_LIST' },
      ],
    }),

    archiveAdminLiveStreamReport: builder.mutation<
      ArchiveReportResponse,
      { id: string }
    >({
      query: ({ id }) => ({
        url: `/v1/live-stream-reports/admin/${id}/archive`,
        method: 'PATCH',
      }),
      transformResponse: (
        r: BaseResponseDto<ArchiveReportResponse> | ArchiveReportResponse,
      ) => unwrap(r),
      invalidatesTags: [{ type: 'LiveStreamReport', id: 'ADMIN_LIST' }],
    }),
  }),
});

export const {
  useCreateLiveStreamReportMutation,
  useGetLiveStreamReportTypesQuery,
  useGetMyLiveStreamReportsQuery,
  useGetAdminLiveStreamReportsQuery,
  useGetAdminLiveStreamReportStatsQuery,
  useGetAdminLiveStreamReportByIdQuery,
  useUpdateAdminLiveStreamReportMutation,
  useArchiveAdminLiveStreamReportMutation,
} = liveStreamReportsApi;

Minimal Kullanim

const [createReport, { isLoading }] = useCreateLiveStreamReportMutation();

await createReport({
  streamId,
  body: {
    type: selectedType,
    description: selectedType === 'other' ? customText : undefined,
  },
}).unwrap();

Notlar

  • type='other' ise description bos birakilmamali.
  • my-reports ve admin endpointlerinde pagination defaultlari page=1, limit=20.
  • Admin archive sonrasi kayit aktif listelerde gorunmez.

On this page