메일 알림 시스템 추가

This commit is contained in:
Yun Chan 2026-06-29 17:07:01 +09:00
parent ddf12a851c
commit 3bf38c50df
22 changed files with 1769 additions and 31 deletions

View file

@ -48,6 +48,66 @@ export interface paths {
patch?: never;
trace?: never;
};
"/admin/notifications": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* List Notifications
* @description Return recent operational email delivery state.
*/
get: operations["list_notifications_admin_notifications_get"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/notifications/process": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Process Notifications
* @description Drain queued email notifications once from the admin console/API.
*/
post: operations["process_notifications_admin_notifications_process_post"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/notifications/test": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Send Test Notification
* @description Queue and process one explicit admin email test.
*/
post: operations["send_test_notification_admin_notifications_test_post"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/tickets": {
parameters: {
query?: never;
@ -1339,6 +1399,85 @@ export interface components {
*/
status: "ok" | "degraded" | "down";
};
/** AdminNotificationDeliveryResponse */
AdminNotificationDeliveryResponse: {
/** Attempts */
attempts: number;
/** Created At */
created_at?: number | null;
/** Event Id */
event_id: string;
/** Id */
id: string;
/** Kind */
kind: string;
/** Last Error */
last_error?: string | null;
/** Provider Message Id */
provider_message_id?: string | null;
/** Recipient Email */
recipient_email: string;
/** Recipient Name */
recipient_name: string;
/** Recipient Role */
recipient_role: string;
/** Sent At */
sent_at?: number | null;
/**
* Status
* @enum {string}
*/
status: "queued" | "sending" | "sent" | "failed" | "skipped";
/** Subject */
subject: string;
/** Updated At */
updated_at?: number | null;
};
/** AdminNotificationProcessResponse */
AdminNotificationProcessResponse: {
/** Failed */
failed: number;
/** Processed */
processed: number;
/** Sent */
sent: number;
/** Skipped */
skipped: number;
};
/** AdminNotificationTestResponse */
AdminNotificationTestResponse: {
/** Failed */
failed: number;
/** Processed */
processed: number;
/** Provider */
provider: string;
/** Recipients */
recipients: number;
/** Sent */
sent: number;
/** Skipped */
skipped: number;
/** Smtp Configured */
smtp_configured: boolean;
};
/** AdminNotificationsResponse */
AdminNotificationsResponse: {
/** Deliveries */
deliveries: components["schemas"]["AdminNotificationDeliveryResponse"][];
/** Failed */
failed: number;
/** Provider */
provider: string;
/** Queued */
queued: number;
/** Sent */
sent: number;
/** Skipped */
skipped: number;
/** Smtp Configured */
smtp_configured: boolean;
};
/** AdminServiceHealth */
AdminServiceHealth: {
/** Detail */
@ -2486,6 +2625,11 @@ export interface components {
};
/** NotificationPreferences */
NotificationPreferences: {
/**
* Account Approval
* @default true
*/
account_approval: boolean;
/**
* Learner Progress
* @default false
@ -4185,6 +4329,106 @@ export interface operations {
};
};
};
list_notifications_admin_notifications_get: {
parameters: {
query?: {
limit?: number;
};
header?: never;
path?: never;
cookie?: {
"__Host-vignette_sid"?: string | null;
vignette_sid?: string | null;
};
};
requestBody?: never;
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminNotificationsResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
process_notifications_admin_notifications_process_post: {
parameters: {
query?: {
limit?: number;
};
header?: never;
path?: never;
cookie?: {
"__Host-vignette_sid"?: string | null;
vignette_sid?: string | null;
};
};
requestBody?: never;
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminNotificationProcessResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
send_test_notification_admin_notifications_test_post: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: {
"__Host-vignette_sid"?: string | null;
vignette_sid?: string | null;
};
};
requestBody?: never;
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminNotificationTestResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
list_tickets_admin_tickets_get: {
parameters: {
query?: {

View file

@ -174,6 +174,7 @@ const DEFAULT_NOTIFICATION_PREFERENCES: NotificationPreferences = {
session_done: true,
safety_signal: true,
learner_progress: true,
account_approval: true,
product_news: false,
};
@ -347,6 +348,12 @@ export default function Settings() {
hint: "교수자와 관리자에게만 표시됩니다.",
roles: ["teacher", "admin"],
},
{
id: "account_approval",
label: "가입 승인",
hint: "신규 가입 승인 요청이 있으면 알려줍니다.",
roles: ["admin"],
},
{
id: "product_news",
label: "제품 소식",