Enhancing Focus with Thematic Sprints in Our Dynamic Development Team

Created by DALL·E

In the fast-paced world of software development, maintaining focus is crucial, especially for our dynamic team, which consists of a core of four developers but can expand to about a dozen. We’ve found that implementing thematic sprints—where each sprint is named after a specific theme or goal—significantly enhances our productivity and engagement

When our team is small, usually capped at six members, we experience a focused output with active involvement from developers in the planning phase. However, we’ve noticed that stories can grow in complexity, leading to a loss of focus and extended timelines. To address this, we started naming our sprints with clear themes, creating a shared understanding of our objectives.

This simple practice reinforces our commitment during daily stand-up meetings, where we consistently reference the sprint theme. By framing our work around these themes, developers stay aligned with our goals and feel a greater sense of ownership.

Moreover, thematic sprints foster collaboration. As we engage with a specific focus, discussions naturally emerge, leading to innovative solutions and richer features. For instance, dedicating a sprint to user experience made our team more attentive to feedback, resulting in improved designs.

In conclusion, thematic sprints have transformed our development process, enhancing focus and creativity while nurturing a culture of collaboration and innovation. This approach has proven invaluable in our journey as a dynamic software development team.

Development questions…

I’ve been working on compiling a set of questions we should ask at the outset of each new feature. In my experience, teams often become laser-focused on coding and implementing new features without considering the broader context. I believe it’s crucial to be proactive and demonstrate the value of our work to the company, as ultimately, the bottom line is what matters most.

For every new feature, let’s ensure we ask these questions. The responses we gather can then inform the creation of tickets and specifications, ensuring that we’re aligned with both technical requirements and organizational objectives.

AspectQuestions
Top Level User Story– What is the main objective or goal of this feature/change?
Security Concerns– Are there any potential security vulnerabilities or risks associated with this work?
Organizational Policies and Processes– Are there specific policies or processes that need to be adhered to during development?
Value Addition– How does this work enhance the application/product?
– What additional benefits or improvements does it bring?
Justification– Why is this work necessary or important?
– What problem or need does it address?
Proving Worth– How can we demonstrate the impact or value of this work?
– What criteria or metrics can be used to measure its success?
Monitoring– What metrics or indicators can be used to track the performance or usage of this feature/change?
– How will we monitor its effectiveness over time?
Technical Requirements– Are there any specific technical constraints or dependencies that need to be considered?
– What technologies or frameworks should be utilized for this work?
User Experience (UX)– How will this work impact the user experience?
– Are there any usability considerations to be aware of?
Testing and Quality Assurance– What testing strategies will be employed to ensure the quality of the implementation?
– Are there any specific test cases or scenarios that need to be addressed?
Scalability and Performance– How will this work scale as the application grows?
– Are there any performance considerations or benchmarks to meet?
Documentation– What documentation needs to be created or updated as part of this work?
– How will knowledge transfer be facilitated for other team members?
Deployment and Rollout– What is the deployment plan for this work?
– Are there any rollout or release strategies to consider?
Feedback and Iteration– How will feedback be collected and incorporated into future iterations?
– What mechanisms are in place for continuous improvement?
Collaboration and Communication– How will communication be maintained between team members and stakeholders throughout the process?
– Are there any collaboration tools or platforms to be used?
Risk Management– What potential risks or challenges could arise during implementation, and how will they be mitigated?
– Is there a contingency plan in place for unexpected issues?

Replacing ObjectId with a string in JSON. Using RegEx

Problem: I have a data dump of a MongoDb query in a JSON file. I need to replace the ObjectID(“12345677abc”) with “12345677abc”.

Using Visual Studio Code’s find and replace

Find:

ObjectId\("([0-9a-fA-F]{24})"\)

Replace with: “$1”

Turns this

"_id" : ObjectId("5e3b1890e032d225a091d43f"),
"userId" : ObjectId("65ed1c2c-922c-4c82-b5bc-7324f69eea10"),

To this

"_id" : "5e3b1890e032d225a091d43f",
"userId" : "65ed1c2c-922c-4c82-b5bc-7324f69eea10",


Bonus:

ISODate\("([^"]+)"\)

Fire and Forget

Yesterday was spent diagnosing what was reported as CORS issue in a Node service used for logging that was being called by front end apps.

CORS turned out to be a red herring, it ended up being the wrong format for a new database connection string, less than gracefully handling errors (it would just die and return 500), but what concerned me was the frontend request (sending a packet to a remote logging service) was not necessary to the successful sequence of editing and saving an object (plus it was sent prior to the event being successful) and would halt following requests.

The frontend fix was a “fire and forget” call to send a logging packet to the Node service, while not ideal if the service was down it would not effect frontend users experience.

const logEvent = (str) => {
  const send = async (str) => {
    // send the request, it might throw an error
    throw new Error(`thrown....${str}`)
  }

  send(str).catch(() => {
    // If you don't catch the error you can/will end up with a non handled exception error.
    console.log('It did not break, log error with service like Azure App Insights')
  })
}

console.log(
  logEvent("do nothing")
)

NPM update

So, for a long time now our projects CI/CD pipelines have an audit step and will prevent merging if there and high risk issues. Nothing complicated just

npm audit

Then a developer would need to sit down and follow their own approach to updating NPM packages. Mine was to install all the patch versions – test, minor versions and test. Then I’d take a stab at any major versions after reading any release notes.

See: https://docs.npmjs.com/about-semantic-versioning

It works, but it is a pain.

Then I found NPM GUI

https://www.npmjs.com/package/npm-gui

After installing it globally, I run the following command

npm-gui

This opens a browser tab and will first show all the global packages and versions. Navigate to your directory that has the package.json file, a nice table of installed node packages is displayed with required, current, compatible and latest versions. Clicking the versions will install them.

I still follow the same work flow of patches, minor and major versions but it takes me far less time and cognitive load to update projects.

It might not be perfect, but the rest of my team have started using this and its helped overcome the dread of package maintenance.

JS Sorting with .localCompare

I’ve been using Javascript for 2 years now and can not remember ever having to sort collections. 95% of what I am doing is backend services work and I try to off load as much data manipulation to the databases, but this week I have had 7 instances of having to sort data.

This caught me out:

For a given collection:

const collection = [ {name: "Dave"}, {name: "Donna"}, {name: "dave"}, {name: "Derek"}, {name: "Dave"},];

Sorted with:

collection.sort(
  (a,b) => { 
    if (a.name < b.name) return -1; 
    if (a.name > b.name) return 1; 
    return 0;
  })

Returns this:

[ { name: 'Dave' },  { name: 'Dave' },  { name: 'Derek' },  { name: 'Donna' },  { name: 'dave' } ]

Which is not what I need.

.localCompare to the rescue

collection.sort(
  (a, b) => a.name.localeCompare(b.name)
)

Returns this:

[ { name: 'dave' },  { name: 'Dave' },  { name: 'Dave' },  { name: 'Derek' },  { name: 'Donna' } ] 

But there is more

.localCompare method has additional options. For the same collection above, this

collection.sort(
  (a, b) => a.name.localeCompare(b.name, 'en', { sensitivity: 'base' })
)

Returns this:

[ { name: 'Dave' },  { name: 'Dave' },  { name: 'dave' },  { name: 'Derek' },  { name: 'Donna' } ] 

Be aware that full implementation of .localCompare in Node.js is dependant on the version you are running.

Quick1: JS funky date requirement

The problem is:

Take a date object, set the time to 09:15 the following day. If that day is a Saturday, Sunday or Monday bump the date to the next Tuesday.

Solution:

const reminderTime = (date: Date): Date => {
  const response = new Date(date);
  
  const SUNDAY = 0;
  const MONDAY = 1;
  const TUESDAY = 2;
  const SATURDAY = 6;
  
  response.setDate(response.getDate() + 1);
  
  if ([SUNDAY, MONDAY, SATURDAY].some((x) => x === response.getDay())) {
    response.setDate(response.getDate() + ((TUESDAY + 7 - response.getDay()) % 7));
  }

  response.setHours(9);
  response.setMinutes(15);

  return response;
};

Is the date local or UTC? That depends on how the Date object passed into the method was created. In either case local or UTC is preserved.

Here are some proofs:

console.log(reminderTime(new Date(2020, 10, 2))); 
// Returns Tue Nov 03 2020 09:15:00 GMT+0000 (Greenwich Mean Time) 

console.log(reminderTime(new Date(2020, 10, 3)));
// Returns Wed Nov 04 2020 09:15:00 GMT+0000 (Greenwich Mean Time)

console.log(reminderTime(new Date(2020, 10, 4))); 
// Returns Thu Nov 05 2020 09:15:00 GMT+0000 (Greenwich Mean Time) 

console.log(reminderTime(new Date(2020, 10, 5)));
// Returns Fri Nov 06 2020 09:15:00 GMT+0000 (Greenwich Mean Time) 

console.log(reminderTime(new Date(2020, 10, 6)));
// Returns Tue Nov 10 2020 09:15:00 GMT+0000 (Greenwich Mean Time) 

console.log(reminderTime(new Date(2020, 10, 7)));
// Returns Tue Nov 10 2020 09:15:00 GMT+0000 (Greenwich Mean Time) 

console.log(reminderTime(new Date(2020, 10, 8)));
// Returns Tue Nov 10 2020 09:15:00 GMT+0000 (Greenwich Mean Time) 

console.log(reminderTime(new Date(2020, 10, 9)));
// Returns Tue Nov 10 2020 09:15:00 GMT+0000 (Greenwich Mean Time) 

console.log(reminderTime(new Date(2020, 11, 31)));
// Returns Fri Jan 01 2021 09:15:00 GMT+0000 (Greenwich Mean Time) 

console.log(reminderTime(new Date(2020, 1, 29)));
// Returns Tue Mar 03 2020 09:15:00 GMT+0000 (Greenwich Mean Time) 

console.log(reminderTime(new Date(2020, 1, 30)));
// Returns Tue Mar 03 2020 09:15:00 GMT+0000 (Greenwich Mean Time) 

Quick1: JS Order array of Date objects

Solution: (Typescript)

(range as Date[]).sort((a, b) => a.valueOf() - b.valueOf());

My first thought was why not just:

(range as Date[]).sort()

But that does not work. Have a look at the MDN documents and you will see the comparison is done with character’s Unicode code.

Try this in your browsers console to see the solution working

const range = [
  new Date("2020-09-10"),
  new Date("2020-12-20"),
  new Date("2020-11-12"),
];

range.sort((a, b) => a.valueOf() - b.valueOf())

Quick1: JS array of dates

I always disliked dates in JS, but as time goes by confidence grows. It does not help that I avoid reaching for external packages unless it is really necessary.

Today I needed to generate arrays of numbers that represent days between two dates.

// Outcome needed. Inputs 2020-10-28 and 2020-11-06
const labels = [28,29,30,13,1,2,3,4,5,6];

// Solution
export const getDatesBetweenDates = (
  startDate: string,
  endDate: string
): number[] => {
  const dates: number[] = [];
  const start = new Date(startDate);
  const end = new Date(endDate);
  while (start <= end) {
    dates.push(start.getDate());
    start.setDate(start.getDate() + 1);
  }
  return dates;
};

I have no idea why I thought that would be hard