Files
tremble7681 7e2cf0c9c8 wip(mechanic): inflight damage-flow + vendor scheme + PhotoAnnotate + TT views
Маркер «вот где остановилась 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/.
2026-05-20 11:16:21 +10:00

80 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 0x3baa00x3bd50 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
1. **DamageGroup** table: `{ id, inspection_id, zone_id, damage_type, severity(0-2), photo_id, created_at }`
2. **DamagePoint** table: `{ id, group_id, x REAL, y REAL, seq_order INT }` — multiple rows per group
3. **DamagePhoto** table: `{ id, image_b64, polyline JSONB }` where `polyline` is `[[x,y], ...]`
4. 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/details` endpoint (API not captured live)
- Whether `GroupId` is a local UUID or server-assigned int
- Whether `DrawingLines` coordinates are normalized (0..1) or absolute pixels