Skip to content

Commit d20d7c8

Browse files
authored
feat: add planet biomes and environmental effects (#40)
* lib(json): added json files for biomes and environmental effects * feat: add new models to schema * chore(mig): create migration file * refractor: modify existing json file * refractor: populate environmental effects and biomes * feat: add routes for biomes * feat: add routes for environmental effects * refractor: add new routes to main file
1 parent ae29634 commit d20d7c8

File tree

11 files changed

+1838
-293
lines changed

11 files changed

+1838
-293
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
Warnings:
3+
4+
- Added the required column `biomeId` to the `Planet` table without a default value. This is not possible if the table is not empty.
5+
6+
*/
7+
-- CreateTable
8+
CREATE TABLE "Biome" (
9+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
10+
"index" TEXT NOT NULL,
11+
"name" TEXT NOT NULL,
12+
"description" TEXT NOT NULL,
13+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
14+
"updatedAt" DATETIME NOT NULL
15+
);
16+
17+
-- CreateTable
18+
CREATE TABLE "Effect" (
19+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
20+
"index" TEXT NOT NULL,
21+
"name" TEXT NOT NULL,
22+
"description" TEXT NOT NULL,
23+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
24+
"updatedAt" DATETIME NOT NULL
25+
);
26+
27+
-- CreateTable
28+
CREATE TABLE "_Effect" (
29+
"A" INTEGER NOT NULL,
30+
"B" INTEGER NOT NULL,
31+
CONSTRAINT "_Effect_A_fkey" FOREIGN KEY ("A") REFERENCES "Effect" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
32+
CONSTRAINT "_Effect_B_fkey" FOREIGN KEY ("B") REFERENCES "Planet" ("id") ON DELETE CASCADE ON UPDATE CASCADE
33+
);
34+
35+
-- RedefineTables
36+
PRAGMA foreign_keys=OFF;
37+
CREATE TABLE "new_Planet" (
38+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
39+
"index" BIGINT NOT NULL,
40+
"name" TEXT NOT NULL,
41+
"ownerId" INTEGER NOT NULL,
42+
"sectorId" INTEGER NOT NULL,
43+
"health" INTEGER NOT NULL,
44+
"maxHealth" INTEGER NOT NULL,
45+
"players" INTEGER NOT NULL,
46+
"disabled" BOOLEAN NOT NULL,
47+
"regeneration" INTEGER NOT NULL,
48+
"liberation" REAL NOT NULL,
49+
"liberationRate" REAL NOT NULL,
50+
"liberationState" TEXT NOT NULL,
51+
"initialOwnerId" INTEGER NOT NULL,
52+
"positionX" REAL NOT NULL,
53+
"positionY" REAL NOT NULL,
54+
"globalEventId" INTEGER,
55+
"biomeId" INTEGER NOT NULL,
56+
"statisticId" INTEGER,
57+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
58+
"updatedAt" DATETIME NOT NULL,
59+
CONSTRAINT "Planet_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "Faction" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
60+
CONSTRAINT "Planet_sectorId_fkey" FOREIGN KEY ("sectorId") REFERENCES "Sector" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
61+
CONSTRAINT "Planet_initialOwnerId_fkey" FOREIGN KEY ("initialOwnerId") REFERENCES "Faction" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
62+
CONSTRAINT "Planet_globalEventId_fkey" FOREIGN KEY ("globalEventId") REFERENCES "GlobalEvent" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
63+
CONSTRAINT "Planet_biomeId_fkey" FOREIGN KEY ("biomeId") REFERENCES "Biome" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
64+
CONSTRAINT "Planet_statisticId_fkey" FOREIGN KEY ("statisticId") REFERENCES "Stats" ("id") ON DELETE SET NULL ON UPDATE CASCADE
65+
);
66+
INSERT INTO "new_Planet" ("createdAt", "disabled", "globalEventId", "health", "id", "index", "initialOwnerId", "liberation", "liberationRate", "liberationState", "maxHealth", "name", "ownerId", "players", "positionX", "positionY", "regeneration", "sectorId", "statisticId", "updatedAt") SELECT "createdAt", "disabled", "globalEventId", "health", "id", "index", "initialOwnerId", "liberation", "liberationRate", "liberationState", "maxHealth", "name", "ownerId", "players", "positionX", "positionY", "regeneration", "sectorId", "statisticId", "updatedAt" FROM "Planet";
67+
DROP TABLE "Planet";
68+
ALTER TABLE "new_Planet" RENAME TO "Planet";
69+
CREATE UNIQUE INDEX "Planet_index_key" ON "Planet"("index");
70+
CREATE UNIQUE INDEX "Planet_statisticId_key" ON "Planet"("statisticId");
71+
PRAGMA foreign_key_check;
72+
PRAGMA foreign_keys=ON;
73+
74+
-- CreateIndex
75+
CREATE UNIQUE INDEX "Biome_index_key" ON "Biome"("index");
76+
77+
-- CreateIndex
78+
CREATE UNIQUE INDEX "Effect_index_key" ON "Effect"("index");
79+
80+
-- CreateIndex
81+
CREATE UNIQUE INDEX "_Effect_AB_unique" ON "_Effect"("A", "B");
82+
83+
-- CreateIndex
84+
CREATE INDEX "_Effect_B_index" ON "_Effect"("B");

prisma/schema.prisma

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ model Planet {
7070
homeWorld HomeWorld[] @relation("HomeWorld")
7171
attacking Attack[] @relation("Attack")
7272
defending Attack[] @relation("Defend")
73+
effects Effect[] @relation("Effect")
74+
biome Biome @relation(fields: [biomeId], references: [id])
75+
biomeId Int
7376
statistic Stats? @relation(fields: [statisticId], references: [id])
7477
statisticId Int? @unique
7578
createdAt DateTime @default(now())
@@ -218,3 +221,23 @@ model Assignment {
218221
createdAt DateTime @default(now())
219222
updatedAt DateTime @updatedAt
220223
}
224+
225+
model Biome {
226+
id Int @id @default(autoincrement())
227+
index String @unique
228+
name String
229+
description String
230+
planets Planet[]
231+
createdAt DateTime @default(now())
232+
updatedAt DateTime @updatedAt
233+
}
234+
235+
model Effect {
236+
id Int @id @default(autoincrement())
237+
index String @unique
238+
name String
239+
description String
240+
planets Planet[] @relation("Effect")
241+
createdAt DateTime @default(now())
242+
updatedAt DateTime @updatedAt
243+
}

src/controllers/biomes.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import type { Context } from "hono";
2+
3+
import { db } from "utils/database";
4+
import parseIntParam from "utils/params";
5+
import witCache from "utils/request-cache";
6+
import parseQueryParams from "utils/query";
7+
8+
export const getBiomeById = await witCache(async (ctx: Context) => {
9+
try {
10+
const id = parseIntParam(ctx, "id");
11+
const query = await parseQueryParams(ctx);
12+
13+
delete query.orderBy;
14+
delete query.where;
15+
delete query.orderBy;
16+
delete (query as any).skip;
17+
delete (query as any).take;
18+
19+
const biome = await db.biome.findUnique({
20+
...(query as any),
21+
where: { id },
22+
});
23+
24+
if (!biome) {
25+
ctx.status(404);
26+
return ctx.json({
27+
data: null,
28+
error: { details: [`Biome with id (${id}) not found`] },
29+
});
30+
}
31+
32+
return ctx.json({ data: biome, error: null });
33+
} catch (error: any) {
34+
console.error(error);
35+
ctx.status(500);
36+
return ctx.json({
37+
data: null,
38+
error: { details: [error.message] },
39+
});
40+
}
41+
});
42+
43+
export const getAllBiomes = await witCache(async (ctx: Context) => {
44+
try {
45+
const query = await parseQueryParams(ctx);
46+
47+
const [count, biomes] = await Promise.all([
48+
db.biome.count({ where: query.where }),
49+
db.biome.findMany(query),
50+
]);
51+
52+
return ctx.json({
53+
data: biomes,
54+
error: null,
55+
pagination: {
56+
page: query.skip / query.take + 1,
57+
pageSize: query.take,
58+
pageCount: Math.ceil((count as number) / query.take),
59+
total: count,
60+
},
61+
});
62+
} catch (error: any) {
63+
console.error(error);
64+
ctx.status(500);
65+
return ctx.json({
66+
data: null,
67+
error: { details: [error.message] },
68+
});
69+
}
70+
});
71+
72+
export const getPlanetsByBiome = await witCache(async (ctx: Context) => {
73+
try {
74+
const id = parseIntParam(ctx, "id");
75+
const query = await parseQueryParams(ctx);
76+
77+
delete query.where;
78+
const planets = await db.planet.findMany({
79+
...query,
80+
where: { biome: { id } },
81+
});
82+
83+
return ctx.json({ data: planets, error: null });
84+
} catch (error: any) {
85+
console.error(error);
86+
ctx.status(500);
87+
return ctx.json({
88+
data: null,
89+
error: { details: [error.message] },
90+
});
91+
}
92+
});

src/controllers/effects.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import type { Context } from "hono";
2+
3+
import { db } from "utils/database";
4+
import parseIntParam from "utils/params";
5+
import witCache from "utils/request-cache";
6+
import parseQueryParams from "utils/query";
7+
8+
export const getEffectById = await witCache(async (ctx: Context) => {
9+
try {
10+
const id = parseIntParam(ctx, "id");
11+
const query = await parseQueryParams(ctx);
12+
13+
delete query.orderBy;
14+
delete query.where;
15+
delete query.orderBy;
16+
delete (query as any).skip;
17+
delete (query as any).take;
18+
19+
const effect = await db.effect.findUnique({
20+
...(query as any),
21+
where: { id },
22+
});
23+
24+
if (!effect) {
25+
ctx.status(404);
26+
return ctx.json({
27+
data: null,
28+
error: { details: [`Effect with id (${id}) not found`] },
29+
});
30+
}
31+
32+
return ctx.json({ data: effect, error: null });
33+
} catch (error: any) {
34+
console.error(error);
35+
ctx.status(500);
36+
return ctx.json({
37+
data: null,
38+
error: { details: [error.message] },
39+
});
40+
}
41+
});
42+
43+
export const getAllEffects = await witCache(async (ctx: Context) => {
44+
try {
45+
const query = await parseQueryParams(ctx);
46+
47+
const [count, effects] = await Promise.all([
48+
db.effect.count({ where: query.where }),
49+
db.effect.findMany(query),
50+
]);
51+
52+
return ctx.json({
53+
data: effects,
54+
error: null,
55+
pagination: {
56+
page: query.skip / query.take + 1,
57+
pageSize: query.take,
58+
pageCount: Math.ceil((count as number) / query.take),
59+
total: count,
60+
},
61+
});
62+
} catch (error: any) {
63+
console.error(error);
64+
ctx.status(500);
65+
return ctx.json({
66+
data: null,
67+
error: { details: [error.message] },
68+
});
69+
}
70+
});
71+
72+
export const getPlanetsByEffect = await witCache(async (ctx: Context) => {
73+
try {
74+
const id = parseIntParam(ctx, "id");
75+
const query = await parseQueryParams(ctx);
76+
77+
delete query.where;
78+
const planets = await db.planet.findMany({
79+
...query,
80+
where: { effects: { some: { id } } },
81+
});
82+
83+
return ctx.json({ data: planets, error: null });
84+
} catch (error: any) {
85+
console.error(error);
86+
ctx.status(500);
87+
return ctx.json({
88+
data: null,
89+
error: { details: [error.message] },
90+
});
91+
}
92+
});

src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import cache from "middleware/request-cache";
99
import rateLimit from "middleware/rate-limit";
1010

1111
import wars from "routes/war";
12+
import biomes from "routes/biomes";
1213
import orders from "routes/orders";
1314
import events from "routes/events";
15+
import effects from "routes/effects";
1416
import planets from "routes/planets";
1517
import sectors from "routes/sectors";
1618
import reports from "routes/reports";
@@ -32,10 +34,12 @@ app.use(cache);
3234
// routes for the api
3335
const routes = [
3436
wars,
37+
biomes,
3538
events,
3639
orders,
3740
reports,
3841
planets,
42+
effects,
3943
sectors,
4044
attacks,
4145
factions,

src/routes/biomes.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { Hono } from "hono";
2+
3+
import * as Biomes from "controllers/biomes";
4+
5+
export default async function biomes(app: Hono) {
6+
app.get("/biomes", Biomes.getAllBiomes);
7+
app.get("/biomes/:id", Biomes.getBiomeById);
8+
app.get("/biomes/:id/planets", Biomes.getPlanetsByBiome);
9+
}

src/routes/effects.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { Hono } from "hono";
2+
3+
import * as Effects from "controllers/effects";
4+
5+
export default async function effects(app: Hono) {
6+
app.get("/effects", Effects.getAllEffects);
7+
app.get("/effects/:id", Effects.getEffectById);
8+
app.get("/effects/:id/planets", Effects.getPlanetsByEffect);
9+
}

0 commit comments

Comments
 (0)