summaryrefslogtreecommitdiff
path: root/lib/notice/service.ts
blob: 9c05b98f0cffeb70dd807cfe25250307ac12fb05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
"use server"

import { getErrorMessage } from "@/lib/handle-error"
import { desc, eq } from "drizzle-orm"
import db from "@/db/db"
import { notice, pageInformation, menuAssignments, users } from "@/db/schema"

import type { 
  CreateNoticeSchema, 
  UpdateNoticeSchema
} from "./validations"

import {
  getNoticesByPagePath,
  insertNotice,
  updateNotice,
  deleteNoticeById,
  deleteNoticeByIds,
  getNoticeById
} from "./repository"

import type { Notice } from "@/db/schema/notice"

// 간단한 공지사항 목록 조회 (페이지네이션 없이 전체 조회)
export async function getNoticeLists(): Promise<{ data: Array<Notice & { authorName: string | null; authorEmail: string | null }> }> {
  try {
    // 전체 데이터 조회 (작성자 정보 포함, 클라이언트에서 검색 처리)
    const data = await db
      .select({
        id: notice.id,
        pagePath: notice.pagePath,
        title: notice.title,
        content: notice.content,
        authorId: notice.authorId,
        isActive: notice.isActive,
        createdAt: notice.createdAt,
        updatedAt: notice.updatedAt,
        authorName: users.name,
        authorEmail: users.email,
      })
      .from(notice)
      .leftJoin(users, eq(notice.authorId, users.id))
      .orderBy(desc(notice.createdAt))

    return { data }
  } catch (err) {
    console.error("Failed to get notice lists:", err)
    return { data: [] }
  }
}

// 페이지별 공지사항 조회 (일반 사용자용)
export async function getPageNotices(pagePath: string): Promise<Array<Notice & { authorName: string | null; authorEmail: string | null }>> {
  try {
    console.log('🔍 Notice Service - 조회 시작:', { pagePath })
    const result = await getNoticesByPagePath(pagePath)
    console.log('📊 Notice Service - 조회 결과:', {
      pagePath,
      noticesCount: result.length,
      notices: result.map(n => ({ id: n.id, title: n.title, pagePath: n.pagePath }))
    })
    return result
  } catch (error) {
    console.error(`Failed to get notices for page ${pagePath}:`, error)
    return []
  }
}

// 페이지별 공지사항 조회 (직접 호출용)
export async function getPageNoticesDirect(pagePath: string) {
  return await getPageNotices(pagePath)
}

// 공지사항 생성
export async function createNotice(input: CreateNoticeSchema) {
  try {
    const result = await insertNotice(input)
    
    return {
      success: true,
      data: result,
      message: "공지사항이 성공적으로 생성되었습니다."
    }
  } catch (error) {
    console.error("Failed to create notice:", error)
    return {
      success: false,
      message: getErrorMessage(error)
    }
  }
}

// 공지사항 수정
export async function updateNoticeData(input: UpdateNoticeSchema) {
  try {
    const { id, ...updateData } = input
    const result = await updateNotice(id, updateData)
    
    if (!result) {
      return {
        success: false,
        message: "공지사항을 찾을 수 없거나 수정에 실패했습니다."
      }
    }
    
    return {
      success: true,
      message: "공지사항이 성공적으로 수정되었습니다."
    }
  } catch (error) {
    console.error("Failed to update notice:", error)
    return {
      success: false,
      message: getErrorMessage(error)
    }
  }
}

// 공지사항 삭제
export async function deleteNotice(id: number) {
  try {
    const success = await deleteNoticeById(id)
    
    if (!success) {
      return {
        success: false,
        message: "공지사항을 찾을 수 없거나 삭제에 실패했습니다."
      }
    }
    
    return {
      success: true,
      message: "공지사항이 성공적으로 삭제되었습니다."
    }
  } catch (error) {
    console.error("Failed to delete notice:", error)
    return {
      success: false,
      message: getErrorMessage(error)
    }
  }
}

// 공지사항 다중 삭제
export async function deleteMultipleNotices(ids: number[]) {
  try {
    const deletedCount = await deleteNoticeByIds(ids)
    
    return {
      success: true,
      deletedCount,
      message: `${deletedCount}개의 공지사항이 성공적으로 삭제되었습니다.`
    }
  } catch (error) {
    console.error("Failed to delete multiple notices:", error)
    return {
      success: false,
      message: getErrorMessage(error)
    }
  }
}

// ID로 공지사항 조회
export async function getNoticeDetail(id: number): Promise<(Notice & { authorName: string | null; authorEmail: string | null }) | null> {
  try {
    return await getNoticeById(id)
  } catch (error) {
    console.error(`Failed to get notice detail for id ${id}:`, error)
    return null
  }
}

// pagePath 목록 조회 (정보 시스템에서 사용)
export async function getPagePathList(): Promise<Array<{ pagePath: string; pageName: string }>> {
  try {
    const result = await db
      .selectDistinct({
        pagePath: pageInformation.pagePath,
        pageName: pageInformation.pageName
      })
      .from(pageInformation)
      .where(eq(pageInformation.isActive, true))
      .orderBy(desc(pageInformation.pagePath))

    return result.map(item => ({
      pagePath: item.pagePath,
      pageName: item.pageName || item.pagePath
    }))
  } catch (error) {
    console.error("Failed to get page path list:", error)
    return []
  }
}

// menu_assignments 기반으로 notice 페이지 경로 동기화
export async function syncNoticeFromMenuAssignments() {
  try {
    // menu_assignments에서 모든 메뉴 가져오기
    const menuItems = await db.select().from(menuAssignments);
    
    // 기존 notice 페이지 경로들 가져오기 (중복 제거)
    const existingNotices = await db.select({
      pagePath: notice.pagePath
    }).from(notice);
    const existingPaths = new Set(existingNotices.map(item => item.pagePath));
    
    let processedCount = 0;
    const missingPaths = [];
    
    // 각 메뉴 항목에 대해 확인
    for (const menu of menuItems) {
      if (!existingPaths.has(menu.menuPath)) {
        missingPaths.push({
          pagePath: menu.menuPath,
          pageName: menu.menuTitle
        });
      }
      processedCount++;
    }
    
    return {
      success: true,
      message: `공지사항 경로 동기화 확인 완료: ${processedCount}개 확인, ${missingPaths.length}개 누락`,
      missingPaths: missingPaths
    };
  } catch (error) {
    console.error("Notice 동기화 오류:", error);
    return {
      success: false,
      message: "공지사항 경로 동기화 중 오류가 발생했습니다.",
      missingPaths: []
    };
  }
}