Files
aiform_dev/docs/SESSION_LOG_2025-11-20.md

117 lines
5.5 KiB
Markdown
Raw Normal View History

# Лог сессии разработки - 20 ноября 2025
## Проблема (из предыдущей сессии)
После верификации телефона не отображался список черновиков, хотя в базе данных есть заявки с `unified_id`.
## Решение
### 1. Исправлен SQL запрос в backend (`claims.py`)
**Проблема:** Запрос строился через конкатенацию строк, что могло приводить к проблемам с параметрами.
**Решение:** Переписан SQL запрос - теперь используется прямой запрос для каждого случая:
- Для `unified_id`: прямой запрос `WHERE c.unified_id = $1`
- Для `phone`: подзапрос через `clpr_user_accounts` и `clpr_users`
- Для `session_id`: прямой запрос `WHERE c.session_token = $1`
```python
if unified_id:
query = """
SELECT
c.id,
c.payload->>'claim_id' as claim_id,
c.session_token,
c.status_code,
c.channel,
c.payload,
c.created_at,
c.updated_at
FROM clpr_claims c
WHERE c.unified_id = $1
ORDER BY c.updated_at DESC
LIMIT 20
"""
params = [unified_id]
```
### 2. Улучшена обработка черновиков в frontend (`ClaimForm.tsx`)
**Проблема:** Черновики из Telegram имеют другую структуру данных (данные в `payload.body`), а не напрямую в `payload`.
**Решение:** Добавлена поддержка обоих форматов:
- **Telegram формат:** данные в `payload.body.wizard_plan`, `payload.body.answers`
- **Web form формат:** данные напрямую в `payload.wizard_plan`, `payload.answers`
```typescript
// ✅ Для telegram черновиков данные могут быть в payload.body
const body = payload.body || {};
const isTelegramFormat = !!payload.body;
// ✅ Извлекаем данные из body (telegram) или напрямую из payload (web_form)
const wizardPlanRaw = body.wizard_plan || payload.wizard_plan;
const answersRaw = body.answers || payload.answers;
const problemDescription = body.problem_description || payload.problem_description || body.description || payload.description;
// ✅ Парсим wizard_plan и answers, если они строки (JSON)
let wizardPlan = wizardPlanRaw;
if (typeof wizardPlanRaw === 'string') {
try {
wizardPlan = JSON.parse(wizardPlanRaw);
} catch (e) {
console.warn('⚠️ Не удалось распарсить wizard_plan:', e);
}
}
```
### 3. Улучшена обработка `claim_id`
**Проблема:** `claim_id` может быть в разных местах в зависимости от формата данных.
**Решение:** Добавлен поиск `claim_id` в нескольких местах:
```typescript
const finalClaimId = claim.claim_id || payload.claim_id || body.claim_id || claim.id || formData.claim_id || claimId;
```
### 4. Добавлено детальное логирование
- В `loadDraft`: логирование всех этапов загрузки черновика
- В `get_draft` (backend): логирование найденных данных
- В `list_drafts` (backend): тестовые COUNT запросы для отладки
### 5. Исправлена обработка `claim_id` в backend
В `get_draft` теперь извлекается `claim_id` из `payload`, если его нет в `row`:
```python
claim_id_from_payload = payload.get('claim_id') if isinstance(payload, dict) else None
final_claim_id = row.get('claim_id') or claim_id_from_payload
```
## Результат
**Черновики теперь возвращаются!** API корректно возвращает список черновиков для `unified_id`.
## Файлы изменены
1. `backend/app/api/claims.py`:
- Переписан SQL запрос для `list_drafts`
- Добавлено логирование и тестовые COUNT запросы
- Улучшена обработка `claim_id` в `get_draft`
2. `frontend/src/pages/ClaimForm.tsx`:
- Добавлена поддержка формата Telegram черновиков
- Улучшена обработка `claim_id` из разных источников
- Добавлено детальное логирование загрузки черновика
3. `frontend/src/components/form/Step1Phone.tsx`:
- (Возможно, были изменения для передачи unified_id)
4. `frontend/src/components/form/StepDraftSelection.tsx`:
- (Возможно, были изменения для отображения черновиков)
## Текущий статус
**Работает:** API возвращает черновики
**Работает:** Загрузка черновиков поддерживает оба формата (Telegram и web_form)
⚠️ **Требует проверки:** Отображение черновиков в UI (StepDraftSelection)
## Следующие шаги
1. Проверить отображение черновиков в UI
2. Протестировать загрузку черновика из Telegram формата
3. Убедиться, что все данные корректно восстанавливаются в форму
feat: Add claim plan confirmation flow via Redis SSE Problem: - After wizard form submission, need to wait for claim data from n8n - Claim data comes via Redis channel claim:plan:{session_token} - Need to display confirmation form with claim data Solution: 1. Backend: Added SSE endpoint /api/v1/claim-plan/{session_token} - Subscribes to Redis channel claim:plan:{session_token} - Streams claim data from n8n to frontend - Handles timeouts and errors gracefully 2. Frontend: Added subscription to claim:plan channel - StepWizardPlan: After form submission, subscribes to SSE - Waits for claim_plan_ready event - Shows loading message while waiting - On success: saves claimPlanData and shows confirmation step 3. New component: StepClaimConfirmation - Displays claim confirmation form in iframe - Receives claimPlanData from parent - Generates HTML form (placeholder - should call n8n for real HTML) - Handles confirmation/cancellation via postMessage 4. ClaimForm: Added conditional step for confirmation - Shows StepClaimConfirmation when showClaimConfirmation=true - Step appears after StepWizardPlan - Only visible when claimPlanData is available Flow: 1. User fills wizard form → submits 2. Form data sent to n8n via /api/v1/claims/wizard 3. Frontend subscribes to SSE /api/v1/claim-plan/{session_token} 4. n8n processes data → publishes to Redis claim:plan:{session_token} 5. Backend receives → streams to frontend via SSE 6. Frontend receives → shows StepClaimConfirmation 7. User confirms → proceeds to next step Files: - backend/app/api/events.py: Added stream_claim_plan endpoint - frontend/src/components/form/StepWizardPlan.tsx: Added subscribeToClaimPlan - frontend/src/components/form/StepClaimConfirmation.tsx: New component - frontend/src/pages/ClaimForm.tsx: Added confirmation step to steps array
2025-11-24 13:36:14 +03:00