Skip to content

Commit

Permalink
feat(backend): ✨ implement API to fetch user urls and store email and…
Browse files Browse the repository at this point in the history
… ttl
  • Loading branch information
DeepaPrasanna committed May 17, 2024
1 parent 82f578f commit 2a963de
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/controllers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export {
shortenUrl,
getLongUrl,
healthCheck,
getUserHistory,
} from "./url.controller";
19 changes: 17 additions & 2 deletions src/controllers/url.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Request, Response } from "express";
import { matchedData, validationResult } from "express-validator";

import {
getUserUrls,
findUrlByCode,
deleteUrlById,
createShortUrl,
Expand All @@ -14,7 +15,9 @@ export async function shortenUrl(req: Request, res: Response) {
if (!result.isEmpty()) {
return res.status(400).send({ errors: result.array() });
}
const { url } = matchedData(req);
const { url, email, ttl } = matchedData(req);

console.log({ url, email, ttl });

if (url.includes("teenyurl.in")) {
return res.status(422).send({ message: "Failed! Domain name not allowed" });
Expand All @@ -30,7 +33,7 @@ export async function shortenUrl(req: Request, res: Response) {
});
}

const code = await createShortUrl(url);
const code = await createShortUrl(url, email, ttl);

return res.send({
message: "success",
Expand Down Expand Up @@ -78,3 +81,15 @@ export async function deleteUrl(req: Request, res: Response) {
export function healthCheck(req: Request, res: Response) {
return res.status(200).send("ok");
}

export async function getUserHistory(req: Request, res: Response) {
const result = validationResult(req);

if (!result.isEmpty()) {
return res.status(400).send({ errors: result.array() });
}
const { email } = matchedData(req);

const data = await getUserUrls(email);
return res.json(data);
}
6 changes: 6 additions & 0 deletions src/models/url.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@ import { Schema, model } from "mongoose";
interface IUrl {
longUrl: string;
code: string;
email?: string;
createdOn: Date;
expiresOn?: Date;
}

const urlSchema = new Schema<IUrl>({
longUrl: { type: String, required: true },
code: { type: String, required: true },
createdOn: { type: Date, required: true },
email: { type: String, required: false },
expiresOn: { type: Date, required: false },
});

export const Url = model<IUrl>("Url", urlSchema);
18 changes: 16 additions & 2 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
import { body, param } from "express-validator";
import { body, param, query } from "express-validator";
import express, { Router } from "express";

import { deleteUrl, getLongUrl, shortenUrl, healthCheck } from "../controllers";
import {
deleteUrl,
getLongUrl,
shortenUrl,
healthCheck,
getUserHistory,
} from "../controllers";

const router: Router = express.Router();

router.post(
"/api/",
body("url").notEmpty().isURL().withMessage("Not a valid url"),
body("ttl").optional().isString().withMessage("Enter a proper date"),
body("email").optional().isEmail().withMessage("Enter a valid email"),
shortenUrl
);

router.get("/", healthCheck);

router.get(
"/history",
query("email").notEmpty().isEmail().withMessage("Email is mandatory"),
getUserHistory
);

router.get("/:code", param("code").notEmpty().isAlphanumeric(), getLongUrl);

router.delete("/:code", param("code").notEmpty().isAlphanumeric(), deleteUrl);
Expand Down
1 change: 1 addition & 0 deletions src/services/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export {
getUserUrls,
findUrlByCode,
deleteUrlById,
createShortUrl,
Expand Down
18 changes: 16 additions & 2 deletions src/services/url.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@ export async function findUrlByLongUrl(longUrl: string) {
return await Url.findOne({ longUrl }).lean();
}

export async function createShortUrl(longUrl: string) {
export async function createShortUrl(
longUrl: string,
email?: string,
ttl?: string
) {
const code = await generateCode();

const url = new Url({ longUrl, code });
const url = new Url({
longUrl,
code,
email,
createdOn: new Date(),
expiresOn: ttl,
});
await url.save();

return code;
Expand All @@ -36,3 +46,7 @@ export async function findUrlByCode(code: string) {
export async function deleteUrlById(id: Types.ObjectId) {
return await Url.deleteOne(id);
}

export async function getUserUrls(email: string) {
return await Url.find({ email }).lean();
}

0 comments on commit 2a963de

Please sign in to comment.