Movebubble Sprint: Day 10

Standup starts late, as Laura was at a ‘women in tech’ breakfast event at the Google campus. Jack is having problems testing the router bug, because new viewings are generating new chats (the old behaviour) rather than being routed to an existing chat with the same agent, and he needs to multiple viewings behaviour in order to reproduce the bug he is trying to fix. It seems this is something that I broke with all of my ‘fixes’ the previous evening, but I don’t have time to look at it immediately because I have a planning meeting with Will and Amy to work out what we’re doing next week, so I just roll back the dev environment temporarily.

Planning goes pretty quickly – Tom is on holiday already, I will be on holiday from Monday and Valerio is off for a week from Wednesday, so we discuss the kind of things that it makes sense for us to work on over the Easter break. From a Water Camels perspective, there are a number of small improvements to the suggested properties and chat system messages which we couldn’t get done this sprint and it would make sense for Jordi and Laura to get on with those; Amy suggests a number of small improvements that Adrian has wanted to work on for a while. We decide that, rather than try and work on stuff as a a single time, we should maintain the two separate team workflows for that week.

I head back to my desk to look at the broken chat routing Jack identified but I’ve barely been sat there for 5 minutes before Andrew calls regarding an issue with the app. Apparently it just hangs when he tries to enter certain screens. It was doing this yesterday as well; I wish I’d known about it yesterday as I could have investigated it properly, but he is going into a meeting in 10 minutes and I’m not sure there is much I can do here.

I take a quick look at the data on the server to check that there is nothing obviously wrong and I also take a look at the logs to see if I can find out where the problem is occurring. Nothing. It’s possible that the chat service and the main API are out of sync, so I suggest to Andrew that I can redeploy one or the other and see if that fixes it. He doesn’t want to gamble on that making things worse though. I tell him he can’t use the test environment as we’re on release day and it’s going to by high churn. ‘Never mind, I’ll just wing it’, he tells me.

Before I get started on my code again, I head over to Laura’s desk as she is sat there with Valerio looking glum. She doesn’t think that the badges issue is going to be done in time for the release. The pair of them take a few minutes to explain the problem to me, with the aid of a conveniently located whiteboard. It seems that they’ve tried a couple of different approaches but the problem is that we’re trying to maintain two data structures that are fundamentally at odds and whichever way they do it something is going to be not quite right.

Valerio seems to have a solution that involves rewriting one of the data stores (at least, that is what I understand) and I ask him how long he thinks it will take to do that. 2 to 4 hours, is the response, if he has no interruptions. But he is on dev support today, so he will probably have interruptions.

I volunteer Laura and I to cover his dev support if he can work on fixing the issue and Laura seems relieved. It’s always demoralising to pick up an issue that looks simple but turns out to be a lot more difficult than imagined due to the way a particular feature is written. It is particularly demoralising when you are relatively new to development, because you feel like you should be doing better and you left with the nagging feeling that it’s not the code that is being difficult but you. I hope that the fact that Valerio was also struggling with the problem is enough to assure Laura that this was just a difficult problem. She does seem happier now that she doesn’t have to deal with it, at least.

I finally get to start looking at the chat initialisation bug, but it’s a challenging one. There’s no obvious reason why I have broken that function and I when I try to reproduce it locally it all works correctly, regardless of whether it is the renter or the agent who initialises. I need some better diagnostics, so I update the code with some minor logging additions and while I’m waiting for it to deploy I help Laura with a dev support issue.

We have a negotiator who is complaining that she keeps getting logged out of the app and that she is missing leads as a result. However, when we look in the database it’s clear that she hasn’t had to log in for a couple of months and the events on Mixpanel show she has successfully been retrieving her profile and leads on a regular basis. What’s more, the events clearly show that she is accessing the app immediately after receiving push notifications and there is less than a couple of minutes delay, so that bit of the function is also working.

It turns out that the real reason she is missing leads is that she has a colleague who is consistently responding to them a lot faster than she is – within 30 seconds! On the one hand, we’re pleased, because this is exactly the kind of thing we are trying to achieve with the two apps, but on the other it feels like there could be a usability problem here in that it doesn’t seem clear to the unhappy negotiator that this is why the leads are being missed.

We need to call her anyway to ascertain if the password issue is still a problem or whether she was conflating a previous issue she had (this was a known problem a few weeks ago) with the more recent one, so it feels like we should try and ask her some open ended questions about the experience as she’s probably the first example we have in the field of an agent being out-responded by a colleague as in most cases we’ve only given the app to one negotiator per branch.

I get back to the chat bug. I have some log diagnostics now and I can reproduce some of the calls between the services in Postman. I still can’t see the problem though – when I run through end to end it all seems fine. It’s not until I’m about to go for lunch that I spot it – there’s been a change of case.

RavenDB stores IDs in the form [Collection]/[IdNumber], where [Collection] is saved in Pascal case. But some of our apps when they call the endpoint use camel case or lower case, so e.g. UserInformation/123 because e.g. userInformation/123. We can get ensure consistency in the code by loading the document and then using the id from the loaded entity rather than the incoming string. As part of my refactoring, I had failed to do this, and now the search for an existing chat was failing to match the UserInformation tag due to a case mismatch.

Having finally identified the problem, the fix is pretty simple, and I get it into our test environment. But it’s 13:20 and I feel like I should have fixed this earlier, to be honest. We’re supposed to have a planning session and a retro this afternoon, but I reckon we’re going to be struggling to fit the retro in and release on time. I don’t want to cancel the retro as we’ve not been particularly good at having them (we’ve probably done 3 over the last 3 months) and I think it’s an important part of our continuous improvement loop, but it is what it is and it’s less important (at least, to the business) than getting the app submitted.

I wonder whether we should move to Wednesday to Wednesday sprints. It’s something that we did in my previous job and it meant that we could do a retro the morning after with the sprint work still fresh in our minds. It also meant that any last minute scrabbling tended to occur mid-week rather than at half-past-pub on a Friday when people would rather be anywhere other than the office. I make a note on my task list to bring this up at the next dev lunch (something else we missed this week). NB should amend Wednesday’s post with this info. 

After lunch, I test that my fix for the chat routing actually works (it does), and then I’m able to reel off and verify about 5 other backend tickets which were all at least partially solved by this and the work that I did the previous evening refactoring and commonising our request viewing code. After that, it’s 14:40 and I have around 40 minutes before our planning session – I do a quick check where everybody is at. Laura thinks she’ll have finished the styling work in the renter app; Valerio is looking good for the badges fix; Jordi is still struggling with a specific case of the router bug in the negotiator app related to offers.

We decide that the router issue is not a show stopper if it is only reproducable in relation to offers – we have so few offers going through the app at the moment that it’s very unlikely to surface in the field. That means Jordi can focus on tidying up a couple of offer message related issues. The same for Laura – there’s still some back end work to be done for the offer messages, but as long as the styling and handling is there then it can be done after we submit for release.

Then it’s planning and Jordi and Laura and myself all sit round and go through what will be on their plate for the following week when I’ll be on holiday. It’s going to be a micro-sprint tidying up some of the work that got descoped this week and as there are only two of them and the Friday is a bank holiday I reckon we have a capacity of about 20 points. That doesn’t get us very far, enough to finish off some of the smaller items that got descoped this time round and also for Jordi to do some work on chat performance improvement.

The latter is something that we’ve wanted to do for a while, since we currently have an MVP implementation of chat that polls a lot of data from the server, and now seems like we may finally be able to make some time for it. Jordi’s a little unsure about it but I think it will be a good exercise for him and it will also help us spread a bit more knowledge about the chat back end around the team.

I let them both know that they’ve done a great job this sprint – we’ve had the usual issues with scope creep and changing goalposts, but after committing to 63 points in the sprint we’ve actually done 77.5 and we’re on track to deliver exactly what we said we would – releases for both renter and negotiator apps with a suggested properties MVP. And we’ve done this despite both Jordi and I taking sick days and a wasted day I spent wrestling with Android Studio. We discuss what we’re going to do to celebrate; one suggestion is a team outing to Barcelona to visit Jordi, who will be moving back there and working remotely next week. I reckon we can make it happen.

We’re out of planning by 15:50. In the meantime, Valerio has finished his work on the renter app and so we can merge that in; the main thing left to do is some last minute regression testing. Jack and Will volunteer to help with that as well while Laura and Valerio handle the merge and getting a suitable version of the renter app onto test flight.

We also need to release the API, which is risky this late on a Friday but we need to ensure that it’s consistent with the app so that there are no problems with the Apple review process. I volunteer to check on it later in the evening and the following day. That way, if there are any visible errors or problems I can roll it back easily enough. I also handle the release, consists mostly of clicking the ‘deploy’ button on our Octopus installation, running through some basic tests in the app to check that the happy paths still work and watching for any errors in the live logs.

At 17:15 we have TGIF, which consists of going round the room and telling everybody how we helped a renter. It’s a weekly ritual that has been going since long before I joined the company. The idea is that everybody maintains a focus on what the company’s mission is. It’s become easier to contribute over the last couple of months; I didn’t used to be allowed to include work I’d done as a developer, which meant I was always trying to think of some person I’d spoken to or given advice to and it was often pretty spurious. But as we’ve moved more towards focussed, data driven decisions, one of the changes is that we’re now allowed to contribute anything as long as it is aligned with the company’s current focus. In this case, several of the things that we’ve done of the last week should directly impact offer conversion, but I decide to focus on offer communications themselves.

Then it is also a chance for people to shout out particularly good work by colleagues and for Aidan (or Jack if Aidan is not around) to reflect on the week and talk about how things are going. We’ve shaken it up a little recently, with weekly figures now being shared on a Monday morning when we can take in the weekend as well, so the speech at the end is a bit shorter. Jack wants to shout out the development teams this week for delivering releases on both apps on time (though we haven’t actually released yet) and I second that, particularly calling out Jordi, Laura and Valerio for their work over the last couple of weeks.

Finally, it’s back to our desks to release the apps. Jordi takes charge of the negotiator app release and Adrian starts the renter app release, though we discuss whether it should be somebody else who manages the full release process. Everybody is pretty keen to get down to the pub, so in the end both Jordi and Adrian grab their laptops and decide to release from there. I have a couple of things I want to tidy up before I go, since I won’t be on Monday, so I form the rear guard with Will and Nicola.

The apps are finally submitted to the app store at around 18:30. All that’s left then is to chill out with a drink.

Movebubble Sprint: Day 9

Today is going to be manic. We’ve got 2 days left of the sprint to fix all of the issues that came out of the bug hunt and I’ve lost my voice to boot. Turns out that Tuesday night hurt me more than I thought; the cold that has been kicking around has come back with a vengeance.

I’m not the only one who is suffering. Jordi has apparently had a back spasm and needs to go a clinic in Angel. He’s unlikely to be in today as a result, or at least not until a lot later. That’s not ideal as he’s in the best position to be fixing bugs in the negotiator app.

After standup, I go through the bugs reported on the wiki page and prioritise them with Laura. It looks like a lot, but actually when we get down to it there’s only really one issue in the renter app that is high priority; the rest are minor styling and copy or related more to the backend code. So she gets started on that while I get started on transferring all the bugs into JIRA and prioritising them.

It’s a tedious task and I get interrupted on a number of occasions – first there’s the issue with SQL replication for chat which we noticed on Tuesday but didn’t get a chance to address and I realise that I haven’t pushed the migration code that applies the correct dates to the chat room. I do that and it seems to sort the issue for Boris. There’s also a call from Andrew who is out in the field, he needs a verification code for a new user of the renter app. I find this for him and get him into the app.

Jordi does make it into the office after all. He went to the clinic but they told him to come back at 2.40pm, and he figured he may as well come in and do a bit of work. So I spend a bit of time going through priorities with him; basically, the priority is ‘fix the router issue’, which was a known problem before the bug hunt and is a show stopper as far as I am concerned.

Once I’ve gotten all the bugs into the system and labelled them so that it is easy for people to identify which ones relate to which bits of the system, there is a question of prioritisation. I reckon I can give a good go at this so I apply a priority to each of them before letting Will know that the backlog is ready for grooming if he has time to do that now. He does. It takes us about 30 minutes to go through and discuss each bug, pull them into a priority order and then work out which ones we’re committing to fix. All in all we pull around 18 bugs into the sprint commitment, leaving the rest on the backlog to be pulled from if we have time.

It’s 12.30pm by the time I can actually start fixing bugs. The first couple are relatively easy – I can fix them just by removing a whole load of unwanted code. Net negative check-ins are always pretty satisfying. It’s like the feeling of achievement you get after a particularly violent cleaning spree.

Next though I need to look at the viewing request endpoint and unpick the event sequence to identify why we’re getting duplicates in some cases and why we’re getting none at all in others. I had suspected the evening before that I was going to have to refactor this code and after about 20 minutes of debugging I’m convinced that that is the right step.

We have a controller method which is around 70 lines of code long, originally written by somebody no longer at the company and then added to by Adrian and myself as we each dodged the bullet of sorting it out, and because of it’s linear complexity it’s pushed us into bad practices elsewhere in the code base where we’re tried to replicate similar but not exactly the same behaviour.

We’ve slowly been trying to improve stuff like this; a couple of months ago Adrian and I sat down to discuss what design philosophy we wanted to apply to the codebase so that when we did refactor stuff like this we could do it in a consistent manner. After we settled on a domain approach one of the things Adrian suggested was a builder pattern, which allows you to write simple, fluent and easily readable code around building complex objects. Or, in other words, 70 lines of ‘if this then that’ becomes:

var viewing = _viewingBuilderFactory
                .NewViewing(request.UserInfoId, request.PropertyId)

The various bits of logic from the controller get refactored into the builder, making it easier to commonise code with other endpoints which may need to build the viewing with a slightly different set of parameters, e.g:

                .NewViewing(userInfoId, propertyInfoId)
                .WithTimeAndPlace(startTime, location)

I’m not 100% happy with the BuilderFactory pattern – in order to manage dependency injection and have a single builder instance per viewing, I need some way of managing the more long-lived services that the builder calls into – but frankly today is not a day when I can spend a few hours playing with design patterns until I have something that is more aesthetically pleasing.

Once I’ve done an initial pass of my code I run my ideas past Adrian, partly to make sure he’s happy with them and partly because I always find it useful to bounce these things off somebody. I find that Adrian is quite good at pointing out holes in my thinking as I have a tendency under pressure to rush through something without necessarily exploring all of the angles. My first pass at the build code isn’t quite right, as it includes a number of calls that really should either be refactored into events or belong in a service model, and him pointing this out helps me to refine what I’ve done.

I bury myself in the rest of the refactoring job and try to be careful not to lose focus on the task in front of me. This code has been paining both Adrian and I for some time now and it’s really satisfying to finally have the chance to improve it; however I need to be careful not to let me remit slip to refactoring other bits of the code that aren’t relevant. I’ve done that before and not only does it take longer to do but it also massively increases the chances of introducing bugs. I now try and do refactoring in small steps, even if it means rewriting the same unit test several times, because small iterations are easier to manage and it’s much easier to identify and fix problems when they occur.

It takes me pretty much the whole afternoon to get to where I want to be. It’s 5pm before I know it. In the meantime, Jordi has gone back off to hospital (and is busy complaining about NHS wait times in Slack) and Laura has raced through a number of the easy bugs but is now back onto her nemesis; the badging issue which has been plaguing her since Monday evening. I’d like to be able to help but while my refactoring should have fixed a number of issues that came out of the bug hunt there is still plenty more for me to do; 6 or 7 more tickets that need fixing. Valerio however does have time to help so he brings his chair over and they start to pair on the problem.

That doesn’t solve the problem of the router bug. With Jordi out most of the day and unable to resolve it we need somebody to look at it fast. At the current rate, that somebody is going to be me; however Will suggests that Jack could look at it as he has some time. I often forget about Jack as an option, as we’ve been making a conscious effort to keep him out of our development process over the last two months to ensure that he has the time to focus on more high level stuff. However, he will occasionally step in and in this case he’s probably the best person to take a look at the issue.

Leaving Jack to it, I tidy up the remains of my refactoring and get the code pushed. Then I check the JIRA board to see where we are up to. We have 19 unstarted issues, 13 in progress, 12 in testing. That feels like too many. But of those 19, 4 are unrelated to our sprint work (they’re just there to make sure I nag the relevant person about their status every now and then), 3 are placeholders for documentation tasks, and another 3 I’m quite comfortable not completing. Around 6 of the remaining 9 are things that I can address now that I’ve finished my refactoring. I think if I just push through for a couple more hours I can break the back of what is left.

Which is exactly what I do. I don’t tend to work late nights, but I’ve been short on development time this week and it feels like a bit more effort here will facilitate us hitting our targets. It’s nearly 9pm by the time I leave; no football tonight and my wife is in Brazil, so no particular need to rush home for anything. At around 7.30pm I remember that some friends are out in Soho tonight and I originally said I wasn’t going but maybe I could catch them later; they miss my text messages though until I’m no the bus back home and by then I’m too tired to want to be sociable.

In the end, I get through another 6 tickets on the back of the refactor, and the feature is really starting to take shape. The full flow from suggest a property to request a viewing to book via the app is pretty much there, we just need to sort a few edge cases. At least, so I think.


Movebubble Sprint: Day 8

Team breakfast this morning is a little different. As we all went out on Tuesday night, I foolishly suggested that we should meet for a fry up at a local cafe, thinking that Aidan might consent to us starting a bit later. He loved the idea but said we should be there for 8:45. Sunil and Jordi have already said they are not making it.

The hangover isn’t great. I haven’t had a drink for a few weeks but yesterday I started at 4pm after the investor’s meeting and I’m trying to work out if cycling in is going to make me feel better or worse right now. The alternative is bus, but then I’ll miss the breakfast. I rule out the tube; I don’t want to vomit down a stranger’s back in a cramped container.

Turns out, cycling makes me feel better. After 30 minutes of exercise in the morning sun and a full English breakfast, I’m actually feeling capable of a day’s work. We take our time eating so we’re not into the office until 10, where we have a late standup and organise ourselves for the day.

I have a couple of backend issues I need to finish off from the day before; Laura is still worried about her workload, so I sit down to help with that. One of her responsibilities was meant to be the test plan but we give that to Will who says he has some time to help. There is also an issue around caching viewings in the renter app which Tom on the other team is looking at but Laura has some work which is dependent upon it. We discuss a couple of options for managing that work with Tom and eventually we decide that we don’t really need that button anyway – how many people are going to book a viewing without looking at the property first? We can add it in later, the important thing is getting the feature out and we need a build ready for the bug hunt at 3.

As I sit down to start work, Amy asks what we agreed with Tom, and I relay the conversation. She’s a little concerned about some other implications of Tom’s work – is the transition going to be right, are we going to confuse the user by pulling them backwards when they should be going forwards? We have limited options due to the nature of the router; I leave Tom and Amy to work it out between them as this is one thing where I don’t need to take responsibility.

The hangover is starting to come back and my brain isn’t really working. I need a coffee. I forget my wallet. It’s 10.49 by the time I get started on development.

I take 10 minutes to go through my to-do list. There were 4 items on it at standup but now I can think of a couple more. The first item of business is to finish the code from yesterday. There should be an event handler that ensures that existing bookings are claimed by an agent when they book. Halfway through doing this Adrian comes to ask me about some tests in the push notification service that look half finished. There’s a lot of stuff commented out. I’m not sure why this is the case, but it’s clear that they should be sorted out, so while I am waiting for a set of tests to run on the main API I start fixing the tests on the push notification service.

This turns out to be a little more complex than I thought, and it takes me a good 40 minutes to fix. I get it done though and the build goes green, unblocking Adrian from finishing off the work he’s doing to transfer the old push notifications to the new service.

Laura then reminds me of a couple of fixes that I had meant to get in earlier; one to stop creating chats for all viewings, only those with chat-enabled agents, and another from our conversation this morning to remove the book viewing button on the property suggestion message because the handler is not ready. I quickly apply both fixes and the return to the work I was initially trying to do.

We move the bug hunt to 4pm. It was scheduled for 3pm as Tom wanted some time to fix things before going on holiday the next day, but Amy convinces him that it’s not his sole responsibility to fix the bugs and there are other perfectly capable people who could do that. It’s more important that we have a working build and an extra hour is going to allow him to do that.

At 13:30 I need to leave to get some physio on my knee at a place in Camden which is around 20 minutes cycle away. I’m back at 14:50. I’ve managed to get very little done in the last 24 hours – with the investor meeting, breakfast and physio appointment – but tonight is a late kickoff in my 5-a-side so I’m planning to stay later anyway and I think I can make up the time.

Moving the bug hunt later has given me a bit more time to write some tests for the claim viewing work I was doing earlier.

I finish writing the tests for the claim viewing code and then push the API around 15:30. I also try and help with a bug related to chat in the app – Laura and Jordi are struggling to separate the badges for chats and viewings. This is related to the issue we were discussing with Simon the previous morning and it’s turned into quite a tricky one to handle. I’m not sure how much help I can be as I don’t know this code very well but I ask enough dumb questions that Jordi seems to hit on an answer, so I leave them to it.

I d0n’t have anything more to do before the bug hunt, so I schedule in some planning and a retro for Friday so that we can sort out what we’re planning to do the following week. We tend to try and get a technical planning session done on the Thursday before a sprint and then a sprint planning on the Monday the sprint starts, but next week several of us are on holiday so we should discuss how we are going to handle that before the event.

Then I head down to the Coop to get an armful of sweets, biscuits and juices with which we can entice people to the picnic table to hunt bugs for us.

The bug hunt doesn’t actually start until 16:30 as there are a couple of last minute issues getting a build out to Test Flight and preparing one for Android. When it does start, it starts badly, as one of the ‘quick fixes’ I pushed out before lunch is actually preventing people from starting chats and I need to patch it quickly so that people can carry on testing. It takes me about 10 minutes to change the code, build locally and then manually patch a new version of the library to our test server, circumventing our Teamcity build which would take a lot longer on account of running all of the tests.

My first patch fixes the issue for renters but not for agents; second time round it seems to work. Once this is resolved the bug hunt goes fairly smoothly. Halfway through I need to stop and answer some questions from Nicola and Andrew relating to the agent dashboard – this is a feature which shows statistics on negotiator usage of the app at their branch, but it currently isn’t very intuitive and we’re double counting some things on account of us generated a lead per agent for each viewing request and mapping the outcomes of the leads rather than of the viewings. I assure them that we’re planning a revamp of the dashboard after Easter, but there’s not much I can do about it now.

Back to the bug hunt and we’ve raised about 30 issues. Many of them are minor; just copy changes, styling and a couple of ‘suggestions’. There are some cases where button handlers aren’t working as well, which are more serious, but easy to fix. The ones I’m most concerned about are the duplicate events and missing notifications. We’ve incurred a lot of technical debt in the back end around viewings and properties and a lot of the function around allowing agents to book a viewing directly for a renter (rather than the renter request it first) was kind of bolted on to the side. It may be time to consider a refactor of that because there are clearly some peculiarities around the way it’s behaving; it’s a bit late in the sprint to be considering ripping out and rewriting two complex endpoints though.

I’ll take a look at that later, though. For now, aside from the issue list, there is a more general question about usability which Amy raises; the new flow seems confusing because now that we have a many viewings to a single chat relationship the discoverability and navigation in and out of those chats/viewings feels unintuitive. Do we need to do something about this?

We discuss with Will. He listens to the concerns but his gut feeling is that this isn’t something we need to worry about. Have we made anything worse? Probably not. Is the new feature a bit raw? Probably yes. But rather than spend another couple of weeks trying to get it out, we should get it out there and see how people interact with it. We’re much more likely to get it right once we know how people react to it in the field. Our testing sessions are a little artificial in that we are putting high volumes through the app without really caring very much about any individual transaction, whereas renters and agents are much more invested in a single transaction and will take more time over their interactions. As such, it is difficult for us to second guess whether the feature is actually as confusing as it may appear in testing.

I wonder if there is some way we can get around this with a more defined kind of role play, but I keep the thoughts to myself for now. It’s late in the day and we want to get a resolution on this. Ultimately, we decide that we should continue but monitor the interaction closely once it is released and try and get some early feedback on what we could improve.

People start to file out for the day but I’m not planning to leave until 8.30pm (kickoff is at 9pm). Still, I’m exhausted – definitely should have taken it a little easier the previous evening. I have a backlog of blog writing to do, and I’d much rather face that than the bug list, so I decide that the fixes can wait until the morning.

Movebubble Sprint: Day 7

Standup starts a bit late this morning, for no particular reason other than it’s hard to get everybody together. With the investment meeting today there’s a palpable sense of nervousness and urgency from Aidan and Will who are finalising the presentation and preparation. We do manage to get everybody together eventually and we each deliver our two minutes.

Jordi is pretty confident of getting everything in the negotiator app ready for the bug hunt. Laura is less confident of the renter app work. She seems visibly a little stressed, which is unusual for her, so I suggest that we sit down and go through priorities after standup.

Adrian would also like some of my time to discuss indexing in MongoDB as he wants to move all of the existing push notifications across to our new push notifications micro-service – this is to support the deeplinking work that Valerio and Tom are doing, since the data structure on the new service is a little more advanced.

I also need to grab some of Simon’s time to discuss what to do about the renter app issue that Laura uncovered the previous evening.

First, though, coffee.

We’re back up from the coffee shop at 10:05 and I spend 5-10 minutes with Laura going through the outstanding work on her plate. I suggest that the viewings bug she found may not actually need to be fixed this sprint – it’s not great, but it’s not a showstopper, so she should focus on the outstanding feature development. That feels more manageable and seems a little more relaxed.

I then do the same with Jordi, just to check what he is working on and whether he really does have the time to get it all done. There is some status message work outstanding but it feels more important to finish the suggested properties feature and then address the router bug, so I say that maybe I can handle those and take them off his plate. Not that my plate is empty, mind you.

It’s 10:25 by the time Laura and I find time to chat to Simon about the viewing status messages; we discuss a couple of alternatives but none of the doable ones seem satisfactory. I suggest that maybe we don’t need to fix it but Laura points out that there is a related issue with badges that also needs solving and that one seems more urgent. I think she’s right, so we make a conscious decision that the status messages in the viewing preview may relate to different viewings and from that starting point we’re able to specify the behaviour that we should attribute to the viewing badges.

Next it’s time to chat with Adrian about the indexes. This is something that I investigated and implemented for chat but it wasn’t a great implementation – the C# library for Mongo has some nice features, including LINQ integration, but seems to be slightly out of sync with the latest MongoDB version. I had some problems creating text-based indexes on collections and also migrating those indexes if and when they changed, and I never had the time to properly resolve these problems. I give Adrian a quick tour of the work I did and point out the areas where I am still unsure, and after about 10 minutes or so he believes he has enough to go with and works on applying the same approach to the push notification service. We discuss having a common library on our Nuget feed but neither of us really has the time to see this up.

Before I can sit down and finish off the development I started yesterday, Boris has a question about SQL replication for our chat database. It’s broken again, but after checking that chat itself is still working and it is just the reporting that is an issue, we decide that it’s not urgent and he agrees that we can look at it later in the week.

It’s 11am, and I can start development for the day.

I finish the ticket I was working on around 11:40 and then merge and push. Laura is a bit uncertain about the test plan for the bug hunt the following day; to be honest, so am I, but I agree to help her with it. The reason I am uncertain is because it is experimental. It’s not something we’ve done before, it’s just an idea we had that might make our testing more efficient.

I don’t know if it will be effective or even really what it should look like, but we spend about 10 minutes discussing it and I suggest that it should basically be a list of features and a list of scenarios that we would like to focus on as part of the bug hunt, and these should be open ended so as not to be too prescriptive about the kind of things that people test. The purpose of a bug hunt is more role play than directed regression testing.

When I get back to my desk, Jack has send round a link to the burndown chart. It was looking good the day before but a fair bit of additional scope crept in over the last 24 hours, so we’re now a little further away from where we want to be. That said, there are a lot of tickets in test and ‘ready for signoff’, but it’s not really clear to anybody in the team who owns the actions on these or, in the case of the latter, what the action should even be. This is something that I would like to remedy but I think it should be part of a retro discussion, so for now it’s just a part of the process that we live with.

Shortly after midday, Jordi points out that a particular even is not firing. It takes me about 5 minutes to fix. Then Sunil wants to show me what he’s done on the CRM, so I sit down with him and we discuss the changes he has made since the previous afternoon.

He’s improved the responsiveness by moving away from tables and towards lists with cards that have slightly more graphical representation of the data. I think that’s a positive change. He’s also fleshed out the flow a bit more and added a couple of panels that were previously missing. I still don’t think that he’s understood the issue with context when onboarding; when adding somebody to the CRM, the team need to be able to see who else is already in the system at that agency and they want to be able to add a bunch of contacts for the same branch in one go. I give him some examples and we reach an understanding. ‘This is why it’s good to talk to you’, he tells me. It’s a good moment. The previous week I was feeling a bit stress and frustrated, mainly because of the illness I’d felt during the latter part, and it’s nice to get good feedback from your colleagues when you’re in danger of falling to a low ebb.

At 12:30 the majority of the company (i.e. everybody except me) go into a meeting where the slides for the investor meeting are demoed. I’m going to see it later so I opt to get some development work done. With nobody else around, I have a chance to focus on development for a bit. I fix a small ticket related to versioning and then while I wait for the build I update the status of a few items on our sprint board. It turns out that our burndown is still pretty good – we’re about 80% of the way to where we should be, and there’s a lot of in flight work that would take us past our target if it were finished today.

At 13:30, the build is green and it’s time to get lunch. I only take 15 minutes today – as I’m going to investor meeting I’m going to lose the afternoon for development and there are some things I want to get done first. When I get back to my desk however Jordi tells me he is having a problem with one of the endpoints. It takes about 5 minutes to ascertain that there is some rogue data in the database, related to the fact that I’d need to push an interim version of the code to our test server in order to make it available via our Nuget feed to other services. I think the new .Net Core projects are going to at least partially solve some of the issues around working with Nuget packages in development, but for now this is just something that happens occasionally when writing features that require communication between multiple services.

By the time I’ve removed the offending data, it’s almost time to go. I’ve just got time for a bit of further discussion with Sunil about the CRM and with Jordi about our eventing model, and then I’m off to the investor meeting which is being held at 3pm in our accountant’s offices near Holborn.


Movebubble Sprint: Day 6

Monday morning comes round again and I’m expecting a busy day; partly because it’s Monday, partly because I missed Friday, but mostly because we’re halfway through a sprint and it’s usually around now that we start to find the things that we missed and difficult questions about edge cases, version migrations and potential scope creep start being asked.

This is not to say that I am cynical about our chances to delivering on time; we’ve factored time for this and accepted it as simply part of the process. The question I don’t currently know the answer to is whether the slack we’ve built into the plan is a realistic amount or not.

After the two team standups and a coffee, I spend the first 10 minutes catching up on emails from Friday and then going through some uncommitted code – I’m slightly surprised to find that I actually did some work on Friday and I need to refresh my memory as to what I was working on. There are a couple of unresolved bug fixes related to some errors which are currently polluting the logs and while I’m at it I decide to review the logs from the weekend to see if there are any other issues highlighted there which might be quick fixes.

I spot two possible logging improvements, an edge case which is generating a null reference exception and a comparison which is failing due to a case mismatch, so I quickly work through these and push what amounts to 5 or 6 small fixes to master at 11:03am – just in time for our Monday Town Hall meeting where Aidan goes through the figures.

It’s another record week, but currently every week is a record week so I wonder for a moment whether we’re becoming desensitised to the company’s growth. On the flip side, while we are definitely moving in the right direction and edging closer to our target conversion rate – the key metric that we believe will enable us to attract venture capital investment in our next funding round – we’re not moving there fast enough. We need to be moving the dial at roughly twice the rate it’s currently going; that said, we’ve only just started trying.

Straight afterwards we go into our dev catch up. We don’t end up discussing much. There’s some talk about the work we’re doing at the moment and I think Laura is starting to feel the strain a little in terms of the work that is still outstanding, but overall the mood feels positive and there’s not much to say this week.

When I get back to my desk I discover that I broke the build – in my haste to push before standing up for the Town Hall meeting I had typed a couple of random characters into my IDE without noticing. I make this kind of mistake mostly because of time incentives; it can take 4 to 5 minutes to run all of the unit tests locally and our CI build can take up to 20 minutes to deploy, and I often have my attention divided in 2 or 3. As a result I sometimes take short cuts without even realising I am doing so in order to get work out so I can move onto the next thing. I make these mistakes less frequently when working with our microservices because the tests are much quicker to run.

While I wait for the build to go green, Laura has a question about the chat status message history. It quickly becomes apparent that we’ve both made different assumptions about how it would work.

The current problem we face is that we have a set of legacy status messages which are generated by viewing events and set of new status messages which get pushed directly to the chat window as part of a conversation with the agent. Many of these messages are duplicate and at the moment we have a fairly inelegant solution merging messages from the two different sources.

We want to migrate to a situation where all messages are surfaced in chat; our different assumptions centre on what to do about viewings with agents who do not have the agent app. Do we start chats for these viewings too, push status messages there, and simply disable the ability to write messages? Or do we stick to the old system of system messages for these viewings and only migrate to the new system for chat-enabled viewings? I am a fan of the first option because it means we can ultimately remove legacy code and keep things cleaner technically, but it turns out there are some good operational reasons for going with the second option and that is the solution towards which Laura had believed we were working.

Eventually, I agree with her that we should adopt the second solution and make a note to make the corresponding change in the back-end. When I get back to my desk Jordi however Jordi also has some questions for me about the behaviour of viewings and chat. As we’ve changed the nature of the relationship between the user and the agent and the code that needs to know about it is distributed between 4 codebases (our original monolith API, the new chat service and our two mobile apps) there are some difficult cases around keeping everything in sync and ensuring that new viewing requests and chats are all routed to the right place.

Jordi is concerned that, currently, starting a chat does not trigger recognition of the relationship with regards to assignment of viewings, so viewing requests could still go to other agents outside of chat. He has a point. We had considered this when talking about the feature but the behaviour had never been specified and this is an oversight on my part. Now there appear to be 3 distinct pieces of additional work that need to be done, though one of those does not need to be part of an MVP. I write up the tickets and pull them into the sprint. I’ve allowed for around 20% to 25% ‘scope creep’, and we’re still well within that; I hope, however, that this isn’t just the start.

I’d like to get on developing for the tickets I just added, but Will has done some testing and the decline viewing messages still aren’t showing. This is a complicated one because depending on the scenario we don’t immediately notify the renter because we want our viewings team to intervene and see if they can get the viewing booked at a different time. With the adoption of the agent app some of this process may potentially change, so I need to make sure that what I code is not just a slavish copy of the requirements on the ticket but that I have also taken the time to take to sales, ops and product about what they think the behaviour should be. I head over to ops to ask Bilyana a couple of questions regards how their team interacts with renters after a viewing is declined and decide that the behaviour we suggested when we wrote up the ticket is probably correct. I double check this with Will; he agrees, and it’s time for lunch.

Just as I’m about to go for lunch though, George raises a dev support ticket. The app isn’t working for a particular agent but he hasn’t included any more details on the ticket, so I need to prompt him to send me more info. He attaches some screen shots to the ticket. Now it’s time to eat.

It’s a nice day so Jordi, Laura and I grab so Itsu sushi and sit in the park at Russel Square. It’s nice to take a proper lunch break; I’m not always very good at doing that. There’s no pressure on me to work through lunch but I often put the pressure on myself; lunch is one of the few times when I can usually get 30 to 60 minutes of completely uninterrupted coding done. It’s easier to take that time however when it’s not gloriously sunny outside.

When we get back, I need to deal with the dev support ticket George raised. The text on the screen in the screenshots is too large and overlapping. I call him to get his phone version and then ask around to see if anybody has the same version. When I describe the problem to Valerio he diagnoses it for me without needing a demo; it’s related to the accessibility settings and we need to limit the size of the text in our React Native app settings for IOS. In the meantime if the agent wants to be able to use the app he’ll need to turn the accessibility settings back to the defaults.

I call the agent back and talk him through the workaround however he is (understandably) not particularly happy that it involves changing the settings for his whole phone. I tell him we will have a fix out in a release in a week or so. He gets a bit grumpy and tells me to ‘keep him informed’ before putting the phone down. I wonder if I need to improve my phone manner and then update the ticket to let George know what the status is.

There’s another dev support ticket from Ben, to merge two agency branches who want all leads to go to the same set of negotiators. I have recently added a tool to our CRM to do exactly this, so I show Ben how to do it and hopefully now that the ops and sales team can resolve this issue themselves it will reduce the overall support load, as this is a request that we had been getting a lot in the previous couple of months.

By 14:25, I’m ready to start development on the tickets I added earlier. Dev support has gone quiet so I get a relatively uninterrupted hour and by 15:30 I’ve written an endpoint to ‘claim’ all of a renter’s viewings – so that if a renter makes multiple viewing requests, the act of joining a chat by a negotiator assigns all outstanding requests to that negotiator. Of the three tickets I raised earlier, this is the most straightforward.

I still need to write a couple of tests for it but we have our weekly cross-team catch up now, where we go round the table and let everybody know what our goals are for the week. Our team’s goals are pretty clear – deliver the new Suggested Property feature for release on Friday. The Space Monkeys team have slightly more disparate goals – Adrian is working on property descriptions and some improvements to the offers flow, while Valerio and Tom are working on deeplinking in the renter app. I let everybody know that we’re still looking good for a release that Friday, though it’s going to be tight. Then again, it always is.

Back at my desk, I finish off the tests for the previous bit of function and pick up the second ticket I raised that morning, which is more complicated. This relates to how incoming viewings are assigned to contacts and the relevant code is more difficult to manipulate. I realise that I need to do some refactoring first as we have a couple of long methods which are more or less duplicating functionality and extending them with the new behaviour isn’t going to improve maintainability. Refactoring takes basically the rest of the afternoon; it’s 17:40 by the time I think I’m ready to commit my changes.

There are a couple more dev support tickets but neither of them appear urgent so I leave it until late and then follow up with the raiser (George) to check that my priority assessment is correct. One relates to email validation and the other to stray bit of data in the CRM – neither is affecting a live user so my current work feels more important and I add them to our backlog with the intention of addressing them later in the sprint.

I also have a chance to chat with Sunil about the CRM design work he’s been doing and give him some feedback. He’s talked to the sales team about their needs and has come up with some wireframe designs for a new interface that we hope will better support them in their aim of onboarding new agents. I built the previous interface myself without any design input and while it was a reasonable prototype it has long been evident that how I believed the team would use it is different from how they actually use it and we need to rethink it in order to give them better context tools and smooth the experience.

Sunil’s done a good job at distilling the various additional features that the sales team have requested; unfortunately he’s missed the main point of the redesign, largely because in his interviews the sales team were more focussed on added value features than on the frustrations that they currently have. I make some suggestions regards context for onboarding and also make some suggestions about responsiveness, since this will be accessed while the sales team are out of office more often than not. I make a mental note to talk further about this tomorrow as I want to make sure we get this right.

Then, while I am thinking about tomorrow, I ask Aidan about the shareholders’ meeting – I’d like to go. He tells me that’s fine and I should get the details from Jack. It means I’ll be out of office from 2.30pm the following day, but it only happens once every 3 months or so and I’d like to get some insight into the financial position of the company and also what kind of things the shareholders care about, as it’s a bit of the picture I don’t really have yet.

I’m about to start development again but Laura has noticed another issue in the renter app, arising from similar issues to those raised by Jordi earlier. It seems that, because viewings to chats are no longer a one to one mapping, the viewing preview doesn’t always make sense as it can contain status messages which relate to a different viewing.

There are a couple of potential solutions to this but neither of them are technically pretty and they both feel like sticky plasters over the root issue, which is that human chat messages as part of renter-negotiator discussion and per-viewing status messages are fundamentally two different types of communication and perhaps need to be treated differently.

This feels like a design issue but Simon has already left, so I drop a slack message to him with a note that we should talk about it in the morning. My feeling is that perhaps we will want to rethink the viewing preview from a design perspective in the long run but in the short term this is something that we can live with. Compromise is the essence of delivery in a startup environment and while this technically unpleasing it’s a compromise I feel we are willing to make.

When we’ve finished discussing, it’s 18:15, which means I have about 20 minutes more development time before I need to get changed and head off to 5-a-side. It’s enough time for me to get started on the changes that my refactoring enabled, but I don’t get much done. I’ll have to come back to it in the morning.

Movebubble Sprint: Day 5

Today I make it into work, but that’s about all. My brain feels heavy and I don’t really have it in me to hold more than a basic conversation. After standup I take a walk to try and feel better but when I come back to my desk I still can’t think. By 11am it’s clear that I’m not going to get any work done so after a quick chat with the CTO I just head home.

It’s inconvenient, as it’s at odds with my plans to keep a sprint blog going (attentive readers may notice that yesterday’s post was less detailed, for the simple reason that I didn’t get round to writing either that or this one until the Tuesday after).

It also feels a little bit like failure. I’ve worked in jobs, particularly early in my career, where turning up at the office has been a chore and I’d take a sick day for a cold without a second thought; but as I’ve taken on more responsibility in my work and found more fulfilment in it I’ve tended to work through sickness where I can. Today I just don’t think that’s going to work.

Still, I do keep tabs on what’s happening through the slack channel – our product manager Will is also working from home today but appears to be doing a fair bit of testing, which is a great help, and Jordi and Laura seem to be in full swing in terms of the number of tickets they are knocking off. By the end of the day it looks like we are pretty close to our expected burn down and everybody is pretty positive about our chances of getting the release out on time. That helps me switch off and relax a bit; I almost manage to spend the rest of the day without thinking about work.


Movebubble Sprint: Day 4

Thursday morning I’m not feeling great. There’s been something going round the office – both Amy and Andrew are off sick – but I can’t tell if I’m ill or if I’m just physically exhausted from a new diet and exercise regime (I’ve given up alcohol and chocolate to coincide with lent and I’ve recently started cycling in to work). I’m also frustrated with the fact that I’m still not set up to develop on Android so I’m not in the greatest mood when I start work.

After the two team standups and a much-needed coffee (extra shot of espresso in my long black today), I jump into finishing off the Android SDK installation. I seem to be having some trouble with versioning but I’m not sure if it is due to the wrong version of the SDK being installed or if we need to update some of the dependencies in our build. Jordi has been avoiding updating React Native for a while now as the last time he tried it resulted in a fair bit of pain and he hasn’t had to do a clean install and build on Windows for some time since he primarily develops on Mac.

I try and do the initial digging myself but it’s clear by 11.30 that it’s going to be much more efficient to ask somebody else for help. Valerio, one of the developers from the Space Monkeys team, volunteers and comes over the help me diagnose the problem. Together we change some of the debugging and we finally get a sensible error message; it looks like one of our plugins needs a higher version of React Native.

We can solve this by limited the version of that particular plugin to the one that we currently have installed elsewhere – our current packages file is set to pull the most recent version it can – but Valerio suggests a git-based tool which can perform the upgrade for us and take care of merge conflicts in packages upon which we depend. I’m not entirely sure I understand the upgrade pipeline at this point but Valerio is pretty confident that this is what is needed so I let him take the reigns. It does take some time to run however so we decide to break for lunch.

Today’s lunch I spend writing up the blog from the previous day; my head feels fuzzy so I’m not particularly sociable, I sit at the break out table but I take minimal part in any conversation and just focus on the writing. By the time I have finished lunch the upgrade job has finished running but there are still some versioning issues. It looks like there is a conflicting version of the SDK on the machine; it’s an old dev machine which was used by Jordi before me and he has previously been through all of this, only the relevant files get installed to personal document space so I hadn’t picked up on this before. I have a horrible moment where I realise that much of the pain I have just been through was probably unnecessary, then I take a moment and focus on the job at hand again.

I fix the conflict and build the project and finally it seems to be doing something. There’s one last gotcha – in order to integrate with our Teamcity build some of the react-native build stuff has been parameterised and this interferes with the auto-launch in the emulator, so after the emulator starts I need to actually click on the negotiator app icon to start working – and then, finally, it works!

We do need to decide what to do about the upgrade though. Jordi is nervous about it as previously it caused mayhem with a number of our plugins and he had to spend a significant amount of time fixing bugs. He doesn’t believe that he has time to do this right now and I agree, but I do think that we should be trying to keep our version at or close to the latest one so we should definitely schedule some time for this. It’s a candidate for work that can be done in the mini-sprint that we are planning when a number of the developers are taking a week’s holiday. In he meantime, I’ll work from the upgraded branch and cherry pick any commits across to the current development branch as and when I complete tickets.

In the afternoon, I start to look at the router bug. This is a little ambitious – it’s been months since I’ve done anything with React or React Native, and even then I didn’t get far beyond enthusiastic beginner. Trying to tackle a bug of this size off the bat feels a little arrogant, but my purpose is not to show off; I believe that Jordi will knock off the remaining feature tickets far faster than me and I don’t want him to get bogged down in a rabbit hole that could end up eating days of his time. Instead, I would rather take some of my own time to investigate whether it is easily solvable and, if it is not, to be informed enough to participate in a conversation about potential temporary workarounds that we can look at in order to get the release out on time.


As a secondary purpose, this is also a learning exercise – a chance for me to dig deeper into the code so I can get my head back into a React Native space. We’ve been saying for weeks that we should promote more cross-functional development within the team so that we’re all able to pick up front and back end tickets, and I’d like to be in a position to help with any front end bugs that come up after the scheduled bug hunt next Wednesday. I think a bit of time spent getting my head round the application internals will help me start to reach a deeper level of understanding of how it’s all put together.

I’m relatively uninterrupted for the rest of the day. Nothing comes in from dev support that needs my attention and everybody seems to be in the deep focus phase of development. Either that or the general feeling of moodiness that has resulted from my sense of low health today is creating a no-go area around me. I normally try to be as approachable tomorrow but today it’s a struggle to even focus on one thing so I’m quite happy for the peace.

Before I know it it’s 18:30pm. I think I’ve mapped out what the problem with the router is and where it is occurring. It looks like it’s emanating from a plugin slightly discouragingly called ‘experimal router’ and is related to the fact that we can’t have two Scenes with the same id on the routing history (i.e. we can’t go from chat to property information to renter information to chat again, because chat is where we started from). Knowing what the problem is and knowing how to solve it are too different things however and I don’t think I have the brain power for the latter today, so it is definitely time to go home.


Movebubble Sprint: Day 3

Wednesday’s we have our team breakfast at 9am. Everybody gets a coffee and a pastry from Hopper and the breakfast host directs 30 mins discussion around a set of questions submitted earlier in the week.

This week, we spend some time discussing what people think are the company’s greatest achievements this year – the success of the sales team in distributing the agent app, the introduction of the chat feature and the first end-to-end transactions through the renter app are among the highlights mentioned. Then we spend some time discussing Freddie’s Movebubble highlights as he is leaving on Friday. They seem to involve a fair bit of getting on tables and giving speeches. Freddie is possible the most passionate person I know. Finally we talk about the meditation sessions that Sunil and Laura have been running every morning at 9.15 – how are people finding them? Laura says that she thinks they help her be more productive. I haven’t tried them yet; I’m rarely in by then, though that might change now I have the new bike.

We do our standups after breakfast, my main focus for the day is to finish testing the API endpoints I set up the day before and then get set up to do some app development. I haven’t worked on either app since before Xmas and I’ve inherited a new machine since then, so that means downloading and installed Android Studio and the other dependencies for developing with React-Native on windows. Foolishly, I think this is unlikely to take more than a couple of hours.

There’s a design hangout at 10:00. This is a session which Simon (head of design) runs every Wednesday morning, to try and tap into the collective creativity of the company and crowdsource design ideas and feedback for problems that he and Sunil are working on. This week we’re focussed on our offers flow. We want people to make more offers in the app and we feel that our current flow is not as good as it could be and so Simon is trying to put together some ideas for how we can improve it.

I don’t always attend these sessions but as I had a productive day on Tuesday I feel like I’d like to be involved in this one. In previous sessions we’ve done something called crazy 8s, where you sketch 8 different ideas on a theme in a short space of time and then vote for each others ideas, kind of like design brainstorming.

This week though we’re doing the 6 hats. We start off by identifying what we know and what we would like to know about the existing offers flow, then how we feel about it, then identifying the positives and then negatives. We don’t get to hats 5 and 6 in time as we’re running out of time, so we move straight into sketching our our ideas on A4 paper. We run through each of them, commenting on what we like about each one (Simon likes the UI component I’ve drawn for selecting pets as well as people as potential inhabitants) and then we hand them to Simon. He may not use what we’ve done, but hopefully it has fed into his creative process and it’s a chance for the rest of us to do a little creative thinking which I find can help to break up the week.

We finish at 11:02, at which point I have a couple of emails to respond to. Jack is asking for feedback on which areas of our tech stack we think have improved in health and which ones have deteriorated and whether there are any areas that we feel we should be focussing on. We’re currently in the process of trying to improve the technical quality of a lot of our existing stack, by improving testability, updating frameworks and breaking things up into smaller components and microservices. It’s hard to find time to do all of this however when the business still demands we press forward at breakneck velocity, so any gains are gradual. We have succeeded in breaking out two or three of our core business features into a smaller services; these have varying degrees of health.

I then spend the next hour testing and deploying my suggested property API code. It all seems to just work, though I will wait until the other team members start using and testing it before declaring it complete, so there’s time for a coffee break and I’m ready to get started setting up React Native Android by midday.

This is where my day starts to go downhill.

Firstly, Android Studio is a behemoth. The basic package is 1.8GB and our internet connection is still pretty slow. Furthermore, I don’t have an SSD on my current dev machine and the disk feels like it is slowly deteriorating; I’d really like to replace it but I’m not sure it’s quite at the point where I can justify that to the accountants. What that means is that both download and install have pretty epic timescales.

Once I do finally get it installed I discovere that it doesn’t have most of the dependencies that I need to work with React Native. I need a specific version of the SDK, plus a specific set of Android Images for the emulator, the SDK tools and a couple of other packages on top. Downloading these takes even longer; I start the process are 14:30 and I’m still waiting the little green bar at 17:00.

In the meantime, I decide to get on with some other work that doesn’t strictly fall into the sprint. First, I need to sanitise the backlog. It’s been growing since December, without anybody really paying much attention to it and now that I’ve taken responsibility for our sprint board it’s something that I really need to get on top of. There are 150+ items in it when I start; an hour later, I’ve managed to closer about 20 as duplicate or done and move another 70 to an ‘Ice box’, for tickets covering stuff that we do want to do but which doesn’t contribute to the current business priority and so isn’t likely to get done any time soon. There’re more pruning I could do, but in the process of doing so I’ve identified 2 or 3 bugs that it makes sense for me to tackle now, so I attempt to do so.

I don’t quite get the time however. After a couple of brief discussions about introducing Code Push (a tool which will allow us to push updates to our app a lot faster in production), Laura has noticed some issues with system messages in the API which require attention. I sit with her for around 30 minutes while we go through and diagnose them, until we reach a point where testing becomes more problematic and so I retreat back to my desk to set up a test environment and follow up.

By 17:20 I’m got my test setup running, and an hour later I’ve diagnosed and fixed the problems. But now we’re having trouble with Teamcity (a Java update has caused problems) so I can’t deploy immediately. In the meantime, the Android dependencies have finally finished installing and, fingers crossed, I can make a start on some UI tickets.

I can’t get it to work though. There’s an error message about being unable to find the right version of tools and I have zero expertise in this area with which to debug. I’m not feeling great either and my brain isn’t functioning at 100%, so I decide that it would be best to debug this and the Teamcity issue in the morning.

It’s not been a satisfactory day; after a full day of productive on Tuesday I feel like today I’ve achieved very little and I’m going to arrive in the following morning with a number of unfinished tasks. I spent a bit of time shuffling cards around the sprint board before I realise that it’s time I just stopped working. 5-a-side football will put me in a better mood.

Movebubble Sprint: Day 2

Today promises to be a quieter day – no meetings scheduled, outstanding support issues largely resolved, and half the development team out at a React conference.

My main goal for the day is to get ahead of the game a little by knocking off at least one of the two API-related tickets which need to be completed to support the new property suggestion feature; if I can get those done early in the sprint it frees me up to help elsewhere and pick up other stuff

Before I dive into that though there are the two standups and the routine morning coffee. Between standups, I also check that yesterday’s efforts to finish off the A/B testing framework ran okay. There can be a delay of a couple of hours after setting up SQL replication for RavenDB before the data fully catches up and as a result I was unable to verify the cohorts before leaving the day before. It turns out we’re allocating 31% where we should be allocating 30%; I fix the off-by-one error and inform the other team that the test framework is good to go.

Once I have my coffee, I start development at around 10.10. I’m able to dive pretty much straight into code – it’s a simple API endpoint to return a subset of our property data sorted in one of four ways. As such, I don’t need any time to think about design and there aren’t any events or triggers to worry about, so I’m in the zone quickly and confident I can bash out the code and associated tests by mid-afternoon.

I’m largely uninterrupted. Laura has a couple of questions about our system messages – she’s only been developing for a few months and is new to C# in particular, so this is expected. As a startup we don’t have a training budget so we handle training in a task-driven manner – Laura picks up tickets like other members of the team and then asks questions when she gets stuck. I tend to help with the backend ones; for front end questions it’s usually Valerio (of the Space Monkeys), Jack (our CTO) or Jordi. In my first job they had a similar approach to training and I was told it usually took around 18 months to become a ‘fully productive’ developer, so I expect this to continue for some time. Already though I have noticed that the frequency of the questions has reduced, which is a positive sign.

Otherwise, it’s nearly lunchtime before I’m pulled out of my zone. Adrian, the lead developer for the Space Monkey’s team, is using our app to find a property for himself, and has noticed some odd behaviour in our chat feature. As soon as he shows me I realise this is related to a configuration error which I pushed on Saturday and fixed the day before. I assure Adrian that the code he’s just pushed should fix this; though I am a little chagrined that I hadn’t realised users would be affected in the way he demonstrates.

Then again, there was a time when any bug that ended up in our live environment had me panicking. In particular, a couple of the mistakes I’ve made over the last six months have had fairly major, if temporary, affects on the usability of our app. However, I’ve come to accept that an inevitable side effect of attempting to do several things at once at double speed is that mistakes get made.

We could slow down and push back, but from a business perspective it’s helpful to be able to maintain the development pace we have, so while bugs which make it production still disappoint me, my reaction is no longer one of self-castigation. Rather, I am constantly asking the question ‘how can we improve the process to prevent this without compromising on development speed’? Not all of the ideas I have relating to this get actioned, but I do feel we are making progress.

By the time we’ve finished discussing and investigating the problem, it’s nearly midday, so I decide to grab an early lunch. Today it’s Hopper meal deal – £4 for a sandwich and a coffee – and I take my laptop to the lunch table so that I can write up yesterday’s blog account.

The first draft takes around an hour – punctuated by 20 minutes of helping Laura debug some irritating quirks of Nuget and Visual Studio – and I’m back at my desk at around 13:30. Writing is not a standard lunch activity for me, it’s just the first chance I’ve had to write up the previous day as I spent the previous evening play football and starting the latest season of Suits which has finally made it onto Netflix and which has become something of a ritual with my wife (complete with our own theme music dance).

I dive back into code and bar one more 10 minute session answering Laura’s API-related questions I’m again able to sink myself into my work, to the point that I’ve finished my ticket and written all associated unit tests by 15:20. However, I’m not able to merge my ticket just yet as the build is broken. Laura has merged her finished status message work, but as she’s not yet fully accustomed to the workflow she has forgotten to check that it builds correctly and run all the tests. I take the opportunity to tease both her and Jordi about this (since Jordi did exactly the same thing on Friday) with a mock ‘appreciation’ – a Slack channel where we post messages when we think somebody has done good work. Jordi, seeing his name mentioned, sends me a worried message from the React conference, wondering what he’s done – I assure him that it’s just banter.

There’s some kind of issue in our dev environment – apparently we’ve fired off 50,000 test emails and used up our Mailgun allowance – but I let Jack and Adrian sort it out as I look down my todo list for something to do while I wait for the build to be fixed. I’ve got some outstanding documentation tasks – nothing critical, but I’ve been trying to formalise our sprint process and get it all on the wiki as I feel like we’ve been guilty of making stuff up a little over the last few months. The idea is that everybody on the team should know not only how we run a sprint but why we do it like we do and that we’re actually able to extract useful metrics relating to velocity, scope creep and our ability to meet deadlines. We haven’t really been keeping those metrics up until recently but I would like that to change.

So I spend 50 minutes updating the wiki space that I started a couple of weeks back – I add a document relating to our technical preplanning session and a table for tracking velocity metrics and support load. Once the build is fixed I save my progress and then go back to development; merging the previous ticket into master and then adding a new branch for the next API ticket. I could have started on this an hour earlier, but as both Laura and I were working in the same space I preferred not to branch off before merging her code as there were a number of conflicts to be resolved.

From there, I’m pretty much on the home straight. I get another hour and a half of development in, finishing at around 18:45. I would normally aim to finish work before this on a Tuesday – other than Friday, it’s the only night of the week when neither my wife nor I have a regular engagement in the evening – but a long lunch coupled with the fact that I was enjoying some uninterrupted development team mean that I’m quite happy to spend a bit of extra time in the office. Today I am the last to leave. I’ve also nearly managed to complete the second API ticket – just a couple more tests to write in the morning – which will put me a day or two ahead of schedule already.

All in all, a good, productive day.

Movebubble Sprint: Day 1

It’s Monday morning and we’re starting a new sprint today. These days are generally pretty hectic – a lot of meetings (sprint planning, weekly KPIs, cross-team catch up, dev catch up) and a lot to think about (what can we commit to in this release? what’s still outstanding from the last one?). Today doesn’t get off to a great start because we arrive into the office to discover that neither of our internet providers are working – apparently some external issue with a cable. So after the standup I bring forward some of the other meetings that I had planned for the day with the hope that the internet connection is back by the time they are done.

I attend two standups – one at 9.45am for my team (Water Camels – don’t ask) and one 9.30am for the other development team (Space Monkeys). The idea is that myself and Adrian, the two lead engineers, attend each other’s standups to ensure we have a good picture of what both teams are doing to try and guard against lapses in communication when the teams are working on cross-functional spaces. Once standup is over, we ritually head down to Hopper to grab our coffees, which is a chance for a slightly more informal catch up (‘hey, how was your evening’ type thing) with the other members of the team.

At 10 we have our dev catch up, brought forward since we’re without internet. There are three developers in Water Camels and we sit round like this every week for 20-30 minutes as a chance for everybody to raise any concerns they have with development, planning, process or anything else really. A couple of really good suggestions have come out of these in the past few weeks; this morning we don’t have much to talk about until Laura suggests we discuss how we’re going to handle Jordi’s remote working arrangements when he starts working from Barcelona. It quickly becomes apparent that our expectations on this are misaligned and this is something that we’re likely to have to work on in the coming weeks.

The internet is still broken when I get out so I then have a catch up with the CTO. We don’t have too much to say; I have a couple of suggestions about how we can reduce the support load by making a key component testable at an earlier phase in our development cycle, however while I do get his buy in I feel like getting the time to actually implement them is unlikely in the next month or so. As a startup with a limited roadmap we’re under constant pressure from business requirements to be implementing new features at the expense of investing in infrastructure and other NFRs; this is something I will need to push for but I don’t see it getting done before the start of May.

Then there’s one last catch up with Jordi regarding his working arrangements before we’re into sprint planning. This is a new relatively responsibility for me, one that I’ve been doing for about 6-8 weeks now. Previously our Head of Product (Will) was handling it but his workload was even more demanding than mine so we decided to split the burden of managing the planning overhead for our team.

Currently, our process is to do a technical planning session on the Thursday before a sprint to pull out all the individual technical requirements and write those up as stories. I’ll then spend a bit of time the following day updating the descriptions and requirements and following up individually with the designer and developers on any outstanding questions, then Monday is really just about sizing the work and then negotiating with Product as to what we can commit to for the next sprint and/or release.

Today, it takes me about 15 minutes to prepare for the meeting than at 11.30am I sit down with Sunil (our team’s designer), Jordi and Laura and we estimate all of the tickets with story points. We allocate points in sizes of 1,2,3,5,8 or 13, where 1 is ‘I could turn this round before you finish your coffe’, and 13 is ‘er, fuck, that’s at least 3 days, maybe we should break this down a bit more’. We try to keep our stories as small as possible as it helps ensure that they are testable and tested. Most of them end up being in the 2 to 5 range (a couple of hours to around a day a half).

We’re targing 30 minutes for planning but we overrun slightly and it takes 45. I then sit down by myself to close off the previous sprint, chatting to each of the others individually at their desks if there is anything in an ambiguous state and moving across an estimate of the relevant number of story points for any unfinished items. It looks like our velocity for the last sprint was about 35 points per week – I’d like to get this up to 45 or 50 but in order to do that we need to reduce the support load. Also, 11 of those points represent scope creep, but I don’t think this is so much of a problem – the nature of our business means there are always things which are ambiguous or missed when we start a development cycle, we just need to make sure we account for this in our planning.

As a result, I reckon that we can handle around 60 points of work before our next targeted release on the 7th April. We’ve estimated the new feature at 73 and have around 10 left over from the previous week (as a direct result of scope creep). I communicate this to Will and we sit down and go through the design and identify around 20 points of work that aren’t required for a true MVP. This takes around 15 minutes; what results is an aggressive but achievable sprint commitment for a paired down version of the new suggested properties feature. I make the appropriate adjustments to our sprint board and then grab a quick 15 minute lunch.

It’s 13:30 and I haven’t written a single line of code.

The afternoon is more development-focussed – and more chaotic. I released some code on Saturday (I don’t normally work weekends, but the code in question was for an overnight job and I really wanted the results to be ready on Monday) and as a result there are a couple of support items that need my attention. One is a configuration bug with the code I released which is easily fixed, but which has highlighted a missing case in our business logic – some events are being fired which make an assumption which isn’t true and so I spent around 90 minutes fixing the code to handle that missing assumption.

During that 90 minutes I also fire off a communication about the scope of our new build, help to diagnose another issue surfacing with our chat feature in live and discuss the outstanding work that needs to be done for our new split testing framework (which is related to the Saturday release). On the back of diagnosing the chat issue, I then need to apply a fix to ensure that we are migrating some dates correctly, as this is affecting our SQL replication (we use a document DB for our production logic and replicate this to a SQL database for use by our data scientist). This takes me about 50 minutes.

Before I can do that though we have a cross-team catch up – once a week, we have a group ‘standup’ where we tell everybody what our main goals for the week are, another attempt to ensure we keep communicating cross-team. I also need to check up on the SQL replication for the split testing code so we can analyse a dry run AA test and check that users are being assigned to cohorts in the correct proportions. There’s a test for a viewing reminder that needs fixing and another chat-related test that has started failing due to Daylight Saving Time. And just when I feel I’m getting on top of it, Jordi identifies a problem with the React Native router that we’re using in the agent app, which basically makes it impossible for us to achieve the navigation structure we’re aiming; at least, without further diagnosing the issue in the third party library.

My day finishes at around 18:15 – I have a 5-a-side game at 19:00. It’s been a particularly chaotic one; so much context-switching has left me with the distinct feeling that I’ve forgotten to do something important, not dissimilar to arriving at the airport and suddenly panicking that you’ve forgotten your passport, or getting halfway to work and glancing down quickly to check that you remembered to put your trousers on. Most days aren’t quite this crazy but then the constant feeling of having a million things to do is energising in a peculiar way.