72 lines
2.3 KiB
JavaScript
72 lines
2.3 KiB
JavaScript
// Design Ref: §2 repo — todo DB CRUD. 외부 연결은 db.js pool 경유.
|
|
import { pool } from "./db.js";
|
|
import { hasPgcrypto, newId } from "./schema.js";
|
|
|
|
// Design Ref: §4 — 응답에서 내부 S3 key 는 제외하고 hasAttachment 만 노출.
|
|
function toDto(row) {
|
|
if (!row) return null;
|
|
return {
|
|
id: row.id,
|
|
title: row.title,
|
|
done: row.done,
|
|
attachment_name: row.attachment_name,
|
|
attachment_type: row.attachment_type,
|
|
hasAttachment: row.attachment_key != null,
|
|
created_at: row.created_at,
|
|
};
|
|
}
|
|
|
|
export async function list() {
|
|
const { rows } = await pool.query(
|
|
"SELECT * FROM todo ORDER BY created_at DESC"
|
|
);
|
|
return rows.map(toDto);
|
|
}
|
|
|
|
// Plan SC: SC-02 — pgcrypto 가용 시 DB default, 아니면 app-side UUID.
|
|
export async function create({ title, attachmentKey, attachmentName, attachmentType }) {
|
|
if (hasPgcrypto()) {
|
|
const { rows } = await pool.query(
|
|
`INSERT INTO todo (title, attachment_key, attachment_name, attachment_type)
|
|
VALUES ($1, $2, $3, $4) RETURNING *`,
|
|
[title, attachmentKey ?? null, attachmentName ?? null, attachmentType ?? null]
|
|
);
|
|
return toDto(rows[0]);
|
|
}
|
|
const { rows } = await pool.query(
|
|
`INSERT INTO todo (id, title, attachment_key, attachment_name, attachment_type)
|
|
VALUES ($1, $2, $3, $4, $5) RETURNING *`,
|
|
[newId(), title, attachmentKey ?? null, attachmentName ?? null, attachmentType ?? null]
|
|
);
|
|
return toDto(rows[0]);
|
|
}
|
|
|
|
// 첨부 업로드 후 키/메타를 기존 todo row 에 반영. Plan SC: SC-02
|
|
export async function setAttachment(id, { key, name, type }) {
|
|
const { rows } = await pool.query(
|
|
`UPDATE todo SET attachment_key = $2, attachment_name = $3, attachment_type = $4
|
|
WHERE id = $1 RETURNING *`,
|
|
[id, key, name, type]
|
|
);
|
|
return toDto(rows[0]);
|
|
}
|
|
|
|
export async function setDone(id, done) {
|
|
const { rows } = await pool.query(
|
|
"UPDATE todo SET done = $2 WHERE id = $1 RETURNING *",
|
|
[id, done]
|
|
);
|
|
return toDto(rows[0]); // 없으면 null
|
|
}
|
|
|
|
// 내부용: 삭제/다운로드 시 attachment_key 가 필요하므로 raw row 반환.
|
|
export async function getRaw(id) {
|
|
const { rows } = await pool.query("SELECT * FROM todo WHERE id = $1", [id]);
|
|
return rows[0] ?? null;
|
|
}
|
|
|
|
export async function remove(id) {
|
|
const { rowCount } = await pool.query("DELETE FROM todo WHERE id = $1", [id]);
|
|
return rowCount > 0;
|
|
}
|