Skip to content

Commit

Permalink
Merge branch '100xdevs-cohort-2:master' into migration
Browse files Browse the repository at this point in the history
  • Loading branch information
DhruvPatel9924 authored Sep 2, 2024
2 parents 5a45c0c + 65bbb1f commit 5a99029
Show file tree
Hide file tree
Showing 18 changed files with 265 additions and 23 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Build on PR

on:
pull_request:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '20'

- name: Install Dependencies
run: npm install

- name: Generate prisma client
run: npm run db:generate

- name: Run Build
run: npm run build
42 changes: 42 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Build and Deploy to Docker Hub

on:
push:
branches:
- master

jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Check Out Repo
uses: actions/checkout@v2

- name: Log in to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and Push Docker image
uses: docker/build-push-action@v2
with:
context: .
file: ./docker/Dockerfile.user
push: true
tags: 100xdevs/week-18-class:latest # Replace with your Docker Hub username and repository

- name: Verify Pushed Image
run: docker pull 100xdevs/week-18-class:latest # Replace with your Docker Hub username and repository

- name: Deploy to EC2
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
sudo docker pull 100xdevs/week-18-class:latest
sudo docker stop web-app || true
sudo docker rm web-app || true
sudo docker run -d --name web-app -p 3005:3000 100xdevs/week-18-class:latest
1 change: 1 addition & 0 deletions apps/merchant-app/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import NextAuth from "next-auth"
import { authOptions } from "../../../../lib/auth"

//@ts-ignore
const handler = NextAuth(authOptions)

export { handler as GET, handler as POST }
16 changes: 0 additions & 16 deletions apps/merchant-app/app/api/user/route.ts

This file was deleted.

8 changes: 8 additions & 0 deletions apps/user-app/app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default function Layout({
<SidebarItem href={"/dashboard"} icon={<HomeIcon />} title="Home" />
<SidebarItem href={"/transfer"} icon={<TransferIcon />} title="Transfer" />
<SidebarItem href={"/transactions"} icon={<TransactionsIcon />} title="Transactions" />
<SidebarItem href={"/p2p"} icon={<P2PTransferIcon />} title="P2P Transfer" />
</div>
</div>
{children}
Expand All @@ -25,6 +26,13 @@ function HomeIcon() {
<path stroke-linecap="round" stroke-linejoin="round" d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
</svg>
}

function P2PTransferIcon() {
return <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" className="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18 9 11.25l4.306 4.306a11.95 11.95 0 0 1 5.814-5.518l2.74-1.22m0 0-5.94-2.281m5.94 2.28-2.28 5.941" />
</svg>

}
function TransferIcon() {
return <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" className="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21 3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5" />
Expand Down
7 changes: 7 additions & 0 deletions apps/user-app/app/(dashboard)/p2p/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SendCard } from "../../../components/SendCard";

export default function() {
return <div className="w-full">
<SendCard />
</div>
}
1 change: 1 addition & 0 deletions apps/user-app/app/(dashboard)/transfer/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default async function() {
const transactions = await getOnRampTransactions();

return <div className="w-screen">
hi
<div className="text-4xl text-[#6a51a6] pt-8 mb-8 font-bold">
Transfer
</div>
Expand Down
30 changes: 30 additions & 0 deletions apps/user-app/app/lib/actions/createOnRamptxn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use server";

import { getServerSession } from "next-auth";
import { authOptions } from "../auth";
import prisma from "@repo/db/client";

export async function createOnRampTransaction(amount: number, provider: string) {
const session = await getServerSession(authOptions);
const token = Math.random().toString();
const userId = session.user.id;
if (!userId) {
return {
message: "User not logged in"
}
}
await prisma.onRampTransaction.create({
data: {
userId: Number(userId), // 1
amount: amount,
status: "Processing",
startTime: new Date(),
provider,
token: token
}
})

return {
message: "On ramp transaction added"
}
}
55 changes: 55 additions & 0 deletions apps/user-app/app/lib/actions/p2pTransfer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"use server"
import { getServerSession } from "next-auth";
import { authOptions } from "../auth";
import prisma from "@repo/db/client";

export async function p2pTransfer(to: string, amount: number) {
const session = await getServerSession(authOptions);
const from = session?.user?.id;
if (!from) {
return {
message: "Error while sending"
}
}
const toUser = await prisma.user.findFirst({
where: {
number: to
}
});

if (!toUser) {
return {
message: "User not found"
}
}
await prisma.$transaction(async (tx) => {
await tx.$queryRaw`SELECT * FROM "Balance" WHERE "userId" = ${Number(from)} FOR UPDATE`;

const fromBalance = await tx.balance.findUnique({
where: { userId: Number(from) },
});
if (!fromBalance || fromBalance.amount < amount) {
throw new Error('Insufficient funds');
}

await tx.balance.update({
where: { userId: Number(from) },
data: { amount: { decrement: amount } },
});

await tx.balance.update({
where: { userId: toUser.id },
data: { amount: { increment: amount } },
});

await tx.p2pTransfer.create({
data: {
fromUserId: Number(from),
toUserId: toUser.id,
amount,
timestamp: new Date()
}
})
// locking
});
}
12 changes: 9 additions & 3 deletions apps/user-app/components/AddMoneyCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Center } from "@repo/ui/center";
import { Select } from "@repo/ui/select";
import { useState } from "react";
import { TextInput } from "@repo/ui/textinput";
import { createOnRampTransaction } from "../app/lib/actions/createOnRamptxn";

const SUPPORTED_BANKS = [{
name: "HDFC Bank",
Expand All @@ -16,22 +17,27 @@ const SUPPORTED_BANKS = [{

export const AddMoney = () => {
const [redirectUrl, setRedirectUrl] = useState(SUPPORTED_BANKS[0]?.redirectUrl);
const [amount, setAmount] = useState(0);
const [provider, setProvider] = useState(SUPPORTED_BANKS[0]?.name || "");

return <Card title="Add Money">
<div className="w-full">
<TextInput label={"Amount"} placeholder={"Amount"} onChange={() => {

<TextInput label={"Amount"} placeholder={"Amount"} onChange={(value) => {
setAmount(Number(value))
}} />
<div className="py-4 text-left">
Bank
</div>
<Select onSelect={(value) => {
setRedirectUrl(SUPPORTED_BANKS.find(x => x.name === value)?.redirectUrl || "")
setProvider(SUPPORTED_BANKS.find(x => x.name === value)?.name || "")
}} options={SUPPORTED_BANKS.map(x => ({
key: x.name,
value: x.name
}))} />
<div className="flex justify-center pt-4">
<Button onClick={() => {
<Button onClick={async () => {
await createOnRampTransaction(amount * 100, provider)
window.location.href = redirectUrl || "";
}}>
Add Money
Expand Down
32 changes: 32 additions & 0 deletions apps/user-app/components/SendCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"use client"
import { Button } from "@repo/ui/button";
import { Card } from "@repo/ui/card";
import { Center } from "@repo/ui/center";
import { TextInput } from "@repo/ui/textinput";
import { useState } from "react";
import { p2pTransfer } from "../app/lib/actions/p2pTransfer";

export function SendCard() {
const [number, setNumber] = useState("");
const [amount, setAmount] = useState("");

return <div className="h-[90vh]">
<Center>
<Card title="Send">
<div className="min-w-72 pt-2">
<TextInput placeholder={"Number"} label="Number" onChange={(value) => {
setNumber(value)
}} />
<TextInput placeholder={"Amount"} label="Amount" onChange={(value) => {
setAmount(value)
}} />
<div className="pt-4 flex justify-center">
<Button onClick={async () => {
await p2pTransfer(number, Number(amount) * 100)
}}>Send</Button>
</div>
</div>
</Card>
</Center>
</div>
}
18 changes: 18 additions & 0 deletions docker/Dockerfile.user
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM node:20.12.0-alpine3.19

WORKDIR /usr/src/app

COPY package.json package-lock.json turbo.json tsconfig.json ./

COPY apps ./apps
COPY packages ./packages

# Install dependencies
RUN npm install
# Can you add a script to the global package.json that does this?
RUN npm run db:generate

# Can you filter the build down to just one app?
RUN npm run build

CMD ["npm", "run", "start-user-app"]
3 changes: 2 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"build": "turbo build",
"dev": "turbo dev",
"lint": "turbo lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\""
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"db:generate": "cd packages/db && npx prisma generate && cd ../..",
"start-user-app": "cd ./apps/user-app && npm run start"

},
"devDependencies": {
"@repo/eslint-config": "*",
Expand Down
3 changes: 2 additions & 1 deletion packages/db/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"name": "@repo/db",
"version": "0.0.0",
"dependencies": {
"@prisma/client": "^5.11.0"
"@prisma/client": "^5.11.0",
"bcrypt": "^5.1.1"
},
"devDependencies": {
"prisma": "5.11.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- CreateTable
CREATE TABLE "p2pTransfer" (
"id" SERIAL NOT NULL,
"amount" INTEGER NOT NULL,
"timestamp" TIMESTAMP(3) NOT NULL,
"fromUserId" INTEGER NOT NULL,
"toUserId" INTEGER NOT NULL,

CONSTRAINT "p2pTransfer_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "p2pTransfer" ADD CONSTRAINT "p2pTransfer_fromUserId_fkey" FOREIGN KEY ("fromUserId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "p2pTransfer" ADD CONSTRAINT "p2pTransfer_toUserId_fkey" FOREIGN KEY ("toUserId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
12 changes: 12 additions & 0 deletions packages/db/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ model User {
password String
OnRampTransaction OnRampTransaction[]
Balance Balance[]
sentTransfers p2pTransfer[] @relation(name: "FromUserRelation")
receivedTransfers p2pTransfer[] @relation(name: "ToUserRelation")
}

model Merchant {
Expand All @@ -24,6 +26,16 @@ model Merchant {
auth_type AuthType
}

model p2pTransfer {
id Int @id @default(autoincrement())
amount Int
timestamp DateTime
fromUserId Int
fromUser User @relation(name: "FromUserRelation", fields: [fromUserId], references: [id])
toUserId Int
toUser User @relation(name: "ToUserRelation", fields: [toUserId], references: [id])
}

model OnRampTransaction {
id Int @id @default(autoincrement())
status OnRampStatus
Expand Down
Loading

0 comments on commit 5a99029

Please sign in to comment.