ваше сообщение коммита

This commit is contained in:
2025-05-28 17:03:36 +03:00
parent cd6e9bc663
commit 5eda7a35c6
5 changed files with 793 additions and 699 deletions

View File

@@ -0,0 +1,3 @@
-- Исправление preferred_language: если строка — преобразовать в массив, если null — в []
UPDATE users SET preferred_language = jsonb_build_array(preferred_language) WHERE jsonb_typeof(preferred_language) = 'string';
UPDATE users SET preferred_language = '[]' WHERE preferred_language IS NULL;

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +1,27 @@
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-05-28T13:03:06.859Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.102Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:03:06.860Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.103Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:03:06.860Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.103Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:03:06.860Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.103Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:03:06.861Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.103Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:03:06.861Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.103Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:03:06.861Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.103Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:03:06.861Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.103Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-05-28T13:04:17.747Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.103Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:04:17.747Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.104Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:04:17.748Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.104Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:04:17.748Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.104Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:04:17.748Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.104Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:04:43.277Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:47:23.104Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:05:12.662Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:49:29.092Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:05:12.663Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:49:29.092Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:06:07.601Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:49:29.093Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:06:07.608Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:49:29.093Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:06:07.609Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:49:29.093Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:07:41.568Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:51:57.933Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:07:41.568Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:51:57.933Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:07:41.569Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:51:57.933Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:07:41.569Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:51:57.934Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:07:41.569Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:51:57.934Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-05-28T13:12:13.523Z"} {"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-05-28T13:52:49.080Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-05-28T13:14:17.520Z"} {"body":{"language":["ru"]},"error":{"code":"22P02","detail":"Expected \":\", but found \"}\".","file":"jsonfuncs.c","length":193,"line":"646","name":"error","routine":"json_errsave_error","severity":"ERROR","where":"JSON data, line 1: {\"ru\"}\nunnamed portal parameter $1 = '...'"},"level":"error","message":"PATCH /api/users/:id error","stack":"error: invalid input syntax for type json\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/users.js:165:20","timestamp":"2025-05-28T14:00:22.853Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:14:17.521Z"} {"body":{"language":["ru","en"]},"error":{"code":"22P02","detail":"Expected \":\", but found \",\".","file":"jsonfuncs.c","length":196,"line":"646","name":"error","routine":"json_errsave_error","severity":"ERROR","where":"JSON data, line 1: {\"ru\",...\nunnamed portal parameter $1 = '...'"},"level":"error","message":"PATCH /api/users/:id error","stack":"error: invalid input syntax for type json\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/users.js:165:20","timestamp":"2025-05-28T14:00:37.773Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:14:17.522Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-05-28T13:14:17.522Z"}
{"level":"error","message":"Error: undefined","timestamp":"2025-05-28T13:18:22.803Z"}
{"action":"call","code":"CALL_EXCEPTION","data":null,"info":{"error":{"code":19,"message":"Unable to perform request"},"payload":{"id":2,"jsonrpc":"2.0","method":"eth_call","params":[{"data":"0x70a08231000000000000000000000000f45aa4917b3775ba37f48aeb3dc1a943561e9e0b","to":"0x351f59de4fedbdf7601f5592b93db3b9330c1c1d"},"latest"]}},"invocation":null,"level":"error","message":"[getUserTokenBalances] Ошибка получения баланса для HB3A (0x351f59de4fedbdf7601f5592b93db3b9330c1c1d) в сети polygon: missing revert data (action=\"call\", data=null, reason=null, transaction={ \"data\": \"0x70a08231000000000000000000000000f45aa4917b3775ba37f48aeb3dc1a943561e9e0b\", \"to\": \"0x351F59dE4FEdBDf7601F5592B93db3B9330c1C1d\" }, invocation=null, revert=null, code=CALL_EXCEPTION, version=6.13.5)","reason":null,"revert":null,"shortMessage":"missing revert data","stack":"Error: missing revert data (action=\"call\", data=null, reason=null, transaction={ \"data\": \"0x70a08231000000000000000000000000f45aa4917b3775ba37f48aeb3dc1a943561e9e0b\", \"to\": \"0x351F59dE4FEdBDf7601F5592B93db3B9330c1C1d\" }, invocation=null, revert=null, code=CALL_EXCEPTION, version=6.13.5)\n at makeError (/app/node_modules/ethers/lib.commonjs/utils/errors.js:129:21)\n at getBuiltinCallException (/app/node_modules/ethers/lib.commonjs/abi/abi-coder.js:105:37)\n at AbiCoder.getBuiltinCallException (/app/node_modules/ethers/lib.commonjs/abi/abi-coder.js:206:16)\n at JsonRpcProvider.getRpcError (/app/node_modules/ethers/lib.commonjs/providers/provider-jsonrpc.js:676:43)\n at /app/node_modules/ethers/lib.commonjs/providers/provider-jsonrpc.js:302:45\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)","timestamp":"2025-05-28T13:19:00.049Z","transaction":{"data":"0x70a08231000000000000000000000000f45aa4917b3775ba37f48aeb3dc1a943561e9e0b","to":"0x351F59dE4FEdBDf7601F5592B93db3B9330c1C1d"}}

View File

@@ -95,7 +95,7 @@ router.put('/profile', requireAuth, async (req, res) => {
// Получение списка пользователей с контактами // Получение списка пользователей с контактами
router.get('/', async (req, res, next) => { router.get('/', async (req, res, next) => {
try { try {
const usersResult = await db.getQuery()('SELECT id, first_name, last_name, created_at FROM users ORDER BY id'); const usersResult = await db.getQuery()('SELECT id, first_name, last_name, created_at, preferred_language FROM users ORDER BY id');
const users = usersResult.rows; const users = usersResult.rows;
// Получаем все user_identities разом // Получаем все user_identities разом
const identitiesResult = await db.getQuery()('SELECT user_id, provider, provider_id FROM user_identities'); const identitiesResult = await db.getQuery()('SELECT user_id, provider, provider_id FROM user_identities');
@@ -113,7 +113,8 @@ router.get('/', async (req, res, next) => {
email: identityMap[u.id]?.email || null, email: identityMap[u.id]?.email || null,
telegram: identityMap[u.id]?.telegram || null, telegram: identityMap[u.id]?.telegram || null,
wallet: identityMap[u.id]?.wallet || null, wallet: identityMap[u.id]?.wallet || null,
created_at: u.created_at created_at: u.created_at,
preferred_language: u.preferred_language || []
})); }));
res.json({ success: true, contacts }); res.json({ success: true, contacts });
} catch (error) { } catch (error) {
@@ -157,13 +158,14 @@ router.patch('/:id', async (req, res) => {
} }
if (language !== undefined) { if (language !== undefined) {
fields.push(`preferred_language = $${idx++}`); fields.push(`preferred_language = $${idx++}`);
values.push(Array.isArray(language) ? JSON.stringify(language) : language); values.push(JSON.stringify(language));
} }
values.push(userId); values.push(userId);
const sql = `UPDATE users SET ${fields.join(', ')} WHERE id = $${idx} RETURNING *`; const sql = `UPDATE users SET ${fields.join(', ')} WHERE id = $${idx} RETURNING *`;
const result = await db.getQuery()(sql, values); const result = await db.getQuery()(sql, values);
res.json(result.rows[0]); res.json(result.rows[0]);
} catch (e) { } catch (e) {
logger.error('PATCH /api/users/:id error', { error: e, body: req.body, stack: e.stack });
res.status(500).json({ error: 'DB error', details: e.message }); res.status(500).json({ error: 'DB error', details: e.message });
} }
}); });

View File

@@ -91,7 +91,7 @@ const allLanguages = [
{ value: 'uk', label: 'Українська' }, { value: 'uk', label: 'Українська' },
{ value: 'other', label: 'Другое' } { value: 'other', label: 'Другое' }
]; ];
const selectedLanguages = ref(Array.isArray(props.contact.language) ? props.contact.language : (props.contact.language ? [props.contact.language] : [])); const selectedLanguages = ref(Array.isArray(props.contact.preferred_language) ? props.contact.preferred_language : (props.contact.preferred_language ? [props.contact.preferred_language] : []));
const langInput = ref(''); const langInput = ref('');
const showLangDropdown = ref(false); const showLangDropdown = ref(false);
const filteredLanguages = computed(() => { const filteredLanguages = computed(() => {
@@ -169,6 +169,9 @@ async function loadMessages() {
} }
onMounted(loadMessages); onMounted(loadMessages);
watch(() => props.contact, loadMessages); watch(() => props.contact, loadMessages);
watch(() => props.contact.preferred_language, (newVal) => {
selectedLanguages.value = Array.isArray(newVal) ? newVal : (newVal ? [newVal] : []);
});
</script> </script>
<style scoped> <style scoped>