<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>HARVEST Time Tracking and Invoicing Blog &#187; Code</title>
	<atom:link href="http://www.getharvest.com/blog/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.getharvest.com/blog</link>
	<description>Time is money.  Track it wisely.</description>
	<lastBuildDate>Fri, 03 Feb 2012 22:54:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Harvest&#8217;s New PDF Engine</title>
		<link>http://www.getharvest.com/blog/2011/11/harvests-new-pdf-engine/</link>
		<comments>http://www.getharvest.com/blog/2011/11/harvests-new-pdf-engine/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 20:57:58 +0000</pubDate>
		<dc:creator>Matt Lettini</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[New Features]]></category>
		<category><![CDATA[Online Invoicing]]></category>
		<category><![CDATA[Product Announcements]]></category>

		<guid isPermaLink="false">http://www.getharvest.com/blog/?p=7196</guid>
		<description><![CDATA[Update: We’ve now added a Snail-mail Friendly option to move the client address to the left for the envelope window. You can find this option, hide columns, and company logo in a new Appearance tab on the Invoices and Estimates configure pages. Today we’re announcing a significant upgrade to our invoicing and estimate platforms: a [...]]]></description>
			<content:encoded><![CDATA[<div style="padding:10px 15px;background:#eee;margin-bottom:20px"><strong>Update:</strong> <i>We’ve now added a Snail-mail Friendly option to move the client address to the left for the envelope window. You can find this option, hide columns, and company logo in a new Appearance tab on the Invoices and Estimates configure pages.</i></div>
<p>Today we’re announcing a significant upgrade to our invoicing and estimate platforms: <strong>a new rendering engine for the PDFs</strong> you send to your clients.</p>
<p>The new engine, which is built with <a href="http://code.google.com/p/wkhtmltopdf/" target="_blank">wkhtmltopdf</a> and <a href="http://liquidmarkup.org/" target="_blank">Liquid-based</a> templates, renders PDFs based on HTML and CSS. This is really exciting, because it allows us to use more flexible and simple code to create them. This means we can have the <strong>exact same code</strong> for invoice and estimate PDFs as we have in the app, which means they now have the same design and options.</p>
<h2>What&#8217;s New</h2>
<p>Implementing this allowed us to make some other features available on Invoices and Estimates:</p>
<ul>
<li>PDFs now have the page number at the bottom (and an option to translate).</li>
<li>You can now hide the type, quantity, and/or unit prices columns.</li>
<li>If you have a company logo uploaded, but still want your invoice to say &#8220;Invoice&#8221; on the page, you now have this option. You can turn it on where you uploaded your company logo in the configure section, and then change the title in translations (i.e. – you&#8217;d rather have &#8220;Tax Invoice&#8221;). The same applies for estimates.</li>
<li>We’ve added quick access to your Web Invoices and Web Estimates.</li>
<li>The new PDF engine is also able to render many more languages. See an example of some languages below:</li>
</ul>
<p><a href="http://www.getharvest.com/blog/wp-content/uploads/2011/11/harvest_international_invoice1.gif" target="_blank"><img src="http://www.getharvest.com/blog/wp-content/uploads/2011/11/harvest_international_invoice_21.gif" alt="" title="Harvest International Invoice" width="580" height="630" class="alignnone size-full wp-image-7282" /></a></p>
<p>The biggest win is that we now have the flexibility we need for adding features to our invoices and estimates in the future. Any change will automatically work in the app and as a PDF.</p>
<p>We hope this new PDF engine makes your Harvest experience even better.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getharvest.com/blog/2011/11/harvests-new-pdf-engine/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
		<item>
		<title>How Harvest Is Made, Part Two</title>
		<link>http://www.getharvest.com/blog/2011/10/how-harvest-is-made-part-two/</link>
		<comments>http://www.getharvest.com/blog/2011/10/how-harvest-is-made-part-two/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 16:46:13 +0000</pubDate>
		<dc:creator>Warwick Poole</dc:creator>
				<category><![CDATA[Behind-the-Scenes]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.getharvest.com/blog/?p=7088</guid>
		<description><![CDATA[Last week I wrote about how developers at Harvest deploy code and own the responsibility of keeping our software quality high. Today I&#8217;ll touch on the tools and process we currently use to collaborate, stay in touch with customers and glean feedback from our infrastructure. Developer collaboration Harvest developers are seldom in the same building, let alone [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I <a href="http://www.getharvest.com/blog/2011/10/how-harvest-is-made/">wrote</a> about how developers at Harvest deploy code and own the responsibility of keeping our software quality high. Today I&#8217;ll touch on the tools and process we currently use to collaborate, stay in touch with customers and glean feedback from our infrastructure.</p>
<h2>Developer collaboration</h2>
<p>Harvest developers are seldom in the same building, let alone the same state or country. <a href="http://www.getharvest.com/blog/2010/01/communicating-effectively-with-a-team-located-around-the-globe/">We work as a distributed team</a>, yet we collaborate extensively. All of our code is hosted with <a href="https://github.com/">GitHub</a>, which makes this collaboration simple. For those familiar with Git:</p>
<ul>
<li>Developers work in feature branches off the master branch, and master is always assumed to be deployable by anybody at any time.</li>
<li>Developers use <a href="http://help.github.com/send-pull-requests/">GitHub Pull Requests</a> all the time, and significant deployments are peer reviewed in this way prior to deployment.</li>
<li>A <a href="https://github.com/defunkt/cijoe">Continuous Integration</a> server constantly tests our code, and reports concerns to the team.</li>
<li>Development takes place locally, but we have multiple production-similar staging environments for testing and <a href="http://www.getharvest.com/blog/2011/10/quality-assured-since-2006/">QA</a>.</li>
</ul>
<h2>Infrastructure collaboration</h2>
<p>We strive to have no &#8216;walls&#8217; over which features or releases are thrown between team members. We share the responsibility of creating and supporting our software. As the &#8216;systems guy&#8217; at Harvest, it&#8217;s important to me that every developer has the ability to manage systems configuration. It&#8217;s also important that if problems arise, the team who responds to these problems is not a siloed operations team, but includes the developers who wrote the code which is running in production.</p>
<p>To this end, we use <a style="font-size: 13px; font-weight: normal;" href="http://www.opscode.com/chef/">Chef</a> to transform our systems configuration into a collaborative effort. Every component of our infrastructure is controlled by Chef. This means that technical team members can view and modify production configuration and roll out systems changes. The beauty of Chef is that everything is protected by Git version control and enhanced by the power of Ruby.<br />
<span id="more-7088"></span></p>
<h2>Customer interaction</h2>
<p>Harvest has a stellar <a style="font-size: 13px; font-weight: normal;" href="http://www.getharvest.com/about/meet-the-team#christopher-gamblee-wallendjack">support</a> <a style="font-size: 13px; font-weight: normal;" href="http://www.getharvest.com/about/meet-the-team#jonathan-lane">team</a> and our customers are generally blown away by their responsiveness and helpfulness. If a customer reports a bug, it will eventually <a style="font-size: 13px; font-weight: normal;" href="http://www.getharvest.com/blog/2011/01/delta-force-secret-to-legendary-customer-support/">end up in the hands of a developer</a> who will interact directly with the customer via Zendesk to resolve the issue. This direct customer contact further enhances a collaborative ideal of &#8216;no walls&#8217; between internal functions.</p>
<p>Harvest has taken this concept one step further with our <strong>Outreach</strong> program. Every customer account has a Harvest team member assigned as an Outreach contact, and nobody at Harvest is exempt. Periodically the system will prompt our customers to direct any questions they have about Harvest to their Outreach contact. This means that every Harvest team member interacts with, helps and understands customers daily. I love this program because it often forces me to delve deeply into our own product and <a href="http://en.wikipedia.org/wiki/Grok">grok</a> the Harvest customer experience. I feel responsible for our product success and customer satisfaction.</p>
<h2>Communication</h2>
<p>Communication is key to our culture of &#8220;Getting Things Done&#8221;, especially given the distributed nature of the Harvest team. We have various tools that we use for communication:</p>
<ul>
<li><strong><a href="http://coopapp.com/">Co-op</a></strong> is where the Harvest team communicates most of the day. In Co-op, we see what everyone is working on, have back and forth discussions and keep our company culture alive by sharing <a href="http://upload.wikimedia.org/wikipedia/commons/2/26/DavidHasselhoff1986.jpg">important</a> <a href="http://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Black_bear_large.jpg/330px-Black_bear_large.jpg">pictures</a> with each other.</li>
<li><strong><a href="http://hipchat.com">HipChat</a></strong> is used extensively for focused discussions and for getting notifications from our various tools. More on tools next.</li>
<li><strong><a href="http://www.skype.com/">Skype</a></strong> is how we hold our infrequent company townhall meetings and see each other&#8217;s beautiful faces.</li>
<li><strong><a href="http://www.google.com/tools/dlpage/res/talkvideo/hangouts/">Google Hangout</a></strong> is how some developers collaborate when pair programming or planning.</li>
<li><strong><a href="http://belugapods.com/">Beluga</a> </strong>is our <a href="http://en.wikipedia.org/wiki/Bat-Signal">bat signal</a>, to round up the team if needed.</li>
<li><strong><a href="http://www.zendesk.com/">Zendesk</a></strong> is used by the Harvest Support and <a href="http://www.getharvest.com/blog/2011/01/delta-force-secret-to-legendary-customer-support/">Delta Force</a> teams communicate with each other, and with our customers.</li>
<li><strong>Kaizen</strong>, an internal tool we developed, is our combined bug tracker, task manager and wiki. The entire team uses Kaizen to keep track of their tasks, assign tasks to one another, and to share knowledge.</li>
</ul>
<div>If you have never tested out <strong><a href="http://coopapp.com/">Co-op</a></strong>, you may like to check it out, particularly if you are already a Harvest customer. Co-op is a very useful communication platform and integrates with Harvest to show you what people on your team are working on. Here I am finishing up this blog post!</div>
<div><a href="http://coopapp.com"><img class="alignnone size-full wp-image-7215" title="Team Iridesco @ Harvest Co-op" src="http://www.getharvest.com/blog/wp-content/uploads/2011/10/Team-Iridesco-@-Harvest-Co-op-1.jpg" alt="" width="562" height="370" /></a></div>
<h2>Metrics and Tools</h2>
<p>Our applications and infrastructure are constantly changing and we rely on a diverse suite of tools for immediate feedback on how everything is performing.</p>
<ul>
<li><strong><a href="http://www.nagios.org/">Nagios</a></strong> monitors hundreds of services across our network and can notify us about problems via email, SMS and Hipchat.</li>
<li><strong><a href="https://www.cloudkick.com/">Cloudkick</a></strong> monitors our production servers from outside of our own networks for a second opinion on how things are performing.</li>
<li><strong><a href="http://pingdom.com/">Pingdom</a></strong> probes our applications from worldwide locations, providing performance data and alerting if there are issues.</li>
<li><strong><a href="http://newrelic.com/">New Relic</a></strong> provides insight into our application performance and a thorough understanding of the customer experience.</li>
<li><strong><a href="http://munin-monitoring.org/">Munin</a></strong> provides trending data on a vast array of metrics across our servers and applications.</li>
<li><strong><a href="http://help.github.com/post-receive-hooks/">GitHub hooks</a></strong> alert the team via HipChat when code is pushed to our repositories.</li>
<li><strong><a href="https://github.com/errbit/errbit">Errbit</a></strong> is the tool we use to capture exceptions and errors from applications for examination.</li>
<li><strong><a href="https://github.com/capistrano/capistrano">Capistrano</a></strong> alerts the team when applications are being deployed, and by whom, via Co-op and HipChat.</li>
</ul>
<p>Finally, we developed an internal tool called <strong>Lumberjack</strong> for mining production logs, and to understand application trends. Lumberjack is a Rails application which collects production logs via <a href="http://www.balabit.com/network-security/syslog-ng">syslog-ng</a>, stores data in <a href="http://mysql.com/">MySQL</a> and aggregated stats in <a href="http://www.mongodb.org/">MongoDB</a>, provides an interface for searching for specific events in logfiles and for charting ad-hoc data sets from the terabytes of log data our systems produce.</p>
<p>Here is an example of the charts a Harvest developer might be looking at at any time of the day:</p>
<p><img title="Metrics dashboards" src="http://www.getharvest.com/blog/wp-content/uploads/2011/10/dashboard.png" alt="" width="591" height="553" /></p>
<p>To sum up this exposé on how we work at Harvest, we share the responsibility for our customer experience. We move quickly but we collaborate. If you think these things sound exciting, we want you to <a href="http://www.getharvest.com/careers">join our team</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getharvest.com/blog/2011/10/how-harvest-is-made-part-two/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>How Harvest Is Made</title>
		<link>http://www.getharvest.com/blog/2011/10/how-harvest-is-made/</link>
		<comments>http://www.getharvest.com/blog/2011/10/how-harvest-is-made/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 16:15:54 +0000</pubDate>
		<dc:creator>Warwick Poole</dc:creator>
				<category><![CDATA[#status]]></category>
		<category><![CDATA[Behind-the-Scenes]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.getharvest.com/blog/?p=6956</guid>
		<description><![CDATA[You may not realize it, but almost every day there are improvements being made to Harvest while our customers are using it. Transparency is a core value here at Harvest, and I&#8217;d like to take you through a little of how we work behind the scenes, in a series of slightly technical posts. The new [...]]]></description>
			<content:encoded><![CDATA[<p>You may not realize it, but almost every day there are improvements being made to Harvest while our customers are using it. Transparency is a core value here at Harvest, and I&#8217;d like to take you through a little of how we work behind the scenes, in a series of slightly technical posts.</p>
<h2>The new Harvest Status page</h2>
<p>We&#8217;ve just released the beta version of a tool we will be using to promote transparency between Harvest operations and our customers: the new <strong><a href="http://harveststatus.com/">Harvest Status Page</a></strong>. Bookmark this tool to keep track of how Harvest is performing at any time.</p>
<h2>Balancing priorities</h2>
<p>I&#8217;ll briefly walk you through the software release process we follow, and in a subsequent post I&#8217;ll talk in more detail about the tools and methods we use. If you are familiar with <a href="http://en.wikipedia.org/wiki/DevOps">DevOps</a> and the concept of continuous deployment you&#8217;ll recognize these in our workflow.</p>
<p>Context determines your opinion on software deployment. Our customers naturally prioritize software stability and the addition of new features as quickly as possible. Customer acquisition, avoiding outages, using cool new technology, and striving for elegant robust code are a few other priorities held by my Harvest coworkers. A natural tension can exist between these priorities. How does Harvest balance this and retain our core focus on a good customer experience?</p>
<p>The simplest answer is: We take small steps quickly through collaboration.</p>
<h2>Release cycle and deployments</h2>
<p>What may be of most interest to customers is how we deploy new code to Harvest. Harvest changes almost every day, usually multiple times per day. In the time it took me to write this blog post, two different developers deployed five production releases of Harvest. Some might be concerned that a process like this promotes poor quality software. In reality, like many other companies, we have found that this iterative, constant change promotes high quality software, exposes and resolves unexpected issues quickly and allows a distributed team to work on different features concurrently. This means, in a nutshell, that when developers deem code ready to go to production, it goes to production. No artificial release schedule governs Harvest software rollout. There is also no manager whose job it is to ensure our software quality because that is the common responsibility of every person committing code at Harvest.</p>
<p>100% bug-free software is an unrealistic goal, but we strive for a bare minimum of issues by having structure in place to address problems quickly and efficiently:</p>
<ul>
<li>All significant code changes are peer reviewed before deployment. In the next post, I&#8217;ll talk about how we do this.</li>
<li>Every developer, designer and sysadmin at Harvest is able to (and does) deploy production code.</li>
<li>Mondays tend to be the busiest traffic day of the week at Harvest, so we rarely release big new features on Mondays. Same goes for late on Fridays, when bugs could linger over a weekend.</li>
<li>We have an internal QA process and production-similar staging environments, where we perform extensive testing when required.</li>
</ul>
<p>Some deployments warrant special care, such as releases which involve <a href="http://guides.rubyonrails.org/migrations.html">database migrations</a> changing large datasets. Certain database operations could produce a poor customer experience while deployments roll out. We have in the past, and will continue to deploy these releases at times of lowest customer impact, although Harvest&#8217;s global customer base reduces this window constantly. We have a maintenance mode which we can employ to take Harvest offline briefly if we need to.</p>
<p>If you have seen Harvest in maintenance mode and we didn&#8217;t notify you, our customer, prior to this deployment, we made a mistake and you can be sure that the team is working on the problem with urgency. It happens, but we think <a href="http://stats.pingdom.com/fo8jpjfpxbbr/123110">Harvest&#8217;s uptime</a> speaks to how infrequently this occurs.</p>
<p>Obviously, when it comes to software which has a third party review process, or runs on customer desktops, such as our <a href="http://www.getharvest.com/iphone-time-tracking">iPhone App</a> and the upcoming <a href="http://www.getharvest.com/mac">Mac App</a>, our process to roll out change is a little different to the core Harvest software that runs on our own servers.</p>
<p>If this post was too technical (or not technical enough), the one thing I hope you will take away from this is: Harvest software changes all the time in small increments. This concept of continuous deployment isn&#8217;t new or revolutionary and it may not work well for every company, but it allows us to strike a balance between stability and agility and keep forward momentum as we build a fairly complex suite of software.</p>
<p>Next week I&#8217;ll touch on the tools we use to review code, communicate as a team and keep on top of our infrastructure performance. If there is something you&#8217;d like me to specifically discuss, let me know in the comments or directly at <a href="mailto:warwick@getharvest.com">warwick@getharvest.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getharvest.com/blog/2011/10/how-harvest-is-made/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>OAuth 2.0 for the Harvest API, Plus a New SDK</title>
		<link>http://www.getharvest.com/blog/2011/10/oauth-2-0-for-the-harvest-api-plus-a-new-sdk/</link>
		<comments>http://www.getharvest.com/blog/2011/10/oauth-2-0-for-the-harvest-api-plus-a-new-sdk/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 19:42:04 +0000</pubDate>
		<dc:creator>Matt Beale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Product Announcements]]></category>

		<guid isPermaLink="false">http://www.getharvest.com/blog/?p=6927</guid>
		<description><![CDATA[At Harvest, we have a ton of pride in our smart and creative users. The ideas you bring to life on top of our Harvest API are always surprising and inspiring. OAuth 2.0 and our new JavaScript SDK are two great tools coming into beta today, and we can&#8217;t wait to see what you do [...]]]></description>
			<content:encoded><![CDATA[<p>At Harvest, we have a ton of pride in our smart and creative users. The ideas you bring to life on top of our Harvest API are always surprising and inspiring. OAuth 2.0 and our new JavaScript SDK are two great tools coming into beta today, and we can&#8217;t wait to see what you do with them!</p>
<p><strong>OAuth 2.0</strong> is an industry standard for API authorization, used by Facebook, Google and others. With OAuth 2.0 you won&#8217;t need to store the passwords of Harvest users to build an integration. That means more security for Harvest users, and less liability for integration authors. You can learn more about the specifics of OAuth 2.0 and our implementation in the updated <a href="http://www.getharvest.com/api/authentication-oauth2">API authentication docs</a>.</p>
<p>Our new <strong>JavaScript SDK</strong> is inspired by the ease of using Facebook Connect. Build integrations in pure client-side JavaScript, without thinking about Cross-domain requests and the details of OAuth 2.0. We&#8217;re already using it to add timers to our bug tracking and support tools. It&#8217;s a great way to bring Harvest to your other web apps.</p>
<ul>
<li>Add timers to your bug tracking software in only HTML and JavaScript.</li>
<li>Import open invoice amounts from Harvest without using server-side programming.</li>
<li>Pull reporting into JavaScript to generate custom visualizations and charts.</li>
</ul>
<p>Again, the best place to learn more is our new <a href="http://www.getharvest.com/api/jssdk-setup">JavaScript SDK documentation</a>.</p>
<h3>Getting Started</h3>
<p>If you&#8217;re a user or partner interested in working with our new API authentication and SDK options, make a request for OAuth credentials <a href="http://hrv.st/qAQNV6">on this form</a>, or drop us a line at <a href="mailto:api@getharvest.com">api@getharvest.com</a> for more information. While in beta, we&#8217;re going to issue credentials manually, and that form is the quickest way to get set up. If you&#8217;re not a code-slingin&#8217; type of person, just know that we&#8217;re giving developers the best tools available for the next generation of Harvest integrations.</p>
<p><em>Your comments and feedback about these API additions are important &#8211; please do get in touch!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.getharvest.com/blog/2011/10/oauth-2-0-for-the-harvest-api-plus-a-new-sdk/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Chosen, a Select Box Enhancement Plug-in for jQuery and Prototype</title>
		<link>http://www.getharvest.com/blog/2011/07/chosen-plug-in/</link>
		<comments>http://www.getharvest.com/blog/2011/07/chosen-plug-in/#comments</comments>
		<pubDate>Mon, 18 Jul 2011 15:36:35 +0000</pubDate>
		<dc:creator>Patrick Filler</dc:creator>
				<category><![CDATA[Behind-the-Scenes]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.getharvest.com/blog/?p=6600</guid>
		<description><![CDATA[In May, we released our improved detailed time reports, which included an improved interface for filtering the data included in your report. The filters are such a significant improvement over regular HTML select boxes that we&#8217;ve decided to share their code with the world. Today, we&#8217;re releasing them as a plug-in we&#8217;re calling Chosen (available [...]]]></description>
			<content:encoded><![CDATA[<p>In May, we released our <a href="http://www.getharvest.com/blog/2011/05/the-new-detailed-time-report/">improved detailed time reports</a>, which included an improved interface for filtering the data included in your report. The filters are such a significant improvement over regular HTML select boxes that we&#8217;ve decided to share their code with the world. Today, we&#8217;re releasing them as a plug-in we&#8217;re calling Chosen (available for jQuery <em>and </em>Prototype).</p>
<p>When building an HTML form, select boxes are often used to present a long list of options because they don&#8217;t take up a lot of space. Once a select element includes more than a handful of options, however, they become difficult for a user to navigate. Typing into a field doesn&#8217;t always work in an expected way (and many users aren&#8217;t even aware of this option) and scrolling through dozens or hundreds of choices is slow and tedious. These problems are especially magnified when the order of options isn&#8217;t immediately clear.</p>
<p><img class="alignnone size-full wp-image-6604" title="Chosen Selects" src="http://www.getharvest.com/blog/wp-content/uploads/2011/07/chosen-selects1.png" alt="" width="580" height="240" /></p>
<p><a href="http://harvesthq.github.com/chosen/">Chosen</a> aims to improve select boxes by adding search-based filtering. When a user clicks into a Chosen element, their cursor is placed in a search field. As the user types, options that don&#8217;t match the search terms are hidden, leaving only useful results behind. Users can select their choice just the same as a standard select element – highlight and click with the mouse or use the keyboard to navigate choices (up and down arrows change the highlight and enter selects).</p>
<p>Additionally, multiple select elements get an improved interface for displaying selected options. User-selected options are displayed as boxes at the top of the element and are always visible. They can be removed with a single click or using backspace.</p>
<h3><span id="more-6600"></span></h3>
<h3>Working With Chosen</h3>
<p>For developers, using Chosen is easy as can be. Chosen works by progressively enhancing a standard HTML select element, so no backend changes need to be made to handle passed data. Options selected via a Chosen field will change the (now hidden) HTML field and data will be passed on form submit in a normal fashion.</p>
<p>We wrote Chosen in <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>, which provides a much more readable syntax for writing javascript. Since CoffeeScript makes maintaining framework-independent, object oriented javascript much easier, we were able to use much of the same code as a base for both our jQuery and Prototype versions of the plug-in. When you grab the source for Chosen, you will also get the CoffeeScript version.</p>
<p>Want to give it a try? <a href="http://harvesthq.github.com/chosen/">Check out the project page</a> or <a href="https://github.com/harvesthq/chosen/">grab the source on github</a>.</p>
<h3>Open source, FTW</h3>
<p>Harvest relies on the contributions of the open source software community on a daily basis and we are excited to give back. We maintain a <a href="https://github.com/harvesthq/">number of open source projects</a> and plan to continue adding to that collection. We encourage you to clone, fork and contribute to Chosen or any of our projects.</p>
<p><em>If working with a great development team and sharing work with the world sounds like your cup of tea, why don&#8217;t you join us? <a href="http://www.getharvest.com/careers">We&#8217;re looking for a few great developers</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.getharvest.com/blog/2011/07/chosen-plug-in/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Harvest API: Your Data in Action</title>
		<link>http://www.getharvest.com/blog/2011/04/harvest-api-your-data-in-action/</link>
		<comments>http://www.getharvest.com/blog/2011/04/harvest-api-your-data-in-action/#comments</comments>
		<pubDate>Fri, 08 Apr 2011 15:30:11 +0000</pubDate>
		<dc:creator>Barry Hess</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Success Stories]]></category>
		<category><![CDATA[Time Tracking]]></category>

		<guid isPermaLink="false">http://www.getharvest.com/blog/?p=5418</guid>
		<description><![CDATA[Recently Chris Wilson from Search Mojo has been writing to us with questions about the Harvest API. Through the pleasant conversations surrounding Chris&#8217;s questions, we learned that Search Mojo was using the API to create an inspiring dashboard. Here&#8217;s how Chris describes it: We created a profitability dashboard to total up which of our clients we [...]]]></description>
			<content:encoded><![CDATA[<p>Recently <a href="http://www.search-mojo.com/about/staff_cw.php">Chris Wilson</a> from <a href="http://www.search-mojo.com/">Search Mojo</a> has been writing to us with questions about the <a href="http://www.getharvest.com/api">Harvest API</a>. Through the pleasant conversations surrounding Chris&#8217;s questions, we learned that Search Mojo was using the API to create an inspiring dashboard. Here&#8217;s how Chris describes it:</p>
<blockquote><p>We created a profitability dashboard to total up which of our clients we are profitable on based on hours, hourly rates and expenses over quarter and month ranges. We then created a score based on that. Your API tool supplied everything and it’s officially up and running on the tvs in the office.</p></blockquote>
<p><img class="alignnone size-full wp-image-5431" title="API Dashboard" src="http://www.getharvest.com/blog/wp-content/uploads/2011/04/api-dash-1.jpg" alt="" width="580" height="387" /><br />
<span id="more-5418"></span></p>
<p>It turns out that they have set up two different dashboards, to keep the clients displayed relevant to the employees who can see the television.</p>
<blockquote><p>At the top left corner is a score based on profit and retention from quarter to quarter by using Harvest and looking at last time stamps and active/inactive projects. The right hand side queries our other database to show vacation and sick leave.</p>
<p>Now onto the bulk of the system. It lists every client and project (column 1 and column 2 respectively). The next bars (one for monthly and one for quarterly) use Google charts to display graphs which include (hourly rate X each employee) + expense cost. We have 2 dashboards setup for our 2 teams in the office so it only lists their clients. This helps us to review our processes to determine which clients are too demanding and which we need to focus on more. As each employee spends more time the chart grows closer to 100% which means we are using 100% of the budget (or the amount the client is paying us). It turns yellow when between 80-100% and red when above 100% (meaning we are over budget and have allocated too much time), otherwise it’ll show green.</p></blockquote>
<p><img class="alignnone size-full wp-image-5432" title="API Dashboard" src="http://www.getharvest.com/blog/wp-content/uploads/2011/04/api-dash-2.jpg" alt="" width="580" height="777" /></p>
<p>Thank you Chris and the whole Search Mojo team for sharing how you use the Harvest API. Those dashboards are an awesome way to utilize your Harvest data to keep tabs on profitability.</p>
<p>If you have an interesting use of the Harvest API that you would like to share, please let us know!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getharvest.com/blog/2011/04/harvest-api-your-data-in-action/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Thebes: A New, Minimal Sphinx Gem for Rails</title>
		<link>http://www.getharvest.com/blog/2011/03/thebes-a-new-minimal-sphinx-gem-for-rails/</link>
		<comments>http://www.getharvest.com/blog/2011/03/thebes-a-new-minimal-sphinx-gem-for-rails/#comments</comments>
		<pubDate>Mon, 07 Mar 2011 19:44:24 +0000</pubDate>
		<dc:creator>Matt Beale</dc:creator>
				<category><![CDATA[Behind-the-Scenes]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Product Announcements]]></category>

		<guid isPermaLink="false">http://www.getharvest.com/blog/?p=4935</guid>
		<description><![CDATA[Recently, we&#8217;ve been sharing a lot of technical lessons from building our new Help Center and in upgrading Harvest to Rails 3. The gem Harvest is releasing today, Thebes, is at the intersection of both projects. Thebes is a wrapper around Sphinx, the search engine we use on most of our projects. Thebes differs from [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, we&#8217;ve been sharing a lot of technical lessons from building our <a href="http://www.getharvest.com/blog/2011/01/help-2-0-the-new-harvest-support/">new Help Center</a> and in <a href="http://www.getharvest.com/blog/2011/01/harvest-is-running-rails-3/">upgrading Harvest to Rails 3</a>. The gem Harvest is releasing today, <a href="https://github.com/harvesthq/thebes">Thebes</a>, is at the intersection of both projects.</p>
<p>Thebes is a wrapper around <a href="http://sphinxsearch.com/">Sphinx</a>, the search engine we use on most of our projects. Thebes differs from other solutions by staying as far away from your Rails code as possible. Instead of hiding the Sphinx configuration file behind a domain-specific language, this library assumes you will write Sphinx config files by hand. In Thebes, you edit an ERB template of your Sphinx configuration and populate it with variables at generation time. For developers needing the most flexible or fastest solution possible, this is a great way to work with Sphinx.<br />
<span id="more-4935"></span></p>
<h3>4 Benefits of Using Thebes</h3>
<p>Thebes has a unique set of priorities compared to most Sphinx solutions. We&#8217;re less concerned with making Sphinx easy, and more concerned with giving you the most flexibility possible. That gives Thebes a powerful feature set.</p>
<ul>
<li><strong>Thebes can use SphinxQL.</strong> <a href="http://sphinxsearch.com/docs/manual-0.9.9.html#sphinxql">SphinxQL</a> is the next-generation language for querying and managing Sphinx indexes. The language is mostly MySQL compatible, and the wrapper in Thebes is a very thin layer on top of the Ruby <a href="https://github.com/brianmario/mysql2">Mysql2 gem</a>. SphinxQL still has some serious bugs, but is already faster than Sphinx&#8217;s native protocol and being used for the next-generation features of Sphinx.</li>
<li><strong>Thebes can generate multiple Sphinx config files</strong>,  and for multiple configurations. If you specify multiple files and configurations in <code>config/sphinx.yml</code>, your generated Sphinx config files can have unique settings. For devs who need to cluster Sphinx or have specific architecture needs, this is a great solution. The servers used by a given app instance are configured separately in <code>config/sphinx_server.yml</code>.</li>
<li><strong>Thebes makes it explicit how you interact with Sphinx and your data store.</strong> If you need to optimize searches for speed, you&#8217;ll want to do things differently than any of the other Rails-Sphinx integrations do them. Thebes doesn&#8217;t provide any code for fetching results from your datastore, so you can choose how it should be done.</li>
<li><strong>Thebes is built on Rails 3.</strong> Thebes is ready for you to use with Rails 3 <em>today</em>. We had used <a href="http://freelancing-god.github.com/ts/en/">ThinkingSphinx</a> for most projects before creating Thebes, but the project has a lot of complexity and ties to ActiveRecord 2.x code. Consequently, the porting of TS to Rails 3 isn&#8217;t turning out to be the smooth road we hoped for.</li>
</ul>
<p>We&#8217;ve migrated several codebases away from ThinkingSphinx and onto Thebes internally and we&#8217;re looking forward to working with it more in the future. It&#8217;s worth remembering that Thebes is designed for minimal intrusion into your Rails code, and it won&#8217;t be the right solution for every app. Combined with Sphinx, we find it to be a great tool, and hope you do to.</p>
<p>We&#8217;re releasing Thebes as an open source solution on our Github account:</p>
<ul>
<li><a href="https://github.com/harvesthq/thebes">https://github.com/harvesthq/thebes</a></li>
</ul>
<p>If you&#8217;re somebody that&#8217;s excited to roll up their sleeves to build new tools, be sure to check out our <a href="http://www.getharvest.com/careers">Harvest Careers</a> page. We’re hiring smart people and would love to talk to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getharvest.com/blog/2011/03/thebes-a-new-minimal-sphinx-gem-for-rails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Easy Rails Asset Handling with HTML5 &amp; S3</title>
		<link>http://www.getharvest.com/blog/2011/02/easy-rails-asset-handling-with-html5-and-s3/</link>
		<comments>http://www.getharvest.com/blog/2011/02/easy-rails-asset-handling-with-html5-and-s3/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 14:00:53 +0000</pubDate>
		<dc:creator>Matt Beale</dc:creator>
				<category><![CDATA[Behind-the-Scenes]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.getharvest.com/blog/?p=4644</guid>
		<description><![CDATA[While working on the new Harvest Help Center, our team had a chance to look at some common web-app issues with fresh eyes. Asset upload is almost certainly a requirement of any modern document-based web site, usually for images or general downloadable assets. There are a few pre-built Rails plugins that address asset upload (most [...]]]></description>
			<content:encoded><![CDATA[<p>While working on the <a href="http://www.getharvest.com/help">new Harvest Help Center</a>, our team had a chance to look at some common web-app issues with fresh eyes. Asset upload is almost certainly a requirement of any modern document-based web site, usually for images or general downloadable assets. There are a few pre-built Rails plugins that address asset upload (most notably <a href="https://github.com/thoughtbot/paperclip">paperclip</a>), but they require database tables and are often designed with server-side storage in mind.  Having a robust server-side solution for assets provides many benefits, but we found they were unnecessary for the simple workflow we had in mind.</p>
<p>We worked at finding something simpler and came up smiling.</p>
<p><span id="more-4644"></span></p>
<h2>Why the traditional model doesn&#8217;t fit</h2>
<p>Harvest uses <a href="http://textile.thresholdstate.com/">Textile</a> to format most of our documents. In Textile, an image is specified as follows:</p>
<pre style="background:#eee;padding:10px;margin:0 0 15px">!http://www.getharvest.com/images/this_image.jpg(alt text here)!</pre>
<p>And linking to an asset is similar:</p>
<pre style="background:#eee;padding:10px;margin:0 0 15px">"Download a PDF":http://www.getharvest.com/assets/document.pdf</pre>
<p>In both these situations the asset URL is written into the document itself. Even if we track the assets in a database, little can be done to modify the assets without breaking existing URLs. For instance, a plan to start with server-side image uploads then later move to a <a href="http://en.wikipedia.org/wiki/Content_delivery_network">content delivery network</a>, commonly called a CDN, isn&#8217;t an option. With the URLs in our documents, we would need to update every document before the CDN could benefit us.</p>
<p>Speaking of CDNs, we knew we wanted to be using one from the start.  The added infrastructure needed for server-side asset storage would never be useful to us.</p>
<p>Once we recognized storing assets on our server and tracking them in a database offered little to our particular requirements, it was time to find a simpler solution.</p>
<p>We came up with a short list of requirements for simple asset handling:</p>
<ul>
<li>No database tables.</li>
<li>Use Amazon S3 for storage, and support using Amazon CloudFront for a CDN.</li>
<li>Use HTML5 for asynchronous uploading.</li>
</ul>
<p>The solution we arrived at uses the excellent <a href="http://www.plupload.com/">Plupload</a>, the <a href="http://amazon.rubyforge.org/">AWS::S3</a> gem and some simple Rails logic.</p>
<h2>Configuring AWS::S3 and Rails</h2>
<p>First, <a href="https://aws.amazon.com/s3/">register for an Amazon S3 account</a> if you don&#8217;t already have one. Then use an S3 client like <a href="http://s3hub.com/">S3Hub</a> to access your account and create buckets for your project:</p>
<ul>
<li>project-development</li>
<li>project-staging</li>
<li>project-production</li>
</ul>
<p>Add the <a href="http://amazon.rubyforge.org/">AWS::S3 Gem</a> to your Gemfile:</p>
<pre style="background:#eee;padding:10px;margin:0 0 15px">gem 'aws-s3', :require =&gt; 'aws/s3'</pre>
<p>Run <code>bundle install</code> and we should be ready to start using S3. Configure AWS::S3 by adding a YAML file and initializer script. In <code>config/initializers/s3_credentials.rb</code>:</p>
<pre style="background:#eee;padding:10px;margin:0 0 15px"># Load AWS::S3 configuration values
#
S3_CREDENTIALS = \
  YAML.load_file(File.join(Rails.root, 'config/s3_credentials.yml'))[Rails.env]

# Set the AWS::S3 configuration
#
AWS::S3::Base.establish_connection! S3_CREDENTIALS['connection']</pre>
<p>In the actual configuration file <code>config/s3_credentials.yml</code>:</p>
<pre style="background:#eee;padding:10px;margin:0 0 15px">development: &amp;defaults
  connection:
    :access_key_id: AAAAAA_your-key-here
    :secret_access_key: 4rpsi235js_your-secret-here
    :use_ssl: true
    # :persistent: true
  bucket: project-development
  max_file_size: 10485760
  acl: public-read

test:
  &lt;&lt;: *defaults
  bucket: project-development

staging:
  &lt;&lt;: *defaults
  bucket: project-staging

production:
  &lt;&lt;: *defaults
  # prefix is optional. This is where you would put your CloudFront Domain
  # Name or your CloudFront CNAME if you have one configured.
  prefix: "http://project.s3.mydomain.com"
  bucket: project</pre>
<p>Now you can interact with Amazon S3 from Rails.</p>
<h2>Building a controller to handle uploads</h2>
<p>For this simple uploader, we have a limited set of requirements for the server-side logic. Uploads should be routed to an action where the asset is pushed to S3, and a URL is returned to the uploading request. Start by creating a controller:</p>
<pre style="background:#eee;padding:10px;margin:0 0 15px">script/rails g controller uploads</pre>
<p>And be sure your new controller is in <code>config/routes.rb</code></p>
<pre style="background:#eee;padding:10px;margin:0 0 15px">resources :uploads</pre>
<p>The AWS::S3 upload code can go into the create action:</p>
<pre style="background:#eee;padding:10px;margin:0 0 15px">class UploadsController &lt; ApplicationController
  # Maybe you have some filters, like :authenticate_admin!

  def create
    s3 = AWS::S3::S3Object.store \
      params[:file].original_filename,
      params[:file].tempfile,
      S3_CREDENTIALS['bucket'],
      :content_type =&gt; params[:file].content_type,
      :access =&gt; :public_read
    render :json =&gt; {
      :url =&gt; public_s3_url(params[:file].original_filename)
    }
  end

private

  def public_s3_url filename
    if S3_CREDENTIALS['prefix'].present?
      "#{S3_CREDENTIALS['prefix']}/#{filename}"
    else
      request.protocol +
      AWS::S3::Base.connections['AWS::S3::Base'].options[:server] +
      "/#{S3_CREDENTIALS['bucket']}/#{filename}"
    end
  end

end</pre>
<p>The method <code>public_s3_url</code> will add a prefix defined in <code>config/s3_credentials.yml</code> allowing us to use a CDN for uploaded assets instead of the URL automatically generated for S3 assets by AWS::S3.</p>
<h2>HTML5 uploads with Plupload</h2>
<p><a href="http://www.plupload.com/">Plupload</a> is a great swiss-army knife for uploading assets. It intelligently handles falling back from one upload strategy to another if one is unsupported by a browser. For our own internal tools at Harvest, we only worry about modern browsers that support HTML5 uploads.  This simplifies our code.</p>
<p>To use Plupload, you first need a container DOM element for the upload system:</p>
<pre style="background:#eee;padding:10px;margin:0 0 15px">&lt;div style="margin: 2em 0;" id="upload_container"&gt;
  &lt;div id="filelist"&gt;&lt;/div&gt;
  &lt;a id="pickfiles" href="#"&gt;[Select files]&lt;/a&gt;
  &lt;a id="uploadfiles" href="#"&gt;[Upload files]&lt;/a&gt;
&lt;/div&gt;</pre>
<p>Plupload needs to be told how to accomplish a few tasks:</p>
<ul>
<li>What the URL for processing uploads is.</li>
<li>How to show selected files before upload.</li>
<li>How to show progress during upload.</li>
<li>Most importantly, <strong>how to parse the returned JSON from our Rails logic and display that URL.</strong></li>
</ul>
<p>In your <code>application.js</code>, create a new instance of <code>plupload.Uploader</code> if the container element is present.  We&#8217;re using jQuery as well as Plupload in this example:</p>
<pre style="background:#eee;padding:10px;margin:0 0 15px">$(function() {
  if( $("#filelist").length ){
    var uploader = new plupload.Uploader({
      runtimes : 'html5',
      browse_button : 'pickfiles',
      max_file_size : '10mb',
      url : '/uploads',
      multiple_queues : true
    });

    // When the user selects files for upload, show them on the page
    //
    uploader.bind('FilesAdded', function(up, files) {
      $.each(files, function(i, file) {
        $('#filelist').append(
          '&lt;div id="' + file.id + '"&gt;' +
          file.name + ' (' + plupload.formatSize(file.size) + ') &lt;b&gt;&lt;/b&gt;' +
          '&lt;/div&gt;'
        );
      });
    });

    // When the file is uploaded, parse the response JSON and show that URL.
    //
    uploader.bind('FileUploaded', function(up, file, response){
      var url = JSON.parse( response.response ).url;
      $("#"+file.id).addClass("uploaded").html( url );
    });

    // Show upload progress over time- with HTML5 doesn't
    // really show values besides 0 and 100.
    //
    uploader.bind('UploadProgress', function(up, file) {
      $('#' + file.id + " b").html(file.percent + "%");
    });

    // When the upload button is clicked, upload!
    //
    $('#uploadfiles').click(function(e) {
      uploader.start();
      e.preventDefault();
    });

    uploader.init();
  }
});</pre>
<p>To upload an asset, the user can click &#8220;[Select files]&#8221; or simply drag files onto that link. They can choose one file, or several. Next they click &#8220;[Upload files]&#8221; and wait for the assets to be sent to S3. After the assets are uploaded, they copy-paste the resulting URLs into Textile markup. That&#8217;s a simple flow with less maintenance or complexity than many other solutions, and provides all the functionality we need for asset handling.</p>
<p>This solution isn&#8217;t ideal for all apps in all situations, but for many of our own internal projects at Harvest it&#8217;s a simple and powerful strategy. We hope you find it useful!</p>
<p>If you think solving common problems in new and imaginative ways is something you do well, be sure to check out our <a href="http://www.getharvest.com/careers">Harvest Careers</a> page, we&#8217;re hiring smart people and would love to talk to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getharvest.com/blog/2011/02/easy-rails-asset-handling-with-html5-and-s3/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>A New Rails 3 Positioning Library: RankedModel</title>
		<link>http://www.getharvest.com/blog/2011/02/a-new-rails-positioning-library-rankedmodel/</link>
		<comments>http://www.getharvest.com/blog/2011/02/a-new-rails-positioning-library-rankedmodel/#comments</comments>
		<pubDate>Tue, 08 Feb 2011 16:44:48 +0000</pubDate>
		<dc:creator>Matt Beale</dc:creator>
				<category><![CDATA[Behind-the-Scenes]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.getharvest.com/blog/?p=4573</guid>
		<description><![CDATA[When we started work on the new Harvest Help Center, it was with the fresh perspective of our recent Rails 3 upgrades. We looked for a simple row sorting solution, but the traditional plugin ActsAsList is showing it&#8217;s age with old ActiveRecord conventions and naive logic. Rising to the challenge, we rolled up our sleeves and built our [...]]]></description>
			<content:encoded><![CDATA[<p>When we started work on the <a href="http://www.getharvest.com/help">new Harvest Help Center</a>, it was with the fresh perspective of our <a href="http://www.getharvest.com/blog/2011/01/harvest-is-running-rails-3/">recent Rails 3 upgrades</a>. We looked for a simple row sorting solution, but the traditional plugin <a href="https://github.com/rails/acts_as_list">ActsAsList</a> is showing it&#8217;s age with old ActiveRecord conventions and naive logic. Rising to the challenge, we rolled up our sleeves and built our own ordering solution, that we have dubbed <a href="https://github.com/harvesthq/ranked-model">RankedModel</a>.</p>
<h2>ActsAsList</h2>
<p>ActsAsList has been around for a long time. I can&#8217;t recall what release of Rails it came out with, but it was well before Rails 1.0. The fact that it has remained the default solution for row ordering so long speaks to how simple the problem of row sorting is. There isn&#8217;t anything too crazy going on in this code:</p>
<ul>
<li>Keep the order of items in an integer column.</li>
<li>When fetching a set of items, default the order statement to sort by that column.</li>
<li>When we move an item to a new position, assign all the other items to their new positions.</li>
</ul>
<p>But there were a few downsides to using ActsAsList:</p>
<ul>
<li>The code does not use <a href="https://github.com/rails/arel">ARel</a>. This means we can&#8217;t chain sorted item collections into complex ARel queries.</li>
<li>If one item is moved, many of the other items are adjusted to compensate for the movement. Many rows in MySQL can be updated by one row&#8217;s reassignment.</li>
</ul>
<p>What&#8217;s a modern Rails developer to do?</p>
<p><span id="more-4573"></span></p>
<h2>Enter RankedModel</h2>
<p>RankedModel is an ActsAsList replacement developed by the crew here at Harvest, written with ARel from the ground up and using an optimized position storage mechanism. It&#8217;s tested with Rspec. Check it out on Github:</p>
<p><a href="https://github.com/harvesthq/ranked-model">https://github.com/harvesthq/ranked-model</a></p>
<p>RankedModel stores rank as any number in a range of 0 to 65534. When you assign a new position to an item, it is assigned a rank between it&#8217;s new neighbors. This means we update one row, not several. Let&#8217;s look at an example involving ducks:</p>
<ol>
<li>Waddly (ranked 13106)</li>
<li>Quacky (ranked 26212)</li>
<li>Webby (ranked 39318)</li>
<li>Beaky (ranked 52424)</li>
</ol>
<p>If we move Beaky to position #2, we need not adjust the ranks of other items to maintain the new order:</p>
<ol>
<li>Waddly (ranked 13106)</li>
<li>Beaky (ranked 19659)</li>
<li>Quacky (ranked 26212)</li>
<li>Webby (ranked 39318)</li>
</ol>
<p>When a newly positioned row is assigned a conflicting rank, the library will redistribute the rank values evenly. The logic is made simpler by a nice abstraction layer that allows developers to focus on the sort logic of a given rank scope and instance.</p>
<p>We think RankedModel is a great, modern solution for a simple problem developers need to deal with often, and we&#8217;ve decided to share it with the community-at-large as an open source solution. We sure hope it&#8217;s as helpful for you as it has been for us.</p>
<p><!-- p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 11.0px 'Lucida Grande'; color: #141414} --><em>Want to work on projects like the Ranked Model Gem? We&#8217;re <a href="http://www.getharvest.com/careers">hiring Rails Developers</a> at all skill levels.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.getharvest.com/blog/2011/02/a-new-rails-positioning-library-rankedmodel/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Delta Force: The Secret to Legendary Customer Support</title>
		<link>http://www.getharvest.com/blog/2011/01/delta-force-secret-to-legendary-customer-support/</link>
		<comments>http://www.getharvest.com/blog/2011/01/delta-force-secret-to-legendary-customer-support/#comments</comments>
		<pubDate>Fri, 28 Jan 2011 14:00:07 +0000</pubDate>
		<dc:creator>Barry Hess</dc:creator>
				<category><![CDATA[Behind-the-Scenes]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.getharvest.com/blog/?p=4393</guid>
		<description><![CDATA[The pride of Harvest is our customer support. We believe the success of Harvest begins and ends with you, our customers. We&#8217;re very excited about our new Harvest Support site, and we have an outstanding frontline support team that talks to 100&#8242;s of customers every week. Many questions are quick to answer, but some require more technical [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-4540 alignright" title="badge" src="http://www.getharvest.com/blog/wp-content/uploads/2011/01/badge.jpg" alt="" width="189" height="186" /></p>
<p>The pride of Harvest is our customer support. We believe the success of Harvest begins and ends with you, our customers. We&#8217;re very excited about our new <a href="http://www.getharvest.com/blog/2011/01/help-2-0-the-new-harvest-support/">Harvest Support</a> site, and we have an outstanding frontline support team that talks to 100&#8242;s of customers every week. Many questions are quick to answer, but some require more technical knowledge.</p>
<p>Since last summer, we&#8217;ve been experimenting with a tiered rotation of team members into bugfix roles: the Fireteam and Delta Force. This system is great for small teams with stretched technical resources, and allows for fast support response without having a bloated support staff.</p>
<p><span id="more-4393"></span></p>
<h2>Fireteam: Ready-Team-Fire-Assist</h2>
<blockquote><p>The concept of the <a href="http://en.wikipedia.org/wiki/Fireteam">fireteam</a> is based on the need for tactical flexibility in infantry operations. A fireteam is capable of autonomous operations as part of a larger unit.</p></blockquote>
<p>A bug discovered by a customer will go through a couple levels of support before arriving in the hands of a developer. After the initial support contact, the ticket is handed to a Fireteam member. This role is shared by two people at Harvest. A Fireteam member has a bit more technical knowledge of Harvest&#8217;s features. Often the Fireteam can answer a customer&#8217;s question without getting the development team involved. Sometimes the Fireteam can even make a small change to correct a bug.</p>
<h2>Classified: Delta Force Two-Soldier Squadron</h2>
<p>If a problem requires more investigation it is passed to an elite team of code warriors &#8211; Delta Force. Sometimes the Fireteam consults with Delta Force to get answers to detailed questions. More often than not a problem that has gotten this far will require more investigation by Delta Force. The ticket will be assigned to a Delta Force team member who will research what is amiss.</p>
<p>Delta Force is comprised of two developers: a primary and a backup. The primary will typically spend his entire week investigating and fixing bugs. The secondary is there to support the primary team member, picking up the slack on a busy week and reviewing fixes coded by the primary team member. Our four developers rotate through these roles one week at a time. The secondary is the previous week&#8217;s primary, which helps with knowledge transfer for ongoing problems.</p>
<p>Delta Force was brought about to protect the rest of the development team from the daily issues that arise in Harvest. These developers can focus on new features, allowing faster and less distracted development. The whole development team is available if Delta Force has questions. In the unfortunate event of major systems problems, the entire development team rallies.</p>
<h2>Weapons of Choice</h2>
<p>Our tools are <a href="http://www.zendesk.com/">Zendesk</a>, an internal task management app called Kaizen, <a href="https://github.com/harvesthq/errbit">Errbit</a> for automated bug notification, chat and email. We are always looking for ways to improve our process. For instance, our <a href="http://www.getharvest.com/careers/junior-rails-developer">new junior developer</a> will be heavily involved in the support process. Kaizen, our custom issue tracking and collaboration tool, is more appropriate for feature development than bug tracking.  We are looking to improve our bug and issues tracking. So far we are considering <a href="https://github.com/blog/411-github-issue-tracker">GitHub Issues</a>, <a title="Redmine" href="http://www.redmine.org/">Redmine</a> or a self-built tool. For emergencies during off hours, we have an open line of communication on <a href="http://www.groupme.com">GroupMe</a>&#8216;s group texting service. This allows available team members to spring into action at a moment&#8217;s notice, and is especially useful when team members are not checking email.</p>
<p>To those of you running software companies: What tools and processes have you found successful for handling support and tracking issues? How do you carve out focused development time while also providing responsive support to your customers? We&#8217;d love to hear your ideas!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getharvest.com/blog/2011/01/delta-force-secret-to-legendary-customer-support/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

