This documentation will self-destruct in 5 seconds... Just kidding! 🕶️
- Overview
- Getting Started
- Authentication
- Base URL
- API Endpoints
- Data Models
- Error Handling
- Security
- Development Setup
The IMF (Impossible Missions Force) Gadget Management API provides secure endpoints for managing mission gadgets. Features include:
- JWT-based authentication
- Role-based access control
- Automatic gadget codename generation
- Status tracking
- Self-destruct capabilities
- Success probability calculation
- Node.js 14+
- PostgreSQL 12+
- NPM or Yarn
- Clone the repository
- Install dependencies:
npm install
- Set up environment variables (see
.env.example
) - Run migrations:
npx prisma migrate dev
- Start server:
npm run dev
DATABASE_URL="postgresql://user:password@localhost:5432/gadget_db"
JWT_SECRET="your-secret-key"
PORT=3000
NODE_ENV="development"
The API uses JWT (JSON Web Token) authentication with HTTP-only cookies. All requests must include a valid JWT token obtained through the sign-in endpoint.
{
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "strict",
expires: new Date(Date.now() + 1 * 60 * 60 * 1000), // 1 hour
path: "/"
}
Development: http://localhost:3000/api
Production: https://your-api-domain.com/api
You can refer swagger api documentation at
https://upraised-assignment-47gq.onrender.com/api-docs
Create a new IMF agent account.
Endpoint: POST /auth/signup
Request Body:
{
"name": "Ethan Hunt",
"email": "[email protected]",
"password": "password123",
"confirmPassword": "password123",
"role": "ADMIN" // Optional, defaults to "USER"
}
Validation Rules:
name
: Required, 1-20 characters, alphabets onlyemail
: Required, valid email format, max 50 characterspassword
: Required, 8-30 charactersconfirmPassword
: Must match password fieldrole
: Optional ("ADMIN" or "USER")
Success Response (201):
{
"success": true,
"message": "User signed up successfully. Signin to continue"
}
Authenticate and receive a JWT token.
Endpoint: POST /auth/signin
Request Body:
{
"email": "[email protected]",
"password": "password123"
}
Success Response (200):
{
"success": true,
"data": {
"token": "jwt_token_here",
"message": "Login successful"
}
}
Get all gadgets with success probabilities.
Endpoint: GET /gadgets
Query Parameters:
status
: Filter by status (AVAILABLE, DECOMMISSIONED, DEPLOYED, DESTROYED)
Success Response (200):
[
"The Phantom - 87% success probability",
"The Matrix - 92% success probability"
]
Add a new gadget with auto-generated codename.
Endpoint: POST /gadgets
Request Body: Empty (name is auto-generated)
Success Response (201):
{
"message": "Gadget added successfully",
"data": {
"id": "uuid",
"name": "The Phantom",
"status": "AVAILABLE",
"updatedAt": "timestamp"
},
"success": true
}
Modify gadget status.
Endpoint: PATCH /gadgets
Request Body:
{
"id": "gadget_uuid",
"status": "DEPLOYED"
}
Success Response (200):
{
"message": "Gadget updated successfully",
"data": {
"id": "gadget_uuid",
"name": "The Phantom",
"status": "DEPLOYED",
"updatedAt": "timestamp"
},
"success": true
}
Soft delete a gadget.
Endpoint: DELETE /gadgets
Request Body:
{
"id": "gadget_uuid"
}
Success Response (200):
{
"message": "Gadget decommissioned successfully",
"data": {
"id": "gadget_uuid",
"status": "DECOMMISSIONED",
"deletedAt": "timestamp"
},
"success": true
}
Trigger gadget self-destruction.
Endpoint: POST /gadgets/:id/self-destruct
URL Parameters:
id
: Gadget UUID
Success Response (200):
{
"message": "Gadget destroyed successfully",
"data": {
"id": "gadget_uuid",
"status": "DESTROYED",
"destroyedById": "admin_uuid"
},
"success": true,
"confirmationCode": 123456
}
model User {
id String @id @default(uuid())
name String
email String @unique
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
role UserRole @default(USER)
destroyedGadgets Gadget[]
}
model Gadget {
id String @id @default(uuid())
name String @unique
status gadgetStatus @default(AVAILABLE)
updatedAt DateTime @updatedAt
deletedAt DateTime?
destroyedBy User? @relation(fields: [destroyedById], references: [id])
destroyedById String?
}
enum gadgetStatus {
AVAILABLE
DECOMMISSIONED
DEPLOYED
DESTROYED
}
enum UserRole {
ADMIN
USER
}
{
"success": false,
"error": "Invalid credentials"
}
{
"success": false,
"error": "Please login to continue"
}
{
"success": false,
"error": "Access denied: Admin privileges required"
}
{
"success": false,
"error": "Invalid status value. Expected one of: AVAILABLE, DECOMMISSIONED, DEPLOYED, DESTROYED"
}
{
"success": false,
"error": "Email already used"
}
{
"success": false,
"error": "Gadget not found"
}
{
"success": false,
"error": "Self destruction failed!. Gadget is already DESTROYED"
}
200
: Success201
: Created400
: Bad Request401
: Unauthorized403
: Forbidden404
: Not Found409
: Conflict500
: Internal Server Error
- JWT-based authentication
- HTTP-only cookies
- Token expiration: 1 hour
- Bcrypt hashing (10 rounds)
- Password validation rules
- No password storage in plain text
- CORS protection
- Input validation using Joi
- SQL injection protection via Prisma ORM
- Admin privileges required for gadget operations
- Role verification middleware
- Secure route protection
- Clone repository
git clone https://github.com/amoghar29/upraised-assignment.git
cd upraised-assignment
- Install dependencies
npm install
- Set up environment variables
cp .env.example .env
# Edit .env with your values
- Run migrations
npx prisma migrate dev
- Start development server
npm run dev
# Generate Prisma client
npx prisma generate
# Reset database
npx prisma reset
# View database in Prisma Studio
npx prisma studio
- Build application
npm run build
- Set production environment variables
- Run database migrations
- Start production server
npm start