Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/problem4/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// The complexity of this function is O(n) because it iterates through all numbers from 0 to n once.
// The efficiency of this function is not optimal for large values of n, as it requires n iterations to compute the sum.
// n is <= Math.MAX_SAFE_INTEGER, so we can safely compute the sum without worrying about overflow in JavaScript.
function sum_to_n_a(n: number): number {
let count = 0
for (let i = 0; i <= n; i++) {
count += i
}
return count
}

// The complexity of this function is O(1) because it uses a constant number of operations to compute the sum, regardless of the value of n.
// The efficiency of this function is optimal for all values of n, as it computes the sum in constant time.
// n is <= Math.MAX_SAFE_INTEGER, so we can safely compute the sum without worrying about overflow in JavaScript.
function sum_to_n_b(n: number): number {
return (n * (n + 1)) / 2
}

// The complexity of this function is O(n) because it iterates through all numbers from 1 to n once using recursion.
// The efficiency of this function is not optimal for large values of n, as it requires n iterations to compute the sum.
// n is <= Math.MAX_SAFE_INTEGER, so we can safely compute the sum without worrying about overflow in JavaScript.
function sum_to_n_c(n: number): number {
return n === 0 ? 0 : n + sum_to_n_c(n - 1)
}
5 changes: 5 additions & 0 deletions src/problem5/express-ts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@



.env
node_modules/
156 changes: 156 additions & 0 deletions src/problem5/express-ts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Express TypeScript Product API

A simple REST API built with Express, TypeScript, and MongoDB (Mongoose) for managing products.

## Features

- Health check endpoint
- Create, read, update, and delete products
- List products with pagination and optional filters
- MongoDB connection via environment variables

## Tech Stack

- Node.js
- Express
- TypeScript
- Mongoose
- dotenv

## Project Structure

```text
src/
index.ts # app entrypoint
configs/
index.ts # config initializer
mongodb.ts # MongoDB connection
controllers/
product.controller.ts # product handlers
models/
products.model.ts # product schema/model
routes/
index.ts # base router
product.route.ts # product routes
```

## Prerequisites

- Node.js 18+
- npm or yarn
- A MongoDB instance (local or cloud)

## Environment Variables

Create a `.env` file in the project root:

```env
MONGO_URI=mongodb://localhost:27017
MONGO_DB=your_database_name
```

## Installation

Using npm:

```bash
npm install
```

Using yarn:

```bash
yarn install
```

## Run the App

Development mode (with auto-reload):

```bash
npm run dev
```

Start mode:

```bash
npm start
```

The server runs on:

```text
http://localhost:3000
```

## API Endpoints

Base path: `/api`

### Health Check

- `GET /healthcheck`

Response:

```json
{ "status": "ok" }
```

### Create Product

- `POST /api/product`

Request body:

```json
{
"name": "Keyboard",
"price": 49.99,
"description": "Mechanical keyboard"
}
```

### Get Product by ID

- `GET /api/product/:id`

### Update Product

- `PUT /api/product/:id`

Request body (any updatable fields):

```json
{
"name": "Keyboard Pro",
"price": 79.99,
"description": "Updated description"
}
```

### Delete Product

- `DELETE /api/product/:id`

### Get All Products

- `GET /api/products`

Optional query params:

- `page` (default: `1`)
- `limit` (default: `10`)
- `name` (case-insensitive partial match)
- `price` (exact number match)

Example:

```http
GET /api/products?page=1&limit=5&name=key&price=49.99
```

## Notes

- If `MONGO_URI` or `MONGO_DB` is missing, the app will throw an error during startup.
- JSON request parsing is enabled globally.
23 changes: 23 additions & 0 deletions src/problem5/express-ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "express-ts",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"dotenv": "^17.4.1",
"express": "^5.2.1",
"mongoose": "^9.4.1"
},
"devDependencies": {
"@types/express": "^5.0.6",
"@types/node": "^25.6.0",
"nodemon": "^3.1.14",
"ts-node": "^10.9.2",
"typescript": "^6.0.2"
},
"scripts": {
"start": "ts-node src/index.ts",
"dev": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/index.ts"
},
"type": "commonjs"
}
11 changes: 11 additions & 0 deletions src/problem5/express-ts/src/configs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { connectToMongoDB } from './mongodb'

export const initConfigs = async () => {
try {
await connectToMongoDB()
console.log('All configurations initialized successfully')
} catch (error) {
console.error('Error initializing configurations:', error)
throw error
}
}
20 changes: 20 additions & 0 deletions src/problem5/express-ts/src/configs/mongodb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { connect } from 'mongoose'

export const connectToMongoDB = async () => {
try {
const mongoUri = process.env['MONGO_URI']
const dbName = process.env['MONGO_DB']
if (!mongoUri || !dbName) {
throw new Error(
'MONGO_URI and MONGO_DB must be defined in environment variables'
)
}
await connect(mongoUri, {
dbName: dbName
})
console.log('Connected to MongoDB')
} catch (error) {
console.error('Error connecting to MongoDB:', error)
throw error
}
}
107 changes: 107 additions & 0 deletions src/problem5/express-ts/src/controllers/product.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { Request, Response } from 'express'
import Product from '../models/products.model'

export const createProduct = async (req: Request, res: Response) => {
try {
const { name, price, description } = req.body as {
name: string
price: number
description?: string
}

if (!name || !price) {
return res.status(400).json({ error: 'Name and price are required' })
}

const product = new Product({ name, price, description })
await product.save()
return res.status(201).json({
status: 'success',
message: 'Product created successfully'
})
} catch (error: any) {
return res.status(400).json({ error: error.message })
}
}

export const getProducts = async (req: Request, res: Response) => {
try {
const {
page = 1,
limit = 10,
name,
price
} = req.query as {
page?: string
limit?: string
name?: string
price?: string
}
const products = await Product.find({
...(name && { name: { $regex: name, $options: 'i' } }),
...(price && { price: Number(price) })
})
.skip((Number(page) - 1) * Number(limit))
.limit(Number(limit))
return res.status(200).json({
status: 'success',
data: products
})
} catch (error: any) {
return res.status(400).json({ error: error.message })
}
}

export const getProductById = async (req: Request, res: Response) => {
try {
const { id } = req.params
const product = await Product.findById(id)
if (!product) {
return res.status(404).json({ error: 'Product not found' })
}
return res.status(200).json({
status: 'success',
data: product
})
} catch (error: any) {
return res.status(400).json({ error: error.message })
}
}

export const updateProduct = async (req: Request, res: Response) => {
try {
const { id } = req.params
const { name, price, description } = req.body
const product = await Product.findByIdAndUpdate(
id,
{ name, price, description },
{ new: true }
)
if (!product) {
return res.status(404).json({ error: 'Product not found' })
}
return res.status(200).json({
status: 'success',
message: 'Product updated successfully',
data: product
})
} catch (error: any) {
return res.status(400).json({ error: error.message })
}
}

export const deleteProduct = async (req: Request, res: Response) => {
try {
const { id } = req.params
const product = await Product.findByIdAndDelete(id)
if (!product) {
return res.status(404).json({ error: 'Product not found' })
}
return res.status(200).json({
status: 'success',
message: 'Product deleted successfully'
})
} catch (error: any) {
return res.status(400).json({ error: error.message })
}
}
29 changes: 29 additions & 0 deletions src/problem5/express-ts/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import express from 'express'
import type { Application, Request, Response } from 'express'
import { initConfigs } from './configs'
import dotenv from 'dotenv'
import routes from './routes'

dotenv.config({
debug: true,
override: true,
encoding: 'utf8'
})

const port = 3000
const app: Application = express()

app.use(express.json({ strict: false }))
app.use(express.urlencoded({ extended: false }))

initConfigs()

app.get('/healthcheck', (_: Request, res: Response) => {
res.status(200).json({ status: 'ok' })
})

app.use(routes)

app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`)
})
10 changes: 10 additions & 0 deletions src/problem5/express-ts/src/models/products.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { model, Schema } from 'mongoose'

const productSchema = new Schema({
name: { type: String, required: true },
price: { type: Number, required: true },
description: { type: String }
})

const Product = model('Product', productSchema)
export default Product
Loading