Initial project upload

This commit is contained in:
Mohamed Mathar Irfan
2026-07-28 17:57:02 +05:30
commit ed6610d5d8
23919 changed files with 3003316 additions and 0 deletions

79
README.md Normal file
View File

@@ -0,0 +1,79 @@
# VerifyPack
Full-stack QR code generation & product verification SaaS.
- **Frontend:** Next.js 14 (App Router) + Tailwind CSS + shadcn-style UI
- **Backend:** FastAPI (Python) + MongoDB (Beanie/Motor async ODM)
- **Auth:** JWT (email + Google OAuth), NextAuth on the frontend
- **Payments:** Razorpay (18% GST) — env-driven
- **Storage/Email:** AWS S3 / SES — env-driven, with mock fallbacks for local dev
> Database note: project originally specced PostgreSQL + Prisma; switched to **MongoDB on EC2**
> for faster single-read consumer verification and to avoid a second datastore on the box.
## Repo layout
```
verify pack/
├── backend/ FastAPI + MongoDB
│ ├── app/
│ │ ├── main.py
│ │ ├── core/ config, security, deps
│ │ ├── db/ mongo connection, seed
│ │ ├── models/ Beanie documents
│ │ ├── schemas/ Pydantic request/response
│ │ ├── services/ email, storage, qr (mockable)
│ │ └── routers/ auth, brands, products, batches, qr, verify, ...
│ ├── requirements.txt
│ └── .env.example
└── frontend/ Next.js 14
├── app/ App Router pages
├── components/ UI + dashboard widgets
├── lib/ api client, utils
└── .env.local.example
```
## Quick start (local dev)
### Backend
```bash
cd backend
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # MONGODB_URL defaults to local mongo
# Fastest way to try it with zero external services (in-memory Mongo, console email):
export MOCK_DB=1 MOCK_EMAIL=1 MOCK_STORAGE=1
# Smoke test (optional): app imports + Beanie init
python -c "import asyncio; from app.main import app; from app.db.mongo import init_db; \
print('routes', len(app.routes)); asyncio.run(init_db()); print('beanie OK')"
python -m app.db.seed # creates demo org, brand, product, batch, QR
uvicorn app.main:app --reload --port 8000
```
API docs at http://localhost:8000/docs · health at /health
> Note: with `MOCK_DB=1` the in-memory store resets each run, so run `seed` and
> `uvicorn` in the **same** process is not possible — for a persistent demo, point
> `MONGODB_URL` at a real Mongo (e.g. your EC2 instance) and seed once.
Demo logins after seeding (against a real Mongo):
- Client admin: `owner@abcpharma.example` / `Owner@123`
- Super admin: `admin@verifypack.example` / `Admin@123`
### Frontend
```bash
cd frontend
npm install
cp .env.local.example .env.local
npm run dev
```
App at http://localhost:3000 — dashboard at `/dashboard`, public verify at `/v/<qr_code>`.
## Service config
Razorpay / Google OAuth / AWS credentials are **env-only** (see `.env.example`).
The Product Admin settings page shows configured/not-configured status only.
With mock flags on, the app runs fully offline:
`MOCK_DB=1 MOCK_EMAIL=1 MOCK_STORAGE=1`.

BIN
__MACOSX/._README.md Normal file

Binary file not shown.

BIN
__MACOSX/._backend Normal file

Binary file not shown.

BIN
__MACOSX/._deploy Normal file

Binary file not shown.

Binary file not shown.

BIN
__MACOSX/backend/._.env Normal file

Binary file not shown.

Binary file not shown.

BIN
__MACOSX/backend/._app Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
__MACOSX/backend/app/._core Normal file

Binary file not shown.

BIN
__MACOSX/backend/app/._db Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
__MACOSX/deploy/._deploy.sh Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
backend/.DS_Store vendored Normal file

Binary file not shown.

36
backend/.env Normal file
View File

@@ -0,0 +1,36 @@
# ===== Core =====
APP_NAME=VerifyPack
ENVIRONMENT=development
SECRET_KEY=change-me-in-production-please-32chars-min
ACCESS_TOKEN_EXPIRE_MINUTES=1440
FRONTEND_URL=http://localhost:3000
# ===== Database (MongoDB on EC2) =====
MONGODB_URL=mongodb://localhost:27017
MONGODB_DB=verifypack
# Set MOCK_DB=1 to run with an in-memory mongo (no server needed)
MOCK_DB=0
# ===== Mock toggles for local dev =====
MOCK_EMAIL=1
MOCK_STORAGE=1
# ===== AWS SES (transactional email) =====
AWS_REGION=ap-south-1
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
SES_FROM_EMAIL=no-reply@verifypack.example
# ===== AWS S3 (uploads) =====
S3_BUCKET=verifypack-uploads
# ===== Google OAuth =====
GOOGLE_CLIENT_ID=58114944919-s9p80m11bqo0mhuvcg2huf0arqg0gl14.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=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
GOOGLE_REDIRECT_URI=http://localhost:8000/auth/google/callback
# ===== Razorpay =====
RAZORPAY_KEY_ID=
RAZORPAY_KEY_SECRET=
RAZORPAY_WEBHOOK_SECRET=
GST_RATE=0.18

36
backend/.env.example Normal file
View File

@@ -0,0 +1,36 @@
# ===== Core =====
APP_NAME=VerifyPack
ENVIRONMENT=development
SECRET_KEY=change-me-in-production-please-32chars-min
ACCESS_TOKEN_EXPIRE_MINUTES=1440
FRONTEND_URL=http://localhost:3000
# ===== Database (MongoDB on EC2) =====
MONGODB_URL=mongodb://localhost:27017
MONGODB_DB=verifypack
# Set MOCK_DB=1 to run with an in-memory mongo (no server needed)
MOCK_DB=0
# ===== Mock toggles for local dev =====
MOCK_EMAIL=1
MOCK_STORAGE=1
# ===== AWS SES (transactional email) =====
AWS_REGION=ap-south-1
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
SES_FROM_EMAIL=no-reply@verifypack.example
# ===== AWS S3 (uploads) =====
S3_BUCKET=verifypack-uploads
# ===== Google OAuth =====
GOOGLE_CLIENT_ID=58114944919-s9p80m11bqo0mhuvcg2huf0arqg0gl14.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=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
GOOGLE_REDIRECT_URI=http://localhost:8000/auth/google/callback
# ===== Razorpay =====
RAZORPAY_KEY_ID=
RAZORPAY_KEY_SECRET=
RAZORPAY_WEBHOOK_SECRET=
GST_RATE=0.18

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="370" height="370" class="segno"><g transform="scale(10)"><path fill="#fff" d="M0 0h37v37h-37z"/><path class="qrline" stroke="#0b1f4d" d="M4 4.5h7m2 0h1m4 0h1m1 0h1m2 0h1m2 0h7m-29 1h1m5 0h1m4 0h2m2 0h1m2 0h1m1 0h1m1 0h1m5 0h1m-29 1h1m1 0h3m1 0h1m2 0h3m3 0h6m1 0h1m1 0h3m1 0h1m-29 1h1m1 0h3m1 0h1m5 0h2m8 0h1m1 0h3m1 0h1m-29 1h1m1 0h3m1 0h1m3 0h3m1 0h5m1 0h1m1 0h1m1 0h3m1 0h1m-29 1h1m5 0h1m1 0h1m2 0h1m3 0h6m1 0h1m5 0h1m-29 1h7m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h7m-20 1h1m3 0h1m2 0h3m-19 1h1m2 0h1m1 0h2m1 0h1m1 0h3m1 0h1m5 0h2m1 0h1m-20 1h2m1 0h2m4 0h1m3 0h2m2 0h2m2 0h1m2 0h1m-27 1h1m2 0h3m1 0h3m1 0h2m1 0h2m1 0h2m1 0h1m1 0h4m-26 1h2m1 0h1m2 0h1m4 0h1m5 0h3m1 0h5m-27 1h2m3 0h1m4 0h1m2 0h1m2 0h1m3 0h2m2 0h1m1 0h2m-29 1h4m1 0h1m2 0h1m1 0h1m2 0h2m1 0h4m1 0h1m4 0h1m-27 1h2m4 0h1m1 0h1m1 0h1m1 0h3m1 0h3m2 0h1m2 0h1m1 0h3m-28 1h1m3 0h1m1 0h6m3 0h2m1 0h1m2 0h2m1 0h1m1 0h1m-28 1h1m2 0h4m1 0h3m2 0h1m2 0h2m1 0h1m1 0h1m3 0h1m1 0h1m-26 1h4m4 0h5m1 0h1m1 0h1m1 0h1m1 0h2m4 0h1m-29 1h1m3 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m3 0h1m3 0h2m1 0h1m1 0h2m-27 1h3m2 0h1m3 0h1m2 0h1m1 0h4m3 0h1m3 0h2m-29 1h1m2 0h1m1 0h4m1 0h1m1 0h1m7 0h5m1 0h1m-19 1h5m1 0h1m3 0h1m1 0h1m3 0h1m1 0h3m-29 1h7m4 0h2m5 0h1m1 0h1m1 0h1m1 0h1m2 0h1m-28 1h1m5 0h1m1 0h3m1 0h1m1 0h1m4 0h2m3 0h1m1 0h2m-28 1h1m1 0h3m1 0h1m9 0h2m2 0h5m2 0h2m-29 1h1m1 0h3m1 0h1m1 0h1m1 0h3m4 0h2m1 0h1m1 0h6m-28 1h1m1 0h3m1 0h1m3 0h2m2 0h1m2 0h2m1 0h2m2 0h1m3 0h1m-29 1h1m5 0h1m2 0h2m1 0h1m1 0h2m1 0h1m2 0h1m3 0h1m2 0h1m-28 1h7m1 0h3m2 0h1m3 0h1m1 0h2m2 0h1m1 0h1m1 0h1"/></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,74 @@
%PDF-1.4
%<25><><EFBFBD><EFBFBD> ReportLab Generated PDF document (opensource)
1 0 obj
<<
/F1 2 0 R /F2 3 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
>>
endobj
3 0 obj
<<
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
>>
endobj
4 0 obj
<<
/Contents 8 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 7 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
5 0 obj
<<
/PageMode /UseNone /Pages 7 0 R /Type /Catalog
>>
endobj
6 0 obj
<<
/Author (\(anonymous\)) /CreationDate (D:20260709160642+05'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260709160642+05'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False
>>
endobj
7 0 obj
<<
/Count 1 /Kids [ 4 0 R ] /Type /Pages
>>
endobj
8 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 769
>>
stream
Gas2I:NN!Z&B4*cMERi)0jagFI&k_l1T_1q9mZ1<N+5c?3*:0iDr2-L^hq$o1li_sp[&5P!!.Z#fB`Jk:LO#aJ5AeF5^:Kr=hoFu]g`Gu5\X&b`*+)hfcb[$S;^9-8+WN6E`Wam!N$AALiug`3hr2+$9mQ0/bWgZjeoDi+!>i[jOTSu7a"(8Tjl-.##<gD<ii^)8jI4>B]K^D:5G(9q@O8UV*G1#`%@u/[^T>oea6b8XD[2b)>5V4TlFAM0(6qW53Qj6&^c5te*HI$qSY"FrOf#n+c_e]>1O1!S(b>m\<?$@X+lS^bSHO1CD*RV5!eag)G/;.Nf0N-S*bg)*1L:+W^uk/Sh2l-)A,sOhl:_gQIukJ(9I(TYmn5U;t$u\p".6gPDA]Y3&@:"NQeHq\/B:$Z!Hn4qdK*c\-U]G?[/HU?],4BJkf9%$+'70GNIS!A7V:^5r5;oYXm(USE#E,Mc-?kJnflA#gQ8lW/;$Q6jsf-c$-E@Zd]cP8;RQKT7pr:r*>Sc2W)=J4`&Q@7C<T$OhfV7h8bWi[cehkRMcbp<3^%M,dmNr%rh,'YDR2E,_sFj@Vij)<jMEURni]hQL8tYg!1EY:+t)3Z/Q860+ic%-l,@4,k1PVof7m5r9DSE"*!(tp9:]"Cc/k'L.q42h`%MhXm/rXWh`^]lrCm7.Til0n*=#FMTVuu3gFC8Wc$@dP'Bui?=hik9_U"K?6u=EN?=&BP=Ziip:7\o`<WBR:d1*?f=4NBmUtX1A'5.P5M?dG#Q~>endstream
endobj
xref
0 9
0000000000 65535 f
0000000061 00000 n
0000000102 00000 n
0000000209 00000 n
0000000321 00000 n
0000000524 00000 n
0000000592 00000 n
0000000872 00000 n
0000000931 00000 n
trailer
<<
/ID
[<f93eb39bf6c4d9968266c7f24a73c006><f93eb39bf6c4d9968266c7f24a73c006>]
% ReportLab generated PDF document -- digest (opensource)
/Info 6 0 R
/Root 5 0 R
/Size 9
>>
startxref
1790
%%EOF

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Some files were not shown because too many files have changed in this diff Show More