What this covers
Trusted sources: Website EndUser + Backend APIs.
Under test: iOS EndUser app (SwiftUI shell + legacy UIKit where still used).
Kingdom catalog is not live bidding — keep Auction vs Kingdom separate.
How to useWork module by module from the sidebar. Tick the checkbox when the scenario passes. Click the eye icon for full steps, pass/fail criteria, and evidence paths.
Arabic UISteps include Arabic labels from the product (e.g. المحفظة, المزايدة). Use those names when navigating.
Issue codesPrimary gap ID is shown in the ID column. Extra related codes appear under it. Use them in defect reports.
Website-only skips
W4-NOTIF-006, W4-NOTIF-007, W3-DTO-010, W3-DTO-011, W3-DTO-006, W6-DET-001, W6-DET-002Review notes
- W9 exceptional bidders (W9-EXC-*): Agent Portal only; EndUser fee waiver is server-side. Website and iOS both have no exceptional UI — no iOS QC gap.
- W7-AWD-006: RevokeProperty emits Wallet but not property status — shared backend limitation; both clients affected. Bid screen mitigates with refetch. Tracked as informational P3 scenario.
Before you start
| Item | Action |
|---|---|
| Environment | Staging (or agreed build) with matching Website + API + iOS build from the parity review. |
| Accounts | Same EndUser account on Website and iOS when comparing money, bids, wallet, and notifications. |
| Reference | When iOS and Website disagree, Website + Backend win unless the review note says both are wrong. |
| Language | Test iOS in Arabic UI. Match Arabic paths in the detail modal. |
| Progress | Checkmarks persist in localStorage on this machine/browser only. |
Priority & tags
Priority: click to include (any selected priority matches).
Tags: click cycles must have → must not have → off.
Example: P1 + timer must have + text must not have = all P1 with timer but not text.
All must have tags are required together (AND).
Eye icon = test steps
Tags
Live Bidding · المزايدة (31)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W3-DTO-002 W3-DET-002 |
bidding dto | P0 |
Specialty lots (camel/vehicle/etc.) crash or blank property detail
تفاصيل المزايدة، إبل، مركبات
Live auctions sell camels, falcons, vehicles, and other non–real-estate lots. Those lots must open and allow bidding like real-estate lots.
What’s wrong: Opening a camel/vehicle/falcon lot shows a blank screen, error, or missing bid chrome (no timer, no confirm).
|
Detail loads with specialty specs and full bid UI, matching Website for the same lot. | |
W1-BID-001 W1-BID-002 |
signalr bidding | P1 |
BidsNumber not reset after success or Property SignalR updates
تأكيد المزايدة، عدد المزايدات
Backend uses client bid-count increment rules. Stale local CountsNumber can send wrong increments and confuse successive bids.
What’s wrong: After a successful bid or after agent updates the lot, the next bid may use a stale increment count.
|
Reset local bid count after successful bid and when applying SignalR Property updates (mirror Website). | |
W1-BID-003 |
bidding | P1 |
Confirm blocked when maxBid is nil on opening-price lot
تأكيد المزايدة، سعر الافتتاح
First bid on a lot with no bids uses opening price; Website/Backend allow MaxBid ?? OpeningPrice.
What’s wrong: Confirm is disabled or blocked on a lot with zero bids even when opening price is valid.
|
User can confirm first bid at opening price path like Website. | |
W1-CALC-001 |
calculations bidding wallet | P1 |
Hardcoded 15% striving VAT instead of API tax rate
قيمة السعي، الضريبة
Tax percentage on striving fees comes from configuration. Wrong % shows wrong total to the bidder.
What’s wrong: Fee/tax lines always use 15% even when auction config differs.
|
Use API strivingPriceTexes; totals match Website for same lot. | |
W1-CALC-002 |
calculations bidding | P1 |
Opening vs current price gated on empty bidders page
سعر الافتتاح، أعلى مزايدة
Banner and fees should use bidNumber/maxBid from property details, not whether the paginated bidders list is still empty.
What’s wrong: Lot shows opening-price framing even when bids exist (or opposite), until bidders list loads.
|
Gate on API bid count fields like Website, independent of bidders page load. | |
W9-BOARD-003 W9-BOARD-002 W3-DTO-008 W9-BOARD-001 |
signalr bidding dto | P1 |
Own-bid detection uses phone; missing applicationUserId on board
لوحة المزايدين، مزايدتي
After your bid arrives live, the app must recognize it as yours for flags like "you have bid on this lot".
What’s wrong: Your live bid is not marked as yours; "isUserHasAnyBid" / own-row highlight may stay wrong because phone is never in SignalR payload.
|
Match applicationUserId; own rows/highlight work like Website. | |
W2-FEE-003 |
no-website calculations signalr | P2 |
Bid screen wallet snapshot is stale on open — no API refetch on appear
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، المحفظة
Before bidding, the app should reflect the latest available balance after deposits, holds, or releases — especially after returning from SADAD/bank app.
What’s wrong: BidOnItemPresenter.init sets currentWalletData from UserDefaultsManager.getWalletData() once. No getWallet() on viewDidLoad/appear. Commented-out client pre-check (~L670–679) would use this stale snapshot. SignalR Wallet listener updates cache only when event fires.
|
Website does not show wallet on bid screen and relies on backend 73 at submit — acceptable. iOS does load wallet into presenter state for validation scaffolding; that state should be fresh. Wallet screen refetches on UIApplication.didBecomeActiveNotification (ZYID-2458 pattern); bid screen does not. | |
W5-ONSITE-012 |
bidding onsite | P2 |
BidderRepresentativeList omits propertyIds array
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، نوع الممثل
Representative row can scope to specific interested lots for agent paddle assignment.
What’s wrong: Interactor never sends BidderRepresentativeList[0].propertyIds; Website form defines propertyIds: [[]] but also often leaves it empty at submit.
|
When interests selected, representative row should include same property GUIDs for downstream AddOnsiteBidder PropertyIds when agent portal expects scoping. | |
W5-REP-001 |
bidding dto | P2 |
BidOnItemHelpers swaps Pending and Approved in representationStatusEnum
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، نوع الممثل
A bidder whose agency request is still under review must not be treated as approved (or vice versa) for any bid-eligibility helper.
What’s wrong: PropertyDetailsResult.representationStatusEnum maps bidderRepresentitveStatus 1→approved, 2→pending (inverted).
|
Backend + Website: Pending=1, Approved=2, Rejected=3 (BidderOrganizationRepresentitveEnum, GetPropertyDetailsOutputDTO.ts). BidOnItemPresenter already uses the correct mapping. | |
W1-BID-007 |
calculations bidding | P2 |
iOS does not reject zero or negative bid amounts before submit
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
Bidders must not send non-positive amounts; the client should block early with the same message as Website.
What’s wrong: confirmBid / addNewBid never checks currentLocalBidding > 0.
|
Website addNewBid() returns early when userAmount <= 0 with “لا يمكن المزايدة بصفر أو أقل!!”. | |
W5-HYB-002 |
text timer bidding | P2 |
iOS missing Arabic message for onsite-only bidder (TransactionNotAccept)
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، جاري
A user registered as an onsite (hall) bidder must not place bids through the online channel; the product should explain that clearly.
What’s wrong: AddNewBidModel.userMessage(forStatusCode:) has no case for 76 (ResponseStatusCode.TransactionNotAccept). Onsite users get generic “قم بالمزايدة بمبلغ اخر” instead of the website toast.
|
Website shows المستخدم حضوري ولا يمكن المزايدة من الموقع when statusCode === TransactionNotAccept (real-estate-details.component.ts ~782–784). Backend returns this when an onsite-linked user attempts online AddNewBid. | |
W7-ACT-006 |
bidding dto | P2 |
iOS My Bids cards hide bids count badge
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، مزايداتي
Bid count on card signals auction heat at a glance.
What’s wrong: MyBidsSUIItem decodes bidsCount but MyBidsItemCardView never renders it.
|
Website overlay shows {{Item.bidsCount}} مزايدة on card image. | |
W7-ACT-005 |
calculations bidding dto | P2 |
iOS My Bids cards omit per-meter bid breakdown
For biddingTypeId == 2 (per sqm), user compares their bid and highest bid per meter.
What’s wrong: MyBidsSUIItem has no propertyDataDTO; card shows raw amount / highestBid strings only.
|
Website my-bids-card when propertyDataDTO.biddingTypeId == 2 shows قيمة مزايدتك للمتر, اعلى مزايدة للمتر, and المساحة بالمتر (amount/areaNumerical, highestBid/areaNumerical). | |
W7-ACT-007 |
bidding | P2 |
iOS My Bids uses page size 5 and infinite scroll only
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، مزايداتي
User controls how many bids appear per page and jumps pages on long histories.
What’s wrong: MyBidsSUIPresenter.pageSize = 5; infinite scroll appends pages; no page-size picker or page jumper.
|
Website app-PaginationControls exposes page size and page number; default pagination from shared Pagination model (typically 10). | |
W8-UX-016 |
text bidding | P2 |
iOS my-bids search field has empty placeholder
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، البحث
Users search auctions by name on my-bids list
What’s wrong: TextField("", text: $presenter.searchText) — no placeholder (MyBidsSUIView.swift)
|
Website placeholder البحث باسم المزاد (my-auctions.component.html:19) | |
W1-BID-006 |
text bidding | P2 |
iOS omits two Website AddNewBid error codes in user messaging
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
Bidders need the same Arabic explanations for onsite-only accounts and expired representation requests.
What’s wrong: AddNewBidModel.userMessage maps 82, 73, 86, 3, 2, 88, 85, 83, 4, 8 but not 76 (TransactionNotAccept) or 104 (CanNotBidWithExpiredRepresentationRequest).
|
Website shows “المستخدم حضوري ولا يمكن المزايدة من الموقع” (76) and “لا يمكن المزايده بطلب تمثيل غير صالح اعد تحميل الصفحة” (104). | |
W8-TERM-007 |
no-website text calculations | P2 |
iOS shows bid success alerts Website does not show
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
Post-bid feedback should match Website: silent success with live UI refresh; errors only via toast/alert.
What’s wrong: SwiftUI: BidOnItemPresenter.addNewBid → showSuccessAlert(message: "تم إضافة المزايدة بنجاح"). UIKit: BiddingVC → "تمت المزايده بنجاح". BidOnItemView binds .alert(... success ...).
|
Website real-estate-details.component.ts: on successful bid, updates state/refetch — no success toast (errors use toastr.ErrorWithTroubleshooting). | |
W1-CALC-003 |
text calculations bidding | P2 |
iOS skips Website’s 3-decimal intermediate rounding on fee lines
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، المحفظة
Fee breakdown lines (striving, VAT on striving, property tax, total) should match Website figures the bidder uses to decide whether to bid.
What’s wrong: calculateFeesAndTaxes keeps full Decimal precision; formatNumber renders 2 decimal places. No toFixed(3) per component.
|
Website UpdateViewValues rounds each of taxesValue, strivingPriceValue, strivingPriceTaxesValue, and totalAmount with parseFloat(...toFixed(3)). Backend awarding math uses Math.Round(..., 3) on components. | |
W1-BID-004 |
bidding | P2 |
Legacy UIKit BiddingVC references deleted BiddingPresenter
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
Secondary UIKit bidding screen should share the same bid actions as Website/SwiftUI or be removed from the target.
What’s wrong: BiddingVC.swift declares var presenter: BiddingPresenter? and BiddingPresenter(biddingView:propertyId:) but BiddingPresenter.swift is absent from the repo; file not listed in project.pbxproj.
|
Either wire BiddingVC to BidOnItemPresenter (which already receives increaseBid/confirmBid calls per codegraph callers) or delete unreachable UIKit bidding. | |
W5-ONSITE-011 |
bidding onsite | P2 |
Registered bidder can still open full registration sheet
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، التسجيل الحضوري
After successful onsite registration, user should see confirmation only — not re-enter the 3-step form.
What’s wrong: When isExistingBidder, UI shows green confirmation card (good), but comment in shouldShowOnsiteButton says user can “always re-open the form”; registered state is non-tappable (aligned). Legacy path unclear for re-registration attempts.
|
Website hides register button when isExistingBidder; shows attended-bidder confirmation section only. | |
W7-ACT-008 |
bidding | P2 |
Search debounce semantics differ on My Bids
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، البحث
Search by auction name should not spam API on partial typing.
What’s wrong: MyBidsSUIPresenter debounces 500ms and refetches on any searchText change (including 1–2 characters).
|
Website searchForm debounces 300ms with filter(v => v == null | |
W8-TERM-004 |
text calculations bidding | P2 |
SwiftUI bids header uses highest_bid (اعلى مزايدة) instead of Website bid-value labels
Bids tab summary row should describe the current leading bid amount using the same words as Website.
What’s wrong: BidsListView labels non-meter column with BidOnItemLocalizedKeys.highestBid → AR اعلى مزايدة (missing hamza on أ).
|
Website: قيمة المزايدة (sidebar + bidder list); meter variant قيمة المزايدة للمتر. | |
W8-TERM-003 |
text bidding | P2 |
UIKit bid screen shows أعلي مزايدة (typo + wrong term) when bids exist
After first bid, users should see current bid semantics (قيمة المزايدة / السعر الحالي) — not “highest bid” marketing language.
What’s wrong: BiddingVC.setTexts sets highestBidTitleLabel.text = "أعلي مزايدة"; table cells use أعلي مزايدة (لكل متر); storyboard fragment matches.
|
Website item sidebar: قيمة المزايدة (item-detailed-card.component.html); cards use السعر الحالي when maxBid set (favorite-card, property-card). Website bidder list column: قيمة المزايدة. | |
W8-UX-015 |
text bidding | P3 |
Empty my-bids button shorter than Website
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
Consistent re-engagement CTA on zero-bid state
What’s wrong: Hardcoded button تصفح المزادات in MyBidsSUIView
|
Website: تصفح المزادات الآن (my-auctions.component.html:71) | |
W7-AWD-006 |
no-website bidding wallet | P3 |
Informational: RevokeProperty emits Wallet only (shared backend)
المحفظة
When an award is revoked, backend emits Wallet but not property status. Both Website and iOS are affected; iOS bid screen may mitigate with refetch.
What’s wrong: Property award status may stay stale until manual refresh after revoke; wallet updates.
|
Known shared limitation — document; prefer refetch property after Wallet if needed. | |
W2-FEE-006 |
no-website calculations bidding | P3 |
iOS bid client-side entry-fee balance pre-check is commented out (Website also relies on backend 73)
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، المحفظة
Optional early warning before submit: "wallet does not cover entry fee" — reduces failed bid attempts.
What’s wrong: BidOnItemPresenter.confirmBid has UIKit-era wallet/entry-fee gate commented out (~L670–679). User proceeds to confirmation and learns only from API 73.
|
Website real-estate-details.component.ts has no client pre-check — only maps 73 after addNewBid. Backend gate is authoritative. | |
W1-BID-008 |
text bidding | P3 |
iOS success toast copy differs from Website silent success
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
Minor UX consistency after a winning bid submission.
What’s wrong: Shows “تم إضافة المزايدة بنجاح” alert; Website only updates state (no success toast on 200). Legacy UIKit used “تمت المزايده بنجاح”.
|
Product choice: either align to Website (state-only) or standardize one Arabic success string app-wide. | |
W7-ACT-011 |
bidding dto | P3 |
isLastBid decoded but not shown on iOS My Bids
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، مزايداتي
User sees whether they are currently the highest bidder on that lot.
What’s wrong: MyBidsSUIItem.isLastBid populated from API; card UI ignores it.
|
Website DTO includes isLastBid; UI may surface winning state (verify product intent on Website template — field present in contract). | |
W8-TERM-010 |
text bidding | P3 |
My Bids card hardcodes non-Website اعلى مزايدة
My Bids list should use same bid-value terminology as property/bid detail surfaces.
What’s wrong: MyBidsItemCardView label: "اعلى مزايدة" (hardcoded, missing hamza).
|
Website equivalent lists use قيمة المزايدة or السعر الحالي depending on context — not أعلى مزايدة. | |
W7-ACT-012 |
bidding dto | P3 |
Selling agent name not shown on iOS My Bids cards
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، مزايداتي
Agent identity helps user distinguish lots across selling agents.
What’s wrong: agentName decoded on MyBidsSUIItem but not rendered (Website card also omits agent in current template — backend field exists).
|
Contract includes agentName; display is product-dependent. | |
W5-REP-005 |
bidding | P3 |
SwiftUI primary bid area does not mirror Website “pending review” banner placement
تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح، نوع الممثل
While representation is pending, the bidder should see a clear waiting state and must not think they can bid yet.
What’s wrong: Pending state is visible on the Representation tab (PendingRepresentationView) but the main bid footer relies on disabled/hidden controls without the prominent waiting banner Website shows next to bid CTAs.
|
Website shows طلب التمثيل قيد الإنتظار waiting div beside bid controls when isBidderRepresentativePending() (real-estate-details.component.html ~501–520). Bid confirm hidden unless approved. |
SignalR / Live Updates · التحديثات المباشرة (10)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W1-HUB-001 W9-HP-001 |
timer signalr bidding | P1 |
Bid screen never joins Auction group — parent auction updates missed
جاري، إنتهى المزاد، تفاصيل المزايدة
When the agent extends or changes the parent auction, bidders watching a lot must see updated end time/status without manual refresh. Critical for Hybrid Plus parent evening cap.
What’s wrong: While on lot detail, parent end-date extend or auction data change does not update status/counter until leave/re-enter.
|
Bid screen joins Auction_{id}; parent extend/AuctionData updates live like Website. | |
W9-BOARD-004 |
text signalr bidding | P2 |
Attended (onsite) bidders not labeled as paddle numbers on SwiftUI board
التحديثات المباشرة، تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
Onsite participants are identified by paddle number in the public board, not personal names
What’s wrong: BidRowView renders userName only; no check for isOnsiteBidder
|
Website: <span ngIf="item?.isOnsiteBidder"> مضرب رقم</span> before name; UIKit: "مضرب رقم \(userName)" | |
W1-HUB-004 |
signalr wallet | P2 |
AuctionPublishDate group join is Home-tab scoped on iOS vs connection-level on Website
التحديثات المباشرة
When operations publishes a new live auction, home/auction lists should update without manual refresh
What’s wrong: HomeSUIPresenter.joinPublishDateGroup() runs on Home appear/connect only. User on Wallet/Profile/Kingdom/Auction-detail never joins until they revisit Home
|
Website JoinAuctionPublishDateGroup() runs inside startConnection() for every hub session | |
W1-BID-005 |
no-website calculations signalr | P2 |
heightsOnlineBid not updated on live PropertyBid SignalR events
التحديثات المباشرة، تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
iOS uses heightsOnlineBid in pre-submit stale checks; it must track the live highest bid like maxBid.
What’s wrong: updatePropertyBid handler updates maxBid and currentLocalBidding but not heightsOnlineBid.
|
Website does not use a separate stale flag; it resets amount from SignalR. iOS should keep heightsOnlineBid in sync with maxBid on every PropertyBid (as HTTP fetch already does ~442–445). | |
W7-ACT-013 |
signalr bidding | P2 |
Legacy UIKit MyBids row tap opens auction hub, not bid screen
التحديثات المباشرة، تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
Tapping a bid row should open the lot bidding/detail experience.
What’s wrong: MyBidsVC+Extensions pushes AuctionVC.buildVC(aucID:aucName:); commented line shows old AucDetailsVC path.
|
Primary SwiftUI path navigates to BidOnItemView(propertyId:); Website links to /item-details/:propertyId. | |
W8-TERM-008 |
text signalr bidding | P2 |
UIKit wallet storyboard says المبلغ المحجوز instead of Website الرصيد المحجوز
Blocked wallet funds are balance (رصيد) reserved for bids — same term as Website wallet page.
What’s wrong: WalletStoryboard.storyboard label text المبلغ المحجوز.
|
Website wallet.component.html: الرصيد المحجوز (~L356). | |
W1-HUB-003 |
signalr | P2 |
User-scoped representative groups are screen-level on iOS, connection-level on Website
التحديثات المباشرة، نوع الممثل، ممثل لنفسه، ممثل لشخص
When agent approves/rejects a bidder representative, the user should learn immediately regardless of which tab they are on
What’s wrong: propertyForUser_{userId} and auctionForUser_{userId} joins occur only inside AuctionSUIPresenter and BidOnItemSignalRManager while those screens are active. connectionDidOpen does not join them
|
Website calls PropertyForUserUpdate() and AuctionForUserUpdate() on every hub connect and again after login/register | |
W1-HUB-005 |
signalr wallet dto | P3 |
iOS hub invoke names mix PascalCase and camelCase
التحديثات المباشرة
Stable wire names reduce cross-platform drift and ease debugging
What’s wrong: Same codebase uses AddToAuctionUpdatesGroup (Pascal) alongside addToPropertyUpdatesGroup, addToWalletUpdatesGroup, removeFromPropertyUpdatesGroup (camel)
|
Website and backend consistently use PascalCase hub method names matching PropertyHub.cs | |
W9-BOARD-005 |
signalr bidding | P3 |
iOS prepends SignalR bids without popping excess rows
التحديثات المباشرة، تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
Board shows a bounded recent-history window consistent across clients
What’s wrong: items.insert(newBidder, at: 0) with no length cap
|
Website on page 1: unshift + pop() when items.length > pageSize | |
W9-BOARD-006 |
signalr bidding privacy | P3 |
UIKit highlights own row by bidder code match, not auth user id
التحديثات المباشرة، تأكيد المزايدة، أعلى مزايدة، سعر الافتتاح
Own-row highlight should be stable for the logged-in account
What’s wrong: BidderPersonCell.setasCurrentuser when row bidderCode == profile.bidderCode
|
Website uses applicationUserId == NameIdentifier (works even when name is masked empty) |
Timers & Hybrid Plus · العدّاد والمزاد الهجين بلس (5)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W7-ACT-010 |
timer dto hybrid-plus | P2 |
GetMyAuctions DTO lacks timer/status fields needed for canonical Hybrid Plus cards
جاري، قادم، إنتهى المزاد، هجين بلس
Hybrid Plus lots need timeType, isExpire, phi/t (on bids list) for accurate live/coming/closed and extension display.
What’s wrong: MyBidsSUIItem uses legacy HP tri-state (isClosed + dates + parentAuctionEndDate) with code comments citing missing DTO fields; same gap on Website my-bids-card.
|
Counter-spec Q3: extend MyAuctionPropertiesDto (and interests DTO) with timeType, isExpire, waitingAwardingCommittee, visible; inject Phi/T on GetMyAuctions like interests service already does. | |
W8-STAT-009 |
text timer hybrid-plus | P3 |
Hybrid Plus running row hardcodes Arabic جاري instead of localization key
جاري
Same canonical label, but EN parity requires keyed string
What’s wrong: MyInterestsItemCardView.hybridPlusRunningLabel uses Text("جاري")
|
Sibling views use auction_status_live.localized(); Website uses جاري in counters | |
W9-HP-005 |
text timer hybrid-plus | P3 |
Missing timeType on HP Infinite open shows numeric counter instead of running message
جاري
Infinite open floor (isClosed=false, timeType=1) must never show a public hammer countdown — only جاري + running copy (Beat B).
What’s wrong: AuctionPropertyCardView.isHybridPlusRunning requires (item.timeType ?? 0) != 0. If timeType is nil (partial HP payload, race before refetch), card falls through to countdownDisplay targeting auctionEndDate.
|
Website showRunningMessage requires isClosed === false && timeType === 1 — strict equality, so nil does not show running message but also showCounter may still be true; iOS should not show misleading countdown when auctionTypeID==4 && isClosed==false and not in phi. | |
W9-TYPE-004 |
timer hybrid-plus | P3 |
Non-HP detail — Website isAuctionFinished() uses backend propertyStatus hint; iOS uses getItemStatusEnum
جاري، قادم، إنتهى المزاد، هجين بلس
Finished vs active sections on detail should follow the same canonical rules as counters and bid gates. Backend propertyStatus is a hint (handbook §Four-way divergence); client canonical function is authoritative.
What’s wrong: iOS behavior diverges from Website for this case (W9-TYPE-004).
|
Both should derive finished state from canonical status (item dates for 1/2/3). iOS already does; Website detail has a legacy hint path. | |
W1-TIME-F003 |
timer hybrid-plus | P3 |
PropertyCountdownTimerView uses legacy date logic, not wired in production
جاري، قادم، إنتهى المزاد، هجين بلس
Countdown/status on bid screens must follow one canonical rule (getItemStatusEnum) so timer and bid gate never disagree.
What’s wrong: PropertyCountdownTimerView.updateAuctionStatus() uses simplified date/isClosed checks and does not implement HP timeType, parent cap, or phi window. File is preview-only — production uses BidOnItemTimerManager + getItemStatusEnum.
|
Production path already uses BidOnItemTimerManager.getAuctionStatus() → getItemStatusEnum. |
Wallet · المحفظة (12)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W3-DTO-001 W2-API-002 |
calculations wallet dto | P0 |
Wallet history truncates fractional SAR amounts
المحفظة، سجل العمليات، المبلغ
Users must see the exact amount deposited or withdrawn. Fractional riyals (halalah) are real money and must not be rounded or cut.
What’s wrong: A transaction of 1,234.56 SAR appears as 1,234 (or the row fails to load). Blocked transactions may show decimals correctly while regular ones do not.
|
Wallet history shows full precision matching Website and backend decimal amounts (e.g. 1,234.56). | |
W3-DTO-009 W2-API-001 |
wallet dto | P1 |
Wallet transactions drop auction item id/name
المحفظة، سجل العمليات
Users should see which lot a wallet transaction relates to when backend provides auctionItemId/name.
What’s wrong: Regular transactions lack lot name/link that Website shows.
|
auctionItemId/name present and shown like Website (blocked txs already have linkage). | |
W2-FEE-001 |
text calculations wallet | P2 |
iOS add-funds API path does not surface GoPay-disabled (status 90) with Website copy
المحفظة، الرصيد المتاح، الرصيد المحجوز
When electronic payment is turned off, the bidder should see that wallet top-up is unavailable and be directed to agent/check alternatives — not a generic failure.
What’s wrong: WalletInteractor.addFundsToWallet treats any non-success status (except 401) as generic "please_check_your_internet_connection_and_try_again". Status 90 (GoPayIsDisabled) is not distinguished.
|
Website wallet.component.ts shows: "الدفع الإلكتروني غير متاح حالياً .. من فضلك تواصل مع وكيل البيع للدفع عن طريق الشيكات" on status 90. Backend returns ResponseStatusCode.GoPayIsDisabled from WalletService.AddFundsToWallet when IsGoPayEnabled config is false. | |
W2-FEE-002 |
calculations wallet dto | P2 |
iOS add-funds max amount uses hardcoded 10M instead of server MaxInvoiceLimit
المحفظة، الرصيد المتاح، الرصيد المحجوز
Each deposit invoice must respect the configured Sadad/GoPay ceiling; exceeding it should be blocked before API call with the same limit Website shows.
What’s wrong: AddToWalletView.validateAmount caps at 10,000,000 hardcoded. WalletSUIPresenter fetches maxInvoiceLimit from payment config but AddToWalletView does not consume it.
|
Website reads MaxInvoiceLimit from GetPaymentConfigurations, validates on input change, and shows formatted limit in error text. Backend rejects amounts above config in AddFundsToWallet. | |
W2-FEE-004 |
text calculations wallet | P2 |
iOS withdraw does not map server InvalidData to Website Arabic over-balance message
المحفظة، الرصيد المتاح، الرصيد المحجوز
When refund request exceeds available balance (not total), user should see the same rejection copy Website shows.
What’s wrong: WalletInteractor.withDrawFromWallet maps non-success to generic errors. WalletSUIPresenter.withDrawFromWallet shows fixed "خطأ في عملية الاسترداد". WithdrawView has client-side amount > available check, but server rejection path is not mapped.
|
Website shows "المبلغ المطلوب إستردادة أكبر من المبلغ المتاح" on StatusCodeEnum.InvalidData (8). Backend WithdrawFundsFromWallet returns InvalidData when amount exceeds available. | |
W2-API-004 |
wallet dto | P2 |
No server-side statusId filter on wallet transactions
Website lets users filter history by status (pending payment, paid, rejected, refunded, etc.) via API.
What’s wrong: Request omits statusId; WalletSUIPresenter / WalletPresenter filter client-side after full page fetch.
|
Website sends statusId in GetUserTransactionsWalletInputDto when user picks filter. | |
W8-TERM-006 |
text calculations wallet | P2 |
Striving fee label uses رسوم السعي where Website uses قيمة السعي
Brokerage (striving) fee row must use قيمة not رسوم to match Website financial disclosure.
What’s wrong: striving_fee localized string = رسوم السعي (%@%%) used in DetailsTabContent / cost sheet via BidOnItemLocalizedKeys.strivingFee.
|
Website real-estate-details.component.html: قيمة السعي (~L144). | |
W2-API-003 |
wallet dto | P2 |
Transaction list sends sortingTypes: 0 (None) instead of Website Descending
المحفظة، الرصيد المتاح، الرصيد المحجوز
Users expect newest transactions first (default sort by date descending).
What’s wrong: GetwalletTransactions hardcodes "sortingTypes": 0.
|
Website wallet-transactions.component uses SortingType.Descending (2); backend DTO default ctor also Descending. | |
W2-FEE-005 |
calculations wallet | P3 |
Blocked-balance detail rows on iOS are not navigable to property details
المحفظة، الرصيد المتاح، الرصيد المحجوز، تفاصيل العقار
User reviewing held entry fees should jump to the lot they are winning — same as Website wallet blocked table.
What’s wrong: BlockedBalanceSheet / BlockedTransactionRow display name + amount only; no tap → property detail.
|
Website wallet.component.html links each blocked row to ['/item-details', item.auctionItemId]. | |
W2-API-007 |
wallet dto | P3 |
GetWallet stamp format differs (epoch ms vs ISO datetime)
المحفظة، الرصيد المتاح، الرصيد المحجوز
Anti-cache stamp on wallet POST body.
What’s wrong: iOS sends yyyy-MM-dd'T'HH:mm:ss; Website sends Date.getTime() string.
|
Either format acceptable — WalletService.GetWallet() does not read GetUserWalletInputDto. | |
W2-API-006 |
calculations signalr wallet | P3 |
UIKit wallet path has no blocked-transactions API usage
المحفظة، الرصيد المتاح، الرصيد المحجوز
Blocked entry fees per active bid should appear in wallet blocked section.
What’s wrong: WalletPresenter / HomeWalletVC never call getBlockedWalletTransactions; feature exists only in SwiftUI WalletSUIPresenter.
|
Website wallet.component + wallet-transactions refresh blocked list on load and on Wallet SignalR event. | |
W2-API-005 |
wallet dto | P3 |
Withdraw response decoded as add-funds model type
المحفظة، الرصيد المتاح، الرصيد المحجوز
Withdraw returns empty WithdrawFundsFromWalletOutputDto; success is status-only.
What’s wrong: withDrawFromWallet decodes body as AddFundToWalletResponseModel.
|
Use withdraw-specific wrapper (or generic ResponseResultDto with empty result). |
Auth & Session · تسجيل الدخول (17)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W4-AUTH-F002 |
auth | P1 |
Account lockout (status 69) not shown on login
تسجيل الدخول، الحساب مقفل
Locked accounts must show a clear lockout message, not a generic OTP/login error.
What’s wrong: Locked user gets wrong/generic error when requesting OTP/login.
|
Status 69 maps to Website-equivalent lockout message. | |
W4-AUTH-F001 |
signalr wallet auth | P1 |
Incomplete logout on Home / Wallet / Notifications paths
تسجيل الخروج
Logout must kill FCM device, clear wallet cache, ForceLogout, and reset SignalR so the next user does not inherit realtime groups.
What’s wrong: Logging out from some entry points leaves session/realtime state; next login may see prior user's live groups or wallet cache.
|
All logout entry points fully tear down like Profile → logout path. | |
W4-AUTH-F003 |
auth | P1 |
Nafath-incomplete legacy users (status 65) blocked wrongly
نفاذ، تسجيل الدخول
Legacy users who still need Nafath completion must be guided through Nafath, not told they entered a wrong OTP.
What’s wrong: Status-65 users cannot proceed; see wrong-OTP style errors.
|
Detect 65 and route to Nafath completion like Website. | |
W8-UX-004 |
text auth | P1 |
Registration SwiftUI flow Arabic-hardcoded (no EN parity)
إنشاء حساب، تسجيل جديد
English users must see localized signup, not Arabic-only hardcoded strings.
What’s wrong: Device/app in English still shows Arabic-only registration copy.
|
Localized signup stack matching Website EN/AR. | |
W8-UX-003 |
text auth | P2 |
English OTP screen title contains typo “phonn” and vague wording
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
OTP step must clearly state code was sent to mobile
What’s wrong: enter_otp_title EN = Enter the OTP sent to phonn number
|
Website AR: يُرجى إدخال الرمز المرسل على رقم الجوال …; EN legacy key: Enter otp received via sms on number | |
W8-UX-006 |
text auth | P2 |
Forgot-password intro asks for “following data to create password” instead of ID + mobile
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
User must enter national ID and registered mobile to receive reset OTP
What’s wrong: forgot_password_subtitle AR ادخل البيانات التالية لإنشاء كلمة مرور جديدة
|
Website step 1: قم بإدخال رقم الهوية و رقم الجوال (forget-password.component.html:52-53) | |
W8-UX-008 |
text auth | P2 |
Legacy OTP screen always shows “رمز التحقق خاطئ” on failure
منتهي
OTP errors should distinguish invalid vs expired where applicable
What’s wrong: OTPVC.FailureAlert uses hardcoded رمز التحقق خاطئ regardless of server/presenter message
|
Website: invalid otp → AR رمز غير صحيح او منتهي; SwiftUI path uses otp_incorrect_error / otp_expired_error | |
W8-UX-001 |
text auth | P2 |
Login screen subtitle uses generic “enter the following data” instead of ID + password instruction
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
User must know exactly which credentials to enter before OTP is sent
What’s wrong: AR hardcoded: ادخل البيانات التالية لتسجيل الدخول in LoginView.swift
|
Website: قم بإدخال رقم الهوية و كلمة المرور لتسجيل الدخول (login.component.html) | |
W4-AUTH-F006 |
auth | P2 |
Login/register OTP rate-limit and duplicate-ID errors under-mapped
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
When OTP send limits are hit or national ID/mobile already exists, the user needs a specific actionable message.
What’s wrong: loginSendOTP collapses most failures to generic network error (no OTPExceededLimits = 20). registerUserOTP handles mobile duplicate (19) but not national-ID duplicate (18). Forgot-password OTP paths have similar generic fallbacks.
|
Backend returns distinct codes: OTPExceededLimits (20), NationalIdAlreadyExist (18), MobileNumberAlreadyExist (19). Website surfaces these in UI. | |
W8-UX-007 |
text auth | P2 |
New-password step says “enter your new password” vs Website “create new password”
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
Password recovery is a regulated flow; step labels must match
What’s wrong: forgot_password_new_password_subtitle EN Enter your new password; AR ادخل كلمة المرور الجديدة
|
Website: قم بإنشاء كلمة المرور الجديدة (forget-password.component.html:104) | |
W8-UX-005 |
text auth | P2 |
Register link says “إنشاء حساب جديد” instead of Website “تسجيل جديد”
Consistent acquisition CTA across platforms
What’s wrong: LoginView link: إنشاء حساب جديد
|
Website login header link: تسجيل جديد (login.component.html:13) | |
W4-AUTH-F007 |
auth | P2 |
Register payload omits optional email field
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
Registration may collect email for receipts and auth emails when the product asks for it.
What’s wrong: AuthenticationInteractor.registerUser has "email" commented out in params; presenter holds email state but it is never sent.
|
Backend RegisterUserInput accepts optional Email; Website register form can supply it. | |
W8-UX-022 |
text auth | P2 |
Signup OTP instructions differ from Website register OTP
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
OTP step must reference mobile number consistently
What’s wrong: SignupOTPView: قم بادخل الرمز المرسل على رقم الجوال (grammar: بادخل)
|
Website register OTP: ادخل رمز التحقق المرسل على جوالك (register.component.html:60,215) | |
W4-AUTH-F005 |
auth | P2 |
Website biometric login/registration not in SwiftUI Authenticator
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
Returning bidders on supported devices can unlock with Face ID / fingerprint instead of OTP on every visit.
What’s wrong: SwiftUI LoginView / AuthenticationPresenter have no biometric login or post-login registration prompt. BiometricService.swift exists for local device unlock only. Website has full BiometricAuthService + LoginApplicationUserService.authenticateWithBiometric() and registration prompt after OTP login.
|
Website prompts for biometric credential registration after first OTP login (when enabled) and supports passwordless biometric re-login via backend BiometricAuthService. | |
W8-UX-002 |
text auth | P2 |
Wrong password/National ID error text does not match Website
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
User must see the same denial reason Website shows after failed login OTP send
What’s wrong: WrongUserOrPass → AR كلمة المرور أو اسم المستخدم خاطئ; EN Password or username is wrong
|
Website AR: خطأ في رقم الهوية أو كلمة المرور; EN (en-US.json): Account information is incorrect | |
W8-UX-009 |
text auth | P3 |
English auth buttons alternate between Login and Sign In
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
Single verb for authentication across app
What’s wrong: Login = Login; go_to_login / profile_login_btn / home_login = Sign In
|
Website en-US.json: Login = Login, login = login (lowercase in places) | |
W4-AUTH-F008 |
no-website auth | P3 |
SwiftUI login OTP skips standalone ValidateOtpForLogin call
تسجيل الدخول، إنشاء حساب، تسجيل الخروج
Some clients validate OTP in a separate step before exchanging tokens.
What’s wrong: LoginOTPView.confirmOTP() calls presenter.login() directly. validateOtpForLogin exists but is marked UIKit-only and unused in SwiftUI.
|
Backend validates OTP inside Login when ignoreOtp=false; separate ValidateOtpForLogin endpoint exists but is optional. Website also posts OTP directly to Login without a separate validate call. |
Notifications · الإشعارات (7)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W4-AUTH-F004 W4-NOTIF-001 W4-NOTIF-002 W1-HUB-002 |
signalr auth notifications | P1 |
No notifications / PropertyForUser hub joins after login
الإشعارات، التحديثات المباشرة
In-app notifications and user-scoped property/rep updates should arrive after login without opening a lot first.
What’s wrong: In-app notification list stays stale until refresh; live UserNotification never arrives; rep updates may miss until opening a lot.
|
On connect when logged in: join notifications + PropertyForUser + AuctionForUser groups; handle UserNotification. | |
W4-NOTIF-003 |
notifications | P1 |
Push tap ignores notificationId (no mark-read)
الإشعارات، فتح الإشعار
Tapping a push should mark that notification read then deep-link, so unread badges stay accurate.
What’s wrong: Opening from push leaves the item unread in the in-app list/badge.
|
Parse notificationId from FCM data; mark-read API then navigate. | |
W4-NOTIF-005 |
notifications | P2 |
Foreground FCM shows system banner only — no in-app notification UX
الإشعارات
Active app should surface notification content consistent with Website toastr + routing affordance
What’s wrong: willPresent returns [.banner, .badge, .sound]; does not update list, badge, or offer tap routing until user taps system banner
|
Website hub path shows custom toastr with body text and tap → redirect | |
W4-NOTIF-004 |
signalr notifications | P2 |
Home unread badge only refreshes on Home appear
الإشعارات
Bell badge on home should reflect new notifications while user browses other tabs
What’s wrong: fetchUnreadNotificationCount() called from HomeView.onAppear only; not tied to push or SignalR
|
Website updates badge on hub event and on header dropdown open | |
W8-UX-013 |
text notifications | P2 |
iOS notifications empty view has no “browse auctions” button
الإشعارات
Empty notifications should guide user back to discovery
What’s wrong: NotificationsView empty state: icon + title + description only
|
Website app-no-data button تصفح المزادات الآن → /home (notifications.component.html:49-51) | |
W4-NOTIF-008 |
notifications | P2 |
List fetch auto-marks returned page as read (all clients)
الإشعارات
Opening notification list/dropdown should not silently clear unread state for unseen items
What’s wrong: Same as Website — GetNotifications backend marks fetched IDs read via MarkListAsRead
|
Product decision: either explicit mark-read on tap only, or document auto-read-on-fetch | |
W8-UX-014 |
text notifications | P3 |
Empty notifications title spacing/hamza differs slightly from Website
الإشعارات
Polished AR copy consistency
What’s wrong: no_notifications_title AR لاتوجد إشعارات حتى الآن
|
Website title لا توجد اشعارات حتى الآن (notifications) / لا توجد اشعارات حتى الآن (no-data title) |
Profile · الملف الشخصي (9)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W4-PROF-002 |
text bidding privacy | P1 |
Bidder name display preference missing on iOS
إعدادات العرض، اسم المزايد
Users choose how their name appears on the bidder board (full/masked/code).
What’s wrong: No preference setting; board privacy choice only changeable on Website.
|
Preference UI + API like Website; board reflects choice. | |
W4-PROF-003 W7-ACT-001 W7-ACT-002 W7-ACT-009 |
— | P1 |
Favorites / My Bids / Interests limited to Property category
اهتماماتي، مزايداتي، التصنيفات
Multi-category favorites and activity (camels, vehicles, etc.) match Website EndUser product; counts per category should be available.
What’s wrong: Only real-estate (Property) items appear; no category tabs/counts for other types.
|
Load all relevant auctionItemTypes; show per-category counts like Website. | |
W4-PROF-001 |
calculations | P1 |
Profile image upload not implemented
الملف الشخصي، الصورة
Users can upload/change avatar on Website EndUser profile.
What’s wrong: No avatar upload control on iOS profile.
|
Upload/change profile image via same APIs as Website. | |
W4-PROF-006 |
calculations dto | P2 |
`regionId` not decoded; address edit pre-fill fragile
الملف الشخصي، حسابي
Region is required to cascade city picker when editing national address
What’s wrong: `UpdateAddressView.onAppear` tries to infer region from `saudiCitiesArr.first(where: cityID)` — fails if cities not pre-loaded
|
Backend returns `RegionId` on `GetUserInformationOutput`; Website pre-selects region in address form via `regionId` on user DTO | |
W4-PROF-005 |
calculations dto | P2 |
Auction participation stats not shown on iOS profile home
الملف الشخصي، حسابي
Profile sidebar communicates bidding history at a glance (, )
What’s wrong: Backend returns stats; iOS decodes into `ProfileResult` but `ProfileHomeView` menu has no stat strip
|
Website `profile.component.html` shows counts under avatar area | |
W4-PROF-004 |
— | P2 |
Category interest counts not fetched on iOS
الملف الشخصي، حسابي
Favorites hub shows aggregate counts per category so users know where their saved lots live
What’s wrong: No URL constant or interactor for count endpoint; My Interests header has no per-category totals
|
Website calls `GetWebsiteUserInterestsCount` on favorites init; `getAuctionCount()` sums enabled categories | |
W4-PROF-007 |
— | P2 |
Preferences / biometric settings absent on iOS (platform subset)
الملف الشخصي، حسابي
Central place for bidding-related preferences (name display; WebAuthn biometric on Website)
What’s wrong: `ProfileRouter` has no preferences route; biometric block is Website-only (`BiometricAuthService`)
|
Website preferences tab for bidder-name setting; biometric where browser supports WebAuthn | |
W4-PROF-008 |
— | P3 |
Hardcoded KYC “ID issue place” on iOS
الملف الشخصي، حسابي
Display field for where identity document was issued
What’s wrong: `PersonalInfoView` `singleRow` hardcodes Saudi Arabia string
|
Website main-info does not show this field; backend has no dedicated column — field is iOS-only filler | |
W4-PROF-009 |
— | P3 |
My Interests status logic legacy vs canonical (known Q3 debt)
الملف الشخصي، حسابي، مزايداتي، اهتماماتي
User must see accurate lot state (live vs upcoming vs closed vs committee) on favorites list
What’s wrong: `MyInterestsItemCardView.cardLiveType` documents website-parity legacy path; `InterestedItem` lacks canonical status fields present on home cards
|
Website favorite cards + backend projections should align with counter-spec canonical status once Q3 fields added to `GetWebsiteUserInterests` payload |
Lists & Search · القوائم والبحث (16)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W3-LIST-002 W3-DTO-013 |
dto | P1 |
AuctionCode missing on auction detail screen
رمز المزاد، تفاصيل المزاد
Auction detail should show the public auction code users use to identify the event.
What’s wrong: AuctionSUI detail shows name/dates but no AuctionCode.
|
auctionCode on detail model + UI like Website/Home cards. | |
W3-LIST-001 |
— | P1 |
Home has no auction search by name or AuctionCode
البحث، رمز المزاد
Users find auctions by name or code on Website; iOS Home lacks this search.
What’s wrong: No search field/results for auction name or code on Home list.
|
Home search calls GetAuctions with auctionName; finds by name or code like Website. | |
W3-LIST-005 |
hybrid-plus | P2 |
Auction type filter (إلكتروني / حضوري / هجين) missing on iOS Home
Users filter by attendance/bidding modality before entering an auction.
What’s wrong: auctionTypes always sent as [] in HomeSUIInteractor.
|
Website checkbox filters set auctionTypes (Online=1, Attended=2, Hypred=3; selecting Hypred also includes Hybrid Plus=4). Backend filters AuctionTypeId set. | |
W3-LIST-003 |
— | P2 |
Filter tab badge counts reflect current page, not server totals
جاري، قادم، منتهي
Tab badges (جاري / قادم / منتهي) communicate how many auctions exist in each lifecycle state.
What’s wrong: HomeSUIPresenter.updateBadgeCounts counts statuses only within the fetched items array for the active request — not totalCount from API nor GetAuctionsCount.
|
Website maintains currentAcutionsCount / inCommingAuctionsCount / endedAcutionsCount from API totalCount or GetAuctionsCount endpoint. | |
W6-LIST-002 |
— | P2 |
First load filters to جاري only; Website defaults to جاري + قادم
جاري، قادم
Hub landing should surface both running and upcoming catalog content unless the user narrows status.
What’s wrong: auctionSelectedStatusIds and propertySelectedStatusIds initialize to [1] (Active only). Filter sheet reset also sets tempStatusIds = [1].
|
Website prepareQueryParameters and getDefaultAuctionsFilters use auctionStatusIds: [Active, Coming] for both auctions and items lists. | |
W6-LIST-004 |
dto | P2 |
iOS lists have no province-level location filter
البحث، رمز المزاد، جاري، قادم
Website lets users filter catalog by province (above city) using provinces on both auctions and items list inputs.
What’s wrong: No provinces in interactor request bodies; no province picker in filter sheets; presenter stores cities only.
|
Website loads provinces (GetAllProvinces / GetAllKingdomProvinces) and sends provinces: [] in SiteGetKingdomAuctionInputDTO / SiteGetKingdomAuctionItemInputDTO. | |
W3-LIST-006 |
— | P2 |
Item category (types) hardcoded to Property only on iOS Home
البحث، رمز المزاد، جاري، قادم
Website routes /auctions/real-state, /animals, /vehicles, /luxurious show auctions containing items of that category.
What’s wrong: types: [1] hardcoded (AuctionItemType.Property). No department-configuration-driven category switching.
|
Website setInput(categoryId) maps department config to AuctionItemTypeEnum[]; GetAuctions filters auctions having any matching item type. | |
W8-STAT-008 |
text | P2 |
Kingdom filter says جهة الإسناد (singular) while Website says جهات الاسناد (plural)
Filter is multi-select; Website label reflects plural entities
What’s wrong: AuctionFilterSheetView section title "جهة الإسناد" and placeholder "اختر جهة الإسناد"
|
Website kingdom-auctions-list.component.html:85 label جهات الاسناد | |
W8-STAT-004 |
text | P2 |
Kingdom filter sheet status chips say الجارية/القادمة/المنتهية while Website filter checkboxes say جاري/قادم/منتهي
جاري، قادم، منتهي
Filter panels on Website Kingdom list use the short masculine status tokens; list-level tabs elsewhere use plural forms — filter sheet should match filter panel, not list tabs
What’s wrong: AuctionFilterSheetView and PropertyFilterSheetView status FilterChipButton titles: "الجارية", "القادمة", "منتهية"
|
Website kingdom-auctions-list.component.ts auctionStatusOptions: { name: 'جاري' }, { name: 'قادم' }, { name: 'منتهي' } rendered in filter checkboxes | |
W8-STAT-006 |
text | P2 |
Kingdom lists/filters/details use inline Arabic strings instead of localization keys
جاري
iOS supports EN via Localizable.strings; live auction Home already uses keys for status/types
What’s wrong: Kingdom views hardcode "جاري", "إلكتروني", "الجارية", filter section headers, etc. across KingdomAuctionsSwiftUIView, AuctionFilterSheetView, AuctionPropsDetailsView, PropertyDetailsView, CityAuctionsSheetView
|
Live Home uses auction_status_, auction_type_, filter_tab_ keys with EN counterparts (Live, Electronic, etc.) | |
W3-LIST-008 |
— | P2 |
No department-configuration gating for category visibility on iOS Home
البحث، رمز المزاد، جاري، قادم
Ops can hide entire asset classes (Properties, Animals, Vehicles, Luxury) per environment.
What’s wrong: Home does not call GetDepartmentConfigurations; always property types:[1].
|
Website home.component.ts and new-auctions.component.ts call DepartmentConfigService; hide/disable categories when value === false. | |
W6-LIST-003 |
dto | P2 |
Property (عقارات) mode cannot filter by supporting authority
Users filter catalog properties by the government/supporting entity backing the auction — same dimension as Website advanced filters.
What’s wrong: getKingdomAuctions (properties endpoint) sends no supportingAuthorities; PropertyFilterSheetView has no supporting-authority section. Auction mode does send the field via getKingdomAuctionsList.
|
Website items list binds URLQueryInput.supportingAuthorities and passes it to SiteGetKingdomAuctionItems; backend SiteGetKingdomAuctionItemInputDTO.SupportingAuthorities is honored. | |
W3-LIST-004 |
— | P2 |
Region filter not available on iOS Home list
البحث، رمز المزاد، جاري، قادم
Users narrow auctions by Saudi region (المنطقة) on the catalog list.
What’s wrong: No region picker; GetAuctions request never sends regionId.
|
Website NewAuctionsComponent.onRegionSelectionChange sets URLQueryInput.regionId; backend filters a.RegionId == input.RegionId. | |
W3-LIST-009 |
— | P3 |
Auction detail property list uses smaller page size than Website
البحث، رمز المزاد، جاري، قادم
Property/lot list inside an auction detail should paginate consistently for large auctions.
What’s wrong: AuctionSUIPresenter uses pageSize = 5 with infinite scroll.
|
Website NewAuctionsDetailsComponent defaults pageSize: 20 with explicit page controls [6,12,24,48]. | |
W3-LIST-007 |
— | P3 |
Default status filter is live-only on iOS vs all three on Website new-auctions
البحث، رمز المزاد، جاري، قادم
First paint of auction catalog shows which lifecycle states are included.
What’s wrong: selectedTypes defaults to [.live] only (HomeSUIPresenter.swift:30).
|
Website NewAuctionsComponent initializes auctionStatusIds: [Active, Coming, Finished]. | |
W3-LIST-010 |
no-website dto | P3 |
Property-level search within auction detail unused on both clients
البحث، رمز المزاد، جاري، قادم
GetHomeAuctionProperitiesByAuctionIdInputDto.Search could filter lots by name/deed inside an auction.
What’s wrong: AuctionSUIInteractor sends "search": "" always.
|
Website initializes search: '' but has no UI wiring; HomeService.GetHomeAuctionProperitiesByAuctionId does not apply input.Search in service body (field exists on DTO only). |
Property Details · تفاصيل العقار (9)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W3-DET-001 |
signalr bidding | P1 |
Hidden lot (visible=false) not dismissed on first load
تفاصيل العقار
If API says a lot is not visible, the user must leave the screen (Website does on first load).
What’s wrong: Opening a hidden lot still shows detail until a later SignalR hide event.
|
Leave/dismiss when initial API returns visible == false. | |
W3-DET-003 W3-DTO-016 |
dto | P1 |
Selling-agent contact tab missing on lot detail
وكيل البيع، تواصل
Users need selling-agent contact (mobile / WhatsApp) on lot detail like Website.
What’s wrong: No agent contact tab or mobile/WhatsApp fields on iOS detail.
|
Agent contact tab with mobile fields matching Website. | |
W3-DET-005 |
— | P2 |
iOS hides auction live broadcast for Online auctions only
تفاصيل العقار
Some online auctions still stream opening/closing ceremonies via auctionLiveVideoLink
What’s wrong: PropertyCarouselView.hasLiveStream requires auctionTypeID != 1 before showing auctionLiveVideoLink
|
Website shows live tab whenever auctionLiveVideoLink is non-empty (no online-type exclusion) | |
W3-DET-006 |
text dto | P2 |
iOS map ignores locationLink when lat/lng are zero
تفاصيل العقار
Some lots only have Google embed URL without normalized coordinates
What’s wrong: MapViewSection shows "no coordinates" placeholder unless latitude/longitude != 0
|
Website location tab renders app-zayid-google-map-iframe from propertyDetailsOutputDTO.locationLink | |
W3-DET-007 |
text | P2 |
Parcel vs plan number labels swapped vs Website
تفاصيل العقار
number = parcel (قطعة), plotNumber = subdivision plan (مخطط) in Saudi deed context
What’s wrong: iOS labels plotNumber → "رقم القطعة", number → "رقم العقار"
|
Website: number → "رقم القطعة", plotNumber → "رقم المخطط" | |
W3-DET-004 W3-DTO-012 |
dto | P2 |
Virtual tour URL missing on iOS property detail
جولة افتراضية
Lots with virtualTourUrl should expose a 3D/virtual tour entry like Website.
What’s wrong: No virtual tour link/viewer on iOS.
|
Decode virtualTourUrl and show tour entry. | |
W3-DET-010 |
— | P2 |
Website location tab split from property tab; iOS merges location into property tab
تفاصيل العقار
Location (map + boundaries) is a first-class navigation destination on Website
What’s wrong: All location rows + map live inside tab 1 "Property details"
|
Website active3 tab 2 "معلومات عن الموقع" is separate with richer boundary layout | |
W3-DET-008 |
dto | P3 |
headerImage never used in iOS media carousel
تفاصيل العقار
Optional hero image distinct from gallery thumb
What’s wrong: Model decodes headerImage but carousel uses image + imagesAndVideos only
|
Website can promote header asset in gallery context | |
W3-DET-009 |
— | P3 |
Interest count (numberOfInterests) not displayed on iOS
تفاصيل العقار، مزايداتي، اهتماماتي، تم البيع
Social proof — how many users favourited the lot
What’s wrong: Star toggle updates isAuctionItemInterested locally; count not shown in UI
|
Website item card surfaces interest count after toggle |
Representatives · الممثلين (2)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W5-REP-003 W5-REP-004 |
bidding | P1 |
Change-representation still offered after user already bid
تغيير صفة الممثل، تأكيد المزايدة
After bidding, representation type must not change (server status 77).
What’s wrong: "تغيير صفة الممثل" still shown after user has bids on the lot.
|
Hide change-rep when isUserHasAnyBidOnProperty (Website gate). | |
W5-REP-002 |
— | P2 |
iOS shows “change representation” on rejected requests; Website hides it
نوع الممثل، ممثل لنفسه، ممثل لشخص
After an agent rejects a representation request, the product should steer the user to agent contact / resubmit flow defined by Website — not offer a change button that implies a clean resubmit path when Website blocks it in the info panel.
What’s wrong: RejectedRepresentationView always shows “change representation role” when the lot is not terminal-closed.
|
Website info tab: تغيير صفة التمثيل only when !result.isUserHasAnyBidOnProperty && !isRequestRejected (real-estate-details.component.html ~1769). isRequestRejected is true when any detail sub-struct has requestStatus/requestStatusId = Rejected (3). |
Onsite Registration · التسجيل الحضوري (10)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W5-ONSITE-002 |
onsite | P0 |
Company / MOA onsite uploads one legacy file instead of required set
ممثل لشركه، السجل التجاري، عقد التأسيس
Company representatives must supply each document the selling agent configured (CR, agency, articles, etc.).
What’s wrong: Only one generic PDF is requested/sent; commercial registration or other required files missing after submit.
|
Separate uploads for each auction-required company/MOA file, matching Website. | |
W5-ONSITE-003 |
onsite | P0 |
Onsite form ignores auction-conditional document rules
التسجيل الحضوري، المستندات المطلوبة
Each auction declares which representative documents are mandatory. The client must block submit until those files are present.
What’s wrong: User can submit with only name/CR/one PDF even when auction requires agency or other files; then gets opaque backend errors.
|
Validators follow auction flags (like Website); submit blocked until required files attached. | |
W5-ONSITE-001 |
onsite | P0 |
Self-representation onsite sends wrong document payload
التسجيل الحضوري، ممثل نفسه
Self-representation ("ممثل نفسه") onsite registration must attach auction-required authorization documents under the correct backend field group.
What’s wrong: Selecting "ممثل نفسه" may submit without the required ownership/authorization files, or registration fails/agent sees empty attachments.
|
PersonalSelf posts documents under on-his-own-behalf fields; required files appear in agent view like Website. | |
W5-ONSITE-008 |
auth onsite | P1 |
idNumber may fall back to JWT userData GUID
رقم الهوية، التسجيل الحضوري
National ID must be the real idNumber, never a GUID fallback.
What’s wrong: Submitted id looks like a GUID or wrong identifier; registration fails validation.
|
Always send real national ID from profile/auth claims. | |
W5-ONSITE-007 |
text onsite | P1 |
Onsite duplicate/conflict errors collapsed to generic message
التسجيل الحضوري، خطأ
Users need specific duplicate/conflict messages to fix registration issues.
What’s wrong: All failures show the same generic error.
|
Map known statuses to Website-equivalent Arabic messages. | |
W5-ONSITE-005 |
auth onsite | P1 |
Onsite register CTA shown when logged out
التسجيل الحضوري، تسجيل الدخول
Onsite registration requires login; guests should be prompted to log in first.
What’s wrong: Logged-out user sees register CTA that leads to broken/empty flow.
|
Hide CTA or route to login then form, like Website. | |
W5-ONSITE-006 |
onsite | P1 |
Onsite Step 1 allows advance with zero properties selected
التسجيل الحضوري، اختيار العقارات
User must select at least one property before continuing registration.
What’s wrong: Next enabled with empty selection.
|
Block advance until ≥1 property selected. | |
W5-ONSITE-004 |
onsite | P1 |
Personal-agent path sends no representative attachment files
ممثل لشخص، المستندات
Personal-agent onsite registration must upload required agency/authorization files.
What’s wrong: Personal-agent submit succeeds without attachments or fails compliance checks.
|
Required personal-agent files collected and posted like Website. | |
W5-ONSITE-010 |
onsite | P2 |
Cheque date not rejected when after today
التسجيل الحضوري
Post-dated cheques should not fund onsite deposit.
What’s wrong: AddEditChequeSheetView.tryFinish requires date present but allows future dates.
|
Website CustomControlValidators.notAfterCurrentDateTimeValidator on checkDate. | |
W5-ONSITE-009 |
onsite | P2 |
Finished-auction gating uses dates only, not auctionStatus
التسجيل الحضوري
Registration must close when auction is finished (auctionStatus = 3).
What’s wrong: shouldShowOnsiteButton uses isClosed + computed auctionLiveType; does not read auctionStatus == 3.
|
Website hides CTA when auctionStatus == 3 regardless of hint drift. |
Hybrid Plus · هجين بلس (4)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W9-HP-002 |
timer hybrid-plus | P1 |
Auction lot cards keep stale parent endDate after parent extend
جاري، إنتهى المزاد، قائمة العقارات
After parent auction extend/end, every lot card must re-evaluate Finished using the new parent cap.
What’s wrong: On auction properties tab, cards still show "جاري" after parent ended; only header may update.
|
All HP cards flip status without leaving screen (Website binds parent into each card). | |
W9-HP-004 |
signalr hybrid-plus | P2 |
AuctionData updates auction header only; Website refetches items
قائمة العقارات، جاري
Parent AuctionData changes should refresh lot list fields, not only the auction header.
What’s wrong: Header updates; property rows stay stale.
|
Refetch properties or merge parent dates into every row like Website. | |
W9-HP-003 |
text timer hybrid-plus | P2 |
Detail shows lot-closed copy instead of parent-expired إنتهى المزاد
إنتهى المزاد
When parent evening cap expires, detail must show parent-expired ended copy like cards.
What’s wrong: Detail timer strip shows generic lot-closed text; cards already know isParentExpired.
|
Same parent-cap branch as cards: "إنتهى المزاد". | |
W1-TIME-F002 W9-TYPE-002 |
no-website timer bidding | P2 |
Hybrid Plus confirm gate missing timerIsActive (Website)
تأكيد المزايدة، جاري
Near timer zero, Website also requires the local timer to be active before confirm; iOS may allow a narrow race before extend event.
What’s wrong: Confirm briefly available when timer already hit zero before parent extend arrives.
|
HP confirm requires timerIsActive like Website. |
Auction Types · أنواع المزادات (2)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W5-HYB-001 W1-TIME-F001 W9-TYPE-001 |
signalr bidding onsite | P1 |
Online bid UI shown on Attended (hall-only) auctions
مزاد حضوري، تأكيد المزايدة
Attended auctions are display-only online; hall staff take bids. End users must not see +/- or confirm bid controls.
What’s wrong: On type "حضوري" auctions, user still sees increment buttons and "تأكيد المزايدة".
|
Bid chrome hidden (Website *ngIf=!isAttended); price can still update via SignalR. | |
W9-TYPE-003 |
text bidding hybrid-plus | P2 |
Classic Hybrid hides date label with HP-only isClosed==null rule
يبدأ، ينتهي، هجين
Classic Hybrid (type 3) is date-driven like Online; users expect start/end labels.
What’s wrong: Date labels hidden incorrectly on Hypred lots.
|
Limit that hide rule to auctionTypeID == 4 (HP only). |
Kingdom Hub · مزادات المملكة (6)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W6-LIST-001 W6-DET-005 W6-LIST-007 |
— | P1 |
Kingdom property favorites not implemented
مزادات المملكة، المفضلة
Website lets users favorite Kingdom catalog items; iOS cannot toggle or list them.
What’s wrong: No heart/favorite on Kingdom item; profile has no Kingdom favorites.
|
Toggle + profile list + API like Website. | |
W6-DET-004 |
— | P2 |
iOS missing sold-out / final-price display
مزادات المملكة، جاري، قادم
When is true, catalog shows final price or “لا توجد مزايدات” when
What’s wrong: `soldOut` and `finalPrice` exist on `KingdomAuctionItem` but no view renders them in cards or `PropertyDetailsView`
|
Mirror Website `kingdom-property-card.component.html` sold-out block | |
W6-LIST-005 |
— | P2 |
iOS opens on المزادات tab; Website kingdom_auctions redirects to items
Landing tab sets whether users first see catalog properties or catalog auctions — product default is properties on Website.
What’s wrong: currentItemType: ItemType = .auctions on presenter init.
|
Website routing: { path: '', redirectTo: 'items', pathMatch: 'full' } under kingdom_auctions. | |
W6-DET-003 |
text | P2 |
iOS shows `cityName` instead of `address` (city + neighborhood)
مزادات المملكة، جاري، قادم
Website labels location “المدينة” but displays = — users see both city and حي
What’s wrong: `PropertyDetailsView` and `PropertyCardViewWithButton` render `property.cityName` only
|
Display `address` when present, else fall back to `cityName` (matches Website card HTML `AuctionItem.address`) | |
W8-STAT-005 |
text | P2 |
Kingdom catalog cards never show sold state or sale price
تم البيع
Kingdom items can be soldOut with finalPrice; Website shows sale value and favorites show تم البيع
What’s wrong: KingdomAuctionsSwiftUIView property cards render status timers from statusId only; no soldOut branch. Model carries soldOut/finalPrice from API
|
Website kingdom-property-card shows سعر البيع with finalPrice when soldOut; favorites use تم البيع | |
W6-LIST-006 |
— | P3 |
iOS map marker fetch may not request all cities
مزادات المملكة، جاري، قادم
Map view should show every city cluster matching current filters, not a truncated page.
What’s wrong: getMapCitiesList sends status/types/cities/agents/authorities/name only — no limit field.
|
Website getMapCitiesList sets limit: -1 explicitly to fetch all matching cities. |
My Activity · نشاطي (2)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W7-ACT-003 W7-ACT-004 |
signalr | P1 |
No live refresh on Interests / My Bids lists
اهتماماتي، مزايداتي
Favorite and My Bids cards should update live when prices/status change, like Website.
What’s wrong: Lists stay stale until pull-to-refresh; new bid not reflected on My Bids until reopen.
|
Join property groups or refetch on relevant events. | |
W7-ACT-014 |
text | P3 |
Website favorites empty-state copy differs slightly from iOS interests
مزايداتي، اهتماماتي، تم البيع
Consistent empty-state guidance when no favorites.
What’s wrong: iOS empty copy in MyInterestsSUIView (Figma-driven).
|
Website: title لايوجد أصول مضافة في قائمة اهتماماتك, CTA تصفح المزادات الآن. |
Add Property · إضافة عقار (6)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W7-ADD-001 |
auth | P1 |
Guests cannot open Add Property
إضافة عقار، تقديم عقار
Website header exposes submit-property to guests; iOS hides it behind login-only navigation.
What’s wrong: Logged-out user cannot find/open Add Property form.
|
Public entry or login-then-form matching Website /submitProperty. | |
W7-ADD-004 |
— | P2 |
Add Property submit skips Saudi phone validation used elsewhere
إضافة عقار
Invalid phone numbers should be rejected before ops receives the lead
What’s wrong: AddPropertyFormView shows 9-digit UI error (phoneError) but submitPropertyRequest() only guards !trimmedPhone.isEmpty. No Utils.isValidSaudiPhoneNumber call (used in SendTechnicalSupportView / legacy UIKit VC)
|
Website submitPropertyForm uses CustomControlValidators.mobileNumberValidator on phoneNumber; invalid numbers block submit | |
W7-ADD-003 |
dto | P2 |
Ops external note (الملاحظات) missing from iOS request history
When ops updates a request they may leave an external note visible to the submitter explaining next steps or rejection reason
What’s wrong: AddPropRequestItem decodes externalNote but AddPropertyRequestCard.detailsSection never renders it
|
Website submit-property-requests.component.html shows "الملاحظات" with {{propertyRequest.externalNote}}. Backend GetPropertyRequestsList returns ExternalNote | |
W7-ADD-002 |
text | P2 |
Property request status labels differ from Website for all three states
إضافة عقار
User reads badge text to know whether ops confirmed listing, rejected it, or is still reviewing
What’s wrong: AddPropertyRequestCard.statusStyle: 0/default → "تحت المراجعة", 1 → "تم المراجعة", 2 → "لم يتم التأكيد"
|
Website getStatusEnumLabel: 0 → "قيد المعالجة", 1 → "تم تأكيد الإدراج", 2 → "لم يتم تأكيد الإدراج". Backend enum: PropertyRequestStatusEnum InProgress=0, Confirmed=1, NotConfirmed=2 | |
W7-ADD-006 |
text | P3 |
Request history date format omits time vs Website
إضافة عقار
User may need timestamp when multiple requests submitted same day
What’s wrong: formatDate outputs dd MMM yyyy (Arabic locale), no time component
|
Website pipe date:'dd/MM/yyyy HH:mm:ss' after convertDateToLocalInObject | |
W7-ADD-005 |
— | P3 |
Successful property submit dismisses without confirmation message
إضافة عقار
User expects explicit acknowledgment that the request was received
What’s wrong: On success, AddPropertySUIView onChange(of: presenter.submitSuccess) calls dismiss() only — no success alert/snackbar
|
Website CreatePropertyRequest success → snackbar "تم الارسال بنجاح" then form reset |
Terminology & Copy · المصطلحات والنصوص (14)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W8-TERM-001 |
text calculations bidding | P1 |
Bid screen RETT label wrong vs Website
قيمة التصرفات، ضريبة التصرفات العقارية
Regulated RETT fee label must match Website wording by attribution type.
What’s wrong: Shows "ضريبة التصرفات العقارية" where Website shows "قيمة التصرفات" (or wrong variant).
|
Mirror Website label by attributionTypeId. | |
W8-STAT-001 |
text | P1 |
Kingdom map status typo جـاري (kashida)
جاري، خريطة المزادات
Active status must read "جاري" without kashida corruption.
What’s wrong: Map sheet shows "جـاري".
|
"جاري" like elsewhere/Website. | |
W8-STAT-003 |
text | P1 |
My Bids uses مباشر/قريباً instead of جاري/قادم
مزايداتي، جاري، قادم
Canonical status words across the app are "جاري" and "قادم".
What’s wrong: My Bids badges say "مباشر" / "قريباً".
|
"جاري" / "قادم" like Website canonical chips. | |
W8-STAT-002 |
text | P1 |
My Interests shows منتهي when sold instead of تم البيع
اهتماماتي، تم البيع، منتهي
Sold lots must show sold copy, not generic ended.
What’s wrong: Sold interest shows "منتهي" while Website shows "تم البيع".
|
Match Website sold copy. | |
W8-UX-017 W8-UX-019 W8-UX-018 |
text | P1 |
Representative type labels diverge from Website regulated names
ممثل لنفسه، ممثل لشخص، ممثل لشركه، ممثل بموجب عقد التأسيس
Representation type names are regulated product copy and must match Website exactly.
What’s wrong: iOS shows shortened/different labels (e.g. "ممثل شخص/شركة") vs Website full set.
|
Use Website: ممثل لنفسه / ممثل لشخص / ممثل لشركه / ممثل بموجب عقد التأسيس. | |
W8-UX-010 |
text | P2 |
Account tab title uses “My Account” not “Personal File”
الملف الشخصي
Profile area naming should match Website navigation
What’s wrong: profile_home_title AR حسابي, EN My Account
|
Website profile nav first item: الملف الشخصي; breadcrumbs use الملف الشخصي (main-info.component.ts:143) | |
W8-UX-012 |
no-website text | P2 |
iOS exposes “Security Settings” row Website does not list
الشاشة نفسها في التطبيق
Profile menu should mirror Website capabilities and naming
What’s wrong: profile_row_security AR اعدادات الامان, EN Security Settings
|
Website embeds change-password inside main-info (تغيير كلمة المرور); separate security hub not in sidebar | |
W8-STAT-007 |
text | P2 |
Live auction detail ended banner omits hamza on إنتهى
إنتهى المزاد
Website consistently uses إنتهى المزاد for parent-auction-ended strips
What’s wrong: AuctionSUIView uses auction_closed_label → AR "انتهى المزاد"
|
Website down-counter.component.html, item-detailed-card use إنتهى المزاد; Home card uses home_card_auction_ended = إنتهى المزاد | |
W8-TERM-005 |
text bidding | P2 |
opening_price_label truncates Website opening-price wording
الشاشة نفسها في التطبيق
Cards and interest lists must show the full statutory label السعر الافتتاحي.
What’s wrong: opening_price_label = سعر الافتتاح (missing definite article + final ي). Used in MyInterestsItemCardView, AuctionPropertyCardView.
|
Website: السعر الافتتاحي (item-detailed-card, translations "Opening Price": "السعر الافتتاحي"). | |
W8-UX-011 |
no-website text | P2 |
Personal-info menu row label differs from Website
الملف الشخصي
Same menu item must read the same on both clients
What’s wrong: profile_row_personal_info AR المعلومات الشخصية, EN Personal Information
|
Website: الملف الشخصي (profile sidebar) | |
W8-TERM-002 |
no-website text calculations | P2 |
SwiftUI VAT row adds “نسبة” prefix Website does not use
VAT line on bid cost breakdown should read like Website’s fee disclosure — label + percentage in parentheses.
What’s wrong: SwiftUI uses نسبة ضريبة القيمة المضافة (%@) in details/cost sheet.
|
Website: ضريبة القيمة المضافة + ({{ result?.taxes }}%) as separate inline elements. | |
W8-UX-020 |
text | P2 |
Terms-not-accepted error uses generic message, not Website validation tone
الشاشة نفسها في التطبيق
User must accept terms before submitting representation
What’s wrong: AuctionRepSetupPresenter error يجب الموافقة على الشروط والأحكام; checkbox uses correct regulated line
|
Website blocks submit via form; regulated checkbox أقرّ باطلاعي على الشروط والأحكام وأوافق عليها (same on iOS checkbox) — inline errors on incomplete rep data use specific toasts e.g. من فضلك قم بإدخال بيانات ممثل لشركة كاملة | |
W8-UX-021 |
text | P3 |
password_rule_ keys defined twice in EN with different text
الشاشة نفسها في التطبيق
Password rules shown during signup/reset must be unambiguous
What’s wrong: en.lproj: first block At least 8 characters … later 8 characters long without white spaces (overwrites)
|
Website password restrictions / use complex password single canonical rule text | |
W8-TERM-009 |
text calculations wallet | P3 |
SwiftUI blocked-transactions list omits Website table headers
الشاشة نفسها في التطبيق
Wallet blocked section identifies which lots hold entry fees — Website table headers set expectations.
What’s wrong: WalletHomeView / BlockedTransactionRow shows item name + amount only; no section headers.
|
Website wallet table: بنود تمت المزايدة عليها + column عربون دخول البند (wallet.component.html ~L394–395). |
DTO / Decode · نماذج البيانات (8)
| ID | Tags | Pri | Scenario — what happens / what’s wrong | Should be (correct) | |
|---|---|---|---|---|---|
W3-DTO-007 |
calculations bidding dto | P1 |
bidNumber typed as Decimal on property detail
عدد المزايدات
Bid count is a count, not money; wrong type can break display/logic.
What’s wrong: Bid count display or logic looks wrong/fractional.
|
Integer bid count matching Website. | |
W3-DTO-005 |
calculations bidding dto | P1 |
Large SAR prices lose precision (non-Decimal list fields)
السعر، المزايدة
Large lot prices must display exact SAR amounts without floating-point drift.
What’s wrong: Very large prices show rounded/off-by-halalah values vs Website.
|
Decimal-safe money fields matching backend/Website. | |
W3-DTO-004 |
signalr bidding dto | P1 |
Required itemType on Property SignalR can fail whole event
التحديثات المباشرة
Partial Property SignalR payloads must not crash decode and drop the entire live update.
What’s wrong: Live property updates sometimes stop applying (stale price/status) when itemType missing.
|
Decode resilient like Website; event still applies. | |
W3-DTO-003 |
dto | P1 |
soldOut ?? false treats unknown as available
تم البيع، اهتماماتي
Unknown sold state must not be shown as available; null soldOut is not the same as false.
What’s wrong: Items with unknown sold flag appear as still available / wrong status.
|
Preserve unknown vs sold; display matches Website when soldOut is null/true. | |
W3-DTO-015 |
dto | P2 |
iOS “on his own behalf” rep model includes unused company fields
الشاشة نفسها في التطبيق
Self-representation requires national ID + permit files, not company CR.
What’s wrong: onHisOwnBehalfRepresentativeDetails declares companyName, crNo.
|
Backend/Website: rejectionReason, requestStatusId, two file attachments only. | |
W3-DTO-017 |
calculations dto onsite | P2 |
Onsite cheque amount type differs across clients
التسجيل الحضوري
Attended auction registration validates cheque amounts.
What’s wrong: OnsiteBidderChequeModel.checkAmount: String?.
|
Website CheckDetailsDTO.checkAmount: number. | |
W3-DTO-014 |
dto | P2 |
Website AuctionItemOutputDto.finalPrice has no backend source
الشاشة نفسها في التطبيق
Final hammer price after sold lot — display only.
What’s wrong: iOS list model has no finalPrice (matches backend).
|
Backend AuctionItemOutputDto has no FinalPrice; Website adds finalPrice: number. | |
W3-DTO-018 |
dto | P3 |
Sold-items count uses inconsistent names and types
الشاشة نفسها في التطبيق
Auction header badge “sold X of Y lots”.
What’s wrong: Detail: soloutItemsCount: String?; home: soloutPropertiesCount: Int?; backend field commented out.
|
Single canonical key and numeric type from backend. |
P0 smoke list
Run these first. Open each ID in its module section for full steps.
- Onsite Registration / RepresentativesCompany / MOA onsite uploads one legacy file instead of required set (W5-ONSITE-002)
- Onsite RegistrationOnsite form ignores auction-conditional document rules (W5-ONSITE-003)
- Onsite Registration / RepresentativesSelf-representation onsite sends wrong document payload (W5-ONSITE-001)
- Live Bidding / Property Details / DTO / DecodeSpecialty lots (camel/vehicle/etc.) crash or blank property detail (W3-DTO-002)
- Wallet / DTO / DecodeWallet history truncates fractional SAR amounts (W3-DTO-001)
Pass rule: All P0 scenarios pass; no critical/blocker defects left open on P1 for the release slice you are signing.
Defect report template
- Surface: iOS (and Website comparison if relevant)
- Scenario ID / issue code from this guide (e.g. W3-DTO-001)
- Steps and expected vs actual
- Account (role only — not password)
- Auction / property used (name or id)
- Build (iOS version / commit if known)
- Screenshot or short recording