Skip to content

Commit 662715a

Browse files
Basic Setup
Basic Setup
1 parent bd96c31 commit 662715a

18 files changed

Lines changed: 3874 additions & 800 deletions

.claude/ANTI-PATTERNS.md

Lines changed: 517 additions & 0 deletions
Large diffs are not rendered by default.

.claude/ARCHITECTURE.md

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# AlianHub Architecture Guide
2+
3+
**[← Back to main guide](../CLAUDE.md)**
4+
5+
## High-Level Design
6+
7+
```
8+
┌─────────────────────────────────────────────────────────┐
9+
│ Web Clients (Vue.js) │
10+
│ Desktop (Electron) │
11+
└───────────┬──────────────────────────┬──────────────────┘
12+
│ │
13+
┌───────▼───────────────────────────▼──────┐
14+
│ API Server (Express.js) — /api/v1, v2 │
15+
│ - Controllers (50+ modules) │
16+
│ - Routes, Middleware, Error Handling │
17+
│ - Socket.io Event Emitter (LiveSync) │
18+
│ - Scheduled Tasks (node-schedule) │
19+
│ - Authentication (JWT, OAuth, Firebase)│
20+
└───────┬──────────────────┬────────────────┘
21+
│ │
22+
┌───────▼────────┐ ┌───▼──────────────┐
23+
│ MongoDB │ │ Storage Layer │
24+
│ (Multi-tenant)│ │ (Wasabi/Server) │
25+
│ (Company-scoped) │ (S3-compatible) │
26+
└────────────────┘ └──────────────────┘
27+
```
28+
29+
## Data Flow
30+
31+
1. **Request:** Client sends HTTP request to `/api/v{version}/endpoint`
32+
2. **Route Matching:** Express router matches request to module controller
33+
3. **Business Logic:** Controller (with chained middleware) processes request
34+
4. **Validation:** Input validation at API boundary
35+
5. **Database:** MongoDB query via `MongoDbCrudOpration(companyId, mongoObj, operation)`
36+
6. **Real-time:** Socket.io emits event for other connected clients
37+
7. **Cache:** In-memory cache invalidated after mutations
38+
8. **Response:** Returns `{ status, statusText, data }` JSON format
39+
40+
## Design Patterns in Use
41+
42+
### Module-Based Organization
43+
The codebase is organized into 50+ feature modules under `Modules/`. Each module encapsulates:
44+
- **Controller:** HTTP request handlers (endpoint logic)
45+
- **Routes:** Route definitions (registered via `exports.init(app)`)
46+
- **Helpers:** Business logic and utilities
47+
- **Schema:** Mongoose schema (if applicable)
48+
49+
### Centralized MongoDB Abstraction
50+
All database queries go through a single function:
51+
```javascript
52+
const result = await MongoDbCrudOpration(companyId, mongoObj, 'findOne');
53+
```
54+
55+
This prevents:
56+
- SQL-injection-like vulnerabilities
57+
- Inconsistent query patterns
58+
- Data scoping bugs (missing companyId)
59+
60+
### Company-Scoped Multi-Tenancy
61+
Every operation includes `companyId` for strict data isolation:
62+
- **Database level:** All queries filtered by companyId
63+
- **API level:** companyId comes from JWT or request params
64+
- **Security:** Prevents accidental cross-company data access
65+
66+
### Error Propagation via Middleware
67+
Errors don't throw — they're set on `req.errorMessageObject` and `next()` is called:
68+
```javascript
69+
try {
70+
// logic
71+
} catch (error) {
72+
req.errorMessageObject = { message: error.message, statusCode: 400 };
73+
next(); // Passes to centralized error handler
74+
}
75+
```
76+
77+
### Cache Invalidation Pattern
78+
In-memory cache (node-cache) is invalidated after mutations:
79+
```javascript
80+
const cacheKey = `project:${projectId}`;
81+
MongoDbCrudOpration(...).then(() => {
82+
removeCache(cacheKey); // Clear stale data
83+
});
84+
```
85+
86+
### Real-Time Events via Socket.io
87+
After data mutations, Socket.io broadcasts events to connected clients:
88+
```javascript
89+
require('../event/socketEventEmitter').emitEvent('TASK_UPDATED', {
90+
taskId, projectId, changes
91+
});
92+
```
93+
94+
This enables LiveSync — all clients see updates in real-time.
95+
96+
## API Versioning Strategy
97+
98+
AlianHub maintains **v1 and v2 endpoints** for backward compatibility:
99+
100+
- **v1 endpoints:** `/api/v1/projects/list`
101+
- **v2 endpoints:** `/api/v2/projects/list` (preferred)
102+
103+
**Rules:**
104+
- v2 is the default for new routes
105+
- v1 remains for legacy clients
106+
- Never mix versions in a single module (consistency)
107+
- v2 may have enhanced request/response formats
108+
109+
## Real-Time Architecture (Socket.io)
110+
111+
Socket.io enables live updates when tasks/projects change:
112+
113+
1. **Connection:** Client connects on page load
114+
2. **Event Listener:** Socket listens for events (`TASK_UPDATED`, `PROJECT_CREATED`, etc.)
115+
3. **Broadcast:** When mutation happens, server emits event to all connected clients
116+
4. **Update:** Client receives event and updates local state
117+
118+
**Key Event Types:**
119+
- `TASK_CREATED`, `TASK_UPDATED`, `TASK_DELETED`
120+
- `PROJECT_CREATED`, `PROJECT_UPDATED`, `PROJECT_DELETED`
121+
- `COMMENT_ADDED`
122+
- `CHAT_MESSAGE`
123+
124+
**Critical:** If you add a mutation, emit the corresponding event or other clients won't see the change.
125+
126+
## Multi-Tenancy Implementation
127+
128+
AlianHub supports running a single instance for multiple companies:
129+
130+
1. **Database Isolation:** All collections include `companyId` field
131+
2. **Request Scoping:** companyId extracted from JWT or request params
132+
3. **Query Filtering:** Every MongoDB query filtered by companyId
133+
4. **Storage Scoping:** File uploads organized under company directory
134+
5. **API Scoping:** Each endpoint validates user belongs to that company
135+
136+
**Security Critical:**
137+
- Missing `companyId` in query → data leak
138+
- Hardcoded `companyId` → wrong company access
139+
- JWT validation failure → authentication bypass
140+
141+
## State Management Layers
142+
143+
### Backend State
144+
- **Database:** Persistent state (projects, tasks, users)
145+
- **In-Memory Cache:** Frequently accessed data (projects, user settings)
146+
- **Socket.io State:** Connected client list
147+
148+
### Frontend State
149+
- **Vuex/Pinia Store:** Global app state (current project, user, UI)
150+
- **Local Component State:** Component-level data (form inputs, modals)
151+
- **Server State:** Fetch from API when needed
152+
153+
## Authentication Flow
154+
155+
1. **Login:** User sends credentials → JWT generated
156+
2. **Token Storage:** Client stores JWT in localStorage
157+
3. **Request:** Client sends JWT in Authorization header
158+
4. **Validation:** Express middleware validates JWT
159+
5. **Scoping:** Extracts userId and companyId from JWT
160+
6. **Authorization:** Endpoint checks user has permission
161+
162+
**Token Format:** Standard JWT with `userId`, `companyId`, `role` claims
163+
164+
## Storage Architecture
165+
166+
Two storage backends supported via abstraction layer:
167+
168+
### Wasabi (S3-Compatible)
169+
- **Use case:** Cloud deployments, scalable file storage
170+
- **Configuration:** WASABI_ACCESS_KEY, WASABI_SECRET_ACCESS_KEY, USERPROFILEBUCKET
171+
- **Implementation:** common-storage/common-wasabi.js
172+
173+
### Local File System
174+
- **Use case:** Self-hosted deployments, development
175+
- **Configuration:** STORAGE_TYPE="server"
176+
- **Implementation:** common-storage/common-server.js
177+
178+
Both support:
179+
- Image resizing (Sharp)
180+
- File uploads
181+
- Presigned URLs (for temporary access)
182+
- Cleanup after deletion

0 commit comments

Comments
 (0)