1 Why am I doing this?
Having worked on Channel Admin Frontend for a number of years now I feel I am well positioned to offer insights into what difficulties we encounter on a regular basis and I am also fortunate enough also have the breadth and depth of experience to recognise why these problems arise and how they can be avoided (or at least mitigated).
I hope this document will be received in a spirit of constructive criticism. It is in no way meant to point fingers or assign blame. My goal is to highlight obstacles and outline a series of actions that can help us clear those obstacles, increase productivity, improve quality and remove impediments to empower our talented staff to innovate and excel, and to further unlock the great potential we have at our disposal.
2 The Past
Working with the Channel Admin Frontend codebase is much more difficult than it should be. The technology it has been built on has been superseded a number of times since its conception but there has been little appetite and no time to schedule upgrades and quality of life improvements. It is also challenging to work with because architectural decisions that have been baked into the app from the ground up prevent us from using methods and technologies that improve developer experience and empower us to do more, and to do it faster. Click the arrow below for a detailed example.
Hot Reloading
For example, it has been standard practice on web app development to use hot-reloading for almost 10 years now. Hot reloading simply enables developers to work on an application, make changes but maintain the application state in realtime without having to reload the page. When it was first introduced as a development practice, it was considered a productivity game-changer, it literally drew gasps at the react conference where the proof of concept was unveiled. It has since become standard practice but it has been impossible to introduce in Channel Admin Frontend as a result of decisions made when the project was first started that have made it impossible to retrofit this critical development aid.
If we were to introduce hot-reloading to the project, after making a code change we would not have to go back to the start of the user flow (select country, navigate the dashboard and menus and so on) to get the app into the state where we can test the changes we have just made. I believe that the productivity gains from this one simple change alone will quickly pay for itself in recovered developer man-hours, but there is so much more we can do, many more gains to be made, that make starting v2 a worthwhile endeavour. I hope to make a convincing case for doing so in this pitch document.
The format of this document will be to describe some of the more obvious pain-points and issues we face, how these problems impact delivery, how we can alleviate them and what the positive benefits of my proposed approach are and the improvements to speed, quality and capabilities they will provide.
3 The Present
The problems we face on a daily basis working on Channel Admin Frontend project can largely be categorised like so:
Ways of Working: Sub-optimal planning and solution design set us up to fail before we write a single line of code. Improvements to planning processes and development practices can provide huge boosts to productivity. This is an area we should actively experiment with.
Technical Debt: Old Code and Deprecated Technology make up a frightening percentage of the codebase on this project. The time to rework the existing codebase and upgrade dependencies has long since past. At this stage, the most efficient way to eliminate tech debt and upgrade to a modern stack is to put this project into maintenance mode and start again on v2.
Organisational Rigidity: UOB is a large multinational organisation and a lot of the problems we face could be mitigated or prevented by better delegation: empowering the developers to have more ownership of the project planning, processes and policies.
Let's look at these issues, the negative impact they have on productivity and capability, and how we can address each of these in turn.
i. Ways of Working
Problem: Inadequate Planning and Coordination
“When you fail to plan, then you plan to fail.” Old adages like this endure because they are true. A large amount of the problems we encounter and the time we waste have their origins in a lack of planning.
Consequences:
It is a strong indicator that something is wrong with our approach that I have worked at UOB as a senior front end developer for many years and have never been asked for my input into API design. APIs exist solely to provide the front end with access, both read and write, to stored data. Poorly designed API responses, (data that is not shaped to the task it is meant to serve before it is returned from the backend) puts the onus on frontend developers to format data to make it usable. Not only is this wasteful and negatively impacts app performance, it is also not a reasonable ask on a project where FE devs are outnumbered by BE by at least 4 to 1.
When API planning is done badly it requires constant revision: when an API is provided that does not suit the purposes it is supposed to, the frontend staff need to request subsequent changes that take time to implement. This feedback and iteration process loop slows delivery and can easily be avoided by better Frontend and Backend collaboration during the planning stage. API responses and error messages should be planned and agreed with frontend in advance before a line of code is written.
Solution:
Failing to plan adequately results in a lot of wasted time and frustration. Inversely, planning well, documenting requirements clearly and then ensuring all eventualities are considered and catered for when preparing to start development ensures all parts of the organisation are aligned in their approach to achieving clearly defined goals. This practice of discussing and agreeing “the API contract” enables smooth delivery and also unlocks better ways of working such as test driven development and iterative solution design through collaboration between front end, back end, UI designers and solution architects.
API request payloads and their corresponding responses should ideally be designed in close collaboration with the front end devs as we are providers of the payloads they accept and the consumers of their output. Many of our APIs are not well considered, some simply dump SQL data in json format on the front end for us to filter, organise and sort, this is wasteful and puts more responsibility and complexity on the front-end where we are already very under resourced.
When API planning is done in collaboration with FE devs, the shape of requests and responses can be designed prior to implementation, this “contract” between FE and BE can be drawn up before any code is written so that the data that is sent to and returned by the API is already fit to use and compatible with its use cases. This cuts iteration time and reduces the amount of complexity, dramatically speeding up delivery time and allowing both ends of the stack to put more time into quality and testing.
Problem: Poor, Unclear, Unmaintained, Obsolete and Incomplete Documentation
The source of truth for the specifications of all aspects of any work carried out on Channel Admin Frontend should be its documentation. Channel Admin Frontend's confluence documentation is very poor, much of it is out of date, in many cases there are conflicting specs for a given API, sometimes there are contradictory specifications even on the same page! There is a lot to be gained by having more discipline around what is documented and how. A formalised format for API docs can be designed and refined in-house and we should strive to develop this standard across all sections of the development process.
Consequences:
So much of our wastage comes from poor communication and diverging assumptions. Over the years we have closed countless invalid defects because the tickets for them have been incorrectly written up due to misunderstandings on expected behaviours on the part of testers. These misunderstandings come about because the documentation they are testing against is often unclear and sometimes contradictory. This can be eliminated if we give greater importance to our documentation and have all aspects of the solution design, development and testing processes refer to the same documentation when planning, implementing and testing any given feature.
Solution:
We should treat our documentation as the first step of every task. Our goal should be to write down and refine through collaboration, the specifications of any and all aspects of our application before we do anything else. Document everything: UI Flows, user capabilities on a per page basis and what actions can be taken to achieve them, REST API request and response specifications, Component APIs and capabilities - all of these things should be clearly detailed in confluence documentation first before a single JIRA ticket is written or a line of code is produced. Refining this documentation should be central to everything we do. Writing clear documentation should be treated with a sense of importance. Once documentation is written it should be treated as a living document and any changes to any given feature or spec should be updated in the documentation first.
Benefit: Alignment from conception to delivery
When we have a disciplined approach to documentation as a single source of truth in this manner, not only does it eliminate so many problems, it also unlocks greater capabilities and new ways of working:
A UI designer or solution designer can provide alternative approaches to UI design or user flow if the requirements of any given feature are clearly detailed. For example, if a User flow document states: “A user can select their desired notification methods” this gives a UI designer more flexibility to design a better UI than “A user selects their desired notification methods from the dropdown menu”. This might seem like nit-picking but the former description gives the UI designer the scope to provide the best user experience, the latter boxes them into a decision already as to how the user carries out their notification option selection. Language matters.
As a front-end developer, if I have a detailed document in confluence of all the requirements of a particular feature I am about to develop, then I can take a test-driven-development approach: This would involve me writing my unit tests first (before writing any code) using the documentation as my source of truth, then I would write my code with a view to passing all my tests. I can only do this when I have clearly detailed requirements before I start writing code.
If a tester is testing a feature and the criteria they are testing against is the same criteria that the developer that implemented that feature worked from, it is a lot less likely the tester will be testing against diverging understandings of what that feature is meant to do: They are literally working from the same document as the person who wrote the code they are testing. This means less mistakes and misunderstanding, less invalid defects being written up and less wasted time for all concerned. This is only possible when all parts of the design and development process are working from the same, clear, well written and accurately detailed specifications.
Documentation is forever and will always remain available for reference long after a piece of work is delivered and forgotten about. This documentation will be invaluable to our future selves (or future generations of Channel Admin Frontend developers) when we come to diagnose/resolve defects, redesign solutions or carry out regression testing in the months or years to come.
Well written documentation is also vital for onboarding developers who join us in the future: The impression this makes can be the difference between new hires feeling they have a high bar to aim for in order to be successful in the organisation they have joined or being worried they have walked into a poorly maintained and badly managed project because the devs who originally worked on it have all left and nobody knows how anything works any more because none of it was documented.
ii. Technical Debt
Problem: Aged, Obsolete Technology and Deprecated Dependencies
The majority of the Channel Admin Frontend code consists of React Class Components, Redux Classic for state management and UI components that are styled with Styled Components. All of these are deprecated libraries that are no longer maintained. They are likely to have dependencies that have identified vulnerabilities. The only time this has ever been addressed during my tenure is when external Pen Testers have highlighted these issues as part of their audits and it has become a compliance issue.
Consequences: Staff Resourcing
One major problem having an aging code-base presents us with is hiring. The longer we continue to use obsolete technology, the harder it is to find people who are still proficient with it, and even if you do find somebody who knows Class components, Redux Classic and Styled-components, they will be senior and thus more expensive and you will probably find they are less than enthusiastic about using such old and cumbersome technology when the modern alternatives are easier to use and provide better capabilities with less overhead.
To a prospective hire, it is an unfortunate truth that an old stack reflects badly on the company using it and will most likely be off putting to the stronger, more capable candidates we interview. I have personally conducted interviews with full stack and front end candidates applying for jobs at UOB and have noticed a change in manner when answering their questions about the project stack. I don't believe this would have happened if we were using a cutting-edge framework and modern approach.
Solutions:
The time to rework the existing codebase and upgrade dependencies has long since passed. The tech debt mountain is insurmountable and at this stage it is simply faster and more efficient to just put this project into maintenance mode and start again with a modern framework.
This undertaking would be best approached using a transitionary approach: The existing app would still be maintained by a small team responsible for providing critical defect support and bug fixes, new features would only be introduced to v1 when they are absolutely critical and urgently required. The functionality for such features should be kept to a bare minimum. The majority of development staff would be assigned to a team dedicated to designing and building Channel Admin Frontend v2, their goal being to develop a new version that provides all the functionality currently being provided by v1. We should endeavour to document everything as we proceed, take the opportunity to reduce dependencies, minimise state to keep the codebase lean and also build and maintain our own UI component library using the web platform: eg. Use HTML Tables over AGgrid, Standard browser Inputs or custom components over MUI, API data as our source of truth and React Context instead of Redux - and only where it's absolutely needed.
Benefit: An AI Opportunity
Another consideration is: AI assistants are coming and in order to be in a position to capitalise on them we would be wise to write our APIs and UIs with this in mind. Model Context Protocol is shaping up to be the next major shift in User interface technology. It is a means of providing the ability for AI and Language models to interface with our software.
In the very near future this will enable users to write or verbally dictate the tasks they want to carry out and to facilitate this, our approach to solution design should consider this forthcoming requirement as we build out the new Channel Admin Frontend.
We have the opportunity right now for this project to go from being years behind in terms of technology and capability to getting ahead of the curve and having this project future-proofed and AI-ready as the Model Context Protocol and the surrounding technology ecosystem evolves. This is gaining momentum right now: Imagine being able to simply ask (verbally or with a text prompt) Channel Admin Frontend to carry out a task that would be complex and time-consuming if done using point/click/type classic UI. If we design our UI and APIs to be MCP-ready these tasks could be carried out almost instantaneously and if we prepare our approach to enable this as the technology evolves and matures we would be in a position to capitalise on this.
iii. Organisational Optimisation
Policies that are instituted and applied across all projects, are ill considered. One-size-fits-all is an approach that seldom works well in large software development organisations. What works well for backend and Java won't necessarily work well for front end and JavaScript.
Problem: 90% Code Coverage
This incentivises poor practices and forces us to focus on things that are orthogonal to the goals we have set out to achieve. It warps the incentive to test and we need more ownership and responsibility for builds and the ability to be pragmatic and flexible about this on a per-project (or even per-repo) level. As an aspiration, 90% code coverage is not a bad thing, but enforcing it at a build level and failing any builds that do not have 90% code coverage is a very bad thing. This has a number of unintended consequences:
Consequences:
Code coverage enforcement can grind development to a halt at the worst possible time: On multiple occasions I have had to put down scheduled sprint work because I have been tasked with resolving an urgent critical defect. After rapidly providing a solution that might have taken less than an hour to resolve, I then have to spend hours, or sometimes even days, writing test for lots of old code that is completely unrelated to the defect because the fix I provided just happened to bring the 30-day code coverage score below the 90% threshold. This not only prevents my sprint work from progressing, it also means we cant ship the urgent fix and it also halts any other code produced by other developers because the build we all share (which is perfectly valid code) is now considered "failed" all because of this non-negotiable 90% threshold rule enforced at CI level. We need to be able to dip below the desired goal of 90% and still produce successful builds. We should not be putting ourselves in the position where one urgent PR can stop the whole show, its short-sighted and self-defeating.
This policy has the potential to put us in a position where a hyper-critical, SL1, apocalyptic, compliance-violating, app-breaking, show-stopping defect could potentially take multiple days to resolve. Thankfully this has not happened yet but it is just a matter of time before it does. I can't overstate just how damaging this one policy has been to productivity, code quality and our ability to deliver quickly.
Code coverage enforcement also warps our incentive to test: We should be writing tests to ensure a given function or component, when provided with a particular input, produces an expected output. Instead, we write tests only to ensure all code is executed in the test suite to hit that 90% mark. Channel Admin Frontend is now littered with tests that have no assertions, they simply exist to execute code to get the coverage up to pass the build. I underlined that point because I cannot stress enough how much of a red-flag this is. Tests like this are a complete waste of resources and time - time that could have been spent writing proper, meaningful tests that will catch bugs before they are deployed to test environments, where they are noticed by testers and written up as defects. Unit tests are supposed to aid developers in catching defects before they are committed to the repo. Sadly the reality is, since it has been instituted, the 90% threshold policy has noticeably decreased code quality, compromised our ability to catch defects at source and dramatically increased our defect count. This is not because we are catching more bugs, it's because we are causing more bugs.
To satisfy this meaningless metric, we do pointless refactors of perfectly valid, clean code, often making it more messy, just to enable us to test edge cases and execute remote code branches. We write tests that don't actually test anything simply to execute those remote code branches. 90% code coverage policy has had the exact opposite effect that was intended - it has made our code less reliable, less well-tested and harder to maintain. It has claimed an absurd amount of man hours for no practical benefit, time that should be used productively on code and real tests.
Solution:
The solution is simple, for all of the reasons above, as a policy 90% coverage enforcement should be stopped immediately. We can aspire to achieve 90% but we should not stop everything the moment we dip below the 90% mark, it is utterly self defeating and a catastrophe just waiting to happen.
Problem: We Don't Do Agile
A source of a lot of the problems we face are due to having project development timelines set by people who are too far removed from the development process, people who are not in a position to have a clear idea of how much work is involved to deliver a particular feature. This unfortunately puts us in a position where we developers have to rush, cut corners and drastically compromise quality to deliver to unrealistic timescales with unachievable deadlines that have no basis in reality.
I believe this stems from the fact that we do not employ any reliable task estimation methodology. The standard practice for this is using typical agile methods (fibonacci numbers or t-shirt sizing of tasks during sprint planning) to gain a good idea of team capacity and velocity. Without employing this proven agile scrum practice we can not have a clear picture of how much work can be produced in a given time-period which is why our estimates are so wildly inaccurate.
Consequences:
The timescales we are presently working towards appear to be no better than uninformed guesses: I recently had a large task assigned to me: a series of brand new functionalities including around a dozen new views requiring many new components and hooks, some of which involved a high degree of complexity. I was given a timeline of less than 2 weeks to deliver all of this, it was a comically unrealistic deadline. I spoke to the project manager and called it out at the time, I told them that I believed the delivery estimate was extremely unrealistic - I later learned that the backend developers had independently done the same - but I do not believe our concerns were relayed to the person who originally came up with the over-optimistic estimate. This resulted in a lot of angry emails and shouting. At the time of writing, nearly 3 months later, it is still in active development and the bad-tempered discourse and blame-game continues.
Solution:
During the above incident, if the concerns about the timeline had been fed back when they were raised by the developers then the timeline could have been revised to a more realistic delivery estimate and a lot of this rancour could have been avoided. Senior Managers are entitled to be annoyed when they are kept in the dark about these concerns.
A more collegiate dialog in both directions and a pragmatic approach to software engineering would have avoided this. All of this had its origins in poor delivery estimates, too much distance and a lack of communication - in both directions of the hierarchy - between management, solution designers and the developers working on implementation. If we can work together to address this, I would bet that the productivity gains would surprise us all.
Agile, when done properly, gives you the data to better measure developer capacity, improve estimates and model changes in productivity, when used to experiment in Ways of working, the results can be extremely powerful.
Benefit: More scope for experimentation on Ways of Working.
One of the best ways to find new optimisations in the delivery process is to experiment with new ways of working. This applies to all departments in the development process.
I'll illustrate this point with an anecdote of one of the most challenging, rewarding and enjoyable periods of my career: In one of my previous roles working as a React.js Consultant at booking.com, each team had complete control over how they delivered what was being asked of them.
On one occasion, during sprint planning, one of the senior developers suggested a change of approach: He thought it might be interesting if we tried a hybrid of Test Driven Development, Pomodoro and Mob-programming: His idea was that, instead of each of the four React Developers on the squad working on our own laptops, we all get around a single laptop which was projected into a big digital whiteboard screen, we set the pomodoro timer to 15 mins and for 15 mins each we take turns 'driving'. The driver, during his 15 mins in the driving seat, would do the implementation while the other three Devs sat behind, observed on the large screen and suggested alternative solutions when they felt there was a better way of doing the particular part of the task the 'driver' was working on.
When the idea of working like this was first suggested I was sceptical (to put it mildly), I personally felt this would be a waste of time and very inefficient but, I was outvoted, and after trying this for a sprint I was utterly astonished with the results:
- We found that our speed had increased dramatically (the code was being produced at a constantly rate; literally non-stop!)
- The quality of work we were delivering was incredibly high (The best approach always won; whenever there was a disagreement on what was the best approach, we would make our respective cases and vote on it and the 'wisdom of crowds' did the rest).
- The knowledge sharing across the team was 100%, everyone knew every line of code that we produced and what id did and why it was done the way it was - there were no silos because we were all present and participating as it was being written.
- No meetings - if we had divided the work load between 4 different devs, each working in isolation, we would need to arrange alignment meetings so the code one dev is working on would work with the code another dev is working on. None of this was needed. Less time talking, more time coding.
- We had full test coverage by design: Test Driven Development is only possible when developers have a clearly defined requirement specification, the first thing we did was write a series of test suites that defined what the end product would do. Once we had our tests we wrote our app code against the tests. We knew we had finished the task as soon as all of our test suites passed.
Working like this was a revelation to me. This hybrid way of working, that I was initially so sceptical about, turned out to be easily one of the most productive and rewarding periods of my career.
Incidentally, This project was my first time using Typescript in a production environment and I learned so much about it by working with Devs who were already knowledgeable in TS that I became proficient enough to start using it on all my projects and have used it ever since. I literally learned a new skill in realtime, on the job, via this Hybrid TDD/Pomodoro/mob-programming way-of-working that we invented as we went along.
The trust Booking.com put in us developers, that enabled us to experiment with this hybrid approach paid dividends: We delivered our part of the project ahead of what was a very tight schedule and we were commended when we presented our findings to the rest of the development department in a developers chapter talk we gave after delivery. I was only there in a contractor capacity but I still have friends that work there and this practice is still used regularly across the department to this day. I feel privileged to have been a part of this innovation, even if I was admittedly the most sceptical and least enthusiastic about it when the idea was first proposed. Because of this experience I also learned not to hold too tightly to my presuppositions, be more open to new ideas and don't be afraid to try new things.
4 The Future
Steps towards a new, future-proof Channel Admin Frontend project. This section details WHAT I believe should be done, for the most part I will not presume to say WHO should do it. That is the purview of management and I will only details the sections where I believe Front-end and UI experience should be brought to bear, as that is my area of expertise and I know where and when the input of front-end Devs can provide additional value.
i. Planning & Processes:
Concept Stage
Planning should begin with a broad conceptual overview, simple short statements that define expected behaviours and capabilities without specifying how they might be achieved.
Concept planning
Using the first few user-flow steps in our current Channel Admin Frontend implementation as an example, we can illustrate the concept stage of the planning process:
LOGIN: The user should be presented with a login page when visiting **channel admin frontend URL**
COMPANY SELECTION: Once logged in, the user should be presented with a choice of which country
they want to administer.
After Selecting their chosen country, the user should be redirected to the dashboard page.
DASHBOARD: From the dashboard page the user should be able to make administrative changes to:
- Company Setup
- Company Role
- User Role
The rationale behind keeping things vague and non-specific at this stage is to simply define WHAT our software feature can enable a user to do. It is for the UI Designers and Frontend developers to determine HOW the users do it in the solution design stage.
Solution Design Stage
Solution design is where UI designers, Solution Architects and Frontend would collaborate on HOW to deliver each of the steps outlined in the concept stage.
Solution planning
Following on from the previous example, lets look at how the solution planners might decide to enable the user to carry out the actions specified in the concept stage:
LOGIN: Using the standard ADFS system, the user logs into the application using their UOB credentials
and is then redirected to the company selection page.
COMPANY SELECTION: The user is presented with a SVG map of the APAC region with each area they
are able to administer highlighted in blue:
- countries that can be administered are further indicated with a clickable button denoting
the region code (UOBS, UOBM, UOBHK etc.)
- After Selecting their chosen country, the user should be redirected to the dashboard page
- if the user only has one country they are permitted to administer this page is bypassed
entirely and the user is redirected to the dashboard.
DASHBOARD: From the dashboard page the user should be able to make administrative changes to:
- Company Setup
- Company Role
- User Role
After detailing in a more specific manner HOW the user goes about doing WHAT the UI should enable them to do, we can then start to break that down into a series of tasks in the deliverables stage.
Deliverables stage
At this stage we would start to write JIRA tickets and break the solutions planned previously into a series of Epics, then each of those Epics would be broken down into Tasks, then each of those Tasks would be split into a series of Subtasks. Once we have a number of atomic tasks we can begin to details how each can be approached and 'priced' in terms of size in the sprint planning stage.
Deliverables
The solution planning stage, having given the Solution Design team, UI designers and Senior Frontend developers the opportunity to come to an agreement on how to achieve the goals laid out in the concept stage, would then pass on their deliverables to the FE team to incorporate into their sprint planning session where EPICs and TASKs will be broken down into a series of SUBTASKS and 'priced' so we can estimate how many sprints might be needed to deliver on all of the requirements provided.
LOGIN:
EPIC: The user should be able to login securely and navigate throughout the apps
TASK: Redirect user to ADFS page if they attempt to browse to a secure route without
logging in.
TASK: Redirect user to Company Selection page url ('/') if they have successfully
logged in via ADFS
COMPANY SELECTION:
EPIC: The user is presented with a map of the APAC region depicting all of the countries
that can be administered. These countries can be selected via click/touch event so that
the user can be redirected to the appropriate dashboard.
TASK: Create a clickable map for all countries that can be administered with Channel Admin Frontend
SUBTASK: Query API for list of countries that the logged-in user has admin privileges for. If the user
only has one country they have admin privileges for then automatically redirect to the
dashboard of that country (eg. If the user only has Malaysia privileges, then they should be
immediately redirected to the Malaysia dashboard URL: '/UOBM/')
SUBTASK: Create an SVG Map of APAC region with each country clearly marked. Countries that the user
can administer should be highlighted by the flag button component and emphasised by colour.
SUBTASK: Create a flag button component that shows which countries can be administered by the user.
On-click the user should be redirected to the appropriate URL (eg. Clicking Singapore would
redirect to '/UOBS/' to show the SG dashboard).
DASHBOARD:
EPIC: From the dashboard page the user should be able to make administrative changes to:
- Company Setup
- Company Role
- User Role
This will be achieved with a tab menu across the top of the dashboard. With each of those
options available for selection.
TASK: Create a horizontal Dashboard Tab Menu that runs along the top of the dashboard view. Clicking
these tabs will navigate to the specific dashboard for each of those sections (eg. Assuming
this is the SG dashboard, clicking the 'Company Setup' tab will redirect the user to
'/UOBS/company-setup')
SUBTASK: The Dashboard Tab Menu component should be responsive and collapse into a drop-down menu
(via a 'burger' icon) when the viewport is too narrow, or there are too many tabs to
accommodate in the users viewport.
TASK: Create a series of Routes for each of the Dashboard Tab Menu items:
- Company Setup = '/UOB*/company-setup'
- Company Role = '/UOB*/company-role'
- User Role = '/UOB*/user-role'
* = the country code of the administered country selected in the previous step
(eg SG = UOBS, HK = UOBHK etc.)
Note how, in this example, we took the opportunity to make a number of changes. Some were mostly cosmetic, such as the map that replaces the 'Country Dropdown'. Others were more impactful such as the choice to abandon the old "Assignment" dropdown on the dashboard and replace it with a tab menu.
Also note how the URL denotes which Country the user is administering. By putting the country code in the URL of all our apps pages we have eliminated a piece of state. We no longer need the country code to be stored in Redux or localstorage because we took the decision to ensure all urls start with '/UOBS/...' (or '/UOBHK/', or '/UOBM/' etc) so the selected country state can now be derived from the URL.
ii. Documentation:
In line with the planning and documentation recommendations made earlier, I would suggest we start by developing and refining our documentation practices by broadly detailing all of the capabilities of each section of Channel Admin Front end in a series of pages on confluence. This should act as the foundation of the structure of the formal documentation that will act as the source of truth for this project going forward. We should aim to make this the exemplar for all other UOB project, set the example others would want to follow.
We should methodically go through the application UI and outline what each section of the app should enable the user to do and use this as the basis to reconsider and re-engineer these solutions from scratch. Once these capabilities are documented, UI designers and Frontend developers should collaborate on how we can create a better user interface that facilitates these capabilities intuitively and comprehensively. A lot of the UI on Channel Admin Frontend has clearly been developed without input from people with UI expertise and this v2 project would be an opportune moment to get their input and apply usability and visual improvements where the opportunities arise to create a fluid and intuitive user experience.
iii. Modernising The Stack:
Typescript: Typescript is a superset of Javascript and one key benefit it has is that it eliminates a whole class of bugs that cannot be caught in javascript alone. Because TS has a compiler which converts TS to JS it can catch bugs before you have run your first build. This is achieved by forcing the developer to define and declare the shapes and types of app data that are valid throughout the app code. This enables the compiler to know when it is possible for these types to deviate from the schema through buggy code or insufficient type checks. Its worth emphasising that it does this not at runtime, but in realtime, in our code-editors as we develop so that the end result ensures all app data is as expected according to the defined schema. It also incentives simplicity and encourages us to think about and plan API requests and responses, function params, component props and all of our application state as a whole prior to implementation which aligns with the proposed new ways of working and documentation discipline outlined throughout this proposal document.
Remix / ReactRouter v7 framework: Existing Channel Admin Frontend was developed when single page apps were all the rage. In the current implementation of Channel Admin Frontend we use react router v3 for simple URL routing. Over the subsequent releases React Router library has grown (via Remix) into a fully fledged application framework. I recommend we develop CAF v2 in the latest version: React Router v7 framework and leverage it's Server Side Rendering capabilities to eliminate our dependency on redux state entirely. Using the DB as our ultimate source of truth reduces complexity and eliminates a source of many of the issues we have by removing the need to sync the redux store with the various databases.
Having the frontend of our app served from the same 'bare metal' (server) as the backend DB and APIs gives us the ability to cut swathes of complexity by having the Database act as the source of truth of application data. Server-side rendered pages will load faster because the data that drives the page is served with the HTML document, literally in the same request and response. Compare this to our current implementation in Channel Admin Frontend v1 where there are a lot of stages in "the waterfall" as the app loads: First the HTML documents is loaded, once that is parsed the javascript bundle is requested, once that is downloaded and executed, API calls are made and the data is loaded often from multiple endpoints. Each of these stages cannot begin until the previous one has finished. All of this is eliminated with react router 7 as the HTML, JS, Data and assets are all served with one page request. Its win-win: the app code becomes much simpler and everything loads lightning-fast.
5 Summary
Action Items to achieve Channel Admin Frontend v2
-
Start to document behaviours of existing v1 application
Methodically go through the app, page by page, creating a series of documents that detail the capabilities of each section of the app. What their purpose is, what they enable the user to do and how the user is currently provided the ability to do it. This would begin the process of producing a formal template for concept documentation going forwards. -
Plan our teams
We will probably require a skeleton squad to maintain v1 while the majority of FE resources would be working on v2 full-time. We would most likely need dedicated backend developers to help rework the APIs that are not up to standard too. Going forward Frontend needs should be the driver that determines the schema for all REST API responses. The data should come out of the API ready for consumption by the Frontend. -
Break down the behaviours document specified above into logical
EPIC tickets.
These tickets will be organised into a schedule, it makes sense to me that we follow a user flow oriented order: Login Flow, Country Selection Page, Dashboard etc. Much like those illustrated in the examples shown in the Agile section above. -
Begin producing the Component Library
The vast majority of UI in the app can be broken down into a series of reusable and composable react components. The bulk of the work at the beginning of this project would involve collecting requirements (from the behaviours document) and speccing out these component then planning a schedule to build them. -
Set a date for feature freeze on v1
Once the majority of resources are focussed on v2 we should set a feature freeze date. After this date only defects, bugfixes and critical features of the highest importance can be worked on in the v1 codebase. -
Begin the provisioning process to host our ReactRouter v7
framework driven site
This will require a node server, We would need to enter into dialog with infra to gauge what is needed for provisioning as we usually work with apache servers which are not compatible with our Frontend needs. -
Agile Training
Refresher courses for all devs. Its been so long since I've done agile I think I would benefit from this too. We have agile coaches. This is the time they start earning their keep... -
Start the planning process
Schedule Sprint Planning meetings to split our EPICs into TASKS and SUBTASKS. These should occur at the start of every 2 week sprint. Here we will estimate how much work we think we can do using fibonacci numbers or t-shirt sizing.
There should also be a Sprint Retrospective at the end of each sprint. Here we will assess what we achieved, what we did well, what we could do better and assess how accurate our sprint planning estimates were. Over time, our estimates will become more accurate allowing us to better predict how long any given amount of work will take as we refine our self-knowledge of our capacity. This session can also be attended by managers to catch up with what has been done, track progress and assimilate feedback. -
Lets Get Started!
We have the future to build!
Thank you for taking the time to consider this proposal, I hope to have brought to light some obstacles and provided some ideas as to how together we might overcome them.
If you have any questions or comments please dont hestiate to get in touch Via Email (hello@anthonycregan.co.uk)