← Back to Work
Full-Stack DeveloperJul – Nov 2022 · 4 months

PropertyMap

A map-centric property valuation platform for the Cambodian real estate market. It enables valuation companies, banks, and institutional investors to record, search, and visualize property data across Cambodia's administrative geography. I joined mid-project on a 7-person cross-functional team — backend, frontend, design, and product. Over 4 months I became one of the highest-volume contributors — shipping 100 commits across 2 repositories, 70 on the React/TypeScript frontend and 30 on the NestJS backend API, with 7+ pull requests reviewed and merged. Key contributions included duplicate property detection, the interactive map experience, and a valuation API integration. My largest refactor: 502 insertions / 2,224 deletions — proving that the best engineering often means less code, not more.

100Commits
2Repos
7+PRs Merged
−1,722Net Lines on Refactor
LayerTechnologies
BackendNestJS, TypeORM, PostgreSQL, Passport JWT, AWS S3
FrontendReact 17, TypeScript, Redux + Thunk + Persist, Google Maps API, Supercluster, Tailwind CSS, Ant Design
InfrastructureDocker, Nginx, PM2

The Challenge

When I joined, the platform had foundational scaffolding but critical product features were missing or broken:

No unified property workflow. Separate, duplicated forms existed for creating and editing properties, with divergent logic paths and ~2,000 lines of redundant code.

Incomplete map experience. Property detail views on the map lacked image carousels, proper geocoding display, and chart visualizations. The map component itself had null-pointer crashes.

No duplicate detection. Users could submit the same property multiple times, polluting the dataset. Neither the frontend nor the API had deduplication logic.

Valuation management gaps. The API lacked proper valuation listing/filtering, and the frontend had no way to delete valuations or view valuation history per property.

UI/UX inconsistencies. Dropdown menus didn't close on outside clicks, date formats were inconsistent, modals had broken state, and document uploads showed invalid dates.

The Solution — Technical Deep Dive

01

Unified Property Create/Update Form

Largest single contribution — 25 commits to one file

Consolidated two separate forms (~1,029 lines each) into a single mode-aware component. One commit: 502 insertions, 2,224 deletions — a net reduction of 1,722 lines while adding functionality.

Implemented cascading address selectors (City → District → Commune → Village) with parent-triggered API re-fetches.

Integrated image and PDF upload pipelines wired to S3-backed attachments.

Added nested valuation sub-form with land/building type classification, pricing fields, and date validation.

02

Duplicate Detection System

Full-stack feature across both repos

Backend: Built a duplicate detection API querying for matching properties based on address and geolocation proximity, with a reviewed-flag to prevent re-flagging.

Cleaned up 27,000+ lines of hardcoded sample data used as a workaround.

Frontend: Shipped the UI flow across 6 consecutive commits — API method in propertyService.ts, visual indicators showing potential matches before submission, edge-case handling across add and update screens.

03

Map Interactive Experience

15 commits on detail views, 7 on the map component

Built a reusable CarouselSwiper component for property photos within map detail views, plus a MapSingle component for single-property rendering.

Created a UseRefDimensions custom hook for responsive dimension tracking.

Fixed null-reference crashes where missing latitude/longitude data caused the entire map to fail.

Implemented expandable valuation history tables with inline chart visualization.

Consolidated legacy map code — deleted 519 lines across redundant components into a single map-component with proper supercluster integration.

04

Valuation API Development

Extended the NestJS valuation module

Implemented filterable, paginated valuation listing across controller, service, and repository layers.

Added valuationFileUrl and buildingType to the DTO for PDF reports and proper categorization.

Built delete valuation API with proper S3 file cleanup via the file service.

05

Reusable Components & Cleanup

Small work that compounded

Built a DropDownMenu component with outside-click detection, replacing 3 separate ad-hoc implementations.

Created an API environment configuration layer, centralizing URL switching across local-dev, pub-dev, and pub-prod — removing hardcoded URLs scattered across the codebase.

Built a full PDF viewing component (291 lines) with route integration for in-app valuation report viewing.

Fixed date formatting inconsistencies across document uploads and valuation cards.

Performed deliberate code cleanup — one commit: 77 insertions, 335 deletions across 20 files.

My Role & Workflow

Operated as a full-stack developer in a team of ~7 contributors, with primary ownership of the property create/update flow, map detail experience, and duplicate detection system.
Followed a branch-based PR workflow — feature work went into update or develop branches, reviewed and merged into main via GitHub PRs. Authored and merged 7+ PRs on frontend and API.
Frequently integrated other team members' work, coordinating on shared feature surfaces through collaborative branch merges.
Performed significant code cleanup and refactoring — multiple commits show deliberate removal of dead code, redundant components, and debug statements.

Key Learnings

01

Consolidate before you build.

Merging the duplicate create/update forms halved the surface area for bugs and made every subsequent feature faster to implement. I now treat redundant code paths as a priority-zero fix.

02

Full-stack ownership of a feature is transformative.

Building duplicate detection from PostgreSQL query → NestJS controller → React UI in a single arc meant zero miscommunication. The API returned exactly what the frontend needed because I designed both sides.

03

Map UIs demand defensive coding.

Geospatial data is inherently messy — null coordinates, missing addresses, malformed upstream data. Map components need the same input validation rigor as an API endpoint.

04

Small reusable components compound.

The DropDownMenu was a single afternoon of work but replaced 3 implementations and prevented a class of bugs across the entire app. The CarouselSwiper got reused in two views immediately.

05

Clean up as you go.

Deleting 27K lines of hardcoded sample data and removing dead components wasn't glamorous, but it made the codebase navigable for the whole team.

← Back to Work