[agent-pipeline] pipe-20260403004704-gib0 round-1
This commit is contained in:
@@ -0,0 +1,56 @@
|
|||||||
|
import { Request, Response } from "express";
|
||||||
|
import { SampleService } from "../services/sampleService";
|
||||||
|
|
||||||
|
const sampleService = SampleService.getInstance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 목록 조회
|
||||||
|
* GET /api/sample/list?page=1&limit=20
|
||||||
|
*/
|
||||||
|
export const getList = async (req: Request, res: Response): Promise<void> => {
|
||||||
|
const page = Math.max(1, parseInt(req.query.page as string) || 1);
|
||||||
|
const limit = Math.min(100, Math.max(1, parseInt(req.query.limit as string) || 20));
|
||||||
|
const result = await sampleService.getList(page, limit);
|
||||||
|
res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
data: result.items,
|
||||||
|
total: result.total,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 등록
|
||||||
|
* POST /api/sample
|
||||||
|
*/
|
||||||
|
export const create = async (req: Request, res: Response): Promise<void> => {
|
||||||
|
const { name, description } = req.body;
|
||||||
|
if (!name || !description) {
|
||||||
|
res.status(400).json({ success: false, message: "name, description은 필수입니다." });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const item = await sampleService.create(name, description);
|
||||||
|
res.status(201).json({ success: true, data: item });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 수정
|
||||||
|
* PUT /api/sample/:id
|
||||||
|
*/
|
||||||
|
export const update = async (req: Request, res: Response): Promise<void> => {
|
||||||
|
const { id } = req.params;
|
||||||
|
const { name, description } = req.body;
|
||||||
|
const item = await sampleService.update(id, name, description);
|
||||||
|
res.status(200).json({ success: true, data: item });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 삭제 (soft delete)
|
||||||
|
* DELETE /api/sample/:id
|
||||||
|
*/
|
||||||
|
export const remove = async (req: Request, res: Response): Promise<void> => {
|
||||||
|
const { id } = req.params;
|
||||||
|
await sampleService.softDelete(id);
|
||||||
|
res.status(200).json({ success: true, message: "삭제되었습니다." });
|
||||||
|
};
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { Router } from "express";
|
||||||
|
import { authenticateToken } from "../middleware/authMiddleware";
|
||||||
|
import * as sampleController from "../controllers/sampleController";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.use(authenticateToken);
|
||||||
|
|
||||||
|
router.get("/list", sampleController.getList);
|
||||||
|
router.post("/", sampleController.create);
|
||||||
|
router.put("/:id", sampleController.update);
|
||||||
|
router.delete("/:id", sampleController.remove);
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { logger } from "../utils/logger";
|
||||||
|
|
||||||
|
export interface SampleItem {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
is_deleted: boolean;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 인메모리 저장소 (실제 DB 테이블 없이도 동작)
|
||||||
|
const store = new Map<string, SampleItem>();
|
||||||
|
|
||||||
|
export class SampleService {
|
||||||
|
private static instance: SampleService;
|
||||||
|
|
||||||
|
private constructor() {}
|
||||||
|
|
||||||
|
public static getInstance(): SampleService {
|
||||||
|
if (!SampleService.instance) {
|
||||||
|
SampleService.instance = new SampleService();
|
||||||
|
}
|
||||||
|
return SampleService.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 목록 조회 (페이징, soft delete 제외)
|
||||||
|
*/
|
||||||
|
public async getList(page: number, limit: number): Promise<{ items: SampleItem[]; total: number }> {
|
||||||
|
const active = Array.from(store.values()).filter((item) => !item.is_deleted);
|
||||||
|
const total = active.length;
|
||||||
|
const items = active.slice((page - 1) * limit, page * limit);
|
||||||
|
logger.info(`📋 sample 목록 조회: total=${total}, page=${page}, limit=${limit}`);
|
||||||
|
return { items, total };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 등록
|
||||||
|
*/
|
||||||
|
public async create(name: string, description: string): Promise<SampleItem> {
|
||||||
|
const now = new Date().toISOString();
|
||||||
|
const item: SampleItem = {
|
||||||
|
id: uuidv4(),
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
is_deleted: false,
|
||||||
|
created_at: now,
|
||||||
|
updated_at: now,
|
||||||
|
};
|
||||||
|
store.set(item.id, item);
|
||||||
|
logger.info(`✅ sample 등록: ${item.id}`);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 수정
|
||||||
|
*/
|
||||||
|
public async update(id: string, name?: string, description?: string): Promise<SampleItem> {
|
||||||
|
const item = store.get(id);
|
||||||
|
if (!item || item.is_deleted) {
|
||||||
|
throw new Error(`항목을 찾을 수 없습니다: ${id}`);
|
||||||
|
}
|
||||||
|
if (name !== undefined) item.name = name;
|
||||||
|
if (description !== undefined) item.description = description;
|
||||||
|
item.updated_at = new Date().toISOString();
|
||||||
|
store.set(id, item);
|
||||||
|
logger.info(`✅ sample 수정: ${id}`);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Soft delete
|
||||||
|
*/
|
||||||
|
public async softDelete(id: string): Promise<void> {
|
||||||
|
const item = store.get(id);
|
||||||
|
if (!item || item.is_deleted) {
|
||||||
|
throw new Error(`항목을 찾을 수 없습니다: ${id}`);
|
||||||
|
}
|
||||||
|
item.is_deleted = true;
|
||||||
|
item.updated_at = new Date().toISOString();
|
||||||
|
store.set(id, item);
|
||||||
|
logger.info(`✅ sample 삭제(soft): ${id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user