-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #102 from Carifio24/solar-eclipse
Add endpoints for Solar Eclipse 2024 story
- Loading branch information
Showing
8 changed files
with
152 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { cosmicdsDB } from "../../database"; | ||
import { logger } from "../../logger"; | ||
import { | ||
isArrayThatSatisfies, | ||
isNumberArray, | ||
} from "../../utils"; | ||
|
||
import { initializeModels, SolarEclipse2024Response } from "./models"; | ||
|
||
initializeModels(cosmicdsDB); | ||
|
||
export interface SolarEclipse2024Data { | ||
user_uuid: string; | ||
user_selected_locations: [number, number][], | ||
timestamp: Date | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export function isValidSolarEclipseData(data: any): data is SolarEclipse2024Response { | ||
return typeof data.user_uuid === "string" && | ||
isArrayThatSatisfies(data.user_selected_locations, (arr) => { | ||
return arr.every(x => isNumberArray(x) && x.length === 2); | ||
}); | ||
} | ||
|
||
export async function submitSolarEclipse2024Response(data: SolarEclipse2024Response): Promise<SolarEclipse2024Response | null> { | ||
|
||
logger.verbose(`Attempting to submit solar eclipse 2024 measurement for user ${data.user_uuid}`); | ||
|
||
const dataWithCounts = { | ||
...data, | ||
user_selected_locations_count: data.user_selected_locations.length | ||
}; | ||
|
||
return SolarEclipse2024Response.upsert(dataWithCounts).then(([item, _]) => item); | ||
} | ||
|
||
export async function getAllSolarEclipse2024Responses(): Promise<SolarEclipse2024Response[]> { | ||
return SolarEclipse2024Response.findAll(); | ||
} | ||
|
||
export async function getSolarEclipse2024Response(userUUID: string): Promise<SolarEclipse2024Response | null> { | ||
return SolarEclipse2024Response.findOne({ | ||
where: { user_uuid: userUUID } | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import router from "./router"; | ||
|
||
module.exports = { | ||
path: "/solar-eclipse-2024", | ||
router | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { Sequelize, DataTypes, Model, InferAttributes, InferCreationAttributes, CreationOptional } from "sequelize"; | ||
|
||
export class SolarEclipse2024Response extends Model<InferAttributes<SolarEclipse2024Response>, InferCreationAttributes<SolarEclipse2024Response>> { | ||
declare id: CreationOptional<number>; | ||
declare user_uuid: string; | ||
declare user_selected_locations: [number, number][]; | ||
declare user_selected_locations_count: number; | ||
declare timestamp: CreationOptional<Date>; | ||
} | ||
|
||
export function initializeSolarEclipse2024ResponseModel(sequelize: Sequelize) { | ||
SolarEclipse2024Response.init({ | ||
id: { | ||
type: DataTypes.INTEGER.UNSIGNED, | ||
allowNull: false, | ||
primaryKey: true, | ||
autoIncrement: true | ||
}, | ||
user_uuid: { | ||
type: DataTypes.STRING, | ||
unique: true, | ||
allowNull: false | ||
}, | ||
user_selected_locations: { | ||
type: DataTypes.JSON, | ||
allowNull: false | ||
}, | ||
user_selected_locations_count: { | ||
type: DataTypes.INTEGER, | ||
allowNull: false | ||
}, | ||
timestamp: { | ||
type: DataTypes.DATE, | ||
allowNull: false, | ||
defaultValue: Sequelize.literal("CURRENT_TIMESTAMP") | ||
} | ||
}, { | ||
sequelize, | ||
engine: "InnoDB" | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { Sequelize } from "sequelize"; | ||
import { SolarEclipse2024Response, initializeSolarEclipse2024ResponseModel } from "./eclipse_response"; | ||
|
||
export { | ||
SolarEclipse2024Response | ||
}; | ||
|
||
export function initializeModels(db: Sequelize) { | ||
initializeSolarEclipse2024ResponseModel(db); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { Router } from "express"; | ||
import { getAllSolarEclipse2024Responses, getSolarEclipse2024Response, isValidSolarEclipseData, submitSolarEclipse2024Response } from "./database"; | ||
|
||
const router = Router(); | ||
|
||
router.put("/response", async (req, res) => { | ||
const data = req.body; | ||
const valid = isValidSolarEclipseData(data); | ||
|
||
if (!valid) { | ||
res.status(400); | ||
res.json({ error: "Malformed response submission" }); | ||
return; | ||
} | ||
|
||
const response = await submitSolarEclipse2024Response(data); | ||
if (response === null) { | ||
res.status(400); | ||
res.json({ error: "Error creating solar eclipse 2024 response" }); | ||
return; | ||
} | ||
|
||
res.json({ response }); | ||
}); | ||
|
||
router.get("/responses", async (_req, res) => { | ||
const responses = await getAllSolarEclipse2024Responses(); | ||
res.json({ responses }); | ||
}); | ||
|
||
router.get("/response/:userUUID", async (req, res) => { | ||
const uuid = req.params.userUUID as string; | ||
const response = await getSolarEclipse2024Response(uuid); | ||
res.json({ response }); | ||
}); | ||
|
||
export default router; |
10 changes: 10 additions & 0 deletions
10
src/stories/solar-eclipse-2024/sql/create_eclipse_response_table.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
CREATE TABLE SolarEclipse2024Responses ( | ||
id int(11) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, | ||
user_uuid varchar(36) NOT NULL UNIQUE, | ||
user_selected_locations JSON NOT NULL, | ||
user_selected_locations_count INT NOT NULL, | ||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
|
||
PRIMARY KEY(id), | ||
INDEX(user_uuid) | ||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci PACK_KEYS=0; |