5 ms·
Yes, these are the "features" that really bog down the excitement when trying to launch -- user invites, user profiles, billing, transactional emails, password
by dalfonso 9y ago
Yes, these are the "features" that really bog down the excitement when trying to launch -- user invites, user profiles, billing, transactional emails, password reset, file upload, PDF conversion, free trial capability, coupon code capability, shared accounts, PERMISSIONS, etc. Then you get to the next level -- search, caching, deploying.
Not exactly in the same vein as the others, but I've never seen soft-deletes done really well either i.e. the user can "delete" something but it still lives in the database. It's one of those features that sounds good but when it comes time to implement, it ends up being more trouble than it's worth.
- btown 9y agoSoft-deletes are highly expensive technical debt until properly wrapped with an API. Until that happens, every developer/consumer needs to remember to check for archived=false. One solution I’ve sometimes used is to move deleted records into a separate NoSQL database at delete-time. Keeps data around if you want to implement “see trashed/archived” later, can be migrated back in under an archived flag once you have that API, but in the meantime everyone else (including, crucially, the analytics team) can pretend that everything in the database is live. A kludge, to be sure, but sometimes a necessary one.
- saurik 9y agoCreate a view and have everyone use the view. Name the original table something like "table_with_deleted_records" to make it stupidly clear what is going on.
- sbov 9y ago+1 on the soft deletes. It potentially adds a corner case to everything you do with that record. It's a permanent tax on your productivity. If you can get away with it, its much better to just delete it out, perhaps moving it into some archive table incase you change your mind later.
- jamesvandyne 9y agoauthor here. You’ve hit the nail on the head. We actually have soft delete in Kwoosh. We’re using Django on the backend. The way we went about implementing it was with a flag on our core data-type (Apps, Screens, Discussions, Tasks etc... all share a common parent class). Then we used an custom Manager class (Django’s name for the bit that lets you set default filters for models) that sets the default filter to only show active items. If we want to query all objects including archived items (like for viewing them as read-only) we just change our code from Task.objects.filter() to Task.all_objects.filter(). We also have another flag for controlling visibility directly. This makes it manageable to remove a parent task, hide the children tasks, and restore into the expected states. I should write a more in depth post on this for workshop. Maybe someone would find it helpful.
- bungie4 9y agoI usually use a date as a soft delete. If it's non-null, its deleted, and, you get to record the actual date of deletion. I've never found it to be a problem. In fact, I find it's more of a problem to physically delete. You just have to design that way from the get go. Not added on after you've realized ppl leave.
- Rapzid 9y agoYeah, I find the sentiment that this is hard to implement without it being YOOGE tech debt odd. There are so many ways to get it out of the way, including just querying through a view if you can't come up with an app-side solution.
- jessaustin 9y agoThe technical debt might be proportional to how many ad-hoc queries you have buried in various modules before you realize that some things do need to be deleted as of a particular date. But as you indicate, with a real DBMS, naive queries can just be pointed at a view.
- bungie4 9y agoAlso, how to deal with down the road queries wrt; churn when you have deleted the data. I'm calling self inflicted technical debt because of shortsightedness or, dare I say it, lack of acumen. :D
- Klathmon 9y agoAnother point I didn't see mentioned was "support and documentation" (not necessarily SaaS specific, but still applicable) I was the lead developer of a greenfield new b2b web application that took several months to develop the MVP for, then another almost 2 years to develop support tooling and systems for. We would get calls that it didn't work with no other information, calls that it didn't work with "my older samsung", emails with pictures taken with another phone of the login screen with no other information, users that didn't know the name of the company they worked for, or even their username in the application. We found suprisingly that there was a subset of our users that couldn't even tell you if they were on iOS or android! But quickly we learned that it's not their job to care about that, it's ours. We spent the next almost 2 years writing in debugging code, shipping logs back to our servers, writing code to send errors back to us to avoid having to ask the user on the phone to "please read out exactly what the error message says" only to find out that it happened to them last week and they don't remember... We wrote code to be able to "playback" what a user is doing in the app before they have a problem so we could identify UX issues, and redesigned UIs to include important information so when users sent us screenshots or pictures of the device we could get useful information from it from anywhere in the app (like app version, os version, username, company, etc...). We wrote documentation for how to enable camera permissions that they may have inadvertently denied for several android versions and flavors and iOS versions because we found that some users would be confused if the images and names were slightly different. If you asked me today what makes our app better than all of our competitors, i'll tell you that it's hands down the "support" capability of the application, and that if a user has a problem, we can track down what they were doing when it happened and figure out a fix (either procedural or technical) sometimes before they even call the problem in! Also, it's a sure fire way to deflate the ego of the hotshot lead developer that thinks he's made the best thing since sliced bread when the most important part of the application is a glorified log shipper!
- jamesvandyne 9y agoSpot on. That's something that's next on my roadmap: building out a help and documentation site/portal. There is so much more that goes into building and launching a SaaS app than just the app itself. I'd to love to hear more about how you identified UX issues from pure logging data. Do y'all write anything up about this online anywhere?
- jimjimjim 9y agosoft delete aka flag delete is a very common thing in databases. If it's a customer account that is being deleted then just set a flag on the record or change the user's status. The last thing you want is to try to resolve a dispute where all the details have been removed from a database. safety first. record everything.
- wolco 9y agoUsing a framework like laravel makes soft deletes easy. Great for prototyping.
- xstartup 9y ago-> user invites, user profiles Not needed -> transactional emails Most transaction email services offer same old SMTP interface.
- jacobwyke 9y agoThese really depend on the product. Kwoosh, the product in the article, is a team based project management tool and so requires a way to add other team members. As for transactional emails, we have found that its the planning, writing, designing, producing content for them that takes time and not the actual sending process.