Files
SweetHome/edit-property-flow.md
mouazkh 30693c6495
All checks were successful
Build frontend / build (push) Successful in 2m13s
fixed some changes in the ccode
2026-07-26 00:09:45 +03:00

6.7 KiB

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

// 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:

_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:

final allImagePaths = <String>[
  ..._existingImagePaths
      .map((path) => path.trim())
      .where((path) => path.isNotEmpty),
  ...uploadedImagePaths,
];

This combined list is passed to AddRentPropertyDtoPropertyInformationDto 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)

{
  "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