The Blog
Sometimes we write stuff.
You can read it here now, or later with the RSS feed,
or Subscribe to our (almost weekly) newsletter.
-
Season 3, Issue 3: Cosmic Maelstrom
1. Team Full
It's exciting times over here at Good Enough HQ!
(There is no Good Enough HQ. I'd say it's in the cloud, but even clouds are now looked down upon as dirtyish things that should not be enjoyed. And not because of air pollution per se, though perhaps because of industry in a sense?)
-
Our ChatGPT Mission Statement
What follows is an edited transcript of my interaction with ChatGPT to help craft a mission statement for Good Enough. The resulting mission statement was surprisingly good and I had some literal LOLs along the way. Though I think we'll leave out the haiku.
-
Actual Customer Support Is Remarkable
What a sad thing to write.
We believe in good software around here. There is a lot of poorly built software on the Internet and in the app stores. Our motivation with Good Enough is to try to put together a few products that feel just right to the folks using them. The things we build, especially those things we charge for, should respect the customer by streamlining something for them that used to be hard. We hope people enjoy using our software, while also not trying to dopamine-hit them such that it becomes addictive.
While we'll do our best, there are still going to be times where we fail in our mission; especially in the beginning as we're figuring out just how a software should work. Those are the times where polite, helpful customer support helps out. Whether a company decides to do this with phone, email, chat, or a combination isn't nearly as important as a human response in a reasonable time.
-
PEOs are Good Enough (for us)
Hi, I’m Patrick. Good Enough brought me on as a part-time Operations Manager who basically does all the things that Shawn and Barry don’t want to do! My first task was to set up payroll for Good Enough’s three employees, something we thought would maybe be worth talking about!
If you intend to build a serious business, you’ll probably end up hiring some people. Once you’ve gotten over the exhilarating high of finding a perfect candidate, you’ll quickly realize that hiring someone has obligated you to legal and tax compliance whack-a-mole. There’s federal, state, and sometimes local (hello NYC!) rules that need to be followed just to keep someone on the payroll (and if your new hire is remote and resides out of state, don’t forget all the rules for that state). You’ll also get the ultimate American experience of providing healthcare for people who don’t really want you involved in their healthcare experience but who often have no better option.
All of this tedious bureaucracy might really sap the enthusiasm you had for your new custom dog stroller business. Don’t you wish you could just make someone else do all the bureaucratic stuff so you can focus on the latest in dog stroller trends? Maybe you can…
-
· Matthew Lettini · TIL
TIL: Use randomness to prevent email trimming
With conversation threading (which almost everyone has enabled), Gmail was trimming the bottom of the emails we send with our new app because they were too similar to the other emails in the conversation thread.
They’re similar because that’s just the link to get back into the app—you know, the important bit to keep our users engaged! Having that trimmed is bad.
The solution to this is silly: Gmail will not trim content if it’s always unique, so now we add a unique/random number to the bottom of every email we send. Insert eye roll.
-
Asking the Right Question
Lately I've been pondering the future for Album Whale. It does what we'd like it to do, and we've spread the word enough that there's now a steady stream of new users coming in each day. So, what's next?
Portrait of the author pondering My first impulse was to answer this question: How do we get people to come back and spend more time on Album Whale?
Following that questions, I came up with a list of ideas on how to get people's attention so that they'd use Album Whale more often. But something didn't sit quite right with me, and it took me a whole night of sleep to figure out what was wrong.
-
Season 3, Issue 2: Britney Coltrane
1. I ❤️HR
The past two weeks Barry and Lettini have been building our next little project, and I tried to deal with the company-side of work: setting up payroll, health insurance, and making sure we’re compliant (hello, bureaucracy!). Back in the day when Danny and I started Iridesco, we had to get on the phone (this was before the iPhone and we had a real telephone) and call people—like a health insurance broker—and fill out a bunch of paperwork.
It’s a different world today and now there are apps for all this HR quagmire. We’re using Justworks, which seems good enough. It’s impressive how they’re able to conceal most of the stink of the rotten business of health insurance (such a shitty, gross, and prohibitively expensive product).
-
Good Enough, A Serious Business
Hello reader, my name is Shawn, and I'm one of the co-founders of Good Enough. I'd like to tell you a bit about how Good Enough came to be and what we plan on doing here.
Barry and I started working together again in early 2022. By “work,” I mean that I’d show up on Slack for a couple of hours each day, make some wise cracks, try to design in Photoshop and give up, and once in a while wrote some poor HTML and CSS. (Barry probably worked a lot more––somebody had to do the heavy lifting!)
Our first public project was DoEvery.Day, and then we didn’t do much for the rest of the year until we met up again in the fall to work on Album Whale.
For me, this half-ass effort wasn’t cutting it. I wasn’t proud of my work, and I felt like I was often not there for Barry. I felt like I had to make a choice: either leave Good Enough and go back to making Neophyte all day, or take it more seriously.
-
· Barry Hess · TIL
TIL: Merge nested attributes in Rails permit params
I am working on a new product that's a bit more complicated than our prior releases. Getting refamiliarized with nested parameters in Rails has been interesting. In this case imagine I have a discussion that, when creating it I also want to create the first comment. The discussion information is in a form with a nested form for the comment. So at the base you have these permitted parameters:
params.require(:discussion).permit(:title, comments_attributes: [:body])
That is fine, but I wanted to assure that the discussion and comment couldn't be messed with and would always be associated with the logged in,
current_user
. Stack Overflow told me this would be pretty straightforward these days. Unfortunately that didn't work for me. Perhaps I'm doing something wrong, but I had to get a little more…into it.def discussion_params
_discussion_params = params.require(:discussion).permit(:title, comments_attributes: [:body])
_discussion_params.reverse_merge!(user_id: current_user.id)
_discussion_params[:comments_attributes].each do |key, value|
_discussion_params[:comments_attributes][key] = value.reverse_merge(user_id: current_user.id)
end
_discussion_params
endI'd be happy to hear that there's an easier way.
-
· Barry Hess · TIL
TIL: JavaScript Turbo Stream Requests
I am working on search for Album Whale and I was very confused when my JavaScript fetch requests were not resulting in turbo_stream rendering getting displayed on my page. I checked my logs to see if the render was happening. I looked for missing
<%=
tags. Debugged andlogger.info
'd all over.Then I finally noticed the following in my Rails logs:
Processing by AlbumsController#search as */*
Oh, I expected that to say something about
TURBO_STREAM
, like:Processing by AlbumsController#search as TURBO_STREAM
This sent me on a dive into headers (I didn't have an
Accept
header on myfetch
request), response handling, and the fetch API.Here's what I came up with for our first rough cut of a working, live search field (this is Stimulus code):