Select Page

9 years at CSOD – Senior Developer to Software Architect

2008  – 2017  – Full time  –  Cornerstone OnDemand Growth Edition, New Zealand

employees in 2008

$

employees in 2013

From startup to a multinational corporation

I have joined Sonar6 in 2007 at the beginning of the venture, we were 7 at the time.
The company grew organically to 35 people and then up to 2000+ when it got acquired by Cornerstone OnDemand in 2013.

During those years I have learned a lot through solving challenges that are in direct relation with the size of the company (from processes, workflows, coding practices, testing, management, etc.) but also related to the development of the product (change of technologies, rework of products, etc.) I used many of the Software Development practices like:

  • Agile Software Development, Iterative and Incremental Development, Scrum, Kanban, Scrum, Extreme Programing, Pair Programming
  • Test-Driven Development, Behavior-Driven Development, Continuous Test-Driven Development, Test Double

I joined Sonar6 as a Senior Developer and progressed to a Software Architect, but I have been working in other areas, wearing multiple hats or helping in CI/CD, system admin, product design, etc.

Core Duties

Software Architect – Product architecture and technical decisions

Worked with the product owner to decide on the technologies to use.
Designed the application and core architecture (front and back end) and implemented the basis.
Designed and implemented the MySQL databases used by Growth Edition products.
Established a coding standard amongst all developers.

Front End Lead

Architecting responsive and mobile first applications consuming RESTful APIs and creating the application base for other developer to build onto.
Running Front End Architecture / Dev meetings.

Senior developer

Part of a team of 16 developers and 5 testers working in an agile environment (kanban / scrum / srumban).
Developing Front and Back end, using Unit Test, Integration Testing and Functional Testing.
Mentoring junior / intermediate developers.
Part of the everyday teamwork but also working on prototyping and developing complex components used by our products.

Technologies Used

html
css
javascript
typescript
Angular
Material Design
Bootstrap
Jasmine
Karma
Protractor
Webpack
RequireJS
NPM
Gulp
Grunt
Bower
Actionscript
C#
php
PHPUnit
xDebug
Symfony
Swagger
.NET
AutoFixture
xUnit
Moq
AWS
Docker
Vagrant
Jenkins

Work Samples

Database Design

Designed and implemented the MySQL databases used by Growth Edition products.
Developed a toolset for easy management of the databases (migration, copy, backup, and update to new schema, etc.

Continuous Integration

Advised and implemented continuous integration using Git, Gulp / Grunt / Ant, Nexus / NPM / NuGet / IVY, Jenkins, … to help Cornerstone Growth Edition to test and deliver a product of quality, faster and on a regular basis.

Front End Technology Changes

Problem: Flash died. We needed to migrate to a new front end technology
Solution: Our suite of product being online, the answer was simple HTML5/Javascript. We also wanted to use a framework so the heavy lifting was already made for us and to benefit of the existing coding guildelines.
Implementation: I have been in charge to find, in a month, the right framework. During this month I have done some research on the different frameworks existing at the time and ended up with 2 finalists: EmberJS and AngularJS. I then prototyped our application with both frameworks – we realized that AngularJS had extra features we needed and was more in line with the way of thinking of our teams. I finally created the base application using AngularJS, RequireJS and custom lazy loading to make the application fully modular. Later Typescript has been added to have a statically typed language.

Front End I18n and Cache

Problem: We wanted to have internationalization and localization in our new AngularJS frontend, but no library existed yet. We also wanted the user to download only the updated modules of our application.
Solution and Implementation:
Cache – I have created in my spare time a Grunt plugin (grunt-hash-extended on npm) to get the hash of the file and change all the name reference in all the other files, then get their hash and so on, i.e Tree parsing.
I18N – I have created a i18n angular module during my spare time. Both libraries are used in our product commercially.

RESTful APis

Problem: We wanted to decouple the front end and back end, and we wanted to provide a way for third party to consume some of our data.
Solution: Obviously creating APIs.
Implementation: We used PHP with the RestMe framework and Symfony to create the RESTful apis. Then we used in C# and .NET (when the company changed technology stack).
The RestMe framework is a framework I have developed during my spare time to be able to create quickly and easily a restful api. This is its sole purpose, hence making it is lighweight compared to the existing framework. It supports modules (which can be chained), pre and post hooks, multiple renderers, … and integrate nicely with another library I have developed: XOAuth-PHP, a xAuth and OAuth (1.0a) client and provider.

SSO

Problem: We needed to have a simple/single way to authenticate a user to all our products. We also wanted to have third parties being able to identify against our APIs.
Solution: We decided to create a SSO provider and consume it on all our different products backend.
Implementation: We have been given 3 months to implement the solution. A workmate and I developed a SSO provider using OAuth 1.0a and xAuth used by all our other back ends/front ends to authenticate the user (meaning the user will authenticate once and have a token that will be valid across all our applications). This SSO provider was also a client for other SSO (we integrated with OKTA and OneLogin). The SSO provider has been developed using two libraries I have created during my spare time and open sourced, RestMe and XOAuth-PHP.
Once completed on time, the solution got checked by Insomnia Security. They only found a minor issue on file permision. Flows and code were OK. This came to be really rewarding as right in the middle of the project, during the OWASP conference we attended, employees of Insomnia Security said during their talk you should never do your own SSO provider as you will likely fail (due to complexity and security).

Product Migration

Problem: The old product (A) was running on PHP hosted on the CSOD data center. The new product (B) was running on C# / .NET on AWS. The new product (B) is really a new product, not just an update, i.e it is not feature aligned, data required might not exist in the old product (A). Nobody really knew the extent of the features of product A, hence the extend of the feature mismatch. Added to this both products lived on seperated host with really tight restriction when it comes to data access, i.e no data could live outside those 2 data hosts.
My team had 6 months to design and implement the solution.
Solution: Create an importer in C# for the new product (B) and define the data structure required. This could then also be used to migrate customers taken from competitors. Create an exporter in PHP for the old product (A) that will get the data from the stores and massage it to fit the required structure by the new product (B) importer. The transfer would be done directly from CSOD data center to AWS.
Implementation: We created the importer in product B, defining the data to receive. Here a zip file containing the media and JSON files to be imported. JSON was used for its simplicity and because it is human/easily readable, hence easier to debug, and we were not limited by the file size. We created the exporter in PHP which would lock the customer out, export such JSON files and medias and package it to a zip file. Then this zip file would be sent to a specific AWS S3 bucket which would trigger a push to SQS with the filename as the message. The product B had a service running on demand (we would do the migration in waves) that would pull from this SQS queue and process the zip file importing the customer to the new DB / Product, then finally unlocking the customer and redirecting it to the new product.