fixed some changes in the ccode
All checks were successful
Build frontend / build (push) Successful in 2m13s
All checks were successful
Build frontend / build (push) Successful in 2m13s
This commit is contained in:
199
edit-property-flow.md
Normal file
199
edit-property-flow.md
Normal file
@ -0,0 +1,199 @@
|
||||
# Edit Property Flow - Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The edit property flow allows property owners to update their rent property listing, including all fields and images. It shares the same screen as add property (`add_rent_property_screen.dart`) and switches behavior based on `widget.initialListing != null` (edit mode).
|
||||
|
||||
## Screen: `add_rent_property_screen.dart`
|
||||
|
||||
### State Variables for Images
|
||||
|
||||
```dart
|
||||
// Existing images loaded from the listing (edit mode)
|
||||
List<String> _existingImagePaths = [];
|
||||
|
||||
// Newly selected images (both add & edit mode)
|
||||
List<XFile> _formImages = [];
|
||||
List<String> _imageSlotIds = [];
|
||||
List<String> _imageFingerprints = [];
|
||||
List<Uint8List> _imagePreviews = [];
|
||||
List<String> _uploadedImagePaths = [];
|
||||
Set<String> _uploadingImageKeys = {};
|
||||
Set<String> _failedImageKeys = {};
|
||||
|
||||
int get _totalImageCount => _existingImagePaths.length + _formImages.length;
|
||||
```
|
||||
|
||||
### Initialization in Edit Mode
|
||||
|
||||
When editing, `_prefillFromInitialListing()` populates `_existingImagePaths` from the API response:
|
||||
|
||||
```dart
|
||||
_existingImagePaths = info.images
|
||||
.map((path) => path.trim())
|
||||
.where((path) => path.isNotEmpty)
|
||||
.toList();
|
||||
```
|
||||
|
||||
### Image Management UI (Edit Mode)
|
||||
|
||||
| Feature | Implementation |
|
||||
|---------|---------------|
|
||||
| **View existing images** | `Image.network` with `ApiConstants.resolveApiFileUrl()` |
|
||||
| **Delete existing image** | X button → `_removeExistingImageAt(index)` removes from `_existingImagePaths` |
|
||||
| **Replace existing image** | Tap on image → `_replaceExistingImageAt(index)` → file picker → upload via `POST /Files/UploadPicture` → replaces URL at same index |
|
||||
| **Add new image** | Upload button → `_handleImageUpload()` → `_addSelectedImage()` → upload via `POST /Files/UploadPicture` |
|
||||
| **Reorder existing images** | Up/down arrow buttons → `_moveExistingImage(index, direction)` |
|
||||
| **Reorder new images** | Up/down arrow buttons → `_moveSelectedImage(index, direction)` (moves all 6 parallel lists together) |
|
||||
|
||||
### Submit - Image Assembly
|
||||
|
||||
On submit, the final image list is built from:
|
||||
|
||||
```dart
|
||||
final allImagePaths = <String>[
|
||||
..._existingImagePaths
|
||||
.map((path) => path.trim())
|
||||
.where((path) => path.isNotEmpty),
|
||||
...uploadedImagePaths,
|
||||
];
|
||||
```
|
||||
|
||||
This combined list is passed to `AddRentPropertyDto` → `PropertyInformationDto` as `images`.
|
||||
|
||||
## API Details
|
||||
|
||||
### Image Upload Endpoint
|
||||
|
||||
```
|
||||
POST /Files/UploadPicture
|
||||
Headers: Authorization: Bearer <token>, Content-Type: multipart/form-data
|
||||
Body: image=<file>
|
||||
Response: { "value": "/Pictures/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.jpg" }
|
||||
```
|
||||
|
||||
The returned path is used in the edit request.
|
||||
|
||||
### Edit Property Endpoint
|
||||
|
||||
```
|
||||
PUT /RentProperties/EditRentProperty/{id}
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Request Body (camelCase contract from swagger)
|
||||
|
||||
```json
|
||||
{
|
||||
"propertyInformation": {
|
||||
"activityStatus": 0,
|
||||
"images": [
|
||||
"/Pictures/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.jpg"
|
||||
],
|
||||
"cordsX": "33.51599774641418",
|
||||
"cordsY": "36.281279544066294",
|
||||
"address": "string",
|
||||
"description": "string",
|
||||
"numberOfBathRooms": 2,
|
||||
"numberOfRooms": 3,
|
||||
"numberOfBedRooms": 3,
|
||||
"space": 120.0,
|
||||
"detailsJSON": "{}",
|
||||
"buildingType": 0,
|
||||
"status": 0,
|
||||
"propertyType": 0,
|
||||
"city": 0
|
||||
},
|
||||
"deposit": 5.0,
|
||||
"acceptedCertificate": 0,
|
||||
"monthlyRent": 0.0,
|
||||
"dailyRent": 56.0,
|
||||
"rating": 1.0,
|
||||
"currencyId": 1,
|
||||
"rentType": 1,
|
||||
"isSmokeAllow": false,
|
||||
"specializedFor": false,
|
||||
"isVisitorAllow": false,
|
||||
"allowedPaymentPeriod": "10:02:00",
|
||||
"type": 0
|
||||
}
|
||||
```
|
||||
|
||||
### Payload Attempt Order (Flutter side)
|
||||
|
||||
The app tries multiple payload shapes as fallback:
|
||||
|
||||
| Order | Label | Structure | Example |
|
||||
|-------|-------|-----------|---------|
|
||||
| 1 | `plain_pascal` | PascalCase direct | `{PropertyInformation: {Images: [...]}}` |
|
||||
| 2 | `wrapped_pascal_outer` | PascalCase with DTO wrapper | `{RentPropertyDto: {PropertyInformation: {Images: [...]}}}` |
|
||||
| 3 | `wrapped_pascal_inner` | PascalCase inside camelCase wrapper | `{rentPropertyDto: {PropertyInformation: {Images: [...]}}}` |
|
||||
| 4 | `wrapped_camel` | camelCase wrapped | `{rentPropertyDto: {propertyInformation: {images: [...]}}}` |
|
||||
| 5 | `plain_camel` | camelCase direct | `{propertyInformation: {images: [...]}}` |
|
||||
| 6 | `multipart_form` | multipart form fields | `PropertyInformation.Images[0] = url` |
|
||||
|
||||
---
|
||||
|
||||
## 🚨 CONFIRMED BACKEND BUG
|
||||
|
||||
### Symptoms
|
||||
- **All scalar fields** (deposit, dailyRent, address, etc.) update correctly via PUT
|
||||
- **`propertyInformation.images`** is ALWAYS ignored by the PUT endpoint
|
||||
- **`propertyInformation.detailsJSON`** is also ignored by the PUT endpoint
|
||||
- The **POST add endpoint** handles both fields correctly
|
||||
|
||||
### Evidence from Direct API Tests
|
||||
|
||||
**Test 1 - camelCase JSON via curl:**
|
||||
```
|
||||
PUT /RentProperties/EditRentProperty/1
|
||||
→ images sent: ["/Pictures/test1.jpg", "/Pictures/test2.jpg"]
|
||||
→ images response: ["/Pictures/f7062fc863a74306a6a0340982669386.png"] ❌ OLD
|
||||
→ address sent: "test address"
|
||||
→ address response: "test address" ✅ UPDATED
|
||||
```
|
||||
|
||||
**Test 2 - PascalCase JSON via curl:**
|
||||
```
|
||||
PUT /RentProperties/EditRentProperty/1
|
||||
→ Images sent: ["/Pictures/new1.jpg", "/Pictures/new2.jpg"]
|
||||
→ images response: ["/Pictures/f7062fc863a74306a6a0340982669386.png"] ❌ OLD
|
||||
→ Address sent: "test pascal"
|
||||
→ Address response: "test pascal" ✅ UPDATED
|
||||
```
|
||||
|
||||
**Test 3 - POST add endpoint (works correctly):**
|
||||
```
|
||||
POST /RentProperties/AddRentProperty
|
||||
→ images sent: ["/Pictures/test1.jpg", "/Pictures/test2.jpg"]
|
||||
→ images response: ["/Pictures/test1.jpg", "/Pictures/test2.jpg"] ✅ STORED CORRECTLY
|
||||
```
|
||||
|
||||
### Root Cause (Backend Side)
|
||||
|
||||
The `EditRentProperty` PUT handler in the backend likely:
|
||||
1. Creates a new `RentProperty` record (or updates it) - scalar fields work
|
||||
2. Updates or assigns the `PropertyInformation` record - but only scalar fields are copied
|
||||
3. The `Images` and `DetailsJSON` properties of `PropertyInformation` are **not mapped/copied** during update
|
||||
|
||||
Comparison with `AddRentProperty`:
|
||||
- The POST handler correctly maps all `PropertyInformation` fields including `Images` and `DetailsJSON`
|
||||
- The PUT handler appears to skip these two fields specifically
|
||||
|
||||
### Required Backend Fix
|
||||
|
||||
The PUT endpoint handler needs to be updated to persist `propertyInformation.images` and `propertyInformation.detailsJSON` when updating existing property information records.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Aspect | Status |
|
||||
|--------|--------|
|
||||
| Image upload (to server) | ✅ Working via `POST /Files/UploadPicture` |
|
||||
| Image management UI (edit mode) | ✅ Delete, Replace, Add, Reorder all implemented |
|
||||
| Image assembly for submit | ✅ Correctly combines kept + new uploaded paths |
|
||||
| Payload format (camelCase/PascalCase) | ✅ Both formats tried correctly |
|
||||
| **PUT edit endpoint** | **❌ Does NOT update images or detailsJSON** |
|
||||
| POST add endpoint | ✅ Fully functional |
|
||||
Reference in New Issue
Block a user