Building GDPR-Compliant User Deletion: A Full-Stack Approach
How we implemented user deletion at Homi with PII anonymization, analytics provider updates, and proper dependency handling—all while maintaining data integrity.
How we rebuilt our 'Add Property' dialog three times in one session based on real user feedback. A case study in iterative design and the importance of staying flexible.
Kristian Elset Bø
Engineer
Every developer knows the adage: "No plan survives contact with the enemy." In software design, we have our own version: No UI survives first contact with users.
Earlier this week, we rebuilt our core "Add Property" dialog three times in a single session. Not because the original design was bad—it was thoughtful, feature-complete, and followed best practices. But it didn't match how users actually wanted to work.
This is the story of how user feedback transformed a complex multi-tab form into a simple three-card information hub, and what we learned along the way.
Our first iteration looked like this:

The thinking:
The problem: 99% of users just wanted to paste a URL and move on. The complexity was overwhelming.
When we showed it to our first Oslo user testing batch imports from Finn.no, the feedback was immediate:
"Wait, where do I paste the URL?"
"Do I need to fill out all this?"
"What's the difference between Auto and Review mode?"
The dialog optimized for comprehensiveness when users needed speed. Classic designer's trap.
We restructured around usage patterns:
Row 1: Import from URL (full width, prominent)
Row 2: Email to Collection (compact sidebar)
Row 3: Bulk Import button
Row 4: Manual creation (collapsed by default)
Better! But still issues:
Then came the insight: This dialog isn't for creating properties—it's for explaining import methods.
The actual property creation happens via Cmd+V clipboard detection (already built into our CollectionProvider). The dialog should educate, not execute.
We split responsibilities:
The breakthrough: Remove all forms from the create dialog.
Card 1 (Blue): Import from URL
Card 2 (Green): Email to Collection
Card 3 (Purple): Bulk Import
Footer: Just two buttons

Instead of maintaining two complete forms (create vs edit), we use this pattern:
const handleManualCreation = () => {
// Create minimal property with smart defaults
createMutation.mutate(
{
propertyListing: {
title: "New Property",
listingType: collection.intention,
unitSystem: collection.unitSystem,
currency: collection.currency,
images: [],
},
},
{
onSuccess: (newListing) => {
closeCreateDialog();
openEditDialog(newListing.id); // Immediately open edit
},
},
);
};
Benefits:
The first user didn't say "this is too complex." They showed confusion through questions and hesitation. Body language and behavior reveal more than words.
Users needed to understand their options before choosing one. Combining education + execution in one dialog created cognitive overload.
We had three import methods:
The dialog should optimize for the 99%, not showcase every feature equally.
Manual creation became:
Each step reveals only what's needed, when it's needed.
Removing forms from the create dialog:
Clean UI = clean code.
We also moved the edit dialog from individual property cards to the CollectionProvider:
// Before: Each card had its own edit dialog state
const [editDialogOpen, setEditDialogOpen] = useState(false);
const [shouldRenderEditDialog, setShouldRenderEditDialog] = useState(false);
// After: One edit dialog for entire collection
const [editingListingId, setEditingListingId] = useState<string | null>(null);
const editingListing = collection.propertyListings.find(
(l) => l.id === editingListingId,
);
Result:
All three iterations happened in one afternoon. Why could we move so fast?
This is only possible with:
We started with more features visible:
We ended with the same features, but only three visible at once. Everything else lives one click away.
Counterintuitive truth: Hiding features can make them more discoverable. A focused interface with clear paths beats a comprehensive one with analysis paralysis.
Your first UI design won't be your last. That's not failure—it's the process.
The faster you can:
...the better your product becomes.
Our "Add Property" dialog will probably change again. Maybe we'll add visual drop zones. Maybe we'll integrate more AI. Maybe users will ask for something we never imagined.
And that's okay. Because we built it to iterate, not to last forever.
The moral: Design for the 99% use case. Make it delightfully simple. Then hide the power features one click away. Your users (and your codebase) will thank you.
Want to see the import feature in action? Try Homi and experience how fast property research can be.

Engineering at Homi, building the future of real estate technology.
Continue reading with these related articles
How we implemented user deletion at Homi with PII anonymization, analytics provider updates, and proper dependency handling—all while maintaining data integrity.
How we built a campaign-ready sync system for Loops that computes dynamic user segments on-demand without polluting our database schema or scattering one-off updates throughout our codebase.
Remember when we redesigned our Add Property dialog and wrote about it? Turns out that design also didn't survive. Here's how we got it right (this time, we think).