Skip to content

Commit 19be992

Browse files
rinaldo stevenazzirinaldo stevenazzi
authored andcommitted
fix db initialization to make the server run
1 parent 4ecb449 commit 19be992

File tree

9 files changed

+170
-9
lines changed

9 files changed

+170
-9
lines changed

.next/trace

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[{"name":"next-dev","duration":375778,"timestamp":48743038978,"id":1,"tags":{},"startTime":1755273250317,"traceId":"67ad9cb661b8ac33"}]
2+
[{"name":"generate-buildid","duration":97,"timestamp":48766044509,"id":4,"parentId":1,"tags":{},"startTime":1755273273323,"traceId":"6b2fe1b57754ff3a"},{"name":"load-custom-routes","duration":160,"timestamp":48766044646,"id":5,"parentId":1,"tags":{},"startTime":1755273273323,"traceId":"6b2fe1b57754ff3a"},{"name":"next-build","duration":47457,"timestamp":48765998214,"id":1,"tags":{"buildMode":"default","isTurboBuild":"false","version":"15.4.6"},"startTime":1755273273276,"traceId":"6b2fe1b57754ff3a"}]

api/index.ts

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// api/index.ts
2+
import express from "express";
3+
import "dotenv/config";
4+
import Global from "../src/controllers/Global.ts";
5+
import EVENTS from "../src/constants/events.ts";
6+
7+
const app = express();
8+
app.use(express.json());
9+
10+
// --- Initialize DB on cold start and await before handling requests ---
11+
const globalController = new Global();
12+
const ready = (async () => {
13+
try {
14+
await globalController.initDB();
15+
console.log("SERVER - initDB - DONE");
16+
} catch (e) {
17+
console.error("SERVER - initDB - ERROR", e);
18+
throw e;
19+
}
20+
})();
21+
22+
app.use(async (_req, _res, next) => {
23+
try {
24+
await ready; // wait for cold-start DB init once
25+
next();
26+
} catch (e) {
27+
next(e);
28+
}
29+
});
30+
31+
// --- Debug route (remove once stable) ---
32+
app.get("/__debug", async (_req, res) => {
33+
res.json({
34+
hasMongoURI: Boolean(process.env.MONGODB_URI),
35+
vercelEnv: process.env.VERCEL_ENV || null,
36+
nodeVersion: process.version,
37+
});
38+
});
39+
40+
// --- Health/base route ---
41+
app.get("/", async (_req, res) => {
42+
console.log("GET /");
43+
res.send("<h1>Hello world</h1>");
44+
});
45+
46+
// --- Routes ---
47+
app.post(
48+
"/score",
49+
async (
50+
req: express.Request<{}, {}, { score: number }>,
51+
res: express.Response
52+
) => {
53+
try {
54+
const { score } = req.body;
55+
const result = await globalController.checkScore(score);
56+
return result.message === EVENTS.SCORED
57+
? res.status(200).send()
58+
: res.status(409).send();
59+
} catch (e) {
60+
console.error("POST /score error:", e);
61+
return res.status(500).json({ error: "Internal error" });
62+
}
63+
}
64+
);
65+
66+
app.post(
67+
"/adduser",
68+
async (
69+
req: express.Request<
70+
{},
71+
{},
72+
{ userName: string; password: string; score?: number }
73+
>,
74+
res: express.Response
75+
) => {
76+
try {
77+
const { userName, password, score } = req.body;
78+
const result = await globalController.addUser({
79+
userName,
80+
password,
81+
score,
82+
});
83+
if (result.message === EVENTS.USER_ALREADY_EXIST)
84+
return res.status(409).send("User Already Exist.");
85+
if (result.message === EVENTS.USER_CREATED)
86+
return res.status(200).json(result.list);
87+
return res.send();
88+
} catch (e) {
89+
console.error("POST /adduser error:", e);
90+
return res.status(500).json({ error: "Internal error" });
91+
}
92+
}
93+
);
94+
95+
app.post(
96+
"/users/:userName/scores",
97+
async (
98+
req: express.Request<{ userName: string }, {}, { value: number }>,
99+
res: express.Response
100+
) => {
101+
try {
102+
const { userName } = req.params;
103+
const { value } = req.body;
104+
if (typeof value !== "number")
105+
return res.status(400).send("value must be a number");
106+
const result = await globalController.addScoreForUser(userName, value);
107+
return result.message === EVENTS.SCORED && result.created
108+
? res.status(201).json({ userId: result.userId, value })
109+
: res.status(409).send();
110+
} catch (e) {
111+
console.error("POST /users/:userName/scores error:", e);
112+
return res.status(500).json({ error: "Internal error" });
113+
}
114+
}
115+
);
116+
117+
app.get("/users", async (_req, res) => {
118+
try {
119+
const list = await globalController.listUsersPublic();
120+
return res.status(200).json(list);
121+
} catch (e) {
122+
console.error("GET /users error:", e);
123+
return res.status(500).json({ error: "Internal error" });
124+
}
125+
});
126+
127+
app.get(
128+
"/scores/top",
129+
async (
130+
req: express.Request<{}, {}, {}, { limit?: string }>,
131+
res: express.Response
132+
) => {
133+
try {
134+
const raw = req.query.limit;
135+
const parsed = raw ? parseInt(String(raw), 10) : 10;
136+
const limit = Number.isFinite(parsed)
137+
? Math.min(Math.max(parsed, 1), 50)
138+
: 10;
139+
const rows = await globalController.getTopScores(limit);
140+
return res.status(200).json(rows);
141+
} catch (e) {
142+
console.error("GET /scores/top error:", e);
143+
return res.status(500).json({ error: "Internal error" });
144+
}
145+
}
146+
);
147+
148+
// Do NOT call app.listen() on Vercel. Export the app for the Serverless Function.
149+
export default app;

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
"main": "src/api/index.ts",
66
"type": "module",
77
"scripts": {
8-
"dev": "node src/api/index.ts",
9-
"build": "node -p tsconfig.json",
10-
"start": "node src/api/index.ts",
8+
"dev": "node api/index.ts",
9+
"build": "echo \"No build step for Vercel Functions\"",
10+
"start": "node api/index.ts",
1111
"typecheck": "tsc -p tsconfig.json --noEmit",
1212
"test": "echo \"Error: no test specified\" && exit 1",
1313
"seed": "node src/scripts/seeder.ts"

src/api/index.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/controllers/Global.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ export default class Global {
2929
async initDB(): Promise<void> {
3030
try {
3131
const db = await this.mongoDB.connect();
32+
console.log("Global Controller - initDB initialisation successful");
3233
this.db = db;
3334
this.users.init(db);
35+
console.log("Global Controller - initDB users initialised");
3436
this.scores.init(db);
37+
console.log("Global Controller - initDB scores initialised");
3538
} catch (e) {
3639
// eslint-disable-next-line no-console
3740
console.log("Global Controller - initDB initialisation failed !!!");

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ app.get(
120120

121121
// ❗ run the HTTP listener only when NOT on Vercel
122122
// if (!process.env.VERCEL_ENV) {
123-
// console.log(`Listening on port ${PORT}`);
123+
console.log(`VERCEL_ENV : ${process.env.VERCEL_ENV}`);
124+
console.log(`Listening on port ${PORT}`);
124125
server.listen(PORT, () => console.log(`Listening on ${PORT}`));
125126
// }
126127

src/services/MongoDB.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ export default class MongoDB {
1111
constructor() {
1212
// eslint-disable-next-line no-console
1313
console.log("MongoDB Class - Constructor");
14-
this.client = new MongoClient(uri);
14+
this.client = new MongoClient(uri, {
15+
serverSelectionTimeoutMS: 10000, // fail fast if unreachable
16+
connectTimeoutMS: 10000,
17+
maxPoolSize: 5,
18+
retryWrites: true,
19+
});
20+
console.log("MongoDB Class - client initialized", this.client);
1521
}
1622

1723
async connect(): Promise<Db> {

tsconfig.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,5 @@
55
"module": "nodenext",
66
"rewriteRelativeImportExtensions": true,
77
"erasableSyntaxOnly": true
8-
// "verbatimModuleSyntax": true
98
}
109
}

vercel.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
{
2+
"$schema": "https://openapi.vercel.sh/vercel.json",
3+
"framework": null,
4+
"buildCommand": "",
5+
"outputDirectory": null,
26
"rewrites": [{ "source": "/(.*)", "destination": "/api" }]
37
}

0 commit comments

Comments
 (0)