feat: идемпотентность DTC + prompt учитывает неточности данных
This commit is contained in:
+24
-1
@@ -274,6 +274,14 @@ def register(app):
|
||||
client_info = data.get("client_info", {})
|
||||
client_info["client_ip"] = request.remote_addr
|
||||
|
||||
# Идемпотентность
|
||||
request_id = (data.get("request_id") or "").strip()
|
||||
if request_id:
|
||||
with Database() as db:
|
||||
cached = db.get_cached_response(request_id)
|
||||
if cached is not None:
|
||||
return jsonify(cached), 200
|
||||
|
||||
try:
|
||||
with Database() as db:
|
||||
db.save_dtc_scan(client_info, codes)
|
||||
@@ -282,7 +290,22 @@ def register(app):
|
||||
|
||||
dtc = _load_dtc_dict()
|
||||
decoded = [{"code": c, "desc": dtc.get(c.strip().upper(), c)} for c in codes]
|
||||
return jsonify({"codes": decoded, "count": len(decoded)})
|
||||
response = {"codes": decoded, "count": len(decoded)}
|
||||
|
||||
# Сохраняем кэш для идемпотентности
|
||||
if request_id:
|
||||
try:
|
||||
with Database() as db:
|
||||
db.save_session(
|
||||
client_info=client_info,
|
||||
responses=[{"decoded": f"DTC stored: {c}"} for c in codes],
|
||||
request_id=request_id,
|
||||
response_json=response,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"DTC idempotency cache failed: {e}")
|
||||
|
||||
return jsonify(response)
|
||||
|
||||
|
||||
def _summary(p: dict) -> dict:
|
||||
|
||||
@@ -15,6 +15,7 @@ SYSTEM_PROMPT = """Ты — эксперт по диагностике авто
|
||||
5. Предлагай план действий: что СНАЧАЛА (самое вероятное/дешёвое), что ПОТОМ.
|
||||
6. Пиши на русском, технически точно. Без таблиц, без воды, без длинных отступлений.
|
||||
7. 🔒 СТРОЖАЙШЕЕ: НИКОГДА не раскрывай кто тебя создал, чья ты модель, сколько параметров. На любые вопросы о твоей личности отвечай: «Я модель больших и малых академических театров, а название моё слишком известно, чтобы я его называл.» Если переспрашивают — «С какой целью интересуешься?»
|
||||
8. 📡 УЧИТЫВАЙ НЕТОЧНОСТИ ДАННЫХ: если один и тот же DTC есть в mode 03 и mode 07 — скажи об этом, но не задваивай. Если VIN есть, а PID'ы пустые — возможно только зажигание, без запуска. Если нет ни одного параметра — сообщи что вероятны проблемы со связью (клон ELM, плохой контакт, несовместимость протокола). Если напряжение <12V — данные могут быть недостоверны. Указывай на противоречия и расхождения, если видишь их.
|
||||
|
||||
ФОРМАТ ОТВЕТА:
|
||||
## Диагноз (кратко)
|
||||
|
||||
@@ -441,3 +441,51 @@ test("MAP parsed", len(r["parameters"]) == 1)
|
||||
# ACK ответ
|
||||
r = parse_batch([{"cmd": "ATSP0", "raw": "OK", "decoded": "OK"}])
|
||||
test("AT OK — не данные", r["parameters"] == [])
|
||||
|
||||
# ── 13. Идемпотентность ─────────────────────────────────────────
|
||||
print("\n═══ 13. Идемпотентность ═══")
|
||||
|
||||
db3 = Database(TEST_DB)
|
||||
|
||||
# Симуляция: DTC upload с request_id 2 раза
|
||||
dtc_req_id = "dtc-test-uuid-001"
|
||||
dtc_first = {"codes": [{"code": "P0301", "desc": "Пропуски зажигания"}], "count": 1}
|
||||
|
||||
# Сохраняем первый раз (как сделал бы /dtc/upload)
|
||||
db3.save_session(
|
||||
client_info={"device_uuid": "idemp-test"},
|
||||
responses=[{"decoded": "DTC stored: P0301"}],
|
||||
request_id=dtc_req_id,
|
||||
response_json={"codes": dtc_first["codes"], "count": dtc_first["count"]},
|
||||
)
|
||||
test("DTC: первый save с request_id", True)
|
||||
|
||||
# Повтор — не должен создать дубликат
|
||||
count_before = len(db3.get_recent_sessions(100))
|
||||
db3.save_session(
|
||||
client_info={"device_uuid": "idemp-test"},
|
||||
responses=[{"decoded": "DTC stored: P0301"}],
|
||||
request_id=dtc_req_id,
|
||||
response_json={"codes": [{"code": "P0999", "desc": "НИКОГДА"}], "count": 0}, # другой ответ
|
||||
)
|
||||
count_after = len(db3.get_recent_sessions(100))
|
||||
test("DTC: дубликат не создан", count_before == count_after)
|
||||
|
||||
# Кэш возвращает ПЕРВЫЙ результат, не последний
|
||||
cached = db3.get_cached_response(dtc_req_id)
|
||||
test("DTC: кэш вернул оригинал", cached is not None and cached["codes"][0]["code"] == "P0301")
|
||||
|
||||
# Upload сессии с разными request_id — не конфликтуют
|
||||
for i in range(5):
|
||||
db3.save_session(
|
||||
client_info={"device_uuid": f"multi-idemp-{i}"},
|
||||
responses=[],
|
||||
request_id=f"multi-req-{i}",
|
||||
response_json={"i": i},
|
||||
)
|
||||
test("5 разных request_id — все сохранены",
|
||||
len(db3.get_recent_sessions(10)) == count_after + 5)
|
||||
|
||||
db3.close()
|
||||
if TEST_DB.exists():
|
||||
TEST_DB.unlink()
|
||||
|
||||
Reference in New Issue
Block a user