diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..3257912
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,122 @@
+
+
+
+
+
+ ๋ฐฉ๋ช
๋ก
+
+
+
+
+
๐ ๋ฐฉ๋ช
๋ก
+
ํ ์ค ๋จ๊ธฐ๊ณ ๊ฐ์ธ์. (Postgres ์ ์ ์ฅ๋ฉ๋๋ค)
+
+
+
+
+
+
+
diff --git a/src/db.js b/src/db.js
index 0c5aec4..4db9186 100644
--- a/src/db.js
+++ b/src/db.js
@@ -13,3 +13,32 @@ export async function pingDb() {
);
return rows[0];
}
+
+// --- ๋ฐฉ๋ช
๋ก(guestbook) ---
+// ํ
์ด๋ธ์ search_path์ ๊ณ ์ ๋ ๋ณธ์ธ schema์ ์์ฑ๋๋ค(schema ์ ๋์ด ๋ถํ์).
+export async function initGuestbook() {
+ await pool.query(`
+ create table if not exists guestbook (
+ id bigint generated always as identity primary key,
+ name text not null,
+ message text not null,
+ created_at timestamptz not null default now()
+ )
+ `);
+}
+
+export async function listMessages(limit = 100) {
+ const { rows } = await pool.query(
+ "select id, name, message, created_at from guestbook order by id desc limit $1",
+ [limit]
+ );
+ return rows;
+}
+
+export async function addMessage(name, message) {
+ const { rows } = await pool.query(
+ "insert into guestbook (name, message) values ($1, $2) returning id, name, message, created_at",
+ [name, message]
+ );
+ return rows[0];
+}
diff --git a/src/server.js b/src/server.js
index e94230a..46a7508 100644
--- a/src/server.js
+++ b/src/server.js
@@ -1,10 +1,16 @@
-// ์ต์ Express ์๋ฒ โ /healthz, /db, /s3 ๋ก ์ฐ๊ฒฐ ํ์ธ.
+// Express ์๋ฒ โ ๋ฐฉ๋ช
๋ก(guestbook) ์น์ฌ์ดํธ + ์ฐ๊ฒฐ ํ์ธ์ฉ /healthz, /db, /s3.
import express from "express";
+import { fileURLToPath } from "node:url";
+import { dirname, join } from "node:path";
import { config } from "./config.js";
-import { pingDb } from "./db.js";
+import { pingDb, initGuestbook, listMessages, addMessage } from "./db.js";
import { pingS3 } from "./s3.js";
+const __dirname = dirname(fileURLToPath(import.meta.url));
+
const app = express();
+app.use(express.json());
+app.use(express.static(join(__dirname, "..", "public")));
app.get("/healthz", (_req, res) => res.json({ ok: true }));
@@ -24,10 +30,37 @@ app.get("/s3", async (_req, res) => {
}
});
-app.get("/", (_req, res) =>
- res.json({ name: "sample", endpoints: ["/healthz", "/db", "/s3"] })
-);
-
-app.listen(config.port, "0.0.0.0", () => {
- console.log(`sample listening on :${config.port}`);
+// --- ๋ฐฉ๋ช
๋ก API ---
+app.get("/api/messages", async (_req, res) => {
+ try {
+ res.json({ ok: true, messages: await listMessages() });
+ } catch (e) {
+ res.status(500).json({ ok: false, error: String(e.message || e) });
+ }
+});
+
+app.post("/api/messages", async (req, res) => {
+ try {
+ const name = String(req.body?.name ?? "").trim();
+ const message = String(req.body?.message ?? "").trim();
+ if (!name || !message) {
+ return res
+ .status(400)
+ .json({ ok: false, error: "name ๊ณผ message ๋ ํ์์
๋๋ค." });
+ }
+ if (name.length > 40 || message.length > 500) {
+ return res
+ .status(400)
+ .json({ ok: false, error: "์ด๋ฆ์ 40์, ๋ฉ์์ง๋ 500์ ์ด๋ด." });
+ }
+ res.json({ ok: true, message: await addMessage(name, message) });
+ } catch (e) {
+ res.status(500).json({ ok: false, error: String(e.message || e) });
+ }
+});
+
+// ์ฑ ์์ ์ ์ ํ
์ด๋ธ ๋ณด์ฅ ํ ๋ฆฌ์จ.
+await initGuestbook();
+app.listen(config.port, "0.0.0.0", () => {
+ console.log(`guestbook listening on :${config.port}`);
});