Маркер «вот где остановилась mechanic-сессия» — не разбито по логическим коммитам,
зафиксировано целиком чтобы не потерять при отвлечении/чекаутах.
Modified:
- pages/InspectionEditor.tsx — расширение damage-flow внутри редактора
- pages/VehicleCard.tsx — vendor data + расширение карточки
- pages/InspectionReview.tsx — обновлённый review
- api/{auth,inspections,photos,vehicles}.ts — новые endpoints для TT + photo flow
- components/damage-flow/DamageClassifyDialog.tsx — multi-step UI
- components/vehicle-scheme/VendorVehicleScheme.tsx — SVG zone interaction
- data/damageVocabulary.ts — обновлённый словарь повреждений
- frontend index.html/manifest/icons — PWA-метаданные
New (untracked):
- components/damage-flow/PhotoAnnotateStep.tsx — новый шаг flow'а
- components/tt/ — vendor TT-state UI
- pages/TtStateDetail.tsx — экран осмотра вендора
- recon/findings/damage_model.md + damage_vocabulary.json + scheme/ — recon docs
Cleanup: удалены bash-garbage 'Last' и 'dict[str' из frontend/.
4.1 KiB
Vendor Damage Data Model — Extraction Notes
Source: Ttc.dll (Xamarin Android app, reverse-engineered from assemblies.blob)
Date: 2026-05-17
Core Objects
DetailDamageCoordinate
A single tap-point placed by the mechanic on the enlarged part SVG.
| Field | Type | Notes |
|---|---|---|
Id |
int/Guid | PK |
X |
float | Relative X on the part SVG canvas |
Y |
float | Relative Y on the part SVG canvas |
InspectionGuid |
Guid | Ties this point to an inspection session |
MetaId |
int | Zone ID (0..56) — which part this point belongs to |
GroupId |
int | Groups multiple points belonging to ONE damage annotation |
ImageWithLinesId |
int | FK → the photo with polyline annotation |
LinesId |
int | FK → the DrawingLines set |
Evidence: backing fields <X>k__BackingField, <Y>k__BackingField, <Id>k__BackingField, <MetaId>k__BackingField, <GroupId>k__BackingField, <ImageWithLinesId>k__BackingField, <LinesId>k__BackingField all found in contiguous block at 0x3baa0–0x3bd50 in Strings heap. GetByGroupId method confirms group-based querying.
DetailDamageCoordinateContract (API wire format)
Same fields as above, serialized as JSON. The JSON property for severity is "degree" (lowercase, confirmed at 0x3d752 in Strings heap alongside "damageDegree" widget name).
DetailDamageDrawPointContract
A single vertex in the finger-drawn polyline annotation on a photo.
| Field | Type | Notes |
|---|---|---|
X |
float | Point X on the photo canvas |
Y |
float | Point Y on the photo canvas |
The polyline is a list of DetailDamageDrawPointContract objects. The parent container is DrawingLines (backing field <DrawingLines>k__BackingField at 0x3cade). Method DrawLine (0x3e3c9) draws each segment. StrokeWidth (0x3f59a) controls line thickness.
The photo itself is stored as Image64StringWithLines (base64 JPEG) and ImageBase64StringWithLines (alternate field). The link between a damage group and its annotated photo is: DetailDamageCoordinate.ImageWithLinesId → VehicleStatePhotoInspection.Id.
Multi-Point Damage Grouping
Yes, multi-point damages are grouped via GroupId. The mechanic taps N spots on the part SVG — each tap creates a DetailDamageCoordinate with the same GroupId. All points in a group share:
- One
damage_type(the vertical list selection) - One
degree(severity: 0=Легкое, 1=Среднее, 2=Тяжелое) - One
ImageWithLinesId(one photo with optional polyline)
The GetByGroupId method (found in Strings heap at 0x394c0) fetches all coordinates for a group. SaveByParts (0x42f4f) persists the full group in one call.
Photo + Polyline Link
Inspection
└─ DetailDamageCoordinate[] (grouped by GroupId)
├─ GroupId = 42 (e.g.)
├─ MetaId = 0 (front bumper)
├─ [X1,Y1], [X2,Y2], [X3,Y3] ← multiple tap points
├─ ImageWithLinesId = 7 ← FK → photo record
└─ degree = 1 (Среднее)
VehicleStatePhotoInspection (id=7)
├─ Image64StringWithLines ← base64 JPEG (the photo)
├─ DrawingLines[] ← list of DetailDamageDrawPointContract
│ └─ [{X:0.2, Y:0.4}, {X:0.5, Y:0.6}, ...] ← polyline vertices
└─ HistoryLines[] ← read-only history of old polylines
Our Implementation Recommendation
- DamageGroup table:
{ id, inspection_id, zone_id, damage_type, severity(0-2), photo_id, created_at } - DamagePoint table:
{ id, group_id, x REAL, y REAL, seq_order INT }— multiple rows per group - DamagePhoto table:
{ id, image_b64, polyline JSONB }wherepolylineis[[x,y], ...] - Severity stored as integer 0/1/2, displayed as Легкое/Среднее/Тяжелое
This mirrors the vendor model exactly while using a standard relational schema.
Known Unknowns
- The exact JSON shape returned by
damage/detailsendpoint (API not captured live) - Whether
GroupIdis a local UUID or server-assigned int - Whether
DrawingLinescoordinates are normalized (0..1) or absolute pixels