Onboarding Senior Developers – Keys to Success

I have hired a bunch of senior developers for some of my clients as part of my CTO-as-a-Service consultancy. I have also hired many senior developers in my past lives in large corporations.

I think that the main thing that I need to ensure is that the new developer does not experience a sense of regret and frustration when they walk in the door. I remember the things that have frustrated me in the past, and I make sure that these situations are not repeated with the new developer.

Here is what I try to have set up on the day that they join:

1) New laptop with enough power that a heavy-duty developer needs.

2) All accounts have been set up. Nothing more frustrating than having the developer sit around for a few days, waiting for access to email and Github.

3) All of the software has been licensed and (maybe) pre-installed. This includes all third-party frameworks and tools that require subscriptions.

4) Up-to-date Wiki and Jira (or whatever project-management software the company is using). Make sure that the architecture and system documentation is up to date.

5) Clear tasks defined for the first few weeks. Maybe there is a small feature that the app needs right away? Give it to the new dev to get them warmed up to the codebase.

6) All HR and Payroll-related items are done. If the person needs a company credit card, the card (or the application for the card) is waiting for them.

7) Proper introductions to the senior team. Does everyone know that the senior developer is joining? Do they already know how the senior developer aligns to the success of the company? If the senior developer is aligned to a certain business unit, do the people in that business unit know what the senior developer will be working on?

8) Make sure that there are people around to answer questions. Especially if the codebase has tricky parts that are difficult to understand. Make sure that all important architecture decisions have been memorialized on the Wiki.

There is nothing more satisfying to the new developer than hearing someone say “XYZ really hit the ground running, and has made an immediate impact”. Do everything you can to make sure that the new developer gets to hear that sentiment expressed by your senior staff.

Getting Started with Visual Studio Code, .NET Core, and AWS Lambda

The way that I have usually written C# .NET Core applications is to use Visual Studio 2017/2019 on my Windows laptop. Since my primary laptop is now a Mid-2012 MacBook Air, I have been using Visual Studio for Mac as my primary IDE for writing C# apps, mainly using Xamarin. I have been a big fan of Visual Studio Code for writing Node and Python apps, but I never tried to write a .NET Core app that targeted AWS Lambda. This article details the steps that I took in order to write my first C#-based Lambda function on my MacBook and deploy it to AWS.

One of CTO-as-a-Service’s clients current has a synchronous function that is used to generate Microsoft Word documents from data that is stored in an SQL Server database. Currently, the document generation process runs on a single HP DL360 server. When many people need to generate documents at the same time, the performance of the server degrades so severely that it impacts the company.

As part of the migration to AWS that I am doing, I wanted to take this document-generation process and move it to a Lambda function on AWS. This way, when the company has to generate a lot of documents at month-end, we can kick off a Lambda function that would generate a single document. The generated document will then be stored on S3, and a notification would be broadcast on SNS.

I wanted to write refactor the code as a Lambda function, but I wanted to do so using Visual Studio Code on my lightweight MacBook instead of using my much-heavier Windows machine. Of course, I could have used my MacBook to remote into my Windows machine, but out of curiosity, I wanted to see if I could do everything on my MacBook.

The first step was to read the AWS documentation on writing Lambda functions using C#. The AWS reference article on .NET development and Lambda functions is here:

https://docs.aws.amazon.com/lambda/latest/dg/dotnet-programming-model.html

Prerequisites on your Computer

Install the AWS CLI

Install the extensions to the dotnet command line. These extensions will let you deploy and invoke a Lambda function from the command line.

dotnet tool install -g Amazon.Lambda.Tools

Install the AWS Lambda Templates extension to the dotnet command line, and ensure that the AWS templates have been installed

dotnet new -i Amazon.Lambda.Templates

Make sure that the new templates have been installed by running this command:

dotnet new -all

In order to generate the code, you need to know which profile you will be using when the Lambda function is deployed and executed. You can find the name of your profile by viewing the file ~/.aws/credentials. The profile should contain your access key, your secret key, and optionally, the region and the output format.

Also, before you start, go into the IAM console on AWS and make sure that the IAM role that you use has policies that will let you access Lambda functions, as well as letting the Lambda functions access certain AWS services (like S3, SNS, Dynamo, etc).

In Visual Studio Code, you should do the following:

  • Install the AWS Toolkit for Visual Studio Code extension
  • Make sure that the various C# extensions have been installed, most notably C# for Visual Studio Code
  • Install the NuGet Package Manager extension

Generate the Project and Code

Generate a simple skeleton project

Open us a Terminal. Create a new directory, and cd to that directory. For example,

mkdir MyFirstLambda

cd MyFirstLambda

We want to generate the skeleton project and code. Run the command:

dotnet new lambda.EmptyFunction –name DocGenerator –profile default –region us-east-1

This will create a directory called ./MyFirstLambda/DocGenerator.

Notice that we are using a profile named default. This should be an entry in the ~/.aws/credentials file.

In Visual Studio Code, open the folder containing your new project. Note that you should open the folder below the new directory you created. In the case above, open the DocGenerator folder, not the MyFirstLambda folder.

When you open this folder in Visual Studio Code, you will be prompted to restore some files. In addition, the .vscode directory might be created for you.

Add build, deploy, and invoke commands to the tasks.json file. (see the Appendix below)

Once the tasks.json file has been set up, you have three commands available to you. Build, Deploy, and Invoke. I just cycle through these commands using Visual Studio Code’s Terminal/Run Task menu. At the end of this cycle, you should have your new Lambda function built, deployed on AWS, and tested.

A simple Lambda function will be generated for you. This function looks like this:

// Function.cs

using Amazon.Lambda.Core;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]

namespace DocGenerator
{
  public class Function
  {
      public string FunctionHandler(string input, ILambdaContext context)
      {
          return input?.ToUpper();
      }
  }
}

The entry point is defined in the file named ./src/DocGenerator/aws-lambda-tools-defaults.json

"function-handler" :              
"DocGenerator::DocGenerator.SNSFunction::FunctionHandler"

Once your Lambda function is running, you can use the AWS Explorer panel to view the Lambda.

Adding SNS Support

In Visual Studio Code, go to the Command Palette, and use the NuGet Package Manager:Add Package function to install the Amazon.Lambda.SNSEvents package.

Write the new SNS function handler.

using Newtonsoft.Json;

namespace DocGenerator
{
public class Function
{
public void SNSMessageFunctionHandler(SNSEvent snsEvent, ILambdaContext context)
{
var jsonEvent = JsonConvert.SerializeObject(snsEvent);
var jsonContext = JsonConvert.SerializeObject(context);

context.Logger.Log(jsonEvent);
context.Logger.Log(jsonContext);
context.Logger.LogLine("-----------------------------------------");
}
}
}

In ./src/DocGenerator/aws-lambda-tools-defaults.json, change the function handler:

“function-handler” :  “DocGenerator::DocGenerator.Function::SNSMessageFunctionHandler”

Build and deploy the new code.

Testing the Code

Go into the SNS Console and create a new topic. Let’s call it Simple-Lambda-Notification.

In the SNS Console, create a new subscription for this topic. For the protocol, choose AWS Lambda. For the endpoint, choose the DocGenerator function.

In the SNS Console, publish a message on the topic. Then look at the CloudWatch log. You should see the log messages that indicate that the message was received from SNS.

The Lambda Context

The LambdaContext is passed into the handler function and contains information about the environment that the function is operating in. You can use the LambdaContext to perform logging to CloudWatch, to determine who called the function, and to get the unique request id in case you need to notify the caller asynchronously that the function has completed. The LambdaContext looks like this:

{
"FunctionName": "DocGenerator",
"FunctionVersion": "$LATEST",
"LogGroupName": "/aws/lambda/DocGenerator",
"LogStreamName": "2019/04/30/[$LATEST]10dd5bcf08994166b84a1d3189f2f18b",
"MemoryLimitInMB": 256,
"AwsRequestId": "c533b777-e333-45ca-a78e-0b12d63c513d",
"InvokedFunctionArn": "arn:aws:lambda:us-east-1:901643335044:function:DocGenerator",
"RemainingTime": "00:00:27.7060000",
"ClientContext": null,
"Identity": {
"IdentityId": "",
"IdentityPoolId": ""
},
"Logger": {}
}

Adding Support for the API Gateway

As illustrated in the architecture diagram above, the entry point to our Lambda function should be a REST call emanating from the AWS API Gateway.

You need to import the NuGet package named Amazon.Lambda.APIGatewayEvents in order to be able to use the C# classes that support the AWS API Gateway.

Create a new class called APIGatewayFunction. Here is the code:

using Amazon.Lambda.Core;
using Amazon.Lambda.APIGatewayEvents;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net;

namespace DocGenerator
{
  public class APIGatewayFunction
  {
      public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request,

ILambdaContext context)
      {
          var jsonEvent = JsonConvert.SerializeObject(request);
          var jsonContext = JsonConvert.SerializeObject(context);
         
          context.Logger.Log(jsonEvent);
          context.Logger.Log(jsonContext);
          context.Logger.LogLine("-----------------------------------------");

          return this.CreateResponse(request);
      }

      private APIGatewayProxyResponse CreateResponse(APIGatewayProxyRequest request)
      {
          int statusCode = (request != null) ?  (int) HttpStatusCode.OK

: (int) HttpStatusCode.InternalServerError;

          PostPayload payload = JsonConvert.DeserializeObject<PostPayload>(
           request.Body ?? "{\"message\": \"ERROR: No Payload\"}");
         
          // The response body is just the upper-case version of the string

// that was passed in
          string body = (payload?.message != null)

? JsonConvert.SerializeObject(payload.message.ToUpper())
                              : string.Empty;

          var response = new APIGatewayProxyResponse
          {
              StatusCode = statusCode,
              Body = body,
              Headers = new Dictionary<string, string>
              {
                  { "Content-Type", "application/json" },
                  { "Access-Control-Allow-Origin", "*" }
              }
          };
 
          return response;
      }
  }

  public class PostPayload
  {
      public string message { get; set;}
  }
}

In ./src/DocGenerator/aws-lambda-tools-defaults.json, change the function handler:

"function-handler" :  "DocGenerator::DocGenerator.APIGatewayFunction::FunctionHandler"

Build and deploy the new code. Now it’s time to create a new API Gateway that will be used to handle the REST integration to the Lambda function.

Create the API Gateway

In the first step, we go into the API Gateway dashboard and create a new REST API called DocGeneratorAPI.


We will create a single resource called Document. Any API calls for this resource should contain /document in the URL path.


We will hook up the API to the new DocGenerator Lambda function that we just created. Notice that we check the Use Lambda Proxy Integration option.


After saving the API, we will just go to the Lambda dashboard for a second to make sure that the API Gateway is a new input source for the Lambda.


Back in the API Gateway dashboard, we want to test the new API. Click on the blue lightning bolt in order to run a test.


We will POST a request that has a simple message body. If successful, we should get a response that has a capitalized version of the message.


We see that the response is indeed the capitalized version.

We can examine the APIGatewayProxyRequest that our function was invoked with.


{
   "Resource": "/document",
   "Path": "/document",
   "HttpMethod": "POST",
   "Headers": null,
   "MultiValueHeaders": null,
   "QueryStringParameters": null,
   "MultiValueQueryStringParameters": null,
   "PathParameters": null,
   "StageVariables": null,
   "Body": "{\n    \"message\": \"This is a document\"\n}",
   "RequestContext": {
       "Path": "/document",
       "AccountId": "XXXXXXXXXXXXXXXX",
       "ResourceId": "ec0wv3",
       "Stage": "test-invoke-stage",
       "RequestId": "88182293-6c2a-11e9-9e20-09edba43f9b6",
       "Identity": {
           "CognitoIdentityPoolId": null,
           "AccountId": "XXXXXXXXXXXXXXXX",
           "CognitoIdentityId": null,
           "Caller": "XXXXXXXXXXXXXXXX",
           "ApiKey": "test-invoke-api-key",
           "SourceIp": "test-invoke-source-ip",
           "CognitoAuthenticationType": null,
           "CognitoAuthenticationProvider": null,
           "UserArn": "arn:aws:iam::XXXXXXXXXXXXXXXX:root",
           "UserAgent": "aws-internal/3 aws-sdk-java/1.11.534 Linux/4.9.137-0.1.ac.218.74.329.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.202-b08 java/1.8.0_202 vendor/Oracle_Corporation",
           "User": "XXXXXXXXXXXXXXXX"
       },
       "ResourcePath": "/document",
       "HttpMethod": "POST",
       "ApiId": "brpqzm8gdj",
       "ExtendedRequestId": "ZAtsDEw2oAMFu6Q=",
       "ConnectionId": null,
       "ConnectionAt": 0,
       "DomainName": "testPrefix.testDomainName",
       "EventType": null,
       "MessageId": null,
       "RouteKey": null,
       "Authorizer": null
   },
   "IsBase64Encoded": false
}

Enhancements

You might notice that the FunctionHandler in the C# code does not examine the HttpMethod and the Path of the request in order to implement different behaviors. The code assumes that a POST request and a specific payload are being passed in. Of course, the FunctionHandler needs to be made bullet-proof so that it will handle different methods and paths.

Appendix

tasks.json

The tasks.json file is located in the .vscode directory of a project and contains a JSON-formatted list of tasks that Visual Studio Code can invoke.


{
   "version": "2.0.0",
   "tasks": [
       {
           "label": "build",
           "command": "dotnet",
           "type": "process",
           "args": [
               "build",
               "${workspaceFolder}/test/DocGenerator.Tests/DocGenerator.Tests.csproj"
           ],
           "problemMatcher": "$tsc"
       },
       {
           "label": "deploy",
           "command": "dotnet",
           "type": "process",
           "args": [
               "lambda",
               "deploy-function",
               "DocGenerator",
               "--region",
               "us-east-1",
               "--profile",
               "default",
               "--function-role",
               "woof_garden_canary"
           ],
           "options": {
               "cwd": "${workspaceFolder}/src/DocGenerator"
           },
           "problemMatcher": []
       },
       {
           "label": "invoke",
           "command": "dotnet",
           "type": "process",
           "args": [
               "lambda",
               "invoke-function",
               "DocGenerator",
               "--region",
               "us-east-1",
               "--profile",
               "default",
               "--payload",
               "Just Checking If Everything is OK"
           ],
           "problemMatcher": []
       }
   ]
}

Thoughts about the role of Chief Architect

Marc Adler, CTO as a Service

The following observations about the role of Chief Architect come from my four previous positions as Chief Architect. I have been Chief Architect of the Equities Division of Citigroup (350,000 in the company, 30,000 people in Equities), of MetLife (65,000 employees), ADP (65,000 employees), and of a small software vendor named Quantifi (roughly 50 employees). I have a mixture of large company and small company experience that has shaped my perceptions. In addition, I owned my own small software business for roughly ten years, and that experience has also shaped my thinking.

I may be slightly biased in my thinking, but in my opinion, the role of Chief Architect is one of the hardest roles out there, both in terms of defining the role and in terms of what is expected of you. Each company has their own idea of what a Chief Architect’s role is, and some companies don’t even know why they need a Chief Architect.

The role of Chief Architect is an extremely “vertical” one. I always like to say that a Chief Architect has to be able to  interact at the CxO level, and be able to talk to the lowest-level coder. The Chief Architect has to be comfortable in executive-level meetings, and must be equally comfortable sitting next to a developer and doing pair-programming or code reviews. Often times, the Chief Architect is called on to explain technology to the CxO-level people. The Chief Architect is often called on to face off with the senior-level technical people at vendors and partners. I have been directly opposite CIOs and CTOs of vendors on many occasions. The Chief Architect should know the business and well as the technology.

In my opinion, there should really be only a single Chief Architect in a division or an enterprise. There should be a single point from where all architectural decisions are made. This jives with the list of responsibilities that a Chief Architect should have (see the list below). If there are multiple Chief Architects, then there is more room for disagreements and to get into “analysis paralysis” mode.

Management

Many times, the Chief Architect has to manage a team of architects. At Citigroup and MetLife, I managed multiple groups which fell under the Architecture organization, and these groups included performance optimization engineers, project managers, and business analysts.

Since I have typically managed teams of architects, I have had to slice my architects into different domains. For example, at Citigroup, I had an architect responsible for Cash Trading Systems, an architect responsible for Derivatives Trading, an architect responsible for Risk, etc. I also had architects devoted to SDLC, architects devotes to performance optimization, etc. Each architect was responsible for a vertical slice of the entire organization, but the architects had to work horizontally as well.

Since the Chief Architect was regarded as a senior or area manager, the Chief Architect often reported to the CIO or CTO of a division. The Chief Architect would often be the CxO’s “right-hand man” when it came to technology. It was unimaginable that a Chief Architect would report to a development manager, since part of the architect’s responsibility was guiding development practices and doing architecture and code reviews (something that would sometimes put the development manager and architect at odds).

Hands-On Participation

A constant question revolves around how hands-on the Chief Architect should be. I advocate for a hands-on architect for various reasons.

The Chief Architect should not be known as a “yellow pad architect” if the CA is to get the respect of the development organization. The developers want to know that the Chief Architect has walked in their shoes before they accept his advice. A Chief Architect should be able to speak to any CxO or sit down and pair-program with the lowest-level developer.

Since the Chief Architect is also responsible for exploring new technologies and delivering proof-of-concepts, the Chief Architect should be able to code these POCs personally.

Therefore, I strongly advocate that the role of Chief Architect not prohibit the CA from diving into a coding role on occasions.

Roles and Responsibilities

The list below is a union of all of the responsibilities that I have had as Chief Architect.

  • Manage the Architecture Organization
  • Attend meetings with current and potential vendors
    • Be able to face off with the CTO or Chief Architect of a vendor and do technical vetting
  • Evaluate vendors and technology using an Architecture-team-developed scorecard
  • Keep abreast of new technologies that might be beneficial to the organization
    • Run the Innovation Lab
    • Meet with vendors
    • Do proof-of-concepts, often involving coding from me or a member of my architecture team
    • Attend industry conferences in order to be able to see what new technologies are hot, and to even see what our competitors are doing.
    • Occasionally give talks or sit on panels at conferences
  • Software development
    • Sometimes, the architecture organization will develop a POC or MVP in order to prove out ideas or to relieve pressure on the normal development organization
  • Give architectural approval for “big ticket” projects
  • Attend executive meetings
    • Often called on to decipher technology or render opinions on technology
  • Liaise directly with senior business stakeholders
    • Find out what kinds of business problems the stakeholders wanted to solve and propose solutions based on their needs
  • Guidance
    • Come up with reference architectures
    • Serve as a general technical resource for the development organization
  • Roadmaps
    • Provide roadmaps that show how the organization will move towards a certain future state
  • SDLC process
    • Do Architecture and Code Reviews
    • Attend Sprint kickoff and retrospectives
    • Provide approvals for code to be deployed into production
    • Advice on coding practices
  • Performance Optimization
    • Help the engineering team with the optimization of certain systems
  • Governance
    • Ensure that the organization is using the appropriate technology and software
    • Ensure that the organization is not using End-of-Life software
  • Architecture Review Boards
    • Run or participate in architecture reviews and approvals
  • Socialization of architecture across the enterprise
    • In the instances where I have been CA of a specific division, I would make the effort to find out what other CAs in other divisions were up to

AWS CodeBuild and Access to RDS

One of my clients whose application runs on AWS had no Continuous Integration (CI). The code is stored on Github, and I had just gotten the developers to write Unit Tests and Integration Tests. There are different tools that you can use for CI, including Jenkins, Travis CI, Circle CI, and more. But, since my client is a heavy user of AWS, I wanted to try AWS CodeBuild, as it seems to be tightly integrated with a lot of other AWS PaaS products.

I set up CodeBuild to pull the code from Github, and to run the Integration Tests using knex mocks. Everything worked smoothly.

The next step was to set up a Postgres/RDS database that was devoted to CI testing, and to switch from using mocks to using a real database.

The problem was that the application code could not access RDS. All access from CodeBuild to RDS was blocked.

The solution that I came up with was as follows:

Note which AWS region your CodeBuild instance is running in. For example, mine is in us-east-1 (select the build and look at the details to find the region).

• In your browser, go to https://ip-ranges.amazonaws.com/ip-ranges.json, and look for the entry for CODEBUILD in the region mentioned above.

• Note the IP address associated with your region of CODEBUILD. For example, the IP address for my instance is 12.345.6.789/28. (Of course, this is a fictitious address)

• Now go to the RDS AWS Dashboard and find the instance of RDS that you want to access through CodeBuild.

• Find the Security Group that the instance of RDS is using

• Navigate to that Security Group

• Go to the Inbound Rules, and add a new rule for CodeBuild. I added a new TCP rule for 12.345.6.789/28, using port range 0-65535.

• Go back to CodeBuild and run the build. CodeBuild should be able to access Github (like before) and now it can access your private RDS instance.


The number of questions found on Google around CodeBuild users accessing RDS are such that I would think that the AWS team would make this into some kind of point-and-click visual interface.

Distributed Systems Meetup in NYC

This a part of the continuing education process that a good CTO/Chief Architect has to maintain. This is a photo from a regular Meetup that I attend, where we discuss Distributed Systems. In this particular event, we were discussing Fault Tolerance in Distributed Systems with our host, Andrew from Venmo.

For people who want to learn about the theory behind distributed systems:

I feel that you can get your Master’s Degree in CompSci solely by going to meetups every week. So much great information is exchanged, and you meet others who are using interesting technology in their day jobs.

Does a Large Software Project Need a Software Architect?

I just answer this question on Quora. I am happy to hear any comments that you might have about my answer.

My background is that I was the Chief Architect of 4 different companies (as now a CTO for Rent), so my answer is colored by my experiences and my biases.

There are all sorts of “architects” out there. Enterprise architects, solutions architects, business architects, software architects, infrastructure architects, etc. Everyone fancies themselves as an architect.

So, what distinguishes an Architect from an ordinary Developer, and why would you need one.

I am going to make an assumption that you are in a large company since you mentioned a “large software project”. I am going to assume that there are teams of developers, project managers, business analysts, etc, and that the project is budgeted at several million dollars.

In large companies, one of the jobs of the Architect is to make sure that what your team is developing is following certain standards. You do not want to be using end-of-life software, you may not want to be using some open source software that is only being developed and maintained by a single person, you want to use software that is a “buy” on the company’s buy/sell/hold list, you want to be using software that passes certain performance criteria, etc.

Another job of the Architect is to make sure that your project is well thought out. Are you thinking about scalability? About different kinds of failover? About certain edge cases? Is your team following good coding practices? Is the software extensible, so that new features can be added easily? Is it easy for other systems in the company to integrate with your platform? Does your application follow a future vision that the business has?

The Architect should be familiar with frameworks and patterns and lessons-learned that other areas of the company have developed, and should be able to recommend their use to you.

Often times, the Architect is closely allied with (or in charge of) the Common Services Team of your organization, so the Architect should be able to recommend frameworks that this central team has developed for the organization.

If your project did not have a good Architect, who would do these jobs for you? The Project Manager? The Product Manager? Both no. The Dev Lead? Maybe they would do some of these tasks, but the Dev Lead will probably live inside the silo of your team and not reach across the whole organization.

I hope this answers your question. Good luck with your project.

A Typical Meeting with a Potential Client

Some of you may be wondering what an initial meeting with CTO-as-a-Service looks like. Here is a typical the first meeting with a potential client, which usually occurs over a cup of coffee.

The potential client was recommended to me by someone in our mutual network. This potential client turned out to be the Poster Child for a CTO-as-a-Service engagement. She is a recent business school graduate that had a great idea (which happens to be aligned with a social cause that I believe in) and had some friends-and-family funding. She is not technical at all. A recommendation was made that she use a low-cost offshore development shop, and unfortunately, this development shop ended up not delivering what they promised and what she wanted.

She has some interest from potential investors, but she needs help in setting things right, and she needs help in setting the technical direction of the product so that it will be flexible and scalable as her vision expands.

As we chatted, it became very apparent that she needs someone like me, but her budget does not allow hiring an experienced CTO full-time.

I told her that is all good. CTO-as-a-Service can work with a client a few hours a week or a few hours a month. You could think of CaaS as you would think of your lawyer or your accountant. I can have weekly check-in calls with an outsourced development team in order to make sure that they are on target. I can draw up the initial technical architecture. You can drag me along to meetings with investors and tech incubators to show them that you have experienced leadership sitting behind your startup.

This potential client is going for more funding in January, and I certainly hope that she chooses me to help her realize her vision.

Free Syncfusion UI Toolkit for Startups

This news is of special interest to startups that are looking to build the first version of their product.

I just found out that Syncfusion, a very well-known manufacturer of UI Toolkits, has just released a free Community Version of all of their tools. The Community version is free to all companies and individuals with less than $1 million USD in annual gross revenue and 5 or fewer developers.

I have used Syncfusion tools for years, starting in the mid-2000’s when I was consulting for Wachovia and building a CRM system for their investment bank. Syncfusion provided a lot of UI components that we would have had to spend a lot of time writing ourselves.

The Community Version has UI components for ASP.NET (MVC and Core), plain old Javascript, WPF, WinForms, UWP, and Xamarin. I am especially looking forward to using the Xamarin components for an app that I am building that is targetting iOS and Android.

Case Study – Helping a Legal Software Company

TL;DR

  • Two week engagment (I can do one day to several month gigs)
  • Brought in to evaluate the current state and recommend a future state
  • The output was a 15-page detailed report, complete with a list of refactorings for the code and architecture, and a product roadmap
  • Client is now seeking approval to rewrite the platform

At CTO As A Service (CaaS), I will do on-site consulting, remote consulting, or I will even travel to your site. For this particular client, I was fortunate to have someone who was located in my home territory of New York City. All I needed to do was to take the M20 bus uptown.

People often wonder where you get your first clients from. In this case, it was from a great recruiter whom I have worked with over the past few years. One of her clients was a Private Equity Firm who took a stake in a company that provides Litigation Financing. An interesting aspect about being a “CTO-for-Rent” and parachuting into different clients is that you end up in domains that you didn’t even know existed.

Litigation Financing is an interesting field, one that is growing very fast. The gist of Litigation Financing is that a company will provide financing to people who are injured in accidents while their lawsuits are active. Often times, these people do not have disability insurance, and because of these accidents, cannot work for a period of time. They need money to live on. A Litigation Financing company will give (not lend) money to these injured people, and when the case is won or settled out-of-court, the money is repaid with a certain added percentage on top. If the lawsuit is not won, then the Litigation Financing company loses money. This means that the underwriters have to use all of their years of experience to decide whether or not to finance somebody.

The Private Equity Firm needed someone to come in, examine the custom-written applications that the company used, and provide an assessment of the current state and the future state. The output of this engagement was a report that detailed all of the things that needed to be fixed in the current versions of the applications, a roadmap for the future state, and recommendations around the development team and development process.

The Litigation Financing company used a low-cost offshore development company to develop the software that managed the cases. One application was written in Visual Basic 6. The main suite was written in VB.NET. The development staff had a bunch of turnover, and the Litigation Finance company was not satisfied with the quality of work.

As an aside, one of the common scenarios where someone might engage my services is to come in and “fix” the work that is done by a low-cost offshored development company. Often times, startups will not have the money to engage high-quality in-house developers, and will farm the initial version of their application out to one of these offshore development shops. Then, when the startup gets some recognition and some investor money, and needs to develop the next stage of their product, they realize that they do not have a good base to work from. This is where I can help out.

I started off by interviewing all of the key stakeholders, and at the same time, dove into the subject of Litigation Finance. I asked very probing questions about the software, their experiences and pain-points with the apps, their interactions with the development company, and where they wanted the future state of the product to be. I also did some analysis of providers of Litigation Financing and Case Management software, and mapped some of the features that I saw into what my client could use in a future-state product.

I then sat down with the source code in order to get a complete understanding of the system. I took the VB.NET code, and using dotPeek from JetBrains, translated the code into C#, which made the code more readable to me. I examined every single module and wrote down a lot of notes about things in the code which could be improved.

Then, I sat down with the senior leadership of both the Private Equity company and the Litigation Finance company, and we had a number of conversations about the future state. There are a lot of technologies that could be incorporated into the product which would make it more powerful and would help my client make better decisions about which injured people to finance. 

At the end, I produced a 15-page report that detailed the fixes for the current state and the migration to the future state, including recommendations around building out an IT organization. I hope to return at a future date to help this client build out the new platform.