4.0.4: Оптимизация SQL и отладка
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m14s

This commit is contained in:
poignatov
2026-01-26 18:17:56 +03:00
parent 99156d578a
commit 6bea094b7f
5 changed files with 32 additions and 15 deletions

View File

@@ -1 +1 @@
4.0.3 4.0.4

View File

@@ -6515,22 +6515,16 @@ func (a *App) getTaskDetailHandler(w http.ResponseWriter, r *http.Request) {
// Загружаем все награды всех подзадач одним запросом // Загружаем все награды всех подзадач одним запросом
if len(subtaskIDs) > 0 { if len(subtaskIDs) > 0 {
placeholders := make([]string, len(subtaskIDs)) // Используем параметризованный запрос с ANY(ARRAY[...])
args := make([]interface{}, len(subtaskIDs)) query := `
for i, id := range subtaskIDs {
placeholders[i] = fmt.Sprintf("$%d", i+1)
args[i] = id
}
query := fmt.Sprintf(`
SELECT rc.task_id, rc.id, rc.position, p.name AS project_name, rc.value, rc.use_progression SELECT rc.task_id, rc.id, rc.position, p.name AS project_name, rc.value, rc.use_progression
FROM reward_configs rc FROM reward_configs rc
JOIN projects p ON rc.project_id = p.id JOIN projects p ON rc.project_id = p.id
WHERE rc.task_id = ANY(ARRAY[%s]) WHERE rc.task_id = ANY($1::int[])
ORDER BY rc.task_id, rc.position ORDER BY rc.task_id, rc.position
`, strings.Join(placeholders, ",")) `
subtaskRewardRows, err := a.DB.Query(query, args...) subtaskRewardRows, err := a.DB.Query(query, pq.Array(subtaskIDs))
if err != nil { if err != nil {
log.Printf("Error querying subtask rewards: %v", err) log.Printf("Error querying subtask rewards: %v", err)
} else { } else {

View File

@@ -1,6 +1,6 @@
{ {
"name": "play-life-web", "name": "play-life-web",
"version": "4.0.3", "version": "4.0.4",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -331,10 +331,20 @@ const formatTelegramMessage = (task, rewards, subtasks, selectedSubtasks, progre
// Формируем сообщения подзадач // Формируем сообщения подзадач
const subtaskMessages = [] const subtaskMessages = []
// #region agent log
fetch('http://127.0.0.1:7243/ingest/dd59cdcd-2e10-41ef-b65f-ebbaae0d7424',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'TaskDetail.jsx:333',message:'Starting subtask messages processing',data:{subtasksCount:subtasks.length,selectedSubtasksCount:selectedSubtasks.size,selectedSubtasks:Array.from(selectedSubtasks)},timestamp:Date.now(),sessionId:'debug-session',runId:'run2',hypothesisId:'B'})}).catch(()=>{});
// #endregion
subtasks.forEach(subtask => { subtasks.forEach(subtask => {
// #region agent log
fetch('http://127.0.0.1:7243/ingest/dd59cdcd-2e10-41ef-b65f-ebbaae0d7424',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'TaskDetail.jsx:336',message:'Checking subtask',data:{subtaskId:subtask.task.id,isSelected:selectedSubtasks.has(subtask.task.id),hasRewardMessage:!!(subtask.task.reward_message && subtask.task.reward_message.trim() !== ''),rewardsCount:subtask.rewards?.length||0},timestamp:Date.now(),sessionId:'debug-session',runId:'run2',hypothesisId:'B'})}).catch(()=>{});
// #endregion
if (!selectedSubtasks.has(subtask.task.id)) return if (!selectedSubtasks.has(subtask.task.id)) return
if (!subtask.task.reward_message || subtask.task.reward_message.trim() === '') return if (!subtask.task.reward_message || subtask.task.reward_message.trim() === '') return
// #region agent log
fetch('http://127.0.0.1:7243/ingest/dd59cdcd-2e10-41ef-b65f-ebbaae0d7424',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'TaskDetail.jsx:340',message:'Processing subtask for message',data:{subtaskId:subtask.task.id,subtaskName:subtask.task.name,rewardsCount:subtask.rewards?.length||0,rewards:subtask.rewards,rewardMessage:subtask.task.reward_message},timestamp:Date.now(),sessionId:'debug-session',runId:'run2',hypothesisId:'B'})}).catch(()=>{});
// #endregion
// Вычисляем score для наград подзадачи // Вычисляем score для наград подзадачи
const subtaskRewardStrings = {} const subtaskRewardStrings = {}
subtask.rewards.forEach(reward => { subtask.rewards.forEach(reward => {
@@ -393,6 +403,9 @@ function TaskDetail({ taskId, onClose, onRefresh, onTaskCompleted, onNavigate })
throw new Error('Ошибка загрузки задачи') throw new Error('Ошибка загрузки задачи')
} }
const data = await response.json() const data = await response.json()
// #region agent log
fetch('http://127.0.0.1:7243/ingest/dd59cdcd-2e10-41ef-b65f-ebbaae0d7424',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'TaskDetail.jsx:395',message:'TaskDetail data loaded',data:{taskId:taskId,subtasksCount:data.subtasks?.length||0,subtasks:data.subtasks?.map(st=>({id:st.task?.id,name:st.task?.name,rewardsCount:st.rewards?.length||0,rewards:st.rewards}))},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});
// #endregion
setTaskDetail(data) setTaskDetail(data)
// Используем информацию о wishlist из ответа API // Используем информацию о wishlist из ответа API
@@ -621,6 +634,9 @@ function TaskDetail({ taskId, onClose, onRefresh, onTaskCompleted, onNavigate })
<div className="task-subtasks"> <div className="task-subtasks">
{subtasks.map((subtask) => { {subtasks.map((subtask) => {
const subtaskName = subtask.task.name || 'Подзадача' const subtaskName = subtask.task.name || 'Подзадача'
// #region agent log
fetch('http://127.0.0.1:7243/ingest/dd59cdcd-2e10-41ef-b65f-ebbaae0d7424',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'TaskDetail.jsx:622',message:'Rendering subtask',data:{subtaskId:subtask.task.id,subtaskName:subtaskName,rewardsCount:subtask.rewards?.length||0,rewards:subtask.rewards},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'C'})}).catch(()=>{});
// #endregion
return ( return (
<div key={subtask.task.id} className="subtask-item"> <div key={subtask.task.id} className="subtask-item">
<label className="subtask-checkbox-label"> <label className="subtask-checkbox-label">

View File

@@ -313,6 +313,9 @@ function TaskForm({ onNavigate, taskId, wishlistId, isTest: isTestFromProps = fa
// Для задач-тестов не загружаем подзадачи // Для задач-тестов не загружаем подзадачи
setSubtasks([]) setSubtasks([])
} else { } else {
// #region agent log
fetch('http://127.0.0.1:7243/ingest/dd59cdcd-2e10-41ef-b65f-ebbaae0d7424',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'TaskForm.jsx:316',message:'Loading subtasks in TaskForm',data:{subtasksCount:data.subtasks?.length||0,subtasks:data.subtasks?.map(st=>({id:st.task?.id,name:st.task?.name,rewardsCount:st.rewards?.length||0,rewards:st.rewards}))},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});
// #endregion
setSubtasks(data.subtasks.map(st => ({ setSubtasks(data.subtasks.map(st => ({
id: st.task.id, id: st.task.id,
name: st.task.name || '', name: st.task.name || '',
@@ -1104,7 +1107,11 @@ function TaskForm({ onNavigate, taskId, wishlistId, isTest: isTestFromProps = fa
/> />
{subtask.rewards && subtask.rewards.length > 0 && ( {subtask.rewards && subtask.rewards.length > 0 && (
<div className="subtask-rewards"> <div className="subtask-rewards">
{subtask.rewards.map((reward, rIndex) => ( {subtask.rewards.map((reward, rIndex) => {
// #region agent log
fetch('http://127.0.0.1:7243/ingest/dd59cdcd-2e10-41ef-b65f-ebbaae0d7424',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'TaskForm.jsx:1107',message:'Rendering subtask reward in form',data:{subtaskIndex:index,rewardIndex:rIndex,reward:reward},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{});
// #endregion
return (
<div key={rIndex} className="reward-item"> <div key={rIndex} className="reward-item">
<span className="reward-number">{rIndex}</span> <span className="reward-number">{rIndex}</span>
<input <input
@@ -1156,7 +1163,7 @@ function TaskForm({ onNavigate, taskId, wishlistId, isTest: isTestFromProps = fa
</button> </button>
)} )}
</div> </div>
))} )})}
</div> </div>
)} )}
</div> </div>