# Architecture Decision Record - Web Front-end Architecture
## Overview
### Status
**DRAFT**
### Contributor
| Name | Role |
|------|------|
|Firyal Fakhrilhadi|Technical Lead|
### Table of Contents
- [Architecture Decision Record - Modern Web Front-end Architecture](#architecture-decision-record---modern-web-front-end-architecture)
- [Overview](#overview)
- [Status](#status)
- [Contributor](#contributor)
- [Table of Contents](#table-of-contents)
- [Background](#background)
- [Positions](#positions)
- [Arguments](#arguments)
- [Decisions](#decisions)
- [Solution Architecture](#solution-architecture)
- [Post Implementation Risk](#post-implementation-risk)
- [References](#references)
## Background
### Positions
1. Current codebase doesn't have any well defined design pattern and/or architecture, resulting in frankenstein like codebase (each part of the code have significantly different approach)
2. Well defined and robust software architecture increase development experience by increasing code readability and testability, which results in easier to achieve excelent robustness level in the application and easier bug tracing.
3. No clear boundary between ui/presentation layer with business logic layer, indicated by some hooks which held business logic function to be placed inside components, which ideally are design to be plain presentation object.
4. Client Portal uses next.js which uses server side rendering with some benefits come with it. Next.js have some conventions that cannot be overriden, such as foldering strategy for pages, which is located at `/pages` or `/src/pages`
5. By the time this document is written, 29th September 2022, Chakra UI compatibility with stitches.js is still in issue.
### Arguments
1. Architectural problems might leads to one million dollar problem for large scale software, which client portal should be considered as one.
2. Large scale application typically have more than one domain of problem to be solved via the app, which Kerjaan Client Portal fulfilled this criteria. Current implementation of client portal have no boundary set between each domain of problem.
3. Boundary between UI/presentation layer and business logic layer should be exist so software testability might be increased by enabling isolation of testing between ui testing and business logic testing.
4. Some foldering strategy should follow next.js convention, such as location of page script since it cannot be overriden.
5. Styling should be controlled via master script, which stitches.js is capable of this functionality.
6. Log tracing is crusial in the success of product maintainability, Sentry is the first choice for error tracing tool.
7. Testing is one way to make sure that migration process to new architecture is safe in production. To ensure we have high confidence in releasing the update, minimum 70% of test coverage should be aimed.
## Decisions
### Solution Architecture
First thing need to be done is to distinguish between various components exist in client portal codebase, is by identifying which one is UI / presentation module, which one is business logic processing module.
|UI / Presentation Layer|Business Logic Layer|
|--|--|
|Pages|Services / API Access|
|Components|React Custom Hooks|
| - Atoms|Application State|
| - Molecules||
| - Organisms||
|**Non-intelligent Objects**|**Intelligent Objects**|
By categorizing UI / presentation layer as **Non-intelligent Objects**, rule of thumb that can be inferred is
> - Logic allowed inside **Non-intelligent Objects** are limited to controlling presentational behavior.
> - All complex logic which involve calculation to data retrieved from state and/or external data source (e.g. functions which calculate payroll, available date options for payroll period, etc.) should be placed in other than UI / presentation layer, which usually uses custom hooks.
#### UI / Presentation Layer
There are several choices for UI library to be used for react project. Some popular libraries are:
1. [Ant-design](https://ant.design/)
2. [Chakra UI](https://chakra-ui.com/)
3. [React Bootstrap](https://react-bootstrap.github.io/)
##### `pages`
Stores codes for page component. This usually import several components from `/components`
##### `components`
Still retain current approach by implementing atomic design to improve code reusability. Components separated into three categories:
1. Atoms
2. Molecules
3. Organism
#### Business Logic Layer
##### `api`
Stores script to access external api, such as endpoints in `kerjaansvc` (while not limited to endpoint maintained internally by Kerjaan team). To ensure excellent development experience can be fulfilled, Axios is the library of choice since compared to native Fetch API, a lot of base functionality such as:
1. Automatic parsing to JSON
2. Use HTTP code as source of truth on error condition
3. HTTP request interception can be done easily via Axios interception API
4. Backward compatibility to various browsers
##### `hooks`
Stores custom hooks used in application. Used primarily to process complex logic in business usecase, so UI/presentation layer (`pages` and `components`) can import the custom hooks, call the hooks inside the component and use it for rendering purpose.
React Query, which is a request wrapper library in hook form with built in caching mechanism should be included in this module.
##### `states`
Stores application state for cross component data usage. Zustand will be used to maintain state for it's simple API (similar to hooks).
#### Architecture Diagram
```mermaid
flowchart TB
subgraph ui
components-->pages
end
subgraph businessLogic_domain1
api_1-->hooks_1
states_1 --> components
states_1 --> pages
hooks_1 --> components
hooks_1 --> pages
end
subgraph businessLogic_domain2
api_2-->hooks_2
states_2 --> components
states_2 --> pages
hooks_2 --> components
hooks_2 --> pages
end
drivers --> businessLogic_domain1
drivers --> businessLogic_domain2
drivers --> ui
```
#### Third Party Libraries Used
1. [Radix-UI Primitives](https://www.radix-ui.com/)
2. [stitches.js](https://stitches.dev/)
3. [zustand](https://github.com/pmndrs/zustand)
4. [React Query](https://tanstack.com/query/v4/?from=reactQueryV3&original=https://react-query-v3.tanstack.com/)
5. [Axios](https://github.com/axios/axios)
6. [React Google Analytics](https://github.com/react-ga/react-ga)
7. [Sentry](https://docs.sentry.io/platforms/javascript/guides/react/)
#### Foldering Strategy
```
/root
/components
/atoms
/molecules
/organisms
/domains
/domain_1
/api
/hooks
/states
/domain_2
/api
/hooks
/states
/drivers
react-query.js <<init react query>>
logger.js <<error logging, init sentry>>
styling.js <<style management, stitches.js>>
analytic.js <<user analytics, Google Analytic>>
request.js <<driver for request, Axios>>
/pages
```
### Post Implementation Risk
1. 100% test coverage is an arguably absurd target since the return of resource spent on increasing test coverage doesn't have siginificant effect on the software quality compared to cost to implement. By using only 70% test coverage treshold tor release, risk of error occurence from existing feature still exist.
## References
1. [Unable to change pages directory in next.js](https://github.com/vercel/next.js/issues/4789)
2. [Chakra UI compatibility issue with stitches.js](https://github.com/chakra-ui/chakra-ui/discussions/4422)
3. [Axios vs Fetch](https://www.geeksforgeeks.org/difference-between-fetch-and-axios-js-for-making-http-requests/#:~:text=Differences%20between%20Axios%20and%20Fetch%3A&text=Axios%20has%20url%20in%20request,installation%20is%20required%20as%20such.)