Skip to content

Commit 21758d7

Browse files
Merge pull request #23 from KushagraJaiswar02/ui/collection-redesign
Collection view redesign: replace table with record-based UI
2 parents 0b429e0 + d9490a7 commit 21758d7

12 files changed

Lines changed: 1684 additions & 381 deletions

File tree

‎backend/app.js‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
const dotenv = require('dotenv');
2+
dotenv.config();
3+
14
const express = require('express')
25
const mongoose = require('mongoose')
36
const cors = require('cors')
4-
const dotenv = require('dotenv');
57
const rateLimit = require('express-rate-limit');
68
const app = express();
79
app.set('trust proxy', 1);
810
const GC = require('./utils/GC');
9-
dotenv.config();
1011

1112
// Middleware
1213
app.use(cors());

‎backend/config/redis.js‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,33 @@ const dotenv = require("dotenv");
33
dotenv.config()
44

55
if (!process.env.REDIS_URL) {
6+
if (process.env.NODE_ENV !== 'production') {
7+
console.log("DEBUG: ENV KEYS:", Object.keys(process.env));
8+
}
69
throw new Error("REDIS_URL is not defined in .env");
710
}
811

9-
const redis = new Redis(process.env.REDIS_URL);
12+
const redis = new Redis(process.env.REDIS_URL, {
13+
retryStrategy(times) {
14+
const delay = Math.min(times * 50, 2000);
15+
if (times > 3) {
16+
console.warn("⚠️ Redis: Max retries reached. Caching will be disabled.");
17+
return null; // Stop retrying
18+
}
19+
return delay;
20+
},
21+
maxRetriesPerRequest: null // Allow requests to fail if not connected
22+
});
1023

1124
redis.on('ready', () => {
1225
console.log('ioredis client is connected and ready.');
1326
});
1427

28+
redis.on('error', (err) => {
29+
console.error('❌ Redis Connection Error:', err.message);
30+
console.error(' -> Ensure Redis is running on localhost:6379');
31+
console.error(' -> Windows: Use WSL or a Memurai/Redis port.');
32+
// Do not throw; lets the app continue without caching if needed
33+
});
34+
1535
module.exports = redis;

‎backend/controllers/auth.controller.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ module.exports.sendOtp = async (req, res) => {
115115
try {
116116
const { email } = onlyEmailSchema.parse(req.body);
117117
const otp = Math.floor(100000 + Math.random() * 900000);
118+
// Secure: OTP logging removed
118119
const existingUser = await Developer.findOne({ email });
119120
if (!existingUser) return res.status(400).json({ error: "User not found" });
120121

@@ -150,8 +151,7 @@ module.exports.verifyOtp = async (req, res) => {
150151
const existingOtp = await otpSchema.findOne({ userId: existingUser._id });
151152
if (!existingOtp) return res.status(400).json({ error: "You havn't requested an OTP" });
152153

153-
console.log(existingOtp.otp);
154-
console.log(otp);
154+
// Secure: OTP verification logging removed
155155
if (existingOtp.otp !== otp) return res.status(400).json({ error: "Incorrect OTP" });
156156

157157
await existingOtp.deleteOne();

‎backend/services/redisCaching.js‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const redis = require("../config/redis");
22

33
async function setProjectByApiKeyCache(api, project) {
4+
if (redis.status !== "ready") return;
45
try {
56
const data = JSON.stringify(project);
67
await redis.set(
@@ -15,6 +16,7 @@ async function setProjectByApiKeyCache(api, project) {
1516
}
1617

1718
async function getProjectByApiKeyCache(api) {
19+
if (redis.status !== "ready") return null;
1820
try {
1921
const data = await redis.get(`project:apikey:${api}`);
2022
if (!data) return null;
@@ -28,6 +30,7 @@ async function getProjectByApiKeyCache(api) {
2830
}
2931

3032
async function deleteProjectByApiKeyCache(api) {
33+
if (redis.status !== "ready") return;
3134
try {
3235
await redis.del(`project:apikey:${api}`);
3336
} catch (err) {
@@ -37,6 +40,7 @@ async function deleteProjectByApiKeyCache(api) {
3740

3841

3942
async function setProjectById(id, project) {
43+
if (redis.status !== "ready") return;
4044
try {
4145
const data = JSON.stringify(project);
4246
await redis.set(
@@ -52,6 +56,7 @@ async function setProjectById(id, project) {
5256

5357

5458
async function getProjectById(id) {
59+
if (redis.status !== "ready") return null;
5560
try {
5661
const data = await redis.get(`project:id:${id}`);
5762
if (!data) return null;
@@ -65,6 +70,7 @@ async function getProjectById(id) {
6570

6671

6772
async function deleteProjectById(id) {
73+
if (redis.status !== "ready") return;
6874
try {
6975
await redis.del(`project:id:${id}`);
7076
} catch (err) {

‎frontend/package-lock.json‎

Lines changed: 77 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎frontend/package.json‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
"preview": "vite preview"
1111
},
1212
"dependencies": {
13+
"@dnd-kit/core": "^6.3.1",
14+
"@dnd-kit/modifiers": "^9.0.0",
15+
"@dnd-kit/sortable": "^10.0.0",
16+
"@dnd-kit/utilities": "^3.2.2",
1317
"@tailwindcss/vite": "^4.1.18",
1418
"@tanstack/react-table": "^8.21.3",
1519
"axios": "^1.13.2",

0 commit comments

Comments
 (0)