Skip to content

Commit 098eeec

Browse files
initial commit
1 parent 5d5d2fb commit 098eeec

38 files changed

Lines changed: 1453 additions & 631 deletions

GEMINI.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# 💎 Mavluda Beauty & Aliya Wedding Room
2+
3+
This project is a high-end management system for a luxury beauty salon (**Mavluda Azizova Beauty House**) and a wedding dress rental service (**Aliya Wedding Room**). Every aspect of the system must reflect the premium nature of these services.
4+
5+
## 🏗️ Project Architecture
6+
7+
The project is structured as a monorepo with a dedicated backend and frontend.
8+
9+
### 🛡️ Backend (NestJS)
10+
- **Architecture**: Hexagonal Architecture (Ports and Adapters).
11+
- **Database**: MongoDB (via Mongoose).
12+
- **Core Principles**:
13+
- **Domain Layer**: Pure business logic, no external dependencies (entities, value objects).
14+
- **Application Layer**: Use cases and business flows (booking, rental logic).
15+
- **Infrastructure Layer**: Framework-specific code, database adapters, external integrations (Instagram, SMS).
16+
- **Key Modules**: `booking`, `inventory` (wedding dresses), `partnership` (influencers), `veil`, `gallery`, `payment`, `user`, `auth`.
17+
18+
### 🎨 Frontend (Angular)
19+
- **Architecture**: Modern, Zoneless, Signal-based.
20+
- **Change Detection**: Zoneless (`provideZonelessChangeDetection()`).
21+
- **State Management**: Reactive signals (`signal`, `computed`, `effect`).
22+
- **Components**: 100% Standalone components.
23+
- **Styling**: Tailwind CSS for a modern, "alive" aesthetic.
24+
- **Internationalization**: i18n support for English (en-US), Russian (ru), and Tajik (tg).
25+
26+
## 📁 Directory Overview
27+
28+
### Root
29+
- `/backend`: NestJS API.
30+
- `/frontend`: Angular SPA.
31+
- `.agent/rules`: Architectural and development mandates.
32+
33+
### Backend Structure (`/backend/src`)
34+
- `/*/domain`: Business entities and logic.
35+
- `/*/application`: Use cases and services.
36+
- `/*/infrastructure`: Controllers, repositories, and DTOs.
37+
- `/*/presentation`: API endpoints (sometimes combined with infrastructure).
38+
- `common/`: Shared config, database connection, decorators, and guards.
39+
40+
### Frontend Structure (`/frontend/src`)
41+
- `pages/`: Route-level components.
42+
- `features/`: Complex UI logic (e.g., auth, language selection).
43+
- `entities/`: Data-focused components and services.
44+
- `widgets/`: Independent, reusable UI blocks (header, sidebar, layouts).
45+
- `shared/`: Generic UI components, pipes, services, and models.
46+
- `core/`: Config, guards, and interceptors.
47+
48+
## 🚀 Key Commands
49+
50+
### Backend
51+
- `npm run start:dev`: Run backend in development mode with watch.
52+
- `npm run build`: Build the backend for production.
53+
- `npm run lint`: Run ESLint with auto-fix.
54+
- `npm run test`: Run unit tests.
55+
56+
### Frontend
57+
- `npm run dev`: Run frontend development server (`ng serve`).
58+
- `npm run build`: Build the frontend for production.
59+
- `npm run preview`: Run production build preview.
60+
61+
## 📏 Development Conventions
62+
63+
### Backend Rules
64+
1. **Hexagonal Purity**: Infrastructure/Controllers -> Application -> Domain. The Domain must not import anything from other layers.
65+
2. **Module Aliases**: Use `@modules/*`, `@common/*`, etc., as defined in `tsconfig.json`.
66+
3. **Entity Mapping**: Every module must strictly map to business domains (e.g., `booking-module` for VIP scheduling).
67+
68+
### Frontend Rules
69+
1. **Zoneless Only**: Never rely on Zone.js. All UI updates must be triggered via signals or explicit change detection.
70+
2. **Signals over Observables**: Use `signal()` for state. Use `toSignal()` when dealing with HTTP calls if needed, but prefer signal-based state management.
71+
3. **Modern Syntax**:
72+
- Use `@if`, `@for`, `@switch` control flows.
73+
- Use `input()` and `output()` instead of `@Input()` and `@Output()`.
74+
- Use `inject()` for dependency injection instead of constructors.
75+
4. **Standalone**: All components, directives, and pipes must be standalone.
76+
77+
## 🛠️ Environment Setup
78+
- **Node.js**: Modern LTS version recommended.
79+
- **Database**: MongoDB instance required for the backend.
80+
- **Environment Variables**: Managed via `.env` in the root and project-specific config files.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// infrastructure/utils/file-system.util.ts
2+
import * as fs from 'fs';
3+
import { join } from 'path';
4+
5+
export function fileDelete(relativeFilePath: string): boolean {
6+
try {
7+
const absolutePath = join(process.cwd(), relativeFilePath);
8+
if (fs.existsSync(absolutePath)) {
9+
fs.unlinkSync(absolutePath);
10+
}
11+
return true;
12+
} catch (err) {
13+
console.error(`Error deleting file ${relativeFilePath}:`, err);
14+
return false;
15+
}
16+
}

backend/src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ async function bootstrap() {
1212
whitelist: true,
1313
forbidNonWhitelisted: true,
1414
transform: true,
15-
transformOptions: { enableImplicitConversion: true },
15+
transformOptions: { enableImplicitConversion: false },
1616
}),
1717
);
1818
app.enableCors({

backend/src/veil/infrastructure/repositories/veil.repository.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
VeilDocument,
77
VeilSchemaEntity,
88
} from '@veil/infrastructure/schemas/veil.schema';
9+
import { fileDelete } from '@common/utils/file-system';
910

1011
@Injectable()
1112
export class VeilRepository {
@@ -39,9 +40,17 @@ export class VeilRepository {
3940
}
4041

4142
async update(id: string, updateData: Partial<Veil>): Promise<Veil | null> {
43+
const veil = await this.findById(id);
44+
if (!veil) {
45+
return null;
46+
}
47+
if (veil.image) {
48+
const isDeleted = fileDelete(veil.image); }
49+
4250
const doc = await this.veilModel
4351
.findByIdAndUpdate(id, { $set: updateData }, { new: true })
4452
.exec();
53+
4554
return doc ? this.toDomain(doc) : null;
4655
}
4756

backend/src/veil/presentation/dto/create-veil.dto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export class CreateVeilDto {
3636

3737
@IsBoolean()
3838
@IsOptional()
39-
@Transform(({ value }: { value: boolean | string }) => value === 'true')
39+
@Transform(({ value }: { value: string | boolean }) => value === 'true')
4040
isAvailable?: boolean;
4141

4242
@IsString()

backend/src/veil/presentation/veil.controller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export class VeilController {
100100

101101
@Delete(':id')
102102
async remove(@Param('id') id: string): Promise<void> {
103+
console.log('lorem', id);
103104
return this.veilService.remove(id);
104105
}
105106
}

0 commit comments

Comments
 (0)