totolist/routes/api.js
2025-08-28 13:57:06 +02:00

144 lines
No EOL
4.4 KiB
JavaScript

const fastifySwagger = require('@fastify/swagger');
const fastifySwaggerUI = require('@fastify/swagger-ui');
module.exports = async function (app, opts) {
const db = require('../db');
const promClient = require('prom-client');
// --- Schémas pour Swagger ---
const Todo = {
type: 'object',
properties: {
id: { type: 'integer' },
title: { type: 'string' },
completed: { type: 'integer', enum: [0, 1] },
created_at: { type: 'string' },
},
};
const TodoCreate = {
type: 'object',
required: ['title'],
properties: { title: { type: 'string' } },
};
const TodoUpdate = {
type: 'object',
properties: {
title: { type: 'string' },
completed: { type: 'integer', enum: [0, 1] },
},
};
// --- Prometheus ---
const register = opts.promRegister;
const counterCreated = opts.counterCreated;
const counterDeleted = opts.counterDeleted;
const gaugeCount = opts.gaugeCount;
function refreshGauge() {
try {
const count = db.all().length;
gaugeCount.set(count);
} catch { }
}
app.get('/api/todos', {
schema: {
response: { 200: { type: 'array', items: Todo } },
tags: ['todos'],
},
}, async () => db.allTodos());
app.get('/api/todos/:id', {
schema: {
params: { type: 'object', properties: { id: { type: 'integer' } }, required: ['id'] },
response: { 200: Todo, 404: { type: 'object', properties: { message: { type: 'string' } } } },
tags: ['todos'],
},
}, async (req, reply) => {
const todo = db.getTodo(req.params.id);
if (!todo) return reply.code(404).send({ message: 'Not found' });
return todo;
});
app.post('/api/todos', {
schema: {
body: TodoCreate,
response: { 201: Todo },
tags: ['todos'],
},
}, async (req, reply) => {
const { title } = req.body;
const users_id = req.session?.user?.id || 1;
const result = db.createTodo(users_id, title);
counterCreated.inc();
refreshGauge();
const created = db.getTodo(result.lastInsertRowid);
reply.code(201);
return created;
});
app.patch('/api/todos/:id', {
schema: {
params: { type: 'object', properties: { id: { type: 'integer' } }, required: ['id'] },
body: TodoUpdate,
response: { 200: Todo, 404: { type: 'object', properties: { message: { type: 'string' } } } },
tags: ['todos'],
},
}, async (req, reply) => {
const id = req.params.id;
if (!db.getTodo(id)) return reply.code(404).send({ message: 'Not found' });
db.updateTodo(id, req.body || {});
const updated = db.getTodo(id);
refreshGauge();
return updated;
});
app.delete('/api/todos/:id', {
schema: {
params: { type: 'object', properties: { id: { type: 'integer' } }, required: ['id'] },
response: { 204: { type: 'null' } },
tags: ['todos'],
},
}, async (req, reply) => {
const id = req.params.id;
const existing = db.getTodo(id);
if (existing) {
db.removeTodo(id);
counterDeleted.inc();
refreshGauge();
}
reply.code(204).send();
});
// Route pour voir tous les users
app.get('/api/users', {
schema: {
response: {
200: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'integer' },
pseudo: { type: 'string' },
discord_id: { type: 'string' },
created_at: { type: 'string' }
}
}
}
},
tags: ['users'],
}
}, async () => db.allUsers());
app.register(fastifySwagger, {
openapi: {
info: {
title: 'Todo API',
version: '1.0.0',
description: 'CRUD de Todo en Fastify (Node.js) + SQLite',
},
servers: [{ url: 'http://localhost:3000' }],
},
});
};