Own your online identity

This post from Fred Wilson echoes a lot of my thoughts. Whether you are posting to twitter, instagram, facebook, Medium, HuffPost, or anything else, it’s always worth remembering that you are leveraging someone else’s platform. That means you are renting it, not owning it. So, you are at the mercy of the platform. Whether in terms of content lifespan, deep linking or even just how your content is presented, you only have as much control as they allow.

That doesn’t mean there isn’t value in these platforms. There is tremendous value because they aggregate eyeballs, have excellent user interfaces and often host your content for free. Just be aware of the price you are paying (TANSTAAFL).

And always maintain a presence that you own if you care about your content. Repost all your content on your own site, so that even if the third party site goes away, you still have your work.  (If that’s not possible, print a PDF and save it in Google Drive, at a minimum.)

It’s not hard to buy a domain and set up a free google site (I wrote up instructions). You can use WordPress.com with your own domain for only a few dollars a month. Even if it isn’t as trafficked or as beautiful as a Facebook note, you control it. Once you’ve seen a few platforms rise and fall and/or change their business plan, you’ll be happy you used them for their leverage, but maintained as much control of your content as you could.


A Few SQL Database Links

So, here are two different relational database links that I am currently interested in.

The first is PostgreSQL Exercises. This is a fun way to sharpen your SQL. While I’m not a big user of PostgreSQL, I have enjoyed it the few times I’ve touched it. And the basics of thinking in SQL are useful across any database.

The second is Modern SQL. I was pointed to this site (in particular this page on pivots) after asking a question on a slack (so I can’t link to it). My question was about how to transform a set of event values (X happened Y ago, then Z happened at Y+1, and so on) up into counts (X happened N times, Z happened M times). But the entire site is worth reading if you are a SQL nerd, especially the use cases.

Bonus, check out this Twitter thread about using a single SQL database as a data source for multiple microservices. Pragmatism!


Tips for working with offshore teams

Remember “The World Is Flat”? For software development, the world is definitely getting more planar. I’ve had the privilege of working with a few offshore software development teams directly, and have discussed the practice with other engineers.  I wanted to share some of my tips. My experience has been in web development, but I believe these tips apply to most general software development. (If you’re looking for a tiger team/extreme expertise in a specific area, I’d treat an offshore team just like another vendor.)

If you can, pick a team that you have worked with before. Just like onsite software development, knowing personalities, strengths and weaknesses of team members is crucial to delivering quality software. If you haven’t worked with someone before, then ask for referrals and check references.

Pick an easy first project. This could be something not on the critical path, a rebuild of outside functionality, or a rewrite of an existing piece of software. If you have a prototype that you can point to and say “make it work like that”, that can reduce complicated requirements discussions. One successful offshore project I know of took a Cordova mobile application and rewrote the app in objective c and android java.

In general, projects that have a lot of iteration and experimentation are tough to offshore, because of communication latency.  You lose out on feedback cycles.

Have a working agreement. This can be an informal document, but you want to specify roles and responsibilities (who is releasing? who signs off on stories that have been finished? how does planning happen?). Make this document a living one.

Having regular time overlap can speed up feedback, to some extent. If you are offshoring to a country in the same timezone, this is painless.  If you are working with a team from an offset timezone, you may need to adjust your sleep schedule.  It is best if both parties have to adjust their lifestyles somewhat–it is more equitable. Record these overlap hours in your working agreement. Shifting my schedule to have a significant overlap doubled the number of feedback cycles (code reviews, questions) that can be made between myself and an offshore developer.

You need one person to own the relationship on each shore. If there are process questions, these folks sort it out. They can button up any lingering requirements uncertainties. They may pull other folks in to make decisions, but this pair owns the success of the offshoring relationship.

Leverage asynchronous tools. Make sure you use a progress tracker like pivotal or trello. slack is fantastic. So are the modern source code management SaaS applications like github and bitbucket. A live prototyping tool like Invision is useful. Record decisions in writing.

Finally, decide how closely you need to follow the code delivery. You may or may not want to see “how the sausage is made” This can be based on a number of factors:

* how much technical expertise does the onshore team have? Are they interested in acquiring more?
* how much time does the onshore team have? You don’t want the onshore team to be a roadblock.
* will the project be standalone (a marketing website)? Or integrated into the main codebase?
* is what the offshore team writing core functionality to your application and/or business?
* who is responsible for maintenance and changes after delivery?

Many of these tips are best practices that should be followed wherever your development team is.  But they are especially important when they aren’t in the next office.

Offshore development can extend your budget and pull in timelines.  It can help you build a better product, or allow you to access skillsets you might not be able to hire.  You just want to make sure it works.


Turning Zendesk tickets into help center articles

We used Zendesk as part of our ticketing system at The Food Corridor. (Other parts are phone calls and an email inbox.)

I’ve been pretty underwhelmed with Zendesk as a ticketing system–I find it hard to understand and the UX is overly complicated for our needs. However, we recently moved a large number of FAQs into the Zendesk help center, and I found that aspect of the software to be awesome. I’m especially excited to see if it cuts down on customer interaction by being integrated into the web widget.

There’s also a cool way to take comments on tickets (typically with answers to common questions) and turn them into help center articles. Here’s how you do that:

An admin needs to install this Zendesk application and I recommend setting the ‘draft only’ option.

Then, the steps are:

  • Go to a ticket.
  • Click on the ‘apps’ button in the upper right hand corner
  • Click ‘post article’
  • Select the comment you want to post (you can only pick one)
  • Enter your title
  • Modify html if you’re comfortable, but realize it will be a draft article regardless, and you’ll have a chance to change it later)
  • Click ‘next’
  • Choose a section of your help center
  • Click ‘post to section’
  • Click the ‘view’ button (for some reason the edit button didn’t work for me)
  • Click ‘edit article’ (upper left)
  • Modify the content if needed using the guide editor, which is nice and WYSIWYG
  • Change from ‘draft’ to ‘published’ to make the answer available

I remember a knowledge base project over 15 years ago that was aiming at sharing knowledge across our organization. It flailed. Zendesk help center seems to be well on the way to achieving such aims.


Ditching Hourly Rates

Back when I was consulting full time, I typically charged by the hour.  For some clients I’d do fixed bid pricing, based on an hourly guess, but that was typically after we had an established relationship.  Otherwise the risk of losing your shirt is just too high.  I’ve done that once or twice–no fun to be working to finish up a project and just knowing your hourly rate is heading far too rapidly towards single digits.

I’m not consulting now, but if I were I’d be following Jonathan Stark’s advice on value pricing.  You can sign up for his free email course, which is valuable.  After that you’re put on his generic email list which is 25% pitches for his business coaching and 75% good tips about value based pricing.

I will be honest, I’d have a lot of fear about moving to value based pricing, the same way I have fear about niching and focusing on a particular market.  Both are scary concepts because when I am a consultant, the feast or famine nature of the business makes me want to say yes to everyone (within my available skillset and time).

But these will be my first two business experiments if I ever go back to my solo consulting practice.  I’ve just read too many success stories (like this one) to not give it a try.


Ask the hard questions

Do you know that moment which happens at almost every meeting or conference call, when a participant refers to a concept that you don’t quite understand?  That moment happens to me often, and has throughout my career.

“The marketing funnel is part of the sales process.”

“We can just flurbuzz the bazznod.”

“We have plenty of runway.”

That is the moment when you can ask the hard question.

“Why is that connected?”

“What does that mean?”

“I’m sorry, I don’t understand.  Could you repeat that?  How do you define runway?”

Asking these questions is important.  Otherwise you and the other parties will be talking past each other, which will only lead to pain down the line when the misunderstanding is crystallized in people, process or code.

I’ve been asking these kinds of questions my entire career.  When I worked at a web consulting company in the early 2000s, there were often company wide conference calls discussing our precarious financial state.  I got a reputation as “the question guy” because I wasn’t afraid of asking the awkward question, even of the CEO in front of the entire company.  I was interested in hearing as real of an answer (as they could share).

If you’re interested in asking hard questions, here are some tips:

  • Pay attention beforehand.  If you are asking a question about something that was just mentioned, or that you should have known, you won’t have credibility.
  • Don’t worry about looking dumb (except if you weren’t paying attention, see above).  If it is a fuzzy concept, chances are others in the room are wondering what it is.  Besides, the goal is to increase your knowledge.  Check your ego.
  • Ask the question from a place of humility and make it about you.  Maybe you just really don’t understand.  I always like the phrase: “I’m sorry, I don’t understand what you just said.”
  • Approach with positive intention.  Don’t ask gotcha questions or try to prove you are smarter than the speaker.
  • If the answer is a bit fluffy or you don’t understand it, ask a second time.  “Thanks, but I’m afraid I still don’t get it.  Could you explain it to me again?”
  • If the speaker don’t answer or hedge again, offer to take it offline.  Depending on who is in the meeting, you don’t want to waste everyone’s time.  But then make sure you follow up.
  • Recognize if the topic is sensitive (financial matters) you may not get a clear answer.  At that point, getting the speaker to define terms but perhaps omit numbers is a win.

Again, the goal here is not to ‘get’ the speaker, it’s to help get everyone on the same page.  Asking tough questions to pin down some of the nebulous concepts we work with every day can help everyone make better decisions.


Saying Thank You

Sometimes it’s a good idea to stop and say thank you.

Thank you to my parents, who instilled a love of learning in me and trusted me to make my own decisions. Now that I have my own children, many of the choices you make seem even wiser now.

Thank you to my wife, my biggest cheerleader and BS detector. It’s a joy to walk through life by your side.

Thank you to Dave B, who took a chance on someone who didn’t have any real software development experience. I still remember troubleshooting winsock issues.

Thank you to Bryan B, who offered me an internship after college and then a job that I couldn’t believe I was getting paid for. The friends and connections I made at that job have reverberated throughout my adult life.

Thank you to all my consulting clients over the last decade plus, from Mike M and Pat M to Brian T to Corey S and Andy P to Josh G, Chris H and Matt K. I always have loved the rush of “I need to deliver but don’t have any idea how to do this” that happens two weeks into every consulting engagement, and I appreciated your patience.

Thank you to Anthony F and Lane H. I learned so much about software development, building a business and how to act from my years working for you.

Thank you to Ashley C. Building something from scratch is a wild ride.

I want to leave you with this comic, from the great Nathan Pyle.

By Nathan Pyle

Thank you.


Seek The Golden Comment: “zeus exit status 1” fix

This bit me yesterday, so I wanted to get it written down.  zeus is a preloader that makes running tests faster.  It can be a bit finicky about the gems available, even when using rvm.

Yesterday, I tried to upgrade a rails 4.2 app to rails 5.  (I failed.)  When I checked out my source branch to work on a different issue, ran a bundle install, and then a zeus start, I saw this:


zeus rake
zeus runner (alias: r)
zeus console (alias: c)
zeus server (alias: s)
zeus generate (alias: g)
zeus destroy (alias: d)
zeus dbconsole
zeus test (alias: rspec, testrb)
exit status 1

And then zeus exited.  I did some google searches and turned up these two issues: 118 and 237. Lots of folks having similar issues.

After reading carefully through these issue, and trying some of the suggested fixes as I did so, I arrived at the golden comment. I reproduce it here in its beautiful entirety:

There’s a lot of “try this” in here, but no actual debugging steps. Here’s how you can find the actual issue:

zeus –log ZEUS.LOG start then cat ZEUS.LOG

Excellent!  Using this logfile I quickly determined that the root issue was a collision in my json gem versions and was able to get zeus running again.

But that’s not really the point. The point is that this user (thank you Steven!) didn’t just provide an answer, he provided the means for me to diagnose and find my own answer.

I wish github had some way of calling out highly recommended comments, as if I’d seen his comment first, it would have saved me some time.

Just goes to show, you should always read the comments fully and look for the golden one when you are troubleshooting.


Leverage

As a software developer, and especially as a senior (expensive) software developer, you need leverage. Leverage makes you more productive.  I find it also makes the job more fun.

Some forms of leverage:

  • test suite. A suite provides leverage both by serving as a living form of documentation (allowing others to understand the code) and a regression suite so that changes to underlying code can be made with assurances that external code behavior don’t happen.
  • libraries and frameworks, like Rails. By solving common problems, libraries, open source or not, can accelerate the building of your product. Depending on the maturity of the library or framework, they may cover edge cases that you would have to discover via user feedback.
  • iaas solutions, like AWS EC2. By giving you IT infrastructure that you can manipulate via software, you can apply software engineering techniques to ensure validity of your infrastructure and make deployments replicable.
  • paas solutions, like Heroku. These may force your application to conform to certain limitations, but take a whole host of operations tasks off your plate (deployments, patching servers). When a new bug comes out affecting Nginx, you don’t have to spend time checking your servers–your provider does. When you reach a certain scale, thost limitations may come back to bite you, but in the early days of a project or company, having them off your plate allow you to focus on business logic.
  • saas solutions, like Google Apps or Delighted. You can have an entire business solution available for a monthly fee. These can be large in scope, like Google Apps, or small in scope, like Delighted, but either way they solve an entire business problem. You can trade time for money.
  • experience, aka the mistakes you’ve made on someone else’s dime. This allows you leverage by pruning the universe of possibilities for solving problems, based on what’s worked in the past. You don’t spend time doing exploration or spikes. Note that experience may guide you toward or away from any of the points of leverages mentioned above. And that experience needs to be tempered with learning, as the software world changes.
  • team. There’s only so much software you can write yourself. A team can help, both in terms of executing against a software design/architecture and improving it via their own experience.

Leverage allows you to be more productive and the more experienced you get, the more you should seek it.


Things I wish I knew about Stripe

Caterpillar

Striped, but not charging your credit card

So, at The Food Corridor, we’ve been using Stripe happily since we launched in June of 2016.  As a developer, I’d used Stripe before in a couple of different ways, but this has definitely been my most sustained use of the payment service.  (If you don’t know what Stripe is, it is an API that makes charging customers as easy as an API call.  More here.)

I wanted to outline some of the things I’ve learned from months of using Stripe.

  • Stripe supports pulling money directly from bank accounts, via ACH, but it really isn’t the same ACH as your bank lets you do.  This is because Stripe isn’t a bank.  The biggest thing to be aware of here is that Stripe ACH takes 7 days to arrive in your bank account.  Another issue is that you have to do verification.  They have two ways of doing verification–micro deposits and Plaid.  Plaid is instant, but only supports major banks, which was a non starter for us (updated 9/8: Plaid supports around 1000 banks now).  The code for micro deposits is straightforward, but be prepared for some customer support issues.  Stripe deposits two amounts and withdraws just one amount, which was confusing for some of our users.  It also takes a couple of days, so if your users are hot to spend money, Stripe ACH may not be a fit.  The win?  Definitely cheaper.  (And I didn’t find any other service that would support both credit card and ACH transactions that was developer friendly.)
  • Don’t forget to set up your webhooks out of the gate.  Stripe mentions this, but I glossed over it in the early days, and missed some events that were important.  (The most relevant is that ACH is asynchronous, so when an ACH transfer fails, it is reported via webhook.  If bank account verification doesn’t work, you’ll get a different kind of webhook.  Review the docs and set up webhooks for all the ACH events.)  If you don’t have time for a full featured webhook processing implementation, Zapier can just send the webhook data to your email. This can be a great stopgap solution.  Or you can use stripe_event.
  • Per support, if a webhook post fails (because your app is down, for example), they are retried once an hour for 72 hours.
  • Speaking of stopgap solutions, the Stripe Dashboard is fantastic for manual processes.  Just because you can automate everything via an API, doesn’t mean you should.  There can be some complicated edge cases with payment processing, especially around refunds, but they can easily be handled with a google doc of instructions and the Stripe Dashboard.  I have found only one use case that the API can handle that the dashboard cannot (a partial refund of an ACH transaction).
  • I have found Stripe support to be excellent, quick and knowledgeable.
  • Occasionally customer charges will be declined because of bank fraud triggers.  Expect to occasionally ask your customers to call their bank.  (I think this has happend about once every third month).
  • Disputes are a total pain, because the process is opaque and slow (expect a resolution in about two months and know you are not in possession of the payment during that time).
  • Make sure to capture the payment id anytime you charge a card or run ACH.  It will make future automation a lot easier.
  • Monthly plans are complicated, so if you can lean on Stripe for management, even if you are doing manual plan management (applying coupons, adding, or removing users from plans via the dashboard), do that.
  • The first payment you charge takes 7 days to move from stripe to your​ bank account.  This is for fraud protection.  Payments thereafter typically take 2 days (but it depends on your country and industry).

And here are some special tips if you are using Stripe Connect (their marketplace product).

  • Read the docs!
  • Remember that first payment timeline?  It applies to every one of the connected accounts.  Think about charging your own credit card as soon as you connect an account to help with customer cash flow.
  • Consider whether you want to use managed vs standalone accounts.  Managed accounts are a lot more work but allow you to have a seamless UX that you control.  Standalone accounts, which we use, are far quicker to setup.  I think this depends on the number of sellers you have in your marketplace.
  • You also want to think about whether to place the charges on the platform account or on the connected accounts.  A major factor there is who bears the Stripe fees, the platform or the sellers.  We charged on the platform account because we wanted all our data in one place.  If you are selling plans, you can’t charge on the platform and use Stripe plans.
  • If you are charging on the platform account, and are using standalone accounts (where the sellers have to set up a stripe account) your sellers won’t see charge descriptions unless you manually copy the description over.  The code looks like:

# this will let the sellers know what invoice the charge was for
transfer_id = charge.transfer
transfer = Stripe::Transfer.retrieve(transfer_id, expand: ['destination_
payment'])
payment_id = transfer.destination_payment
payment = Stripe::Charge.retrieve(payment_id, {stripe_account: destinati
on_account_id})
payment.description = description
payment.save

Happy charging!



© Moore Consulting, 2003-2017 +