๊ธฐ๋ณธ ๊ตฌ์กฐ

๐Ÿ“Ž ๊ธฐ๋ณธ ๊ตฌ์กฐ

server
 โ”œโ”€ routes
 โ”‚    โ”œโ”€ auth.js
 โ”‚    โ”œโ”€ todo.js
 โ”œโ”€ controllers
 โ”œโ”€ models
 โ”œโ”€ middleware
 โ”‚    โ””โ”€ auth.js
 โ””โ”€ app.js

Todo API

๐Ÿ“Ž ๋‚ ์งœ๋ณ„ ์กฐํšŒ

router.get("/", authMiddleware, async (req, res) => {
  const { date } = req.query;

  const todos = await Todo.find({
    userId: req.user.id,
    date,
  });

  res.json(todos);
});

๐Ÿ“Ž์›”๋ณ„ Summary API

router.get("/summary", authMiddleware, async (req, res) => {
  const { month } = req.query;

  const start = new Date(`${month}-01`);
  const end = new Date(start);
  end.setMonth(end.getMonth() + 1);

  const todos = await Todo.find({
    userId: req.user.id,
    date: { $gte: start, $lt: end },
  });

  const summary = {};

  todos.forEach((todo) => {
    const d = todo.date.toISOString().slice(0, 10);

    if (!summary[d]) summary[d] = { total: 0, remaining: 0 };

    summary[d].total++;
    if (!todo.done) summary[d].remaining++;
  });

  res.json(
    Object.entries(summary).map(([date, value]) => ({
      date,
      ...value,
    }))
  );
});

์ธ์ฆ

๐Ÿ“ŽJWT ๊ฒ€์ฆ middleware

function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.split(" ")[1];
  if (!token) return res.status(401).json({ message: "Unauthorized" });

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (err) {
    return res.status(401).json({ message: "Invalid token" });
  }
}