From 24291d3feb7cf68b8aa4d00a5591c9fa5b595a1a Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:50:18 -0300 Subject: [PATCH 01/12] docs(agenda.repository): Add JSDoc comments for improved code documentation This commit enhances the agenda.repository.js file by adding JSDoc comments to various functions, providing clear descriptions of parameters and return values. This improves code readability and maintainability, facilitating better understanding for future developers working on the repository. --- backend/src/repositories/agenda.repository.js | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/backend/src/repositories/agenda.repository.js b/backend/src/repositories/agenda.repository.js index 3e0ae38..aad7cac 100644 --- a/backend/src/repositories/agenda.repository.js +++ b/backend/src/repositories/agenda.repository.js @@ -44,6 +44,10 @@ function uniqueByTelegramId(users) { return uniqueUsers; } +/** + * @param {Object} data - The data to resolve the responsible users. + * @return {Array|null} The responsible users or null. + */ function explicitResponsibleUsers(data) { const explicit = data.responsibleUserIds || data.responsibleTelegramIds || data.members; @@ -65,6 +69,10 @@ function explicitResponsibleUsers(data) { return null; } +/** + * @param {number|string} value - The value to parse as money. + * @return {number} The parsed money. + */ function parseMoney(value) { if (typeof value === "number") { return value; @@ -79,6 +87,10 @@ function parseMoney(value) { return Number.isFinite(amount) ? amount : 0; } +/** + * @param {number|string} value - The value to parse as due date. + * @return {string} The parsed due date. + */ function parseDueDate(value) { const text = String(value ?? ""); const brazilianDate = text.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/); @@ -90,6 +102,10 @@ function parseDueDate(value) { return text; } +/** + * @param {Object} row - The row to map the agenda. + * @return {Object} The mapped agenda. + */ function mapAgenda(row) { if (!row) { return row; @@ -123,6 +139,11 @@ function mapAgenda(row) { }; } +/** + * @param {Object} data - The data to build the update. + * @param {Object} columnMap - The column map. + * @return {Object|null} The build update. + */ function buildUpdate(data, columnMap) { const entries = Object.entries(data) .filter(([field]) => @@ -154,6 +175,12 @@ function buildUpdate(data, columnMap) { }; } +/** + * @param {Object} db - The database client. + * @param {Object} data - The data to resolve the responsible users. + * @param {Object} creator - The creator user. + * @return {Promise} The resolved responsible users. + */ async function resolveResponsibleUsers(db, data, creator) { const explicitUsers = explicitResponsibleUsers(data); if (explicitUsers) { @@ -203,6 +230,12 @@ async function resolveResponsibleUsers(db, data, creator) { return creator ? [creator] : []; } +/** + * @param {Object} db - The database client. + * @param {number} telegramUserId - The Telegram user id. + * @param {number} chatId - The chat id. + * @return {Promise} True if the user belongs to the chat, false otherwise. + */ async function userBelongsToBotInstallationChat(db, telegramUserId, chatId) { const result = await db.query( `SELECT 1 @@ -220,6 +253,12 @@ async function userBelongsToBotInstallationChat(db, telegramUserId, chatId) { return result.rowCount > 0; } +/** + * @param {Object} db - The database client. + * @param {number} telegramChatId - The Telegram chat id. + * @param {Array} users - The users to filter. + * @return {Promise} The filtered users. + */ async function filterUsersByBotInstallationChatId(db, telegramChatId, users) { const telegramIds = uniqueByTelegramId(users).map((user) => Number(user.telegram_id) @@ -248,6 +287,11 @@ async function filterUsersByBotInstallationChatId(db, telegramChatId, users) { return result.rows; } +/** + * @param {Object} db - The database client. + * @param {Object} data - The data to resolve the bank. + * @return {Promise} The resolved bank or null. + */ async function resolveBank(db, data) { if (data.bankId) { const result = await db.query( @@ -274,6 +318,11 @@ async function resolveBank(db, data) { return null; } +/** + * @param {Object} db - The database client. + * @param {number} id - The id of the agenda. + * @return {Promise} The agenda row or null. + */ async function getAgendaRow(db, id) { const result = await db.query( `SELECT @@ -317,6 +366,7 @@ async function getAgendaRow(db, id) { * Inserts a new agenda payment. * @param {Object} data - The data to insert. * @param {Function} next - Callback called with the inserted agenda or false. + * @return {Promise} The inserted agenda or false. */ async function insetAgendaPayment(data, next) { const db = await getClient(); @@ -441,7 +491,7 @@ async function insetAgendaPayment(data, next) { /** * Retrieves unpaid agenda payments by responsible Telegram user. * @param {number} senderId - The Telegram user id to search for. - * @return {Promise} Matching agenda payments or false. + * @return {Promise} The matching agenda payments or false. */ async function getAllAgendaPaymentBySender(senderId) { try { From df79a19f3235fcea55b9548a81aae464869c690b Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:50:24 -0300 Subject: [PATCH 02/12] refactor(users.repository): Simplify telegramDisplayName function logic This commit refactors the telegramDisplayName function in users.repository.js by removing redundant checks for user display names. The function now directly constructs the display name from first and last names, improving clarity and efficiency in user data handling. --- backend/src/repositories/users.repository.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/backend/src/repositories/users.repository.js b/backend/src/repositories/users.repository.js index bb0ccc7..96a93ac 100644 --- a/backend/src/repositories/users.repository.js +++ b/backend/src/repositories/users.repository.js @@ -2,12 +2,9 @@ import { getClient, query } from "../db/postgres.js"; function telegramDisplayName(user = {}) { return user.displayName || - user.display_name || - [user.firstName || user.first_name, user.lastName || user.last_name].filter( - Boolean, - ).join(" ") || + [user.firstName, user.lastName].filter(Boolean).join(" ") || user.username || - String(user.telegramId || user.telegram_id || user.senderId || ""); + String(user.firstName || ""); } function userPayloadFromData(data = {}) { From 982bb244dd4e2ca0eb644655ee12c1023d34f790 Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:50:32 -0300 Subject: [PATCH 03/12] docs(agenda.service): Add JSDoc comments for agenda payment functions This commit enhances the agenda.service.js file by adding JSDoc comments to the createAgendaPayment, getAllAgendaPayments, getAgendaPaymentsByUser, getAgendaPayment, updateAgenda, and deleteAgenda functions. The comments provide clear descriptions of parameters and return values, improving code readability and maintainability for future developers. --- backend/src/services/agenda.service.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/backend/src/services/agenda.service.js b/backend/src/services/agenda.service.js index 5b74ded..effbb5a 100644 --- a/backend/src/services/agenda.service.js +++ b/backend/src/services/agenda.service.js @@ -7,30 +7,55 @@ import { updateAgendaPayment, } from "../repositories/agenda.repository.js"; +/** + * @param {Object} data - The data to create the agenda payment. + * @return {Promise} The created agenda payment. + */ function createAgendaPayment(data) { return new Promise((resolve) => { insetAgendaPayment(data, resolve); }); } +/** + * @return {Promise} The all agenda payments. + */ function getAllAgendaPayments() { return new Promise((resolve) => { getAllAgendaPayment(resolve); }); } +/** + * @param {number} telegramId - The Telegram user id. + * @return {Promise} The agenda payments by user. + */ async function getAgendaPaymentsByUser(telegramId) { return getAllAgendaPaymentBySender(telegramId); } +/** + * @param {number} id - The id of the agenda payment. + * @return {Promise} The agenda payment by id. + */ async function getAgendaPayment(id) { return getAgendaPaymentById(id); } +/** + * @param {number} id - The id of the agenda payment. + * @param {Object} data - The data to update the agenda payment. + * @param {number|null} telegramId - The Telegram user id. + * @return {Promise} The updated agenda payment. + */ async function updateAgenda(id, data, telegramId = null) { return updateAgendaPayment(id, data, telegramId); } +/** + * @param {number} id - The id of the agenda payment. + * @return {Promise} The deleted agenda payment. + */ async function deleteAgenda(id) { return deleteAgendaPayment(id); } From 668281e83b5b88dd9db1b025a13f0cf0978c0d1a Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:50:38 -0300 Subject: [PATCH 04/12] feat(server): Add registration tracking and JSDoc comments for Telegram user management This commit introduces functionality to track Telegram user registrations and their memberships within the bot. It adds a new `trackTelegramUserAndMembership` function and a helper function `registrationKey` to generate unique keys for registration messages. Additionally, JSDoc comments are added to enhance code documentation, improving clarity and maintainability for future developers. --- tele_bot/src/server.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tele_bot/src/server.js b/tele_bot/src/server.js index a14676b..9ab061b 100644 --- a/tele_bot/src/server.js +++ b/tele_bot/src/server.js @@ -5,6 +5,8 @@ import SchedulesEveryday from "./schedules/schedules_everyday.js"; import Paid from "./agendas/paid.js"; import Pix from "./agendas/add_pix_to_db.js"; import DeleteAgenda from "./agendas/delete_agenda.js"; +import { registerTelegramUserAndMembership } from "./utilities/registerTelegramUserAndMembership.js"; +import { handleUserMessage } from "./handlers/handleUserMessage.js"; import { agendaUsersState, deleteAgendaState, @@ -12,8 +14,6 @@ import { paidState, pixState, } from "./state/memoryState.js"; -import { registerTelegramUserAndMembership } from "./utilities/registerTelegramUserAndMembership.js"; -import { handleUserMessage } from "./handlers/handleUserMessage.js"; /** * Creates a new instance of the bot. @@ -26,6 +26,12 @@ new SchedulesEveryday(bot); const trackedRegistrationMessages = new Set(); +/** + * Generates a unique key for a Telegram registration message. + * + * @param {Object} msg - The Telegram message object. + * @returns {string} The generated key. + */ function registrationKey(msg = {}) { return [ msg.chat?.id || "no-chat", @@ -34,6 +40,11 @@ function registrationKey(msg = {}) { ].join(":"); } +/** + * Registers a Telegram user and their membership in a bot installation. + * + * @param {Object} msg - The Telegram message object. + */ function trackTelegramUserAndMembership(msg) { const key = registrationKey(msg); if (trackedRegistrationMessages.has(key)) { From 06b06e6d86caa8f1409bef7293b4a7d86c4d4c56 Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:50:43 -0300 Subject: [PATCH 05/12] refactor(agenda_payment): Update member label function and streamline imports This commit refactors the AgendaPayment class by replacing the getAgendaMemberDisplayName function with getMemberName for improved clarity. Additionally, it consolidates and organizes import statements for better maintainability, enhancing the overall structure of the agenda_payment.js file. --- tele_bot/src/agendas/agenda_payment.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tele_bot/src/agendas/agenda_payment.js b/tele_bot/src/agendas/agenda_payment.js index b0e2bea..afaef2a 100644 --- a/tele_bot/src/agendas/agenda_payment.js +++ b/tele_bot/src/agendas/agenda_payment.js @@ -1,4 +1,8 @@ import moment from "moment"; +import agendaFormatter from "../utilities/agenda_formatter.js"; +import getMemberName from "../utilities/get_member_name.js"; +import generateBankKeyboard from "../utilities/generate_banks_keyboard.js"; +import getUserPixBySenderBankAsKeyboard from "../utilities/get_all_pix_as_keyboard.js"; import { getBotInstallation, getBotInstallationUsers, @@ -6,11 +10,7 @@ import { insetAgendaPayment, insetPix, } from "../api/backendClient.js"; -import agendaFormatter, { - getAgendaMemberDisplayName, -} from "../utilities/agenda_formatter.js"; -import generateBankKeyboard from "../utilities/generate_banks_keyboard.js"; -import getUserPixBySenderBankAsKeyboard from "../utilities/get_all_pix_as_keyboard.js"; + function parseCurrency(value) { if (typeof value === "number") { @@ -263,7 +263,7 @@ class AgendaPayment { } memberLabel(member) { - return getAgendaMemberDisplayName(member); + return getMemberName(member); } generateMembersKeyboard() { @@ -420,6 +420,7 @@ class AgendaPayment { ); return true; } + console.log(isInseted); const paymentSummary = agendaFormatter(isInseted); // Send the summary message this.bot.sendMessage(isInseted.chatId, paymentSummary, { From dd7722b58b9dabc7eddf15cda9fc0a0ed9c4bca6 Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:50:49 -0300 Subject: [PATCH 06/12] refactor(agendas): Streamline import statements in paid.js This commit refactors the paid.js file by removing duplicate import statements and consolidating them into a single section. This enhances code clarity and maintainability by ensuring a cleaner structure for the import declarations. --- tele_bot/src/agendas/paid.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tele_bot/src/agendas/paid.js b/tele_bot/src/agendas/paid.js index a6cb66b..b07b7c8 100644 --- a/tele_bot/src/agendas/paid.js +++ b/tele_bot/src/agendas/paid.js @@ -1,12 +1,9 @@ -// const allAgendaAsKeyboard = require("../utilities/all_agenda_as_keyboard"); -// const agendaFormatter = require("../utilities/agenda_formatter"); - +import allAgendaAsKeyboard from "../utilities/all_agenda_as_keyboard.js"; +import agendaFormatter from "../utilities/agenda_formatter.js"; import { getBotInstallation, updateAgendaPayment, } from "../api/backendClient.js"; -import allAgendaAsKeyboard from "../utilities/all_agenda_as_keyboard.js"; -import agendaFormatter from "../utilities/agenda_formatter.js"; class paid { constructor(bot) { From eb6b65412aebc52ae6d25297325fa0e4d489cb4a Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:50:56 -0300 Subject: [PATCH 07/12] refactor(agendas): Update import statements and member name function This commit refactors the someone_paid.js file by replacing the getAgendaMemberDisplayName function with getMemberName for improved clarity. It also consolidates import statements, enhancing code organization and maintainability. --- tele_bot/src/agendas/someone_paid.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/tele_bot/src/agendas/someone_paid.js b/tele_bot/src/agendas/someone_paid.js index 502fad4..4e73fbd 100644 --- a/tele_bot/src/agendas/someone_paid.js +++ b/tele_bot/src/agendas/someone_paid.js @@ -1,16 +1,11 @@ -// const {updateAgendaPayment, getAgendaPaymentById } = require('../api/backendClient.js'); -// const agendaFormatter = require('../utilities/agenda_formatter.js'); -// const allAgendaAsKeyboard = require('../utilities/all_agenda_as_keyboard.js'); - +import agendaFormatter from "../utilities/agenda_formatter.js"; +import allAgendaAsKeyboard from "../utilities/all_agenda_as_keyboard.js"; +import getMemberName from "../utilities/get_member_name.js"; import { getAgendaPaymentById, getBotInstallation, updateAgendaPayment, } from "../api/backendClient.js"; -import agendaFormatter, { - getAgendaMemberDisplayName, -} from "../utilities/agenda_formatter.js"; -import allAgendaAsKeyboard from "../utilities/all_agenda_as_keyboard.js"; class SomeonePaid { /** @@ -76,7 +71,7 @@ class SomeonePaid { const memberButtons = this.members .filter((member) => member.isResponsible !== false) .map((member) => [{ - text: `${getAgendaMemberDisplayName(member)} ${ + text: `${getMemberName(member)} ${ member.isPaid ? "✅" : "❌" }`, callback_data: `member_${member.telegramId}`, From 19bc3b305cc4a51f61695fd98e144540bdce43b4 Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:51:09 -0300 Subject: [PATCH 08/12] refactor(agenda_formatter): Replace getAgendaMemberDisplayName with getMemberName and add JSDoc comments This commit refactors the agenda_formatter.js file by replacing the getAgendaMemberDisplayName function with getMemberName for improved clarity. It also adds JSDoc comments to the memberPaid function, enhancing code documentation and maintainability. --- tele_bot/src/utilities/agenda_formatter.js | 73 +++------------------- 1 file changed, 9 insertions(+), 64 deletions(-) diff --git a/tele_bot/src/utilities/agenda_formatter.js b/tele_bot/src/utilities/agenda_formatter.js index 780ffec..0a960ce 100644 --- a/tele_bot/src/utilities/agenda_formatter.js +++ b/tele_bot/src/utilities/agenda_formatter.js @@ -1,61 +1,10 @@ -function cleanText(value) { - const text = String(value ?? "").trim(); - return text && text !== "null" && text !== "undefined" ? text : null; -} - -function getAgendaMemberDisplayName(member = {}) { - const username = cleanText( - member.username || - member.telegramUsername || - member.user?.username || - member.user?.telegramUsername, - ); - - const firstName = cleanText( - member.firstName || - member.first_name || - member.user?.firstName || - member.user?.first_name, - ); - - const lastName = cleanText( - member.lastName || - member.last_name || - member.user?.lastName || - member.user?.last_name, - ); - - const displayName = cleanText( - member.displayName || - member.display_name || - member.user?.displayName || - member.user?.display_name, - ); - - if (displayName) { - return displayName; - } - - const fullName = [firstName, lastName].filter(Boolean).join(" ").trim(); - if (fullName) { - return fullName; - } - - if (username) { - return username.startsWith("@") ? username : `@${username}`; - } - - return String( - member.telegramId || - member.telegram_id || - member.user?.telegramId || - member.user?.telegram_id || - member.user_id || - member.id || - "Unknown", - ); -} +import getMemberName from "./get_member_name"; +/** + * Checks if a member has paid. + * @param {Object} member - The member object. + * @returns {boolean} True if the member has paid, false otherwise. + */ function memberPaid(member = {}) { return Boolean( member.isPaid || @@ -70,13 +19,13 @@ function memberPaid(member = {}) { * @param {Object} agenda - The agenda object containing the payment information. * @returns {string} The formatted string. */ -function agendaFormatter(agenda) { +export default function agendaFormatter(agenda) { const members = Array.isArray(agenda.members) ? agenda.members : []; const memberLines = members.length > 0 ? members .filter((member) => member.isResponsible !== false) .map((member) => - `${getAgendaMemberDisplayName(member)} ${memberPaid(member) ? " ✅" : " ❌"}` + `${getMemberName(member)} ${memberPaid(member) ? " ✅" : " ❌"}` ) .join(" \n") : `Pago ${agenda.isPaid ? " ✅" : " ❌"}`; @@ -90,8 +39,4 @@ function agendaFormatter(agenda) { `--------------------------------\n` + `${memberLines}\n` + `--------------------------------\n\n`; -} - -export { getAgendaMemberDisplayName }; - -export default agendaFormatter; +} \ No newline at end of file From 00317731b1e2e409e8af62a1bc9f311db22aae03 Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:51:15 -0300 Subject: [PATCH 09/12] feat(get_member_name): Add getMemberName function to retrieve member names with fallback options This commit introduces the getMemberName function, which consolidates various methods of retrieving a member's name from different properties. It includes a cleanText utility function to sanitize input values and ensures that the function returns the most appropriate name or identifier. JSDoc comments are added for improved documentation and maintainability. --- tele_bot/src/utilities/get_member_name.js | 68 +++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tele_bot/src/utilities/get_member_name.js diff --git a/tele_bot/src/utilities/get_member_name.js b/tele_bot/src/utilities/get_member_name.js new file mode 100644 index 0000000..2f2601f --- /dev/null +++ b/tele_bot/src/utilities/get_member_name.js @@ -0,0 +1,68 @@ +/** + * Clean text + * @param {*} value + * @returns + */ +function cleanText(value) { + const text = String(value ?? "").trim(); + return text && text !== "null" && text !== "undefined" ? text : null; +} + +/** + * Get member name + * @param {Object} member + * @returns {string} member name + */ +export default function getMemberName(member = {}) { + comsole.log(member); + const username = cleanText( + member.username || + member.telegramUsername || + member.user?.username || + member.user?.telegramUsername, + ); + + const firstName = cleanText( + member.firstName || + member.first_name || + member.user?.firstName || + member.user?.first_name, + ); + + const lastName = cleanText( + member.lastName || + member.last_name || + member.user?.lastName || + member.user?.last_name, + ); + + const displayName = cleanText( + member.displayName || + member.display_name || + member.user?.displayName || + member.user?.display_name, + ); + + if (displayName) { + return displayName; + } + + const fullName = [firstName, lastName].filter(Boolean).join(" ").trim(); + if (fullName) { + return fullName; + } + + if (username) { + return username.startsWith("@") ? username : `@${username}`; + } + + return String( + member.telegramId || + member.telegram_id || + member.user?.telegramId || + member.user?.telegram_id || + member.user_id || + member.id || + "Unknown", + ); +} \ No newline at end of file From e647d82c3a082321bbfa44875772ac5a0ee53b7f Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:51:20 -0300 Subject: [PATCH 10/12] docs(registerTelegramUserAndMembership): Add JSDoc comments for registerTelegramUserAndMembership function This commit enhances the registerTelegramUserAndMembership.js file by adding JSDoc comments to the registerTelegramUserAndMembership function. The comments provide clear descriptions of the function's parameters and return values, improving code readability and maintainability for future developers. --- tele_bot/src/utilities/registerTelegramUserAndMembership.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tele_bot/src/utilities/registerTelegramUserAndMembership.js b/tele_bot/src/utilities/registerTelegramUserAndMembership.js index f1dc45a..fba841c 100644 --- a/tele_bot/src/utilities/registerTelegramUserAndMembership.js +++ b/tele_bot/src/utilities/registerTelegramUserAndMembership.js @@ -1,6 +1,11 @@ import { upsertBotInstallationUser, upsertUser } from "../api/backendClient.js"; import { registerBotInstallation } from "./registerBotInstallation.js"; +/** + * Registers a Telegram user and their membership in a bot installation. + * @param {Message} msg - The Telegram message object. + * @returns {Object} An object containing the registered installation, user, and membership. + */ async function registerTelegramUserAndMembership(msg) { const installation = await registerBotInstallation(msg); const telegramUser = msg?.from; From 57ee8806705b46a03fb9d0a7442427b8482c62b2 Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:52:18 -0300 Subject: [PATCH 11/12] fix(agenda_payment): Add missing payment summary message in AgendaPayment class This commit adds a missing line to generate the payment summary message in the AgendaPayment class. The change ensures that the summary is properly formatted and sent to the user, enhancing the functionality of the payment process. --- tele_bot/src/agendas/agenda_payment.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tele_bot/src/agendas/agenda_payment.js b/tele_bot/src/agendas/agenda_payment.js index afaef2a..998631d 100644 --- a/tele_bot/src/agendas/agenda_payment.js +++ b/tele_bot/src/agendas/agenda_payment.js @@ -421,6 +421,7 @@ class AgendaPayment { return true; } console.log(isInseted); + const paymentSummary = agendaFormatter(isInseted); // Send the summary message this.bot.sendMessage(isInseted.chatId, paymentSummary, { From c67f4ba4c85e13af318ff9763a1e0d084383ea39 Mon Sep 17 00:00:00 2001 From: prince nyarko Date: Sun, 2 Aug 2026 19:57:43 -0300 Subject: [PATCH 12/12] docs(README): Update environment variable descriptions and enhance deployment instructions This commit revises the README.md file to clarify the descriptions of environment variables, including `POSTGRES_PASSWORD`, `BACKEND_URL`, `ALLOWED_USERS`, and `ADMIN_USERS`. It also updates the deployment instructions to specify Node.js version requirements and improve clarity on the use of Docker and PostgreSQL. Additionally, a new bot command `/ia` is introduced, and the schema application process is detailed for better understanding. --- README.md | 55 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 4b4f304..7542cf0 100644 --- a/README.md +++ b/README.md @@ -99,22 +99,28 @@ docker compose -f docker-compose.yml -f docker-compose.dev.yml down | Variable | Required | Default | Description | | --- | :---: | --- | --- | | `BOT_TOKEN` | Yes | — | Telegram token issued by BotFather. | -| `POSTGRES_PASSWORD` | Recommended | `telebot` | Password for the `telebot` database user. | +| `POSTGRES_PASSWORD` | No | `telebot` | Password for the `telebot` database user. Set a strong value outside local development. | | `BACKEND_PORT` | No | `3000` | Backend port exposed on the host. | -| `BACKEND_URL` | No | `http://backend:3000` | API URL used by the bot outside the standard Compose setup. | +| `BACKEND_URL` | No | `http://localhost:3000` outside Compose | API URL used by the bot. Both Compose files set it to `http://backend:3000`. | | `ADMIN_PANEL_PORT` | No | `3001` | Admin panel port exposed on the host. | | `ADMINER_PORT` | No | `8080` | Adminer port exposed on the host. | -| `VITE_BACKEND_URL` | No | `http://localhost:3000` | Browser-visible API URL baked into the admin build. | -| `ALLOWED_USERS` | No | Empty | Comma-separated Telegram user IDs allowed by backend rules. | -| `ADMIN_USERS` | No | Empty | Comma-separated Telegram user IDs with admin status. | -| `CHAT_ID` | No | — | Legacy fallback Telegram chat ID. | -| `BILLS_THREAD_ID` | No | — | Legacy fallback topic for new bills. | -| `PAID_THREAD_ID` | No | — | Legacy fallback topic for payment confirmations. | +| `VITE_BACKEND_URL` | No | `http://localhost:3000` in development | Browser-visible API URL compiled into a development admin build. | +| `ALLOWED_USERS` | No | Empty (allow all new users) | Comma-separated Telegram IDs used to set `is_allowed` when a user is first registered. | +| `ADMIN_USERS` | No | Empty | Comma-separated Telegram IDs used to set `is_admin` when a user is first registered. | +| `CHAT_ID` | No | — | Legacy chat ID consumed by the unused `constant_payment` helper. | +| `BILLS_THREAD_ID` | No | — | Fallback topic for new bills when the selected installation has no configured topic. | +| `PAID_THREAD_ID` | No | — | Fallback topic for payment confirmations when the selected installation has no configured topic. | | `LOG` | No | `false` | Enables additional logging when set to `true`. | `VITE_BACKEND_URL` is used by the visitor's browser, so it must be reachable from that browser. A Docker-internal hostname such as `backend` will not work -for users outside the Compose network. +for users outside the Compose network. Vite replaces this value at build time, +not when the container starts. The development Compose overlay supplies it to +the Vite build; the prebuilt production image uses the value with which that +image was published. + +`ALLOWED_USERS` and `ADMIN_USERS` do not overwrite existing database records on +restart. Change an existing user's flags from the admin panel or API. ## Bot Commands @@ -128,6 +134,7 @@ for users outside the Compose network. | `/delete` | Delete a registered bill. | | `/cancel` | Cancel the current operation. | | `/help` | Show the available commands. | +| `/ia` | Display the bot's informational AI placeholder message. | To create a bill, a user must first be seen in a group or channel where the bot is present. The flow then asks for the target chat, bill details, amount, and @@ -276,9 +283,11 @@ The schema is defined in `backend/src/db/schema.sql` and contains: - `bot_installation_topics` - `bot_installation_users` -The backend applies the schema during startup. The development setup stores -PostgreSQL data in the `postgres_data` Docker volume. To discard all local -development data and rebuild the database, run: +The backend applies the idempotent schema during every startup. PostgreSQL also +runs the mounted schema automatically when it initializes an empty data +directory. The development setup stores PostgreSQL data in the `postgres_data` +Docker volume. To discard all local development data and rebuild the database, +run: ```bash docker compose -f docker-compose.yml -f docker-compose.dev.yml down -v @@ -293,33 +302,36 @@ docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build ## Run Services Without Docker -Use Node.js 20 or newer and start PostgreSQL separately. Set `DATABASE_URL` for -the backend and use separate terminals for each service. +Use Node.js 20.19 or newer (or Node.js 22.12 or newer) and start PostgreSQL +separately. Set `DATABASE_URL` for the backend and use separate terminals for +each service. Run `npm ci` in each directory for a reproducible install. ```bash # Backend cd backend -npm install +npm ci DATABASE_URL=postgres://telebot:password@localhost:5432/telebot npm run dev ``` ```bash # Telegram bot cd tele_bot -npm install +npm ci BOT_TOKEN=your_token BACKEND_URL=http://localhost:3000 npm run dev ``` ```bash # Admin panel cd admin_panel -npm install +npm ci VITE_BACKEND_URL=http://localhost:3000 npm run dev ``` -## Production +## Deployment with Compose -The production Compose file uses images published to GitHub Container Registry: +The base Compose file uses prebuilt images from GitHub Container Registry. The +current image tags are `:dev`, despite the services running with +`NODE_ENV=production`: ```bash docker compose pull @@ -328,6 +340,11 @@ docker compose ps ``` The admin image is built with Vite and served by nginx on container port `80`. +Its backend URL is fixed when the image is built; setting `VITE_BACKEND_URL` on +the running production container does not change it. The PostgreSQL service +bind-mounts `/Kojo/Docker/tele_bot_node/postgres`, so adjust that host path in +`docker-compose.yml` before deploying on a different machine. + To inspect a service, use `docker compose logs -f backend`, `tele_bot`, or `admin_panel`.