JavaScript · 47 строк
Три роута: список 50 последних диалогов с числом непрочитанных, отметка «прочитано до сообщения N» и общий счётчик для красной цифры на иконке. Счётчик кэшируется в Redis.
База — PostgreSQL через pg, Redis — клиент redis v4 с промисами. Групповые чаты бывают до 500 участников. Отметьте строки с ошибками.
В работе: Красная цифра на вкладке «Сообщения» и список диалогов в веб-версии.
Как проверяем
Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Ответ один на подход: после него показываем разбор.
Источник: наша задача на данных VK: диалоги и непрочитанные сообщения. Условие пересказано своими словами.
Давали на собеседовании?
const express = require("express");const { pool } = require("./db");const { redis } = require("./cache");const router = express.Router();router.get("/api/dialogs", async (req, res) => {const userId = req.session.userId;const { rows: dialogs } = await pool.query("SELECT d.id, d.title, d.peer_id FROM dialogs d " +"JOIN dialog_members m ON m.dialog_id = d.id WHERE m.user_id = $1 " +"ORDER BY d.last_message_at DESC LIMIT 50",[userId]);for (const d of dialogs) {const { rows } = await pool.query("SELECT count(*) FROM messages WHERE dialog_id = $1 AND id > " +"(SELECT last_read_id FROM dialog_members WHERE dialog_id = $1 AND user_id = $2)",[d.id, userId]);d.unread = rows[0].count;}const total = dialogs.reduce((sum, d) => sum + d.unread, 0);redis.set(`unread:${userId}`, total);res.json({ dialogs, total });});router.post("/api/dialogs/:id/read", async (req, res) => {const { lastMessageId } = req.body;await pool.query("UPDATE dialog_members SET last_read_id = $1 WHERE dialog_id = $2",[lastMessageId, req.params.id]);redis.del(`unread:${req.session.userId}`);res.sendStatus(204);});router.get("/api/unread", async (req, res) => {const key = `unread:${req.query.userId}`;const cached = redis.get(key);if (cached) {return res.json({ total: cached });}res.json({ total: 0 });});module.exports = router;