Skip to content

Commit 4f88fbb

Browse files
Merge pull request #31 from yash-pouranik/docs/architecture-diagram
docs: add full architecture diagram
2 parents ec58b3f + 5b4b1be commit 4f88fbb

1 file changed

Lines changed: 304 additions & 0 deletions

File tree

ARCHITECTURE_DIAGRAM.md

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
# urBackend — Architecture Diagram
2+
3+
## 1. System Overview
4+
5+
```mermaid
6+
graph TB
7+
subgraph Clients["👤 Clients"]
8+
DEV["Developer\n(Dashboard User)"]
9+
EXTAPP["External App\n(API Consumer)"]
10+
end
11+
12+
subgraph Frontend["🖥️ Frontend — Vite + React\nurbackend.bitbros.in"]
13+
PAGES["Pages\nLogin / Register / Dashboard\nProject Detail / Storage / Analytics"]
14+
CTX["AuthContext"]
15+
COMPS["Components\nNavbar / Modals / Tables / Charts"]
16+
end
17+
18+
subgraph Backend["⚙️ Backend — Express.js\nRender / Railway"]
19+
APP["app.js\nEntry Point"]
20+
21+
subgraph Middleware["🛡️ Middleware"]
22+
RL_DASH["dashboardLimiter\n1000 req / 15 min"]
23+
RL_API["apiLimiter\n(limiter)"]
24+
CORS_ADMIN["adminCorsOptions\nWhitelist CORS"]
25+
AUTH_MW["authMiddleware\nJWT (Developer)"]
26+
API_MW["verifyApiKey\nHashed API Key + Redis Cache"]
27+
VERIFY_EMAIL["verifyEmail\nOwner isVerified check"]
28+
LOGGER["logger\nAPI usage logger"]
29+
end
30+
31+
subgraph Routes["📡 Routes"]
32+
R_AUTH["/api/auth"]
33+
R_PROJ["/api/projects"]
34+
R_DATA["/api/data"]
35+
R_UAUTH["/api/userAuth"]
36+
R_STORE["/api/storage"]
37+
R_SCHEMA["/api/schemas"]
38+
end
39+
40+
subgraph Controllers["🧩 Controllers"]
41+
C_AUTH["auth.controller\nregister / login\nchange-password / delete\nsendOtp / verifyOtp"]
42+
C_PROJ["project.controller\ncreateProject / updateProject\ncreateCollection / deleteCollection\ngetData / insertData / editRow\ndeleteRow / uploadFile / listFiles\ndeleteFile / analytics\nupdateExternalConfig"]
43+
C_DATA["data.controller\ninsertData / getAllData\ngetSingleDoc / updateSingleData\ndeleteSingleDoc"]
44+
C_UAUTH["userAuth.controller\nsignup / login / me"]
45+
C_STORE["storage.controller\nuploadFile / deleteFile\ndeleteAllFiles"]
46+
C_SCHEMA["schema.controller\ncheckSchema / createSchema"]
47+
end
48+
49+
subgraph Utils["🔧 Utils / Services"]
50+
CONN_MGR["connection.manager\nBYOD DB connections\n(registry cache)"]
51+
INJECT["injectModel\nDynamic Mongoose Model"]
52+
QUERY["queryEngine\nDynamic Query Builder"]
53+
STORE_MGR["storage.manager\nSupabase / External Storage"]
54+
EMAIL["emailService\nNodemailer / SMTP"]
55+
ENCRYPT["encryption\nAES-256-GCM"]
56+
GC["GC.js\nGarbage Collector\n(stale connections + storage)"]
57+
REDIS["redisCaching.js\nProject-by-APIKey Cache"]
58+
VALID["input.validation\nSchema-based Validator"]
59+
end
60+
end
61+
62+
subgraph Data["🗄️ Data Layer"]
63+
MONGO_MAIN["MongoDB Atlas\n(urBackend Internal DB)"]
64+
MONGO_EXT["External MongoDB\n(BYOD — User's own DB)"]
65+
SUPABASE["Supabase Storage\n(urBackend Internal)"]
66+
SUPABASE_EXT["External Storage\n(BYOD — User's own)"]
67+
REDIS_DB["Redis\n(Upstash)"]
68+
end
69+
70+
DEV -->|"Browser"| Frontend
71+
EXTAPP -->|"x-api-key header"| R_DATA & R_UAUTH & R_STORE & R_SCHEMA
72+
73+
Frontend -->|"JWT Bearer Token"| R_AUTH & R_PROJ
74+
APP --> Routes
75+
R_AUTH --> AUTH_MW --> C_AUTH
76+
R_PROJ --> AUTH_MW --> VERIFY_EMAIL --> C_PROJ
77+
R_DATA --> API_MW --> LOGGER --> C_DATA
78+
R_UAUTH --> API_MW --> LOGGER --> C_UAUTH
79+
R_STORE --> API_MW --> LOGGER --> C_STORE
80+
R_SCHEMA --> API_MW --> LOGGER --> C_SCHEMA
81+
82+
C_AUTH --> MONGO_MAIN
83+
C_PROJ --> CONN_MGR
84+
C_DATA --> CONN_MGR
85+
C_UAUTH --> CONN_MGR
86+
C_STORE --> STORE_MGR
87+
C_SCHEMA --> CONN_MGR
88+
89+
CONN_MGR -->|"isExternal: false"| MONGO_MAIN
90+
CONN_MGR -->|"isExternal: true\n(decrypt config)"| MONGO_EXT
91+
STORE_MGR -->|"isExternal: false"| SUPABASE
92+
STORE_MGR -->|"isExternal: true"| SUPABASE_EXT
93+
94+
API_MW -->|"Cache lookup"| REDIS_DB
95+
96+
C_AUTH --> EMAIL
97+
```
98+
99+
---
100+
101+
## 2. API Request Flow — External App (API Key)
102+
103+
```mermaid
104+
sequenceDiagram
105+
participant App as External App
106+
participant MW as verifyApiKey Middleware
107+
participant Redis as Redis Cache
108+
participant DB as MongoDB (Projects)
109+
participant Ctrl as Controller
110+
participant DataDB as Data DB (Internal / External)
111+
112+
App->>MW: Request with x-api-key header
113+
MW->>Redis: Lookup hashed API key
114+
alt Cache hit
115+
Redis-->>MW: Return cached project
116+
else Cache miss
117+
MW->>DB: findOne({ apiKey: hashedKey })
118+
DB-->>MW: Project doc (with owner, resources)
119+
MW->>Redis: Store in cache
120+
end
121+
MW->>MW: Check owner.isVerified
122+
MW->>Ctrl: req.project attached → next()
123+
Ctrl->>DataDB: Query (internal or external via connection.manager)
124+
DataDB-->>Ctrl: Results
125+
Ctrl-->>App: JSON Response
126+
```
127+
128+
---
129+
130+
## 3. BYOD (Bring Your Own Database/Storage) Flow
131+
132+
```mermaid
133+
flowchart TD
134+
A["API Request arrives"] --> B["verifyApiKey middleware\nattaches req.project"]
135+
B --> C{"project.resources.db\n.isExternal?"}
136+
C -->|No| D["Use urBackend shared\nMongoDB connection"]
137+
C -->|Yes| E["connection.manager.js\nCheck registry cache"]
138+
E --> F{"Active connection\nin registry?"}
139+
F -->|Yes| G["Reuse cached connection"]
140+
F -->|No| H["Decrypt AES-256-GCM\ncredentials from Project doc"]
141+
H --> I["mongoose.createConnection(dbUri)"]
142+
I --> J["Store in registry\nwith lastAccessed timestamp"]
143+
J --> G
144+
G --> K["injectModel.js\nCreate dynamic Mongoose model\nfor collection + schema"]
145+
D --> K
146+
K --> L["queryEngine.js\nBuild + execute query"]
147+
L --> M["Return result to controller"]
148+
```
149+
150+
---
151+
152+
## 4. MongoDB Data Models
153+
154+
```mermaid
155+
erDiagram
156+
Developer {
157+
ObjectId _id
158+
string email
159+
string password
160+
boolean isVerified
161+
date createdAt
162+
date updatedAt
163+
}
164+
165+
Project {
166+
ObjectId _id
167+
string name
168+
string description
169+
ObjectId owner
170+
string apiKey
171+
string jwtSecret
172+
number storageUsed
173+
number storageLimit
174+
number databaseUsed
175+
number databaseLimit
176+
object resources
177+
date createdAt
178+
date updatedAt
179+
}
180+
181+
Collection {
182+
string name
183+
FieldSchema[] model
184+
}
185+
186+
FieldSchema {
187+
string key
188+
string type
189+
boolean required
190+
}
191+
192+
OTP {
193+
ObjectId userId
194+
string otp
195+
date createdAt
196+
}
197+
198+
Log {
199+
ObjectId project
200+
string method
201+
string route
202+
number status
203+
number responseTime
204+
date createdAt
205+
}
206+
207+
Developer ||--o{ Project : "owns"
208+
Project ||--o{ Collection : "has"
209+
Collection ||--o{ FieldSchema : "has fields"
210+
Project ||--o{ Log : "generates"
211+
Developer ||--o{ OTP : "receives"
212+
```
213+
214+
---
215+
216+
## 5. Frontend Structure (Vite + React)
217+
218+
```mermaid
219+
graph TD
220+
subgraph Entry["Entry"]
221+
MAIN["main.jsx"]
222+
APP["App.jsx\nReact Router"]
223+
end
224+
225+
subgraph Providers["Providers"]
226+
AUTHCTX["AuthContext\n(JWT token + developer state)"]
227+
end
228+
229+
subgraph Pages["Pages"]
230+
LP["Landing Page"]
231+
LOGIN["Login / Register"]
232+
DASH["Dashboard\n(Projects list)"]
233+
PROJ["Project Detail\n(Collections, API Key, Settings)"]
234+
COLL["Collection View\n(Browse & manage data)"]
235+
STORE_PG["Storage Page\n(File upload / delete)"]
236+
ANALYTICS["Analytics Page"]
237+
PROFILE["Profile Page"]
238+
BYOD_PG["BYOD Config Page"]
239+
end
240+
241+
subgraph Components["Shared Components"]
242+
NAVBAR["Navbar"]
243+
SIDEBAR["Sidebar"]
244+
MODALS["Modals\n(Create Project / Collection,\nBulk Mail, Schema, etc.)"]
245+
TABLES["Data Tables"]
246+
CHARTS["Usage Charts"]
247+
end
248+
249+
MAIN --> APP
250+
APP --> AUTHCTX
251+
AUTHCTX --> Pages
252+
Pages --> Components
253+
Pages -->|"fetch / axios"| BackendAPI["Backend REST API"]
254+
```
255+
256+
---
257+
258+
## 6. Security & Rate Limiting
259+
260+
| Layer | Mechanism | Limit / Detail |
261+
|---|---|---|
262+
| Dashboard routes (`/api/auth`, `/api/projects`) | `dashboardLimiter` | 1000 req / 15 min |
263+
| API consumer routes | `limiter` (custom) | Configurable |
264+
| Developer auth | JWT (`authMiddleware`) | Bearer token, signed per dev |
265+
| API consumer auth | `verifyApiKey` | SHA-256 hashed key + Redis cache |
266+
| Email verification gate | `verifyEmail` | `owner.isVerified` must be `true` |
267+
| CORS | `adminCorsOptions` | Whitelist: `urbackend.bitbros.in` only |
268+
| Credential storage | AES-256-GCM encryption | BYOD DB/Storage configs encrypted in MongoDB |
269+
| File uploads | `multer` memory storage | 10 MB per file limit |
270+
271+
---
272+
273+
## 7. Infrastructure Overview
274+
275+
```mermaid
276+
graph LR
277+
subgraph Hosting["Hosting"]
278+
FE["Frontend\nVercel"]
279+
BE["Backend\nRender / Railway"]
280+
end
281+
282+
subgraph External["External Services"]
283+
MONGO["MongoDB Atlas\n(Primary DB)"]
284+
RDS["Upstash Redis\n(API Key Cache)"]
285+
SUP["Supabase\n(File Storage)"]
286+
SMTP["SMTP Server\n(OTP / Emails)"]
287+
end
288+
289+
subgraph BYOD["BYOD (User-owned)"]
290+
USER_MONGO["User's MongoDB Atlas"]
291+
USER_SUP["User's Supabase"]
292+
end
293+
294+
FE -->|"HTTPS REST"| BE
295+
ExternalApp["External App"]
296+
FE -->|"HTTPS REST"| BE
297+
ExternalApp -->|"x-api-key"| BE
298+
BE --> MONGO
299+
BE --> RDS
300+
BE --> SUP
301+
BE --> SMTP
302+
BE -.->|"Optional BYOD"| USER_MONGO
303+
BE -.->|"Optional BYOD"| USER_SUP
304+
```

0 commit comments

Comments
 (0)