All files / src/routes/api/v1 me.js

0% Statements 0/30
0% Branches 0/16
0% Functions 0/4
0% Lines 0/29

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105                                                                                                                                                                                                                 
/**
 * API v1 — Compte utilisateur (read-only)
 *
 * GET /api/v1/me        — Profil (plan, email)
 * GET /api/v1/me/usage  — Utilisation actuelle vs limites
 *
 * @module routes/api/v1/me
 */
 
const express = require('express');
const { pool: db } = require('../../../db');
const { requireScope } = require('../../../middleware/apiAuth');
const { getPlanLimits } = require('../../../config/plans');
const { apiSuccess } = require('../../../helpers/apiResponse');
const { getUsage } = require('../../../middleware/apiRateLimit');
 
const router = express.Router();
 
// ─── GET /me ────────────────────────────────────────────────────────────────
 
router.get('/', requireScope('read'), async (req, res, next) => {
  try {
    const { rows } = await db.query(
      'SELECT id, email, plan, created_at FROM users WHERE id = $1',
      [req.user.id],
    );
 
    if (rows.length === 0) {
      return res.status(404).json({ error: { code: 'NOT_FOUND', message: 'Utilisateur introuvable.' } });
    }
 
    apiSuccess(res, {
      id: rows[0].id,
      email: rows[0].email,
      plan: rows[0].plan,
      created_at: rows[0].created_at,
    });
  } catch (err) {
    next(err);
  }
});
 
// ─── GET /me/usage ──────────────────────────────────────────────────────────
 
router.get('/usage', requireScope('read'), async (req, res, next) => {
  try {
    const plan = req.user.plan || 'free';
    const limits = await getPlanLimits(plan);
 
    // Compter les ressources en parallele
    const [servers, monitors, ssl, webhooks, alertRules, backupSchedules, statusPages, chatToday] = await Promise.all([
      db.query('SELECT COUNT(*) FROM servers WHERE user_id = $1', [req.user.id]),
      db.query('SELECT COUNT(*) FROM uptime_monitors WHERE user_id = $1', [req.user.id]),
      db.query('SELECT COUNT(*) FROM ssl_certificates WHERE user_id = $1', [req.user.id]),
      db.query('SELECT COUNT(*) FROM webhooks WHERE user_id = $1', [req.user.id]),
      db.query('SELECT COUNT(*) FROM alert_rules WHERE user_id = $1', [req.user.id]),
      db.query('SELECT COUNT(*) FROM backup_schedules WHERE user_id = $1', [req.user.id]),
      db.query('SELECT COUNT(*) FROM status_pages WHERE user_id = $1', [req.user.id]),
      db.query(
        `SELECT COUNT(*) FROM chat_messages cm
         JOIN chat_sessions cs ON cs.id = cm.session_id
         WHERE cs.user_id = $1 AND cm.created_at > NOW() - INTERVAL '24 hours'`,
        [req.user.id],
      ),
    ]);
 
    const toLimit = (v) => v === Infinity ? -1 : v;
 
    apiSuccess(res, {
      plan,
      usage: {
        servers: { current: Number.parseInt(servers.rows[0].count), limit: toLimit(limits.servers) },
        uptime_monitors: { current: Number.parseInt(monitors.rows[0].count), limit: toLimit(limits.uptime_monitors) },
        ssl_certificates: { current: Number.parseInt(ssl.rows[0].count), limit: toLimit(limits.ssl_certificates) },
        webhooks: { current: Number.parseInt(webhooks.rows[0].count), limit: toLimit(limits.webhooks) },
        alert_rules: { current: Number.parseInt(alertRules.rows[0].count), limit: toLimit(limits.alert_rules) },
        backup_schedules: { current: Number.parseInt(backupSchedules.rows[0].count), limit: toLimit(limits.backup_schedules) },
        status_pages: { current: Number.parseInt(statusPages.rows[0].count), limit: toLimit(limits.status_pages) },
        chat_messages_today: { current: Number.parseInt(chatToday.rows[0].count), limit: toLimit(limits.chat_messages_per_day) },
      },
    });
  } catch (err) {
    next(err);
  }
});
 
// ─── GET /me/rate-limit ─────────────────────────────────────────────────────
 
router.get('/rate-limit', requireScope('read'), async (req, res) => {
  const plan = req.user.plan || 'free';
  const limits = await getPlanLimits(plan);
  const limit = limits.api_requests_per_hour ?? 0;
  const usage = getUsage(req.user.id);
 
  apiSuccess(res, {
    plan,
    used: usage?.used ?? 0,
    limit,
    remaining: usage ? usage.remaining : limit,
    reset_at: usage?.reset_at ?? null,
  });
});
 
module.exports = router;