Aller au contenu principal

Stack : Node.js + Express + TypeScript

Configuration pour .cursorrules ou CLAUDE.md

Langage et version

  • Node.js 20 LTS
  • TypeScript strict
  • tsconfig.json avec strict: true

Framework

  • Express.js avec typescript-express
  • Middleware pattern pour validation et auth
  • Async/await obligatoire

Base de données

  • Prisma ORM (schéma source de vérité)
  • Migrations auto avec Prisma Migrate

Exemple : Middleware et route

// middleware/auth.ts
export const requireAuth = (req: Request, res: Response, next: NextFunction) => {
const token = req.headers.authorization?.split(" ")[1];
if (!token) return res.status(401).json({ error: "Unauthorized" });

try {
const decoded = jwt.verify(token, process.env.JWT_SECRET!);
(req as any).user = decoded;
next();
} catch {
return res.status(403).json({ error: "Invalid token" });
}
};

// routes/users.ts
router.post("/users", requireAuth, async (req: Request, res: Response) => {
const { email, name } = req.body;
if (!email || !name) {
return res.status(400).json({ error: "Missing fields" });
}

const user = await prisma.user.create({
data: { email, name }
});

return res.status(201).json(user);
});

Test avec Jest

describe("POST /users", () => {
it("should create user with valid token", async () => {
const response = await request(app)
.post("/users")
.set("Authorization", `Bearer ${adminToken}`)
.send({ email: "test@example.com", name: "Test" });

expect(response.status).toBe(201);
expect(response.body.email).toBe("test@example.com");
});

it("should reject without token", async () => {
const response = await request(app)
.post("/users")
.send({ email: "test@example.com", name: "Test" });

expect(response.status).toBe(401);
});
});