Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tifaucz committed Mar 11, 2024
1 parent f73f5f0 commit 117b6b7
Show file tree
Hide file tree
Showing 19 changed files with 22,923 additions and 1,823 deletions.
25 changes: 22 additions & 3 deletions common/types/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,30 @@ export type QueryUserArgs = {

export type Ship = {
__typename?: 'Ship';
active: Scalars['Boolean'];
class?: Maybe<Scalars['String']>;
id: Scalars['ID'];
image?: Maybe<Scalars['String']>;
class?: Maybe<Scalars['String']>;
name?: Maybe<Scalars['String']>;
image?: Maybe<Scalars['String']>;
active: Scalars['Boolean'];
abs?: Maybe<Scalars['Int']>;
home_port?: Maybe<Scalars['String']>;
imo?: Maybe<Scalars['Int']>;
mmsi?: Maybe<Scalars['Int']>;
model?: Maybe<Scalars['String']>;
roles?: Maybe<Array<Maybe<Scalars['String']>>>;
status?: Maybe<Scalars['String']>;
type?: Maybe<Scalars['String']>;
year_built?: Maybe<Scalars['Int']>;
missions?: Maybe<Array<Maybe<Mission>>>;
createdAt: Scalars['Date'];
updatedAt: Scalars['Date'];
};

export type Mission = {
__typename?: 'Mission';
id: Scalars['ID'];
flight: Maybe<Scalars['String']>;
name: Maybe<Scalars['String']>;
};

export type ShipsInput = {
Expand Down
4 changes: 4 additions & 0 deletions config/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { ensureEnvVars } from './ensureEnvVars';
import { nodeEnv, NodeEnv } from './nodeEnv';

import * as dotenv from 'dotenv';
dotenv.config();


interface AuthScope {
userId?: string;
ip?: string;
Expand Down
10 changes: 9 additions & 1 deletion controllers/ship.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import { AuthScope } from '../config';
import { db } from '../models';
import { ShipAttributes } from '../models/ship';

const get = async ({ pagination }: { pagination: PaginationInput }, authScope: AuthScope): Promise<ShipAttributes[]> => {
const get = async ({ pagination }: { pagination?: PaginationInput }, authScope: AuthScope): Promise<ShipAttributes[]> => {
if (pagination) {
const { limit, offset } = pagination;
return db.Ship.findAll({
limit: limit,
offset: offset,
});
}

const ships = await db.Ship.findAll();

return ships;
Expand Down
118 changes: 118 additions & 0 deletions helpers/mockMissions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
[
{
"name": "High-seas payload retrieval phase II",
"flight": "CRS-22"
},
{
"name": "Saltwater impact assessment on rocket components",
"flight": "Transporter-3"
},
{
"name": "Dynamic positioning system validation for launch pads",
"flight": "Starlink-16"
},
{
"name": "Autonomous drone ship navigation trials",
"flight": "Turksat 5A"
},
{
"name": "Crew Dragon splashdown and recovery test",
"flight": "Crew-2"
},
{
"name": "Fairing catch and refurbishment operations",
"flight": "GPS III SV05"
},
{
"name": "Deep-sea telemetry data collection initiative",
"flight": "CRS-23"
},
{
"name": "Orbital debris tracking and analysis mission",
"flight": "Inspiration4"
},
{
"name": "Experimental landing pad coating endurance test",
"flight": "Starlink-17"
},
{
"name": "Long-duration sea state monitoring for launch stability",
"flight": "Starlink-18"
},
{
"name": "Underwater acoustic environment survey for rocket launches",
"flight": "Starlink-19"
},
{
"name": "Rocket booster retrieval and transport efficiency study",
"flight": "Starlink-20"
},
{
"name": "Sea-based radar cross-section measurements",
"flight": "Starlink-21"
},
{
"name": "Maritime navigation safety protocols for space operations",
"flight": "Starlink-22"
},
{
"name": "Automated sea vessel coordination for fleet management",
"flight": "Starlink-23"
},
{
"name": "Sea-to-space communication link optimization project",
"flight": "Starlink-24"
},
{
"name": "Environmental impact study of sea-based rocket launches",
"flight": "Starlink-25"
},
{
"name": "High-altitude wind pattern analysis over launch sites",
"flight": "Starlink-26"
},
{
"name": "Rocket propellant spill containment and recovery drill",
"flight": "Starlink-27"
},
{
"name": "Spacecraft heat shield splashdown recovery test",
"flight": "Starlink-28"
},
{
"name": "Offshore emergency response readiness for crewed flights",
"flight": "Starlink-29"
},
{
"name": "Sea-based launch viewing and public safety coordination",
"flight": "Starlink-30"
},
{
"name": "Recovery vessel speed and maneuverability enhancement",
"flight": "Crew-3"
},
{
"name": "Post-splashdown astronaut medical protocol simulation",
"flight": "AX-1"
},
{
"name": "Satellite deployment support and tracking ship mission",
"flight": "CRS-24"
},
{
"name": "Experimental ocean landing pad stabilization techniques",
"flight": "Transporter-4"
},
{
"name": "Multi-stage rocket component separation analysis at sea",
"flight": "Starlink-31"
},
{
"name": "Sea-based rocket launch noise pollution study",
"flight": "Starlink-32"
},
{
"name": "Recovery ship fleet synchronization and timing trials",
"flight": "Starlink-33"
}
]
135 changes: 111 additions & 24 deletions helpers/populate.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,122 @@
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('dotenv').config();
}
import { db } from '../models';
import { cleanDb } from '../helpers/testHelpers';
import fetch from 'node-fetch';
import { cleanDb, postQuery } from '../helpers/testHelpers';
import * as fs from 'fs';
import * as path from 'path';
import { Mission } from '../models/mission';

const testConnection = async () => {
try {
await db.sequelize.authenticate();
console.log('Connection to the database has been established successfully.');
} catch (error) {
console.error('Unable to connect to the database:', error);
}
};

const populate = async () => {
await cleanDb();
console.log('Populating database...');

const ships = await fetch('https://spacex-production.up.railway.app/api/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: '{ ships { id name image class active } }' }),
})
.then(res => res.json())
.then(data => data.data.ships);

await Promise.all(
ships.map((ship: any) => {
return db.Ship.create({
await testConnection();
try {
await cleanDb();
console.log('Database cleaned.');

const mockMissionsPath = path.join(__dirname, './mockMissions.json');
const mockMissions = JSON.parse(fs.readFileSync(mockMissionsPath, 'utf8'));
let missionModels: Mission[] = [];

for (const mission of mockMissions) {
const newMission = await db.Mission.create({
flight: mission.flight,
name: mission.name,
});
missionModels.push(newMission);
}
console.log('Missions table populated with mock data.');

console.log('Fetching ship data...');
const shipQuery = `
query {
ships {
id
name
image
class
active
abs
home_port
imo
missions {
name
flight
}
mmsi
model
position {
latitude
longitude
}
roles
status
type
year_built
}
}
`;

/*
Null fields:
attempted_landings:Int
course_deg:Int
position:ShipLocation
speed_kn:Float
successful_landings:Int
url:String
weight_kg:Int
weight_lbs:Int
*/

const ship_data = await postQuery(shipQuery);
const ships = ship_data.ships;

for (const ship of ships) {
let assignedMissions: Mission[] = [];
if (!ship.missions) {
const numberOfMissions = Math.floor(Math.random() * 3) + 1;
for (let i = 0; i < numberOfMissions; i++) {
const randomMissionIndex = Math.floor(Math.random() * mockMissions.length);
if (!assignedMissions.includes(missionModels[randomMissionIndex])) {
assignedMissions.push(missionModels[randomMissionIndex]);
} else {
i--;
}
}
}

const addedShip = await db.Ship.create({
id: ship.id,
active: ship.active,
name: ship.name,
class: ship.class,
class: ship.class ? ship.class.toString() : '',
image: ship.image,
abs: ship.abs,
home_port: ship.home_port,
imo: ship.imo,
mmsi: ship.mmsi,
model: ship.model,
roles: ship.roles,
status: ship.status,
type: ship.type,
year_built: ship.year_built,
});
}),
);
await addedShip.addMissions(assignedMissions);
}

await db.sequelize.close();
console.log('Database population complete.');
} catch (error) {
console.error('An error occurred while populating the database:', error);
} finally {
await db.sequelize.close();
console.log('Database connection closed.');
}
};

if (require.main === module) {
Expand Down
14 changes: 13 additions & 1 deletion helpers/testHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import * as supertest from 'supertest';
import { db } from '../models';
import fetch from 'node-fetch';

const cleanDb = async () => {
await db.sequelize.query('USE `spacex`');
await db.sequelize.query('SET FOREIGN_KEY_CHECKS = 0', { raw: true });
await db.sequelize.drop();
await db.sequelize.sync();
Expand All @@ -19,4 +21,14 @@ const checkApolloResponse = (response: supertest.Response) => {
}
};

export { cleanDb, checkApolloResponse };
const postQuery = async (query) => {
const response = await fetch('https://spacex-production.up.railway.app/api/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: query }),
});
const { data } = await response.json();
return data;
}

export { cleanDb, checkApolloResponse, postQuery };
20 changes: 20 additions & 0 deletions helpers/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,23 @@ export const isEmail = (s: string) =>
// eslint-disable-next-line no-useless-escape
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
);



export const filterNullFieldsFromShips = (ships) => {
const nullFields = {};
if (ships.length > 0) {
Object.keys(ships[0]).forEach((field) => {
nullFields[field] = true;
});
}
for (const ship of ships) {
for (const field in ship) {
if (ship[field] !== null) {
nullFields[field] = false;
}
}
}
const fieldsNullForAllShips = Object.keys(nullFields).filter((field) => nullFields[field]);
return fieldsNullForAllShips;
};
Loading

0 comments on commit 117b6b7

Please sign in to comment.