What is this?
Like many of you, I just had yet another idea for an app. This time instead of typing the details into another word file in my “cool ideas” folder, Im going to put 24 working hours into it to develop a MVP and then share it on Twitter. Im also planning to document and share the process and the experience here on this post.
Who am I?
My name is James Collado (@james_collado), I am a software developer living in Dublin, Ireland.
The idea
Im big into entrepreneurship, startups, software and Twitter.
Too often I find interesting, valuable links on Twitter with advice for entrepreneurs that I really want to read but dont have the time for it there and then. A possible solution would be to bookmark them for later, but later there would be more links, more interesting, valuable and useful things to read. On top of that, articles usually take longer to read than the time Im willing to put into it.
It would be useful to have an app where one can consume bits of knowledge / advice regarding entrepreneurship, super quickly and super direct. No sign up, no closing the ‘subscribe to our newsletter’ popup or the cookies popup, no in-your-face ads, no scrolling down until you find what you wanted, no ‘install our app’, no nosense an dno distractions.
A super focused app that you can open, consume a couple nuggets of info and close back in the time you wait for an elevator.
The solution: technical requirements
The app fundamental concept is an ‘advice card’.
*Warning: the section ahead is a bit technical. Fear not, I will walk with you to the other side of it. I promise you will learn something and have fun.
An advice card has:
-id (int, a number)
-creation timestamp
-owner profile picture [1] str(99) (this is linked from twitter, we do not store images)
-owner fullname [1] str(99)
-owner twitter handle str(99)
-title str(120) (the title is 120 chars long)
-body str(5*140) (5 times the size of a tweet)
-vote_up (int) (a simple counter)
-vote_down (int) (another counter)
-views (int) (you guessed it: another counter!)
-approved (bool) (is this card approved? this is a TRUE/FALSE field)
-key str(6) (this is a random key for the card, used to retrieve a card by a unique url, like: xxx.com/getcard/fQ2whj)
[1] Those items are pulled from Twitter on a recurring basis (every x hours / every x days). In It we say that we ‘cache’ that data. It would be too costly, slow and inefficient to ask Twitter for a name + profile pic url *every time* somebody reads a card. Therefore we ask once and reuse that data for hours or days until it gets ‘refreshed’
The app has a database of ‘advice cards’ (a simple mysql table will do), in fact this whole app is only going to have 1 table.
A non-logged user can:
- See one advice card upon arrival to the page (complete with owner, voting data, etc)
- Request another random advice card to be shown to her
- Rate the currently on display card with an UP vote or a DOWN vote (this is necessary to improve the quality of cards.)
- See and copy a url link to share the current advice card with others
In order to prevent multiple voting by the same user, in an ideal world the user would be logged in so we can track things. In this MVP we either leave it completely open and call it a day or perhaps we could go the extra mile and have a tiny side table to keep track of what IP has voted for what card:
-vote_id (int)
-ts (timestamp)
-ip (str 15)
-card (int)
We could have this table autoprunning (auto deleting) everything older than X days. This would be a super simple way to prevent the too obvious undesired effect of a user multi voting a card on the spot.
A user can then log to the app with her Twitter account.
Doing so will enable 1 simple “Submit Advice Card” form with two fields:
- Title
- Body
We have all the other pieces from her Twitter account!
The logged in user can then submit this form. The data is checked for nastiness (sanitized). You must always check, validate, inspect, escape and clean the user provided data, even on a MVP. Specially on a MVP. After all you do have a responsibility with your users and the data they entrust you with. The ride may not be fun or useful, but it has to be safe for everyone. The data is checked and cleaned, then stored in the cards table with the ‘approved’ flag set to FALSE.
A human (me for now!) is supposed to read those cards and approve them if they are not spam/crap. This is not a very scalable process, but just MVP work. In the real world you would publish right away whatever you get, and if the first X votes are bad you disapprove this card and, maybe, ban the twitter user from ever posting again. You could also auto-approve anything coming from a user with more than n followers and auto reject anything from less ‘important’ accounts. Again this is an MVP so manual approval process that is!
User Interface
A picture is worth 1k words:
Simple, direct and to the point.
Technologies
For simplicity (and speed!) sake Im going to build a web-app, that is, you don’t install this just open the page in your mobile/desktop browser.
A pretty standard tech stack:
- PHP for the server side language
- MySQL as the database to host our 1 table
- JavasScript with Jquery as a client side language
- HTML/CSS with Bootstap for a simple and quick UI design.
Twitter API to ‘sign’ cards with a user account from twitter and to pull some user details from there.
We could have used Ionic Framework, which is a very good mobile-app oriented framework with a lot of functionality. This uses Angular JS as a client side language. It has the added advantage that it could be wrapper with Cordova into a native app.
For the time being lets roll with Bootstrap for the MVP. Ionic+Cordova could be a nice way to reach ‘native app’ status with a one size fits all solution if we want to walk that way.
Software Architecture
This is a MVP. Dont expect *any* serious architecture!
There is no versioning system, a simple ftp account and code editor will do. There is no big fancy framework; there is no lightweight framework! No model-view-controller design. Im not even going to use a templating system like Smarty for PHP. Application logic and presentation are going to have to suck it up and coexist on the same few files. There is no folder structure and Im not even going to use objects! Im going to have:
- header.php – html head and the DB connection stuff
- index.php – this is the main reading/browsing cards files. 80% happens here
- submit_card.php – the form to add advice cards to the app
- votes.php – this will just listen for up/down votes ajax calls
- bottom.php – the footer of the page
Dirty, ugly and QUICK. Perfect for a MVP. If the app gets some traction we will then go all fancy and rewrite everything properly.
What’s in a name?
“A rose by any other name would smell as sweet” said Shakespeare, but people have never smell our app and if we call it something ugly and hard to remember it’s not going to fly.
The whole thing is about ‘advice cards’. Im tempted to drop in keywords like ‘startup’ or ‘entrepreneur’, but even if the content is super focused to start with I want the name to have a wider scope. I could always have ‘boards’ or tags in the future, and cards can be in one or more boards! (entrepreneurship, motivational, finance, health, etc etc!).
As a rule of thumb ‘.com’ is KING. I usually would play around with the name until I manage to find an available .com that suits the project. (Like I did with my company: stality.com). For this 24 hours MVP Im just going to search for any available tld for ‘advicecards’. After a few searches, advicecards.me it is! Domain registered, after the nameservers propagate around the world things will start to work. Lets give it a few hours.
Distribution
Simple: once the MVP is up and running Im going to publish some advice cards myself. I will then ask some of the friendly and brilliant startup founders I know in Dublin to drop by with some advice. At that point I will tell people in the startup community (my target audience!) in Dublin about it.
I may also drop this post and the app to /r/startups and see what the Reddit community has to say about this.
It really is going to be giving the wheel a kick. You can kick it harder to go further, but unless the wheel (the project) has value in and on its own it will eventually stop. Since it is a small side project, I will give it a small kick and see what happens. If there is any merit in the idea+implementation it will gain momentum. If nobody likes it it will die, and that is ok. Remember, in the startup world: Fail Faster.
Time tracking
1:00am to 4:00am – Friday night/Saturday morning really. Four hours to do the thinking, app design, feature list, scope, write this blog post (which also doubles as a simple road-map) and register the domain. Went to sleep.
Saturday, 11:00am the domain is still ‘pending’. If it doesnt hurry up the MVP may be ready before the domain!
Half an hour to setup the hosting for the new domain, including MySQL user accounts and to create the simple mysql table.
Building the header/footer, backbone, connecting to DB from PHP. It was all too messy and I decided to factor all DB operations into one class of its own. That class handles now connection and all read/writes operations to the DB. It acts a a simple service module. I will then invoke methods from the rest of the app to read/write to DB. Since there are no data models, everything is going to be associative arrays (dictionaries). No built-in data masking / validation on fancy data models, but such is life for an MVP!
Building a bunch of methods in my DBAccess class to read/write cards, store votes, and keep track of the views.
Lunch break.
After a quick tech support chat the domain is now active! (advicecards.me ! )
Got bootstrap and font awesome linked from a cdn (content delivery network). I want this to work ultrafast.
Adding the new site to Google Analytics to see some traffic data and pretty charts.
Adding a few test advice cards to the table manually as seed data.
Creating a first index.php file for browsing cards, no design, just raw data coming from the DB.
Works! I can get random advice cards and browse them! After 2 minutes of playing with the UI I have this:
Making the ‘get random card’ button work.
21:15, After ten hours working on this Im taking a break for a walk…. stretching the legs, resting the eyes, back and wrist…
22:50 – back on the hot chair. Im going to finish the bottom of the advice cards. I have to display the number of views, number of likes, like button and the shareable link. Im thinking about displaying the views/likes as a % bar with green/orange. A bit more work but it will look better I think. Im also looking into Apache mod_rewrite to use clean cool URLs like “advicecards.me/ac/dr4f8E” instead of “advicecards.me/?ac=dr4f8E”.
We have entered Sunday, the clock is ticking.
00:52am – The bottom of the cards is done. mod_rewrite gave hassle as usual but now it is working as intended. The UI is very polished. Users can see views, likes and a share link, all super clean and clear. I dropped the % bar idea, it was not easy to understand for users. Im now going to add a simple link to tweet.
The entire page now weights 140K. I need to keep it short so it would load fast. It has to compete with native apps on mobile so it better moves ultra fast. Im using CDN for all I can. Here is a breakdown of weight: 33K for jQuery, 10K for Bootstrap js, 22K for bootstrap css, 10K for Google Analytics, 29K for the Twitter Js to build the share button (that is NOT the full API!)
2:02am – The voting button works. It turns from red to grey, increments the counter, changes the icon inside and ‘deactivates’ itself so you cannot click it twice. (and obviously send the vote to the server via jQuery call). Im now building the top menu with a few static pages / links. I may add a single page with comments, reusing something like Disqus for rapid deployment.
2:15am – Registered with Disqus and installed the comments in /comments.php, works like a charm. I like Disqus.
Created statics pages for statistics, about, scoreboard (best advice-givers and such). The data is not there, just a to-do of what I want to do. Adding the actual cards is now priority number one. I have to get up to speed with the Twitter API, ask for a API key and get cracking on that. Statistics / scoreboard can wait until later.
4:18am Logging off for tonight. The twitter API is giving problems, it’s more difficult than I expected it to be (or Im just too tired and cannot connect the dots). So there is that, the submit-a-card form will have to wait until tomorrow. After 15 hours of coding my productivity went down in the last hour. Time to fold it. I think Im 80% there.
Sunday 23:00 – Today was my girlfriend birthday, so no work during the day. I must admit it broke my ‘code run’ but it was a fun day and I needed the break after the full working week + killer Saturday. Now back on the hot chair!
00:37am – Registering for a twitter API key and working out the API calls I need. The Twitter API is a great pain to get working. You need to get your encoding nailed or you get an unfriendly ‘error’. Anyway after some work the twettegration is completed. I can pull a tweeter account’s details, name, handle and profile pic which is what I wanted, and a host of other data I dont need.
1:10am – I accidentally overwrote an index.php file. Some code was lost. This is what happens when you dont use a versioning system, dammit. It’s going to take an hour to redo that. *insert deep and motivational quote regarding fighting adversity here* *insert some random cursing*.
3:37am – Stupid fiasco fixed. Project Backup. Now onto the Submit a Card Form. Here is the biggie. The form only has 2 boxes: title and body. The user pic, name and handle are pulled from Twitter. I wanted to have a very polished form, so I put in the extra time to make it transparent to the user. If you are NOT signed in with twitter, you see a ‘sign with twitter button’. After you sign in with Twitter all you see is the simple form to create an advice card. You can navigate away, every time you come back the form is waiting for you there, transparently. One ‘page’ with two faces that is all. No in-the-middle pages to navigate.
The statistics and scoreboard pages are NOT finished, but thats what happens when you extend the original specifications while you are building it.
The next step would be building the content, the entrepreneurship advice that is! The plan is to invite, annoy, ask, suggest, beg and get free food and drinks for my good friends and brilliant entrepreneurs in the startup community in Dublin in order to have some of them kill a couple minutes here and there creating Advice Cards.
It is now Monday morning, 5:18am and the MVP for AdviceCards.me is ready.
From idea to MVP in exactly 24 hours of work: advicecards.me
~ The End ~
Comments? Feedback? My twitter (dont be shy, tell me something): @james_collado