community.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. 'use server';
  2. import { ResultDto } from '@/types/response/common';
  3. import {
  4. StockBoardPostsResponse,
  5. TrendingStocksResponse,
  6. PostPredictionResponse,
  7. TrackRecordResponse,
  8. LeaderboardResponse,
  9. CreateStockPostRequest,
  10. CreateStockPostResponse,
  11. EquippedItemsResponse
  12. } from '@/types/community';
  13. import { fetchJson } from '@/lib/utils/server';
  14. const JSON_HEADERS = { 'Accept': 'application/json' } as const;
  15. // 종목 가상보드 글 목록 (익명 · SSR) — GET /api/stock-boards/{code}/posts?page=
  16. export async function fetchStockBoardPosts(code: string, params: { page?: number; perPage?: number }): Promise<ResultDto<StockBoardPostsResponse>>
  17. {
  18. const queryParams = new URLSearchParams();
  19. queryParams.set('page', String(params.page ?? 1));
  20. queryParams.set('perPage', String(params.perPage ?? 20));
  21. return await fetchJson<StockBoardPostsResponse>(`/api/stock-boards/${encodeURIComponent(code)}/posts?${queryParams.toString()}`, {
  22. method: 'GET',
  23. headers: JSON_HEADERS
  24. });
  25. }
  26. // 종목 트렌딩 랭킹 (익명 · SSR) — GET /api/stock-boards/trending?count=
  27. export async function fetchTrendingStocks(params: { count?: number } = {}): Promise<ResultDto<TrendingStocksResponse>>
  28. {
  29. const queryParams = new URLSearchParams();
  30. queryParams.set('count', String(params.count ?? 20));
  31. return await fetchJson<TrendingStocksResponse>(`/api/stock-boards/trending?${queryParams.toString()}`, {
  32. method: 'GET',
  33. headers: JSON_HEADERS
  34. });
  35. }
  36. // 글의 예측 메타 + 채점 상태 (익명 · SSR) — GET /api/posts/{id}/prediction
  37. export async function fetchPostPrediction(postID: number): Promise<ResultDto<PostPredictionResponse>>
  38. {
  39. return await fetchJson<PostPredictionResponse>(`/api/posts/${postID}/prediction`, {
  40. method: 'GET',
  41. headers: JSON_HEADERS
  42. });
  43. }
  44. // 회원 트랙레코드 (익명 · SSR · 회원 SID 기준) — GET /api/members/{sid}/track-record
  45. export async function fetchTrackRecord(sid: string): Promise<ResultDto<TrackRecordResponse>>
  46. {
  47. return await fetchJson<TrackRecordResponse>(`/api/members/${encodeURIComponent(sid)}/track-record`, {
  48. method: 'GET',
  49. headers: JSON_HEADERS
  50. });
  51. }
  52. // 적중률 리더보드 (익명 · SSR) — GET /api/track-records/leaderboard?page=
  53. export async function fetchTrackRecordLeaderboard(params: { page?: number; period?: string } = {}): Promise<ResultDto<LeaderboardResponse>>
  54. {
  55. const queryParams = new URLSearchParams();
  56. queryParams.set('page', String(params.page ?? 1));
  57. if (params.period) queryParams.set('period', params.period);
  58. return await fetchJson<LeaderboardResponse>(`/api/track-records/leaderboard?${queryParams.toString()}`, {
  59. method: 'GET',
  60. headers: JSON_HEADERS
  61. });
  62. }
  63. // 종목 가상보드 글 작성 (JWT · SSR) — POST /api/boards/stock/posts
  64. export async function createStockBoardPost(body: CreateStockPostRequest): Promise<ResultDto<CreateStockPostResponse>>
  65. {
  66. return await fetchJson<CreateStockPostResponse>('/api/boards/stock/posts', {
  67. method: 'POST',
  68. headers: { ...JSON_HEADERS, 'Content-Type': 'application/json' },
  69. body: JSON.stringify(body)
  70. });
  71. }
  72. // 작성자 지위 배지 배치 조회 (익명 · SSR) — GET /api/members/equipped-items?ids=1,2,3
  73. export async function fetchEquippedItems(memberIDs: number[]): Promise<ResultDto<EquippedItemsResponse>>
  74. {
  75. const ids = memberIDs.filter(id => id > 0).join(',');
  76. return await fetchJson<EquippedItemsResponse>(`/api/members/equipped-items?ids=${ids}`, {
  77. method: 'GET',
  78. headers: JSON_HEADERS
  79. });
  80. }