Files
request-portal/src/webparts/requestPortal/shared/ai/gemini.service.ts
T
gorbenko.pavel 023c0913f1
Tests / frontend-test (pull_request) Successful in 1m32s
fix: заявка на оплату под реальный API справочников и OCR
Сверено с api-tnsu-portal (DictionaryController, DocumentController):
- статьи ДДС — CashFlowItems?id=<группа> (было groupId, сервер отвечал 400);
- OCR — Document/extractPDFText, текст в file_content пишется до ответа,
  поэтому колонка читается сразу, без опроса;
- договоры и банковские счета — постраничные, поиск на сервере (search),
  иначе находились только первые 50 записей; фильтра по компании у
  договоров нет;
- счета по проекту с откатом на фильтр только по компании: совпадение Id
  проекта из /Project с bank_accounts.project_id не гарантировано;
- Id-фильтры передаются только в формате GUID, иначе API отвечает 400;
- подписи записей по реальным полям (account_number, bank, valuta,
  counterparty_name); разбор вынесен в oneCRecords.ts с тестами;
- код позиции потребности — lineNumber;
- пустой ответ Gemini (200 с error) считается ошибкой.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 12:35:53 +05:00

38 lines
1.7 KiB
TypeScript

import { AadHttpClient, HttpClientResponse } from '@microsoft/sp-http';
import { WebPartContext } from '@microsoft/sp-webpart-base';
import { APPROVAL_API_CLIENT_ID, DICTIONARY_API_BASE_URL } from '../config';
/** JSON-схема ответа в формате, который принимает прокси Gemini (как в СТ). */
export interface IGeminiSchema {
type: 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean';
properties?: Record<string, IGeminiSchema>;
items?: IGeminiSchema;
required?: string[];
}
/**
* POST /Proxy/Gemini { prompt, responseSchema } → объект, подогнанный под схему.
* Тот же вызов делает СТ (CtService.scorePaymentTerms); ответ прокси — уже
* разобранный JSON, без обёртки.
*/
export async function askGemini<T>(context: WebPartContext, prompt: string, responseSchema: IGeminiSchema): Promise<T> {
const client = await context.aadHttpClientFactory.getClient(APPROVAL_API_CLIENT_ID);
const response: HttpClientResponse = await client.post(
`${DICTIONARY_API_BASE_URL}/Proxy/Gemini`,
AadHttpClient.configurations.v1,
{
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt, responseSchema })
}
);
if (!response.ok) {
throw new Error(`Proxy/Gemini: ${response.status} ${response.statusText}`);
}
const body = (await response.json()) as T & { error?: unknown };
// Пустой ответ модели прокси отдаёт как 200 с { error } — это сбой, а не данные.
if (body && typeof body.error === 'string') {
throw new Error(`Proxy/Gemini: ${body.error}`);
}
return body;
}