Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
326 changes: 326 additions & 0 deletions ARCHITECTURE_ANALYSIS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,326 @@
# Architecture Analysis - GreenCity

## Current Architecture Overview

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ CLIENT LAYER โ”‚
โ”‚ 42 HTML Templates + 64 JavaScript Files โ”‚
โ”‚ Issues: Duplicate code, inline styles, outdated libs โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ CONTROLLER LAYER โ”‚
โ”‚ 29 @RestController classes โ”‚
โ”‚ Issues: No API versioning, direct service coupling โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ SERVICE LAYER โ”‚
โ”‚ 54 ServiceImpl classes โ”‚
โ”‚ Issues: 100+ line methods, 17 dependencies, N+1 queries โ”‚
โ”‚ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ HabitService โ”‚ โ”‚ UserService โ”‚ โ”‚ EventService โ”‚ โ”‚
โ”‚ โ”‚ 17 deps โ”‚ โ”‚ 12 deps โ”‚ โ”‚ 15 deps โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ ModelMapper โ”‚ <-- Performance issue โ”‚
โ”‚ โ”‚ (360+ calls) โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ REPOSITORY LAYER โ”‚
โ”‚ 41 Repository interfaces โ”‚
โ”‚ Issues: Inconsistent patterns, some N+1 queries โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ DATABASE LAYER โ”‚
โ”‚ PostgreSQL + Liquibase โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

## Module Structure

```
greencity/
โ”œโ”€โ”€ core/ (Web layer - Controllers, Templates)
โ”œโ”€โ”€ service/ (Business logic - 54 implementations)
โ”œโ”€โ”€ service-api/ (Service interfaces)
โ””โ”€โ”€ dao/ (Data access - Entities, Repositories)
```

### โœ… Strengths
- Clear module separation
- Spring Boot 3.2.2 (modern)
- Proper use of dependency injection
- Repository abstraction

### โŒ Weaknesses
- Service layer bloat (100+ line methods)
- Missing facade pattern
- Direct controller โ†’ multiple services coupling
- No bounded contexts

## Problem Areas Detailed

### 1. Service Layer Complexity

```java
HabitServiceImpl
โ”œโ”€โ”€ 17 injected dependencies
โ”œโ”€โ”€ 45+ public methods
โ”œโ”€โ”€ buildPageableDtoForDifferentParameters() - 35 lines
โ”‚ โ”œโ”€โ”€ Maps entities to DTOs
โ”‚ โ”œโ”€โ”€ Enriches with favorite status
โ”‚ โ”œโ”€โ”€ Loads acquired users (N+1)
โ”‚ โ”œโ”€โ”€ Loads habit assigns (N+1)
โ”‚ โ””โ”€โ”€ Checks custom habits
โ””โ”€โ”€ Multiple responsibilities mixed
```

**Recommendation:** Apply SOLID principles
```java
HabitServiceImpl
โ”œโ”€โ”€ HabitMapper (separate)
โ”œโ”€โ”€ HabitEnricher (separate)
โ”œโ”€โ”€ HabitValidator (separate)
โ””โ”€โ”€ Core business logic only
```

### 2. Data Access Patterns

**Current (N+1 Problem):**
```java
// In buildPageableDtoForDifferentParameters()
for (HabitDto habitDto : habits) {
// ๐Ÿ”ด Repository call inside loop
habitDto.setAmountAcquiredUsers(
habitAssignRepo.findAmountOfUsersAcquired(habitDto.getId())
);

// ๐Ÿ”ด Another query in loop
Habit habit = habitRepo.findById(habitDto.getId())
.orElseThrow(...);

// ๐Ÿ”ด Yet another query
List<HabitAssign> habitAssigns =
habitAssignRepo.findHabitsByHabitIdAndUserId(habitDto.getId(), friendId);
}
// Total: 1 + (N * 3) queries for N habits
```

**Recommended (Batch Loading):**
```java
// Load all at once
List<Long> habitIds = habits.stream()
.map(HabitDto::getId)
.collect(Collectors.toList());

// Single batch query
Map<Long, Long> userCounts =
habitAssignRepo.findAmountOfUsersAcquiredBatch(habitIds);

// Single batch query
Map<Long, Habit> habitsById =
habitRepo.findAllByIdIn(habitIds);

// Enrich without additional queries
// Total: 1 + 2 queries regardless of N
```

### 3. DTO Proliferation

```
268 DTO classes organized as:
โ”œโ”€โ”€ *Dto (150 classes) - Generic DTOs
โ”œโ”€โ”€ *VO (45 classes) - Value Objects
โ”œโ”€โ”€ *Request (38 classes) - API Requests
โ”œโ”€โ”€ *Response (35 classes) - API Responses
โ””โ”€โ”€ Mixed patterns causing confusion
```

**Issues:**
- Inconsistent naming
- Duplicate fields across DTOs
- Hard to find correct DTO to use
- Large mapping configuration

**Recommendation:**
```
Standardize to:
โ”œโ”€โ”€ *Request - Client โ†’ Server
โ”œโ”€โ”€ *Response - Server โ†’ Client
โ””โ”€โ”€ *Data - Internal transfer
```

### 4. Frontend Architecture

```
HTML Templates (42 files)
โ”œโ”€โ”€ Inline styles (256 instances)
โ”œโ”€โ”€ Embedded scripts
โ”œโ”€โ”€ Duplicate CDN imports
โ””โ”€โ”€ jQuery 3.5.1 (2020)

JavaScript (64 files)
โ”œโ”€โ”€ buttonsAJAX.js (10 files, 4,349 lines)
โ”‚ โ””โ”€โ”€ Massive duplication
โ”œโ”€โ”€ ES5 syntax (var, function)
โ”œโ”€โ”€ No module system
โ””โ”€โ”€ No build process
```

**Issues:**
- No separation of concerns
- Hard to maintain
- No reusability
- Security vulnerabilities

**Recommendation:**
```
Create modern structure:
src/
โ”œโ”€โ”€ js/
โ”‚ โ”œโ”€โ”€ common/
โ”‚ โ”‚ โ”œโ”€โ”€ api.js (AJAX utilities)
โ”‚ โ”‚ โ”œโ”€โ”€ dom.js (DOM utilities)
โ”‚ โ”‚ โ””โ”€โ”€ url.js (URL utilities)
โ”‚ โ”œโ”€โ”€ components/
โ”‚ โ”‚ โ”œโ”€โ”€ sort-table.js
โ”‚ โ”‚ โ””โ”€โ”€ language-switcher.js
โ”‚ โ””โ”€โ”€ pages/
โ”‚ โ”œโ”€โ”€ habits.js
โ”‚ โ””โ”€โ”€ users.js
โ”œโ”€โ”€ css/
โ”‚ โ”œโ”€โ”€ base/
โ”‚ โ”œโ”€โ”€ components/
โ”‚ โ””โ”€โ”€ pages/
โ””โ”€โ”€ Build with Webpack/Vite
```

## Dependency Graph (Simplified)

```
Controller
โ†“ (depends on)
Service (too many responsibilities)
โ†“ (360+ calls)
ModelMapper (performance bottleneck)
โ†“
DTO Layer (268 classes)
โ†“
Repository (41 interfaces)
โ†“
Entity Layer
```

**Problem:** Too many layers with unclear boundaries

**Recommended:**
```
Controller
โ†“
Facade (new - orchestration)
โ†“
Service (single responsibility)
โ†“
Mapper (compile-time - MapStruct)
โ†“
Repository
```

## SOLID Principles Violations

### Single Responsibility Principle
โŒ `HabitServiceImpl` handles:
- Habit CRUD
- Translation management
- Custom habit logic
- User assignments
- Friend habits
- DTO mapping
- Validation

โœ… Should be split into:
- `HabitService` - Core CRUD
- `HabitTranslationService` - I18n
- `HabitAssignmentService` - User assignments
- `HabitSharingService` - Friend features

### Open/Closed Principle
โŒ Adding new habit types requires modifying existing methods

โœ… Use strategy pattern:
```java
interface HabitTypeHandler {
HabitDto process(Habit habit);
}

class StandardHabitHandler implements HabitTypeHandler { }
class CustomHabitHandler implements HabitTypeHandler { }
```

### Dependency Inversion
โŒ Services depend on concrete ModelMapper

โœ… Depend on abstraction:
```java
interface EntityMapper<E, D> {
D toDto(E entity);
E toEntity(D dto);
}
```

## Recommended Refactoring Strategy

### Phase 1: Quick Wins (1-2 weeks)
1. Update frontend dependencies
2. Extract common JavaScript utilities
3. Create Thymeleaf fragments

### Phase 2: Performance (3-4 weeks)
1. Migrate to MapStruct
2. Fix N+1 queries with batch loading
3. Add caching for frequent queries

### Phase 3: Architecture (2-3 months)
1. Introduce facade layer
2. Split large services
3. Standardize DTOs
4. Add API versioning

### Phase 4: Long-term (6+ months)
1. Consider bounded contexts
2. Evaluate microservices
3. Implement CQRS for read-heavy operations
4. Add event-driven architecture

## Metrics Tracking

| Metric | Current | Target | Progress |
|--------|---------|--------|----------|
| Service Method Length | 100+ lines | < 30 lines | ๐Ÿ”ด 0% |
| Service Dependencies | 17 max | < 5 max | ๐Ÿ”ด 0% |
| DTO Classes | 268 | 150 | ๐Ÿ”ด 0% |
| Code Duplication | 4,349 JS lines | < 2,000 lines | ๐Ÿ”ด 0% |
| Test Coverage | Unknown | > 80% | ๐Ÿ”ด 0% |
| API Response Time | Unknown | < 200ms | ๐Ÿ”ด 0% |

## Conclusion

The architecture is fundamentally sound (layered, modular) but needs refinement:
- **Immediate:** Fix security and performance issues
- **Short-term:** Reduce complexity and duplication
- **Long-term:** Introduce patterns for better scalability

Focus on incremental improvements rather than big rewrites.
Loading
Loading