<?xml version='1.0' encoding='utf-8' ?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Social Memory Complex: development</title>
<link href="https://www.socialmemorycomplex.net/tags/development/feed.xml" rel="self" />
<link href="https://www.socialmemorycomplex.net/tags/development/" />
<updated>2026-05-24T21:17:06+00:00</updated>
<id>https://www.socialmemorycomplex.net/tags/development/</id>
<entry>
  <title>Business and Legal Pitfalls in Web Development</title>
  <link href="http://socialmemorycomplex.net/2010/11/05/business-and-legal-pitfalls-in-web-development/" />
  <updated>2010-11-05T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/11/05/business-and-legal-pitfalls-in-web-development/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>Last month I attended <a href="https://wordcamprichmond.org">Wordcamp Richmond</a> and saw a great presentation by <a href="https://twitter.com/gatewood5000">Christopher Gatewood</a> entitled <a href="https://wordcamprichmond.org/conferences/wordcamp-rva-2010/#Gatewood">The Seven Business Pitfalls for Wordpress and Web Professionals</a>. The talk was informative enough that I took copious notes, and I’m publishing them in the hopes that others will benefit. I’ve since gotten Chris to help me draft some agreements and can tell you he’s a great resource for this kind of stuff.</p>

<h3 id="the-seven-pitfalls">The Seven Pitfalls</h3>
<ol>
  <li>Half + Half = Half
    <ul>
      <li>Getting half of the money up front doesn’t track with the work</li>
      <li>Always get money up front</li>
      <li>Progress payments that track with feature deliveries</li>
    </ul>
  </li>
  <li>Scope Creep
    <ul>
      <li>Bullet point list of scope</li>
      <li>Define client and dev responsibilities
        <ul>
          <li>If you don’t know what’s IN scope, you don’t know what’s OUT of scope</li>
        </ul>
      </li>
      <li>No silent accommodations
        <ul>
          <li>Don’t let out of scope work creep in without speaking up</li>
          <li>Even if you don’t charge, let them know it’s out of scope</li>
          <li>“Agreement or approval in writing, for which email will suffice”</li>
          <li>Inaccurate contracts or agreements that don’t reflect the way you work can be worse than nothing</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Subcontractor Cash Squeeze
    <ul>
      <li>Decide when payment takes place up front</li>
      <li>Place this decision in agreement</li>
      <li>Helps to decide not just timing but whether the payment occurs <em>at all</em></li>
    </ul>
  </li>
  <li>Stay in range
    <ul>
      <li>Incremental approvals</li>
      <li>Wait for an email</li>
      <li>Who has authority to sign off? Get 1 or 2 people whom you can copy on all communications.</li>
      <li>Due dates suck, make sure <em>delays are not your problem</em></li>
      <li>Iterative dates stemming from previous iterations to prevent hard-coded calendar dates</li>
    </ul>
  </li>
  <li>No free launch
    <ul>
      <li>Control and Rights
        <ul>
          <li>don’t charge for delivery</li>
          <li>make iterative releases to staging that YOU control</li>
          <li>hosting not transferred to them until final payment</li>
          <li>IP does not transfer until final payment (DMCA)
            <ul>
              <li>Your work includes a licensing component, be clear about it</li>
              <li>Client doesn’t “own” it until you’re paid</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>After delivery, are you a priority?
        <ul>
          <li>Late fees</li>
          <li>Interest charges</li>
          <li>Attorney fees</li>
          <li>Costs of collection</li>
          <li>You can always use the carrot of waiving the fees</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Work in Progress
    <ul>
      <li>It’s expensive</li>
      <li>Invoice the silence
        <ul>
          <li>claim the right to invoice without getting communication</li>
          <li>define the calculation of what would be owed</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Failure to Flex
    <ul>
      <li>Give recalcitrant or hard-up client options
        <ul>
          <li>Shrink scope</li>
          <li>Pay in stages over time</li>
        </ul>
      </li>
      <li>Always good to work with client when possible to deliver and get paid</li>
      <li>Get more money on the front end for risky, small clients</li>
      <li>You need to consider that you <em>may not get paid</em> so try to limit exposure</li>
    </ul>
  </li>
</ol>

<p>###Other stuff###</p>
<ul>
  <li>Building on GPL Platforms, what do I own IP in?
    <ul>
      <li>You can own IP in themes / software that sits on top</li>
      <li>You’re contributing to the platform if you get into the source</li>
      <li>You don’t give up rights to content</li>
      <li>BE CLEAR ABOUT WHAT CLIENT WILL OWN AND NOT OWN ON DELIVERY / PAYMENT</li>
    </ul>
  </li>
</ul>
]]></content>
</entry><entry>
  <title>Scaling Up Without Growing</title>
  <link href="http://socialmemorycomplex.net/2010/10/30/scaling-up-without-growing/" />
  <updated>2010-10-30T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/10/30/scaling-up-without-growing/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>I had a great time visiting my good friend <a href="https://someguysblog.com">Jim</a> in Charlotte this past weekend while the wives were selling crafts at the Country Living show in Atlanta. Many hijinks ensued, but one of the most rewarding was our discussion of different approaches to co-working, as well as expansions on the concept that could redefine how we work. We come at the conversation from two different angles, and I want to give Jim the opportunity to explain his vision, so I won’t go into too much detail about his particular suggestions.</p>

<p>It suffices to say that Jim has been co-working at a local space for some time now. Where he sees opportunity is in an organization that could take care of the administration - invoicing, taxes, space provisioning - leaving freelancers, small proprietors, and other independent developers free to pursue their business. The organization could be run on the mutual model, where all the “clients” are owners.</p>

<p>I’m intrigued by this idea, but I want to skin a slightly different cat. My experience of co-working has been quite different due to Richmond’s lack of a dedicated space for it. Our group has had to be more ad hoc, using Twitter and Google Groups to spontaneously organize meetings at local coffee shops on an irregular basis. Everything I’ve read on starting a co-working venue stresses the need to build the community first, rather than getting the location and expecting people to come to it.</p>

<p>Building on this idea of community-centric development, where developers working on their own client projects reach out to each other for mutual aid and support, I start to wonder whether the co-working group could not be more. Having worked as an employee for software companies - especially consultancies, agencies, contractors, and the like - it begins to occur to me that what we’re building in the community solves many of the problems that impel developers towards employment in the first place.</p>

<p>After all, while it’s no cakewalk, freelancing in the development world has never been easier. Especially in the emergent technologies such as more dynamic, web-oriented languages and mobile development, work is plentiful. The capital requirements are almost zero, as you probably already own everything you need to get started - an internet connection, a computer, and maybe a phone. It’s all about your ability to deliver, to manage client relationships, and carve out an area of expertise that differentiates you. Plenty of tools exist for managing the invoicing, taxes, and client communication for pennies a day.</p>

<p>Because of the relative ease of going out on your own, we should expect to see an increase in independent developers. The demand is definitely there; while it can be a good deal for us individually, it’s often an extremely good deal for the client. Agencies have so much overhead they need to balance that their rates can be three or four times what we can afford to charge. While we may boost our earnings by eliminating all that overhead, it seems clear to me that, more often than not, the client is the one who benefits the most by the lower costs and decreased commitments that come from piecemeal contracting with independents rather than investing in a full scale relationship with another business.</p>

<p>The danger is not that we cannot compete, but that we become an alternative to wage labor for these clients and that they will treat us as such. Reduced compensation is not the only downside of employment; there’s also the lack of control and the sense of dependency that people feel towards their employer. By having a more flexible contract from which either party can more easily walk away, we get more bargaining leverage to be sure, but that says nothing about the relationship we will have once we agree on a billing rate. Clients can be just as bossy and disrespectful as bosses, and they will often try with independent contractors what they would never dream of trying on a consultancy.</p>

<p>Indie developers get treated like ersatz employees precisely because, often, that’s how we sell ourselves: hired hands to the the client’s bidding. We’re cutting out the staffing agency, perhaps, but we’re certainly not positioning ourselves as serious competitors to agencies who aren’t selling services so much as bundles of expertise. In order to have control over the kind of work we do, in order to build a reputation as a source of solutions and not just a tech odd jobber, we have to be able to compete with the IT firm. But what is a firm / agency / consultancy, after all? It’s just a bunch of people who do what we do, with a few differences.</p>

<p>First, they know where to find each other on a regular basis, and so they can work together as a rule rather than as a special appointment they make with each other. Freelance for a while and you’ll realize this is no small matter. In doing so, they build a rapport, a collective competency that multiplies their individual capabilities. Being able to break problems up into sections and tackle in tandem - or being able to have a manager who can help organize this - increases predictability and, often, quality.</p>

<p>Second, it’s not just their status as a team; it’s the diversity of their skills. Very few agencies only do development; they usually couple it with a hefty dose of design, marketing and strategy acumen, project management, client management, etc. A one stop shop staffed with a team of people all specializing in different parts of the delivery of software can serve as a compelling package deal. Clients are willing to pay three to four times what freelancers will charge just to have all their technology needs taken care of by one vendor.</p>

<p>Third, they don’t have to focus on running the business per se: the bookkeeping, the billing, the facilities management, the recruiting, following up on leads, getting paid. Because the people doing our kind of work are employees, they enter into the employment agreement assuming these details will be taken care of (or that they will focus on these details and not have to do development work). The organization handles mundane concerns that so often bog independents down.</p>

<p>Before we ask how we indies can compete, we should first ask ourselves whether we really want to. I’m not convinced we should position ourselves as direct competitors necessarily. Doing our own bookkeeping and client management may suck sometimes, but it’s awfully grounding; we never lose perspective and get disconnected from the meat and potatoes of how we earn our living. There is a certain confidence and self-reliance from knowing that what you’re building is <em>yours</em>. You’re expanding your skill set beyond being a geek prodigy to being a person who can have an impact in the industry and in the community on your own terms, not some boss’s or accountant’s. If your point is to grow to become an agency, then this article isn’t going to appeal to you anyway, because I think employees suck just as much as employers.</p>

<p>But the facade of a fully integrated, unified, monolithic firm can make freelancers seem quite inadequate. It’s a myth, of course: there’s very little that an organization can bring to bear on a problem independent of the specific individuals involved - specific individuals that can vary in quality, are not always easily replaced when they up and leave, etc. Committing to delivering consistency to clients outside the boundaries of the firm can be dishonest when there’s no consistency within the boundaries of the firm, but we’ve convinced ourselves that’s the myth clients want to hear. That’s why firms place so much emphasis on building their own corporate brand; because it serves as a convenient stand-in for the people who actually do the work but could leave anytime. The brand will never quit, and the client’s relationship is with the brand, not the people.</p>

<p>The myth of the firm works, not because it’s a uniquely superior solution for the client, but rather because a more honest arrangement has not been demonstrated competitive. After all, the biggest strength of a firm is the productive relationships developed between the workers. Funnily enough, this is precisely what we’re building in a co-working community; a place where people know they can go for support, for assistance in an area outside their expertise, for a rapport and feeling of camaraderie. If this is where the agency’s strength lies, there’s no reason independent producers couldn’t come together to build their own teams that are not tied to a brand or a boss but can nevertheless produce client value at least competitive with a firm.</p>

<p>Imagine a non-profit entity organized by independent developers in a town for the purposes of managing a workspace and perhaps administrative staff for our individual businesses. We don’t go into the office because we <em>need</em> to; we go because we <em>want</em> to - because we want the company, we want to compare notes on solutions or commiserate about problems, and we want to see what others are doing. We build the relationships with each other without needing to control each other via employment.</p>

<p>Now some interesting possibilities arise. Imagine if I am trying to sign a client for a project, but they need more development labor than I can provide. Or they need a designer. Well, it just so happens I know some guys I can call in. They may not work “for” me, but we have a rapport, we’ve worked through problems in the past, and I trust them. I know what they bill. I can bring them in and do the work - perhaps as subcontractors, perhaps through an ad hoc entity, perhaps as independent contractors with the client. It doesn’t really matter; what matters is that we’re finding a way to meet a client’s needs outside of growing our own business and hiring people. We’re capturing the strength of the firm without becoming it.</p>

<p>Here are some other possibilities:</p>

<ul>
  <li>
    <p>We offer training for people who want to get involved in software development, and give them opportunities to exchange their time and energy to learn the skills they’d need to build their own business and perhaps join our group.</p>
  </li>
  <li>
    <p>We become a destination for clients who, perhaps at first, merely want advice. We place an emphasis on educating them about quality so they can make informed decisions about IT services. By making them better clients who can employ our expertise in a less distorted, more efficient manner, we help the entire industry. And we get great leads.</p>
  </li>
  <li>
    <p>People who still work for “the man” in I.T. now have another option. They have more leverage in demanding better pay and treatment from their employer, because now they see the alternative. They might even be able to pick up some work from us if they get fired or need to quit. This raises the bar for wage labor and all boats rise.</p>
  </li>
</ul>

<p>If some of the above sound like a trade guild or union, then you’re understanding me. But it neither has to necessarily work out like that nor like anything in particular. The precise direction in which any of this would evolve is a secondary concern.</p>

<p>What’s more important to me is that we see the potential and possibilities in the act of striking out on our own. We don’t need to conform to the standards set by a bunch of large, corporatist behemoths who thrive off of inefficiency and mediating between the client and the producer. We don’t have to think of our independence as wage labor by another name. There’s room for real organizational innovation in the business of software development.</p>

<p>By taking initiative in solving our own problems, by meeting our own needs creatively and unconventionally, we might transform this stagnant and conservative industry. Who knows, we might even provide an organizational model for how workers in other industries can better work. Remember: we didn’t stop working for “the man” just to do business like him!</p>
]]></content>
</entry><entry>
  <title>Treeoid</title>
  <link href="http://socialmemorycomplex.net/2010/08/11/treeoid/" />
  <updated>2010-08-11T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/08/11/treeoid/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>I’m a bit late mentioning this, but I released another super-beta gem in the hopes it might help another poor soul: <a href="https://rubygems.org/gems/treeoid">treeoid</a>, the missing “acts_as_tree” library for <a href="https://mongoid.org">mongoid</a>. It couldn’t be simpler, really: it gives you a “parent” accessor and a “children” collection. On top of that, it provides a scope allowing you to list a set of treeoid objects in hierarchical order, which is perfect for front end integration.</p>

<p>The tests are there but nominal; I’d love to see them fleshed out. I also had some ideas for making it cooler; for example, I keep an array of an object’s descendants in the object, allowing me to hierarchically order objects. This opens up some novel means to simplify how I implement the parent and children accessor. Imagine this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>field :ancestry, type =&gt; Array # contains ids of all ancestors including self, already exists

# but instead of a parent_id accessor

def parent_id
  ancestry.at(-2) # the parent can be fetched from the ancestry list
end
</code></pre></div></div>

<p>This also allows all descendants of a given object to be easily fetched - if the id shows up in the ancestry, return it! It’s this kind of out-of-the-box thinking that has really endeared <a href="https://mongodb.org">MongoDB</a> to me. I hope you can benefit from this and help me improve it. Or help with <a href="/2010/07/25/announcing-greedy/">greedy</a>. I’d love to get said help at <a href="https://cvreg.org">CVREG</a>’s <a href="https://www.cvreg.org/2010/8/9/august-meeting-celebrate-whyday">upcoming</a> <a href="https://whyday.org/">Why Day</a> hackfest.</p>
]]></content>
</entry><entry>
  <title>RailsConf Dispatch - Test Always?</title>
  <link href="http://socialmemorycomplex.net/2010/06/08/railsconf-dispatch-test-always/" />
  <updated>2010-06-08T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/06/08/railsconf-dispatch-test-always/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>There were two conveniently sequential presentations today at RailsConf that reminded me of some thoughts I’d had regarding testing: <a href="https://en.oreilly.com/rails2010/public/schedule/detail/14131">Michael Feathers</a>’ talk on legacy code and <a href="https://en.oreilly.com/rails2010/public/schedule/detail/14216">Glenn Vanderberg</a>’s talk on real software engineering. It seems to me that both talks had a theme in common: what is the function of tests? Why do we want them, what role do they play from an engineering perspective in the larger process, and what precisely are they meant to indicate to us?</p>

<p>Michael at one point talked about the expense of 100% code coverage for tests, instead recommending we test the parts of the code that change the least and are most important. Ugly code in legacy projects has utility, he explained, and untested code is a rational response to churn. Afterwards, Glenn discussed software development in the context of engineering principles from older, more established disciplines like structural engineering, finding areas of similarity, analogy, and abject difference. However, his testing point compared experiments in code to experiments in more physical engineering fields, remarking on how relatively cheap tests are for us. I suppose the common thread I found concerned the emphasis on cost: that what it <em>means</em> for us to do our job well is to do it effectively, and not subordinate our conscience and creativity to a mechanical process.</p>

<p>For some background, I’ve been practicing behavior driven development for a year or two. I love the confidence that testing gives me, independent of the value to the client. Verifying that my code works is fine and all, but what lets me sleep at night is the assurance derived from approaching a problem in a rational, systemic manner. By moving in small chunks and expressing problems in terms I understand well enough to programmatically recreate, I ground myself in a real comprehension of the system I’m building at the most relevant level and stage. I avoid the confusion of jumping ahead, thinking too large scale or minutely, or making unwarranted assumptions that come back to bite.</p>

<p>But I’ve found there are definitely times when testing first is the wrong approach. Remember: testing is supposed to reinforce your understanding of the problem. But what happens when you fundamentally don’t understand it? When you first encounter the project, you don’t necessarily <em>have</em> expectations or any way of identifying what a successful outcome is. Test first is supposed to get you to think about these things, but there’s no substitute for writing and running code.</p>

<p>Experimentation, trial and error, and playing around are important discovery mechanisms that give us the understanding we then apply to more rigorous processes. Spending time writing tests that do nothing but reinforce the fact that you don’t know what you’re doing is stupid. I’ve found that you have to think carefully about what you’re expecting your tests to actually accomplish for you, as you can dig yourself down rabbit holes needlessly by stressing form over function.</p>

<p>Similarly, as Feathers pointed out, even well understood requirements and algorithms often cost more to test than its worth. Code that changes often can cause test churn that burns up effort needlessly. And often we write large swaths of code that, while useful, just isn’t that critical to the success or failure of the project. Given these tensions, 100% coverage may not simply be an unreasonable goal - it may be positively wasteful.</p>

<p>Again, the problem is deeper, as Glenn pointed out in his talk. Historically (and surprisingly in spite of salient warnings as early as the 60’s) “Software Engineering” with capital letters has been biased towards a philosophy of formal, defined process models that demand predictability and reproducibility. Although behavior driven development may seem to encapsulate this philosophy, remember that when we’re dealing with behavior we’re not necessarily realizing mathematical precision at the level many engineers would expect. Accuracy is important in some engineering contexts, but flexibility can sometimes trump it.</p>

<p>A final thought that I consider my unique contribution to this discussion: if you do test first, consider that your tests may be disposable. It’s great that you are using tests to drive the development, and building a test suite imparts tremendous satisfaction as you pile on more and more features. But just because a given test is useful to <em>writing the code</em> doesn’t mean it’s useful for <em>verifying the project’s success</em>. It may in fact be, but that should be a demonstrable standard - don’t let your personal satisfaction detract you from the big picture goal of the project.</p>

<p>100% code coverage is increasingly seen as superfluous because areas of code churn are just a fact of software development. You may find the changes are so targeted and frequent that more exploration and manual play pays off more than working out programmatic unit tests. Also, why wouldn’t your test suite have cruft just like your source code? Perhaps your legacy tests reflect an emphasis on certain requirements that are just too rigid. In that sense, paring down the tests-as-specs is entirely consistent with the project’s interests as it reflects the actual state of the project. Tests out of sync with current requirements are often worse than no tests at all.</p>

<p>Conventions and best practices are no excuse to forget our responsibilities to the client’s budget. The point is not to adopt a rule that tests are no longer important to maintain; rather, avoid blindly following <em>any</em> rule for its own sake, especially when you’re being paid to use your brain. Your job is not to write code; it’s to deliver client value, and that requires careful thought. Depending on the importance of a given section of code, rewriting that unit test may be less useful than scrapping it for the moment - or perhaps focusing on integration tests instead. Always be willing to step outside your comfort zone to better understand the project and realize it’s criteria for success - even if you lose a bit of sleep over it.</p>
]]></content>
</entry><entry>
  <title>RailsConf Dispatch - Rescue Missions</title>
  <link href="http://socialmemorycomplex.net/2010/06/07/railsconf-dispatch-rescue-missions/" />
  <updated>2010-06-07T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/06/07/railsconf-dispatch-rescue-missions/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>The first tutorial class at <a href="https://en.oreilly.com/rails2010">RailsConf</a> on <a href="https://s3.amazonaws.com/tammer_saleh/production/assets/vtm_rails_antipatterns.pdf">Rails Anti-Patterns</a> has been phenomenal and incredibly validating given my experiences with consulting. <a href="https://tammersaleh.com/">Tammer Saleh</a> gave a wonderful talk on how to handle troubled legacy codebases - what he calls “rescue missions”. It’s particularly relevant for me as much of my early freelance work centered on failing projects I was dumped into.</p>

<p>Because of the success of Rails, there’s a lot of shitty code out there for you to fix. The harder issue is figuring out why shitty code was delivered, which can be trickier to figure out than you’d think. It can be really difficult to change the course of a project when much more than merely the code is dysfunctional.</p>

<p>Tammer suggested a ton of coping strategies, many of which end up being good practices for most situations. I’m sharing my cursory notes here in case others are interested. Feel free to strike up a conversation in the comments to explore these points. I’ll link to the slides when they become available.</p>

<ul>
  <li>Considering a code rescue mission
    <ul>
      <li>client relationships can be adversarial</li>
      <li>many problems are with process and not just programming, where the programmer didn’t push back on features</li>
      <li>when devs don’t want to follow convention, disaster often ensues</li>
      <li><em>15 min code review</em> to get clear on situation before contract signed
        <ul>
          <li>models
            <ul>
              <li>how many models? Too many is bad.</li>
              <li>search for “assert_true” to see where scaffolding was used</li>
              <li>empty models</li>
              <li>superfluous raw SQL</li>
            </ul>
          </li>
          <li>controllers
            <ul>
              <li>non-RESTful controllers</li>
              <li>pseudo-validations in create actions (manual checks in actions not using conventions but inline)</li>
              <li>monolithic controllers (three controllers &amp; a zillion actions)</li>
              <li>custom authentication</li>
            </ul>
          </li>
          <li>views
            <ul>
              <li>PHP-style inline ruby / SQL in the views</li>
              <li>inconsistent file structure</li>
              <li>poor markup, no rails helpers involved</li>
              <li>layout code in views</li>
              <li>duplication - too DRY can be bad, but duplication should be avoided</li>
            </ul>
          </li>
          <li>lib
            <ul>
              <li>reinventing the wheel</li>
              <li>duck punching - reopening class</li>
            </ul>
          </li>
          <li>general danger signs
            <ul>
              <li>huge files</li>
              <li>feature bloat</li>
              <li>bad ruby style</li>
              <li>gratuitous metaprogramming</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>Once you’ve concluded this is a rescue mission, identify its root causes - it’s never about the code itself
        <ul>
          <li>hard technical problems</li>
          <li>poor developers - hard to identify, you can’t judge from the code necessarily</li>
          <li>process reasons</li>
          <li>personality reasons
            <ul>
              <li>a lack of focus on quality</li>
              <li>artificial deadlines</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>think carefully about taking the job
        <ul>
          <li>reputation damage likely</li>
          <li>client probably doesn’t have much money left</li>
          <li>Core question: <em>can you fix this?</em> Not just the code but client issues that caused bad code.</li>
          <li>Will fixing this result in future good work?</li>
          <li>How much money? This is painful, difficult, and risky work - you should be well paid. Rule of thumb: 50% over base.</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Proceeding with the rescue mission
    <ul>
      <li>train the client
        <ul>
          <li>all of the work you do on the code is useless if the client keeps their bad habits</li>
          <li>send them the 37 signals book, dog-ear pages to pay attention to</li>
          <li>my job is not to be just a code monkey. I’m here for <em>advice and negotiation on features</em>. Push back!</li>
          <li>force payment of tech debt
            <ul>
              <li>explain long term costs</li>
              <li>70-80% of core development budget</li>
            </ul>
          </li>
          <li>you must be willing to lose the client</li>
        </ul>
      </li>
      <li>fix process
        <ul>
          <li>establish trust</li>
          <li>record everything
            <ul>
              <li>transcript, voice recording, etc.</li>
              <li>documentation for yourself</li>
              <li>communication</li>
              <li><em>visibility</em></li>
            </ul>
          </li>
          <li>weekly standups</li>
          <li>tools
            <ul>
              <li>github - get client subscribed to commit feed for visibility (they don’t need to understand)</li>
              <li>pivotal tracker
                <ul>
                  <li>client prioritization of stories</li>
                  <li>emergent velocity is crucial</li>
                  <li><em>use low velocity as an argument for fixing tech debt</em></li>
                </ul>
              </li>
              <li>basecamp &amp; campfire for communication</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>fix codebase
        <ul>
          <li>peer programming
            <ul>
              <li>transfer domain knowledge</li>
              <li>teaches best practices</li>
              <li>keeps you focused</li>
            </ul>
          </li>
          <li>integration tests are a necessity on rescue missions
            <ul>
              <li>cover common paths</li>
              <li><em>integration tests for existing behavior, functional/unit tests for added or modified behavior</em></li>
            </ul>
          </li>
          <li>work in small chunks, mixing in:
            <ul>
              <li>client value</li>
              <li>low impact, high yield pieces</li>
              <li>reduce tech debt</li>
            </ul>
          </li>
          <li>focus on issues <em>slowing you down</em></li>
          <li>DON’T GET DISTRACTED by all the issues, just record them and move on
            <ul>
              <li>don’t do code comments, because client can’t see that</li>
            </ul>
          </li>
          <li><em>remote tracking</em> feature branches
            <ul>
              <li>isolate refactoring</li>
              <li>increase visibility</li>
              <li>protects you from rabbit hole excursions - you can always trash the whole thing</li>
              <li>git remote branch gem available</li>
            </ul>
          </li>
          <li>balance of refactorings w/ features</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Other field tactics
    <ul>
      <li>Too many models
        <ul>
          <li>consider a much more denormalized model than often desired</li>
          <li>it’s never just one more model to throw in</li>
          <li><em>extra code is a liability</em></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
]]></content>
</entry><entry>
  <title>acts_as_enumerated Blowing Up Your Testing Spot?</title>
  <link href="http://socialmemorycomplex.net/2009/12/24/acts-as-enumerated/" />
  <updated>2009-12-24T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2009/12/24/acts-as-enumerated/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>If acts_as_enumerated classes are borking when you run your tests, here’s a nasty workaround I did that just might work for you:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class MembershipStatus &lt; ActiveRecord::Base
  if RAILS_ENV == 'test'
    def self.[](label)
      case label
      when :pending
        MembershipStatus.new(:id =&gt; 1)
      when :accepted
        MembershipStatus.new(:id =&gt; 2)
      when :denied
        MembershipStatus.new(:id =&gt; 3)
      when :invited
        MembershipStatus.new(:id =&gt; 4)
      end
    end
  else
    acts_as_enumerated
  end
end
</code></pre></div></div>
]]></content>
</entry>
</feed>
