Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Netmanager] Fixed typescript errors and added Dockerfile #2395

Merged
merged 9 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions netmanager-app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Use the official Node.js image as a base
FROM node:18

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Expose the application port
EXPOSE 3000

# Command to run the application
CMD ["npm", "start"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add .dockerignore file.

Create a .dockerignore file to exclude unnecessary files from the build context:

.git
.gitignore
node_modules
.next
.env*
npm-debug.log*
README.md
.vscode
coverage

🛠️ Refactor suggestion

Enhance Dockerfile with production best practices.

Consider the following improvements:

  1. Add multi-stage builds to reduce final image size
  2. Include environment variable handling
  3. Add health checks
  4. Specify a non-root user for security

Here's an optimized version:

# Build stage
- FROM node:18
+ FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
- RUN npm install
+ RUN npm ci
COPY . .
+ RUN npm run build

+ # Production stage
+ FROM node:18-alpine
+ WORKDIR /app
+ COPY --from=builder /app/.next ./.next
+ COPY --from=builder /app/node_modules ./node_modules
+ COPY --from=builder /app/package*.json ./

+ # Add healthcheck
+ HEALTHCHECK --interval=30s --timeout=3s \
+   CMD wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1

+ # Use non-root user
+ USER node

EXPOSE 3000
- CMD ["npm", "start"]
+ CMD ["npm", "run", "start"]

Committable suggestion skipped: line range outside the PR's diff.

61 changes: 61 additions & 0 deletions netmanager-app/app/types/devices.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Site } from "./sites";

export interface DeviceSite {
_id: string;
visibility: boolean;
Expand Down Expand Up @@ -60,3 +62,62 @@ export interface DevicesSummaryResponse {
message: string;
devices: Device[];
}

interface HealthTip {
title: string;
description: string;
image: string;
}

interface AQIRange {
min: number;
max?: number;
}

interface AQIRanges {
good: AQIRange;
moderate: AQIRange;
u4sg: AQIRange;
unhealthy: AQIRange;
very_unhealthy: AQIRange;
hazardous: AQIRange;
}

interface Averages {
dailyAverage: number;
percentageDifference: number;
weeklyAverages: {
currentWeek: number;
previousWeek: number;
};
}

export interface Measurement {
_id: string;
site_id: string;
time: string;
__v: number;
aqi_category: string;
aqi_color: string;
aqi_color_name: string;
aqi_ranges: AQIRanges;
averages: Averages;
createdAt: string;
device: string;
device_id: string;
frequency: string;
health_tips: HealthTip[];
is_reading_primary: boolean;
no2: Record<string, unknown>;
pm10: { value: number };
pm2_5: { value: number };
siteDetails: Site;
timeDifferenceHours: number;
updatedAt: string;
}

export interface ReadingsApiResponse {
success: boolean;
message: string;
measurements: Measurement[];
}
72 changes: 17 additions & 55 deletions netmanager-app/app/types/grids.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,23 @@
export interface Grid {
_id: string;
visibility: boolean;
name: string;
admin_level: string;
network: string;
long_name: string;
createdAt: string;
sites: Site[];
import { Site } from "./sites";

export interface CreateGrid {
name: string;
admin_level: string;
shape: {
type: "MultiPolygon" | "Polygon";
coordinates: number[][][][];
};
network: string;
Comment on lines +6 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Clarify the coordinates type in the shape property

The coordinates property is currently typed as number[][][][], which corresponds to a MultiPolygon coordinate structure. However, when the type is "Polygon", the coordinates should be number[][][]. To accurately represent both geometries, consider defining shape as a union type.

Apply this diff to adjust the shape property:

 export interface CreateGrid {
   name: string;
   admin_level: string;
-  shape: {
-    type: "MultiPolygon" | "Polygon";
-    coordinates: number[][][][];
-  };
+  shape:
+    | {
+        type: "Polygon";
+        coordinates: number[][][];
+      }
+    | {
+        type: "MultiPolygon";
+        coordinates: number[][][][]; 
+      };
   network: string;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
shape: {
type: "MultiPolygon" | "Polygon";
coordinates: number[][][][];
};
shape:
| {
type: "Polygon";
coordinates: number[][][];
}
| {
type: "MultiPolygon";
coordinates: number[][][][];
};

}

export interface Site {
export interface Grid {
_id: string;
isOnline: boolean;
formatted_name: string;
location_name: string;
search_name: string;
city: string;
district: string;
county: string;
region: string;
country: string;
latitude: number;
longitude: number;
visibility: boolean;
name: string;
approximate_latitude: number;
approximate_longitude: number;
generated_name: string;
data_provider: string;
description: string;
site_category: SiteCategory;
groups: string[];
grids: Grid[];
devices: Device[];
airqlouds: unknown[];
admin_level: string;
network: string;
long_name: string;
createdAt: string;
updatedAt?: string;
pm2_5?: number;
}

interface SiteCategory {
tags: string[];
area_name: string;
category: string;
highway: string;
landuse: string;
latitude: number;
longitude: number;
natural: string;
search_radius: number;
waterway: string;
sites: Site[];
numberOfSites: number;
}

export interface Device {
_id: string;
group: string;
authRequired: boolean;
serial_number: string;
api_code: string;
groups: string[];
}
98 changes: 88 additions & 10 deletions netmanager-app/app/types/sites.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,98 @@
export interface Site {
id: string;
name: string;
description: string;
country: string;
_id: string;
nearest_tahmo_station: {
id: number;
code: string | null;
longitude: number;
latitude: number;
timezone: string | null;
};
images: unknown[];
groups: unknown[];
site_codes: string[];
site_tags: string[];
isOnline: boolean;
formatted_name: string;
location_name: string;
search_name: string;
parish: string;
village: string;
sub_county: string;
city: string;
district: string;
county: string;
region: string;
country: string;
latitude: number;
longitude: number;
name: string;
network: string;
parish: string;
subCounty: string;
approximate_latitude: number;
approximate_longitude: number;
bearing_in_radians: number;
approximate_distance_in_km: number;
lat_long: string;
generated_name: string;
altitude: number;
greenness?: string;
nearestRoad?: number;
mobileAppName?: string;
mobileAppDescription?: string;
data_provider: string;
description: string;
weather_stations: Array<{
code: string;
name: string;
country: string;
longitude: number;
latitude: number;
timezone: string;
distance: number;
_id: string;
}>;
createdAt: string;
lastActive: string;
grids: Array<{
_id: string;
name: string;
admin_level: string;
visibility: boolean;
}>;
devices: Array<{
_id: string;
visibility: boolean;
mobility: boolean;
status: string;
isPrimaryInLocation: boolean;
category: string;
isActive: boolean;
device_number: number;
name: string;
createdAt: string;
device_codes: string[];
network: string;
approximate_distance_in_km: number;
bearing_in_radians: number;
latitude: number;
longitude: number;
ISP: string;
previous_sites: string[];
groups: string[];
host_id: string | null;
cohorts: unknown[];
serial_number: string;
isOnline: boolean;
lastActive: string;
}>;
airqlouds: unknown[];
site_category?: {
tags: string[];
area_name: string;
category: string;
highway: string;
landuse: string;
latitude: number;
longitude: number;
natural: string;
search_radius: number;
waterway: string;
};
}

export interface Device {
Expand Down
Loading
Loading