Skip to content

Commit c6f13ec

Browse files
authored
feat(web): modernize frontend stack to TypeScript + Vite, expand test coverage, and harden OpenTelemetry tracing (#257)
* Repository Fixes * Added AI-DLC to Repository * chore: upgrade dependencies, migrate to TypeScript strict mode, and Mantine v7 - Updated all dependencies to latest versions (React 18.3.1, React Router 6.30.3, etc.) - Converted entire codebase from JavaScript to TypeScript with strict mode enabled - Migrated Mantine UI from v6.0.22 to v7.17.8, updating all component APIs: - AppShell, color scheme, Group/Stack/Grid layout props - Input sections, Autocomplete renderOption, Stepper, Pagination - Added Mantine v7 native CSS imports - Updated test dependencies (@testing-library suite, @types/jest) - Removed --legacy-peer-deps requirement * chore(web): migrate CRA to Vite/Vitest, upgrade core deps, and align Mantine DatePickerInput to string dates - replace react-scripts workflow with Vite + Vitest - upgrade React, Mantine, React Router, and OpenTelemetry to compatible latest versions - update env/config/docs for Vite and dist output - fix Search date handling to use YYYY-MM-DD picker values and MM-DD-YYYY backend params * refactor: add TS file purpose summaries, clarify function intent, and standardize imports to @/ aliases * test: maximize coverage and document updated testing standards * feat(otel): modernize tracing implementation and validate with targeted tests Migrate OpenTelemetry bootstrap and instrumentation flow. Add route-level and service-level span coverage with regression tests. Harden tracing fallback/error sanitization behavior and validate with full coverage run. * Remove AI-DLC * Updated based on Copilot suggestions
1 parent 06b13b1 commit c6f13ec

100 files changed

Lines changed: 9213 additions & 19084 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
# Add environment variables in this format:
66
# KEY=VALUE
77
#
8-
# Each ENVIRONMENT VARIABLE define will be availaible in
9-
# `process.env.KEY` in your code
8+
# Each browser-exposed environment variable must use the `VITE_` prefix.
9+
# Variables are available in application code through `import.meta.env`.
1010
#
1111
# SESSION_SECRET=super_long_seacret_that_should_be_replaced
1212

1313
# FlyFast - Flight Search Backend
14-
REACT_APP_FLIGHT_SEARCH=http://localhost:8080
14+
VITE_FLIGHT_SEARCH=http://localhost:8080
1515

1616
# Aternity APM Collector
1717
# https://hub.docker.com/r/aternity/apm-collector
18-
REACT_APP_OPENTELEMETRY_ENDPOINT=http://localhost:55681
18+
VITE_OPENTELEMETRY_ENDPOINT=http://localhost:55681

.github/workflows/ci.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- "**"
7+
pull_request:
8+
branches:
9+
- "**"
10+
11+
concurrency:
12+
group: ci-${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
build-test:
17+
name: Type Check, Test, Build
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Node
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: "22.14.0"
28+
cache: npm
29+
30+
- name: Install dependencies
31+
run: npm ci
32+
33+
- name: Type check
34+
run: npm run type-check
35+
36+
- name: Run tests with coverage gate
37+
run: npm run test:ci
38+
39+
- name: Build
40+
run: npm run build

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
# production
1212
/build
13+
/dist
1314

1415
# misc
1516
.DS_Store

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

Dockerfile

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,40 @@
1-
# Dockerfile
2-
# 24.10.31
1+
FROM node:22-alpine AS react-build
32

4-
# Stage 1, Building React Application
5-
6-
FROM node:lts-slim AS react-build
3+
# Pin npm for reproducible dependency behavior across local and CI builds.
4+
RUN npm install -g npm@11.7.0
75

86
WORKDIR /app
7+
COPY package*.json ./
8+
RUN npm ci --prefer-offline --no-audit
99
COPY . .
10-
11-
## Dependencies
12-
13-
# method 1: install deps from package.json (not immutable)
14-
# RUN npm install
15-
16-
# method 1 with legacy
17-
# RUN npm install --legacy-peer-deps
18-
19-
# method 2: clean-install will install dependencies from the package-lock.json (immutable)
20-
RUN npm clean-install
21-
22-
# method 2 with legacy
23-
# RUN npm clean-install --legacy-peer-deps
24-
25-
## Build
26-
2710
RUN npm run build
11+
RUN npm prune --production
2812

29-
#######################################################################################
30-
31-
# Stage 2, Setting Up Production Environment
13+
FROM nginx:1.27.0-alpine
3214

33-
FROM nginx:1.27
15+
RUN apk add --no-cache curl gettext
3416

3517
COPY default.conf.template /etc/nginx/conf.d/default.conf.template
36-
COPY --from=react-build /app/build /usr/share/nginx/html
18+
COPY --from=react-build /app/dist /usr/share/nginx/html
3719

38-
ENV REACT_APP_FLIGHT_SEARCH="http://flyfast-flightsearch:8080"
39-
ENV REACT_APP_OPENTELEMETRY_ENDPOINT="http://apm-collector:55681"
20+
ENV VITE_FLIGHT_SEARCH="http://flyfast-flightsearch:8080"
21+
ENV VITE_OPENTELEMETRY_ENDPOINT="http://apm-collector:55681"
4022

4123
EXPOSE 80
4224

25+
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
26+
CMD curl -f http://localhost/ || exit 1
27+
28+
LABEL maintainer="FlyFast Development Team"
29+
LABEL description="FlyFast Web UI static frontend"
30+
4331
## Initial command to launch the app
44-
# CMD /bin/bash -c "envsubst '\$REACT_APP_FLIGHT_SEARCH \$REACT_APP_OPENTELEMETRY_ENDPOINT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
32+
# CMD ["/bin/sh", "-c", "envsubst '$VITE_FLIGHT_SEARCH $VITE_OPENTELEMETRY_ENDPOINT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"]
4533

4634
## Command modified to add Observability with ALLUVIO UJI
4735
# * The head of the index.html must contain the TAG PLACEHOLDER defined in the env variable ALLUVIO_TAG_PLACEHOLDER
4836
# * in order to inject ALLUVIO_UJI_TAG in the index.html master page of the app
4937
# * ALLUVIO_UJI_TAG must be configured at runtime (ex. )
5038
ENV ALLUVIO_TAG_PLACEHOLDER="<alluvio_tag_placeholder\/>"
5139
ENV ALLUVIO_UJI_TAG="<!-- my ALLUVIO UJI TAG -->"
52-
CMD /bin/bash -c "sed -i \"s|$ALLUVIO_TAG_PLACEHOLDER|$ALLUVIO_UJI_TAG|\" /usr/share/nginx/html/index.html && envsubst '\$REACT_APP_FLIGHT_SEARCH \$REACT_APP_OPENTELEMETRY_ENDPOINT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
40+
CMD ["/bin/sh", "-c", "sed -i \"s|$ALLUVIO_TAG_PLACEHOLDER|$ALLUVIO_UJI_TAG|\" /usr/share/nginx/html/index.html && envsubst '$VITE_FLIGHT_SEARCH $VITE_OPENTELEMETRY_ENDPOINT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"]

README.md

Lines changed: 74 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
# FlyFast - WebUI
22

3+
![Coverage Badge](https://img.shields.io/badge/coverage-96%25-brightgreen)
4+
![Test Status](https://img.shields.io/badge/tests-passing-brightgreen)
5+
36
This repository contains the source code for the WebUI of FlyFast.
47

58
For the source code of the backend, head over to [FlightSearch](https://github.com/Aternity/FlyFast-FlightSearch). This will be necessary to make any backend calls but is not required for viewing the WebUI.
69

710
To view the full source code and to run the whole application through Docker, head over to [FlyFast](https://github.com/Aternity/FlyFast).
811

12+
## Tech Stack
13+
14+
- **React 19** with TypeScript (strict mode)
15+
- **Vite 6** (build tool and dev server)
16+
- **Vitest 3** (test runner)
17+
- **Mantine 8** (UI components)
18+
- **React Router 7** (routing)
19+
- **OpenTelemetry** (tracing)
20+
921
## Prerequisites
1022

1123
1. [Git](https://git-scm.com/) (Optional)
12-
2. a Docker host, for example [Docker Desktop](https://www.docker.com/products/docker-desktop) (Optional)
13-
3. [NodeJS](https://nodejs.org/en/) (Required)
14-
4. [FlightSearch](https://github.com/Aternity/FlyFast-FlightSearch) (Required Only For Making Backend Calls)
24+
2. A Docker host, for example [Docker Desktop](https://www.docker.com/products/docker-desktop) (Optional)
25+
3. [Node.js 22.14.0](https://nodejs.org/en/) (Required)
26+
4. [FlightSearch](https://github.com/Aternity/FlyFast-FlightSearch) (Required only for backend calls)
1527

1628
## Getting Started
29+
1730
1. Clone/download this repository.
1831
```
1932
git clone https://github.com/Aternity/FlyFast-WebUI.git
@@ -22,26 +35,31 @@ To view the full source code and to run the whole application through Docker, he
2235
```
2336
cd FlyFast-WebUI
2437
```
25-
3. You can either start the application using [NodeJS](#step-by-step-using-nodejs) or [Docker](#step-by-step-using-docker).
38+
3. You can either start the application using [Node.js](#step-by-step-using-nodejs) or [Docker](#step-by-step-using-docker).
2639
2740
## Step by Step Using NodeJS
41+
2842
1. Install the dependencies required to run this application:
2943
```
30-
npm install --legacy-peer-deps
44+
npm install
3145
```
32-
2. Make sure to set the environment variables for the application. Take a look at [.env.example](.env.example) and follow the instructions on there.
33-
- `REACT_APP_FLIGHT_SEARCH` is the Flight Search URL, which should be on port `8080`, if you are using the [FlightSearch](https://github.com/Aternity/FlyFast-FlightSearch).
34-
- `REACT_APP_OPENTELEMETRY_ENDPOINT` is the APM Collector URL, which should be on port `55681`, if you are using the [Aternity APM Collector](https://hub.docker.com/r/aternity/apm-collector)
46+
2. Set the environment variables for the application. Copy [.env.example](.env.example) to `.env` and fill in the values.
47+
- `VITE_FLIGHT_SEARCH` — the Flight Search URL (default port `8080`), used if you are running [FlightSearch](https://github.com/Aternity/FlyFast-FlightSearch).
48+
- `VITE_OPENTELEMETRY_ENDPOINT` — the APM Collector URL (default port `55681`), used if you are running the [Aternity APM Collector](https://hub.docker.com/r/aternity/apm-collector).
49+
50+
Environment variables are accessed in source code via `import.meta.env.VITE_*`.
51+
3552
3. Select one of the following [scripts](#available-scripts) that best suits your purpose.
3653
3754
## Step by Step Using Docker
38-
1. Build our docker:
55+
56+
1. Build the Docker image:
3957
```
4058
docker build . -t flyfast-webui
4159
```
42-
2. Run our docker container:
60+
2. Run the container:
4361
```
44-
docker run --rm -p 80:80 -e REACT_APP_FLIGHT_SEARCH=http://localhost:8080 -e REACT_APP_OPENTELEMETRY_ENDPOINT=http://localhost:55681 flyfast-webui
62+
docker run --rm -p 80:80 -e VITE_FLIGHT_SEARCH=http://localhost:8080 -e VITE_OPENTELEMETRY_ENDPOINT=http://localhost:55681 flyfast-webui
4563
```
4664
3. Open [http://localhost:80](http://localhost:80) to view it in your browser.
4765
@@ -51,62 +69,77 @@ In the project directory, you can run:
5169
5270
### `npm start`
5371
54-
Runs the app in the development mode.\
55-
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
72+
Runs the app in development mode using Vite.\
73+
Open [http://localhost:5173](http://localhost:5173) to view it in your browser.
5674
57-
The page will reload when you make changes.\
58-
You may also see any lint errors in the console.
75+
The page hot-reloads when you make changes.
5976
6077
### `npm test`
6178
62-
Launches the test runner in the interactive watch mode.\
63-
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
79+
Runs the Vitest test suite once and reports results.
6480
65-
### `npm run build`
81+
### `npm run test:watch`
6682
67-
Builds the app for production to the `build` folder.\
68-
It correctly bundles React in production mode and optimizes the build for the best performance.
83+
Runs Vitest in watch mode, re-running affected tests on file changes.
6984
70-
The build is minified and the filenames include the hashes.\
71-
Your app is ready to be deployed!
85+
### `npm run test:ui`
7286
73-
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
87+
Opens the Vitest browser UI for interactive test inspection.
88+
89+
### `npm run build`
7490
75-
### `npm run eject`
91+
Builds the app for production into the `dist/` folder.\
92+
The build is minified and filenames include content hashes.
7693
77-
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
94+
### `npm run preview`
7895
79-
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
96+
Serves the production build from `dist/` locally for inspection before deployment.
8097
81-
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
98+
### `npm run type-check`
8299
83-
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
100+
Runs TypeScript validation without emitting build artifacts.
84101
85-
## Additional Information
102+
### `npm run test:ci`
86103
87-
### Code Splitting
104+
Runs the complete test suite with coverage gate enforcement (80% minimum coverage on statements, branches, functions, and lines). This is used in CI/CD pipelines.
88105
89-
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
106+
## Testing
90107
91-
### Analyzing the Bundle Size
108+
FlyFast-WebUI maintains comprehensive test coverage with a focus on critical business logic and user workflows:
92109
93-
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
110+
- **Coverage Target**: 80% minimum on all metrics (statements, branches, functions, lines)
111+
- **Current Coverage**: 94% statements, 85% branches, 86% functions, 94% lines
112+
- **Test Approach**:
113+
- Unit tests for services, utilities, and component logic
114+
- Integration tests for multi-component workflows (search → results → checkout)
115+
- Per-file test coverage for all pages and components
116+
- Mocked Mantine provider and React Router for isolated component testing
94117
95-
### Making a Progressive Web App
118+
To run tests:
119+
- **Run all tests**: `npm test`
120+
- **Watch mode**: `npm run test:watch`
121+
- **Interactive UI**: `npm run test:ui`
122+
- **With coverage**: `npm run test:ci`
96123
97-
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
124+
Test files are co-located with source code using the `.test.tsx` and `.test.ts` naming convention.
98125
99-
### Advanced Configuration
126+
## Docker Build Notes
100127
101-
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
128+
The Dockerfile uses a multi-stage build:
129+
- **Build stage**: Node 22 Alpine — installs dependencies and runs `vite build` (output in `dist/`)
130+
- **Runtime stage**: NGINX 1.27 Alpine — serves the static assets; injects `VITE_*` environment variables at container startup via `envsubst`
102131
103-
### Deployment
132+
Build image:
104133
105-
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
134+
```bash
135+
docker build -t flyfast-webui .
136+
```
106137

107-
### `npm run build` fails to minify
138+
Run container:
108139

109-
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
140+
```bash
141+
docker run --rm -p 80:80 -e VITE_FLIGHT_SEARCH=http://localhost:8080 -e VITE_OPENTELEMETRY_ENDPOINT=http://localhost:55681 flyfast-webui
142+
```
110143

111144
## License
112145
Copyright (c) 2022 Riverbed Technology, Inc.

default.conf.template

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ server {
88
}
99

1010
location /flightsearchapi {
11-
proxy_pass ${REACT_APP_FLIGHT_SEARCH};
11+
proxy_pass ${VITE_FLIGHT_SEARCH};
1212
}
1313

1414
location /tracingapi {
1515
rewrite /tracingapi/(.*) /$1 break;
16-
proxy_pass ${REACT_APP_OPENTELEMETRY_ENDPOINT};
16+
proxy_pass ${VITE_OPENTELEMETRY_ENDPOINT};
1717
}
1818
}

index.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<link rel="icon" href="/favicon.ico" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1" />
7+
<meta name="theme-color" content="#000000" />
8+
<meta
9+
name="description"
10+
content="FlyFast - Your trusted flight booking platform"
11+
/>
12+
<link rel="apple-touch-icon" href="/logo192.png" />
13+
<link rel="manifest" href="/manifest.json" />
14+
<alluvio_tag_placeholder/>
15+
<title>FlyFast</title>
16+
</head>
17+
<body>
18+
<noscript>You need to enable JavaScript to run this app.</noscript>
19+
<div id="root"></div>
20+
<script type="module" src="/src/index.tsx"></script>
21+
</body>
22+
</html>

0 commit comments

Comments
 (0)