Accedo Build Elevate Web
For a detailed overview of Elevate across platforms please visit Build Elevate Confluence Page
What is Elevate
An advanced application starting point that jump-starts the development process with user flows, page templates, UI components populated with content, and base integrations ready for customization.
Getting Started
Project Setup
Prerequisites
Elevate Web uses pnpm as dependency manager, if you want to use another alternative, please go to package.json
file and update the packageManager
value
For more information, please visit official node section about packageManager
We use nvm to select proper node version.
Install dependencies and run app
# First, install nvm, the node version used in this project is defined in the .nvmrc file.
nvm use
pnpm i
# Run the development server
pnpm dev
Debug the application
NPM Scripts
Project App Structure
Elevate Web is a Next.js based application, so some conventions are based on the conventions defined in the framework itself, we recommend you to read at least App Routing Conventions
Component Structure
We are going to follow the a Component structure based on two concepts:
- Complexity-based: reusable components that can be used across any page/template, with a separation in two:
- simple: stateless, very reusable components
- complex: Usually composed from other simple components and can have state
- Feature-based: every complex component, that is not going to be reusable, but just part of an specific feature (EPG, Auth, Player, ...)
Besides that, we need to take into account that Pages/views and partially, any possible route-based template will be created under the app
folder following the App Routing Conventions from Next.js
The reason to keep this structure and not a pure Atom-based model is to avoid having all the components under the components folder, making very hard to traverse and look for the proper component, but limit it with the feature-based list of components and then simplify the 3-4 other layers (pages/views should be always under the app
folder due to Next.js) into 2 at least initially to have a clear separation for the atomic, non-composed ones (and also stateless) from the others.
General Structure
📂 docs ───────> project documentation
📂 public ───────> web static assets
📂 src ───────> source dir
├─ 📂 app ───────> next.js routes
│ └─ 📂 [[...routeSegments]] ───────> Single dynamic route page (more on the next section)
│ └─ 📄 layout ───────> default page layout
│ ...
├─ 📂 components ───────> Complexity-based Components folder
│ └─ 📂 simple ───────> Simple Components (Reels components or not composed and without state)
│ └─ 📂 base ───────> Reels Components (Component from the Component library based on PD&A Reels)
│ └─ 📂 complex ───────> Complex Components (composed from simple components or with state)
├─ 📂 config ───────> Application configuration
├─ 📂 context ───────> App global React contexts
├─ 📂 dataModels ───────> Any app data model
├─ 📂 dev-utils ───────> Utilities used for development purposes
├─ 📂 features ───────> Feature-based Components folder
│ └─ 📂 ... ───────> A per feature folder, it will include all the needed code outside of the Data Fetching related one
├─ 📂 hooks ───────> App hooks, use for common shared utilities fns and Service access
├─ 📂 providers ───────> App Providers (as per the Elevate Service Architecture)
├─ 📂 services ───────> App Services (as per the Elevate Service Architecture)
├─ 📂 types ───────> Typescript type utilities and global types
├─ 📂 utils ───────> Global utils
├─ 📂 views ───────> Application dynamic views (mapped from [[...routeSegments]]) and mapper
📄 .env ───────> environment variables
📄 next-env.d.ts ───────> next.js type defs
📄 next.config.js ───────> next.js config
📄 package.json ───────> project readme
📄 [other configs] ───────> Any other config file
Elevate Routes Mapping
Project Documentation
General Documentation
Documentation for Elevate Web is created using Docusaurus inside the docs
folder. There a separate "project" inside that folder which it's own npm project structure and so on.
The initial page uses this README.md file to create and display its content
To access documentation:
cd docs
pnpm start
To create documentation build:
cd docs
pnpm run build
pnpm run serve
If you need to add any extra Documentation, please add a new entry into docs/docs
You can use the helper command from the root of the repository to access the documentation:
pnpm run docs
Diagrams
Elevate uses mermaid for the diagrams which integrates directly with Github and with an integration with Docusaurus
Components
Code rules
General
Code and CSS Style Guidelines
We are using eslint, eslint stylistic and stylelint to define the project code style and ensure that everyone follows the same rules.
We enforce the usage of typescript as default language to ensure better type check and remove possible situations/issues.
Please refer to the .eslintrc.json
and .stylelintrc.json
to see the specific configuration we use for each tool.
You can also read the Next.js Docs about the default eslint config.
App Styling
Elevate Web uses CSS Modules together with Design tokens to create the styles for the applications and components.
Style entry point file is globals.css
and there is includes all the Design System tokens from _variables.css
.
Custom pages/layout styles, component styles or features styles should be included in it's own folder and use Design System tokens when possible.
NOTE
Font Family is not used based on the Design tokens variables but using next/font/google
instead as it's the standard way of working on Next.js
Testing
We use jest, testing-library, storybook and playwright for the Automatic testing of the application.
jest
is used as test runner and assertion librarytesting-library
is used for the component and component interaction library on the simple cases.storybook
is used for the component interaction test for more detailed casesplaywright
is used for end to end testing.
GitFlow and Related Rules
Branching and Code Reviews
We have a main branch main
and usually we work toward that branch every time, we don't use long-live branches, develop branch or any other alternative. Our philosophy is to Ship as fast as possible into the main branch and use the Setup validations to ensure everything works as expected.
We follow a Ship/Show/Ask approach where:
- We Ship directly into
main
branch anything that doesn't require any validation or it's totally straightforward. - We Show creating a PR into
main
with the tag[SHOW]
to create a PR that doesn't require manual validation, but that can benefit for it or has something that can be interesting to show to peers. Automatic validations will help to avoid merging an invalid PR. - We Ask creating a PR that requires manual validation for any peer/contributor to ensure a patter is properly implemented or there's no mistake into the implementation (apart from the automatic validations)
For all the cases, there's a PR template for Github located in .github/pull_request_template.md
Branch Naming conventions
We use short-live feature branches to handle features work, and bugfix branches for aby fix needed.
The prefixes for those are: feat
and fix
and the general naming convention for the branches will be:
{type}/BUILDELEVATE-XXXX_description-name
: for ticket related branches{type}/description-name
: for non-ticket related branches
Github Actions
Validations
We have separate Github actions created to do all the actions related to a change for every PR (creation, change) and main push that will execute (pr.yml
and main.yml
):
Then we have splitted the workflows into validations (validations.yml
) and deployments.
The validations will:
- All the code validations (linters and tsc)
- Unit and component test validation with code coverage report
- Danger Pull request analysis
- Sonar Analysis with report to SonarCloud, including the test coverage from the test report and the automatic generation of sonar properties from template
After all the static validations the main workflows, will trigger the CI/CD workflows if the conditions for the trigger checks are met (ie: we wouldn't trigger from pr.yml
the deployment if the trigger was an edited
event.action as it will not include code changes)
CI/CD
We have three separate Github actions created for each of the deploy types as workflow_call
:
- Nextjs Application deployment on
ci.yml
- Documentation deployment on
documentation.yml
- Component Documentation deployment on
component-docs.yml
This process will deploy it corresponding application/static site following the rules:
https://ci-elevateweb-main.ocs2.ps.accedo.tv
for the Nextjs App onmain
branchhttps://ci-elevateweb-{N}.ocs2.ps.accedo.tv
for the Nextjs App on a PR with numberN
on Githubhttps://gdoc-elevateweb-main.ocs2.ps.accedo.tv
for the General Documentation onmain
branchhttps://gdoc-elevateweb-{N}.ocs2.ps.accedo.tv
for the General Documentation on a PR with numberN
on Githubhttps://cdoc-elevateweb-main.ocs2.ps.accedo.tv
for the Component Documentation onmain
branchhttps://cdoc-elevateweb-{N}.ocs2.ps.accedo.tv
for the Component Documentation on a PR with numberN
on Github
Danger PR Analysis
We use Danger to do some aumatic validations of de "quality" of the Pull request and also to report back into the Pull Request based on the base branch and the Status of the Pull Request.
You can find the specific code into the Dangerfile file.
Commit messages guide
We enforce the usage of convential commits to create explicit commit messages
We use commitlint with @commitlint/config-conventional
and husky
to ensure that the commits follow the proper messages. Please don't skip hooks
Versioning
Together with the Commit rules, we do automatic versioning based on the rules applied on convential commits following Semantic Versioning