Utilizziamo i cookie per migliorare la tua esperienza sul sito
CodeWorlds

PROJEKT: Kompleksowa Aplikacja Imperium Romanum

Ave, legacie! Konsul Caesar.js powierzył Ci największe wyzwanie - stworzenie kompletnej aplikacji do zarządzania rzymskim imperium. To będzie prawdziwy test wszystkich umiejętności, które zdobyłeś podczas nauki NestJS!

Specyfikacja Projektu: Imperium Management System

Twoja aplikacja musi być kompletnym systemem zarządzania legionami rzymskimi, obsługującym:

1. System Użytkowników i Autoryzacji

  • Rejestracja i logowanie legionistów z różnymi rangami
  • JWT Authentication z refresh tokenami
  • Role-based access control (RBAC)
  • Multi-factor authentication dla konsulów

2. Zarządzanie legionami

  • Legiony - różne typy, pojemności, wyposażenie
  • Żołnierze - legionacy z umiejętnościami i historiami
  • Kampanie - wyprawy po trybuty z planowaniem tras
  • Forty - bazy operacyjne z zasobami

3. System tributów

  • Inventory management - skrzynie, tributy, artefakty
  • Trading system - wymiana między legionami
  • Auction house - licytacje rzadkich przedmiotów
  • Value tracking - śledzenie wartości w czasie

4. Komunikacja i Koordynacja

  • Real-time messaging - WebSocket communication
  • Legion announcements - ogłoszenia dla legionów
  • Battle coordination - koordynacja podczas bitew
  • Weather alerts - powiadomienia o pogodzie

5. Analytics i Raporty

  • Performance dashboards - statystyki legionów
  • Tribute reports - analizy zysków
  • Legion analytics - wydajność legionów
  • Predictive insights - AI-driven predictions

Struktura Techniczna

Core Modules

1// app.module.ts
2import { Module } from '@nestjs/common';
3import { ConfigModule } from '@nestjs/config';
4import { TypeOrmModule } from '@nestjs/typeorm';
5import { GraphQLModule } from '@nestjs/graphql';
6import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
7import { BullModule } from '@nestjs/bull';
8import { CacheModule } from '@nestjs/cache-manager';
9import { EventEmitterModule } from '@nestjs/event-emitter';
10
11// Custom modules
12import { AuthModule } from './auth/auth.module';
13import { LegionModule } from './legion/legion.module';
14import { LegionaryModule } from './legionary/legionary.module';
15import { TributeModule } from './tribute/tribute.module';
16import { CampaignModule } from './campaign/campaign.module';
17import { CommunicationModule } from './communication/communication.module';
18import { AnalyticsModule } from './analytics/analytics.module';
19import { WebsocketModule } from './websocket/websocket.module';
20
21// Configuration
22import { databaseConfig, redisConfig, appConfig } from './config';
23import { validationSchema } from './config/validation.schema';
24
25@Module({
26 imports: [
27 // Configuration
28 ConfigModule.forRoot({
29 isGlobal: true,
30 load: [databaseConfig, redisConfig, appConfig],
31 validationSchema,
32 }),
33
34 // Database
35 TypeOrmModule.forRootAsync({
36 useFactory: (configService: ConfigService) => configService.get('database'),
37 inject: [ConfigService],
38 }),
39
40 // GraphQL
41 GraphQLModule.forRoot<ApolloDriverConfig>({
42 driver: ApolloDriver,
43 autoSchemaFile: 'schema.gql',
44 subscriptions: {
45 'graphql-ws': true,
46 },
47 context: ({ req, connection }) =>
48 connection ? { req: connection.context } : { req },
49 }),
50
51 // Redis & Caching
52 BullModule.forRootAsync({
53 useFactory: (configService: ConfigService) => configService.get('redis'),
54 inject: [ConfigService],
55 }),
56
57 CacheModule.registerAsync({
58 useFactory: (configService: ConfigService) => ({
59 store: 'redis',
60 ...configService.get('redis'),
61 ttl: 300, // 5 minutes default
62 }),
63 inject: [ConfigService],
64 }),
65
66 // Event system
67 EventEmitterModule.forRoot(),
68
69 // Feature modules
70 AuthModule,
71 LegionModule,
72 LegionaryModule,
73 TributeModule,
74 CampaignModule,
75 CommunicationModule,
76 AnalyticsModule,
77 WebsocketModule,
78 ],
79 providers: [
80 // Global guards
81 {
82 provide: APP_GUARD,
83 useClass: JwtAuthGuard,
84 },
85 {
86 provide: APP_GUARD,
87 useClass: RolesGuard,
88 },
89 // Global interceptors
90 {
91 provide: APP_INTERCEPTOR,
92 useClass: LoggingInterceptor,
93 },
94 {
95 provide: APP_INTERCEPTOR,
96 useClass: TransformInterceptor,
97 },
98 // Global filters
99 {
100 provide: APP_FILTER,
101 useClass: AllExceptionsFilter,
102 },
103 ],
104})
105export class AppModule {}

Advanced Features Implementation

1// auth/strategies/jwt.strategy.ts
2@Injectable()
3export class JwtStrategy extends PassportStrategy(Strategy) {
4 constructor(
5 private configService: ConfigService,
6 private userService: UserService,
7 ) {
8 super({
9 jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
10 ignoreExpiration: false,
11 secretOrKey: configService.get<string>('jwt.secret'),
12 });
13 }
14
15 async validate(payload: any) {
16 const user = await this.userService.findById(payload.sub);
17 if (!user || !user.isActive) {
18 throw new UnauthorizedException('Legionary not found or inactive');
19 }
20 return user;
21 }
22}
23
24// websocket/legion-communication.gateway.ts
25@WebSocketGateway({
26 cors: {
27 origin: '*',
28 },
29})
30export class LegionCommunicationGateway
31 implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
32
33 @WebSocketServer()
34 server: Server;
35
36 private logger: Logger = new Logger('LegionCommunicationGateway');
37 private legionaryConnections = new Map<string, string>(); // socketId -> legionaryId
38
39 afterInit(server: Server) {
40 this.logger.log('Legion Communication Gateway initialized');
41 }
42
43 async handleConnection(client: Socket, ...args: any[]) {
44 try {
45 const token = client.handshake.auth.token;
46 const legionary = await this.authService.validateToken(token);
47
48 this.legionaryConnections.set(client.id, legionary.id);
49 client.join(`cohort_${legionary.cohortId}`);
50 client.join(`legion_${legionary.legionId}`);
51
52 this.server.to(`cohort_${legionary.cohortId}`).emit('legionaryJoined', {
53 legionary: legionary.name,
54 message: `${legionary.name} dołączył do komunikacji`,
55 });
56
57 this.logger.log(`Legionary ${legionary.name} connected to legion communication`);
58 } catch (error) {
59 this.logger.error('Connection failed:', error);
60 client.disconnect();
61 }
62 }
63
64 handleDisconnect(client: Socket) {
65 const legionaryId = this.legionaryConnections.get(client.id);
66 if (legionaryId) {
67 this.legionaryConnections.delete(client.id);
68 this.logger.log(`Legionary ${legionaryId} disconnected`);
69 }
70 }
71
72 @SubscribeMessage('cohortMessage')
73 handleCohortMessage(client: Socket, payload: any) {
74 const legionaryId = this.legionaryConnections.get(client.id);
75 const legionary = this.userService.findById(legionaryId);
76
77 client.to(`cohort_${legionary.cohortId}`).emit('cohortMessage', {
78 from: legionary.name,
79 message: payload.message,
80 timestamp: new Date(),
81 });
82 }
83
84 @SubscribeMessage('legionAnnouncement')
85 @UseGuards(WsJwtGuard, WsRolesGuard)
86 @Roles('CENTURION', 'CONSUL')
87 handleLegionAnnouncement(client: Socket, payload: any) {
88 const legionaryId = this.legionaryConnections.get(client.id);
89 const legionary = this.userService.findById(legionaryId);
90
91 this.server.to(`legion_${legionary.legionId}`).emit('legionAnnouncement', {
92 from: legionary.name,
93 rank: legionary.rank,
94 message: payload.message,
95 priority: payload.priority || 'normal',
96 timestamp: new Date(),
97 });
98 }
99}
100
101// analytics/services/advanced-analytics.service.ts
102@Injectable()
103export class AdvancedAnalyticsService {
104 constructor(
105 private dataSource: DataSource,
106 @InjectQueue('analytics') private analyticsQueue: Queue,
107 ) {}
108
109 async generateLegionPerformanceReport(legionId: number, period: string) {
110 const job = await this.analyticsQueue.add('legion-performance', {
111 legionId,
112 period,
113 });
114
115 return { jobId: job.id };
116 }
117
118 async getPredictiveTributeInsights(legionId: number) {
119 // Machine learning predictions (przykład z TensorFlow.js)
120 const historicalData = await this.getHistoricalTributeData(legionId);
121 const predictions = await this.mlPredict(historicalData);
122
123 return {
124 predictedTributeValue: predictions.value,
125 confidence: predictions.confidence,
126 recommendedActions: predictions.actions,
127 timeframe: '30 days',
128 };
129 }
130
131 private async mlPredict(data: any[]) {
132 // Przykład prostego ML modelu
133 const values = data.map(d => d.value);
134 const trend = this.calculateTrend(values);
135 const seasonality = this.calculateSeasonality(data);
136
137 return {
138 value: trend.nextPrediction * seasonality.factor,
139 confidence: Math.min(trend.confidence * seasonality.confidence, 0.95),
140 actions: this.generateRecommendations(trend, seasonality),
141 };
142 }
143
144 @Cron('0 2 * * *') // Codziennie o 2:00
145 async generateDailyReports() {
146 const legions = await this.getActiveLegions();
147
148 for (const legion of legions) {
149 await this.analyticsQueue.add('daily-report', {
150 legionId: legion.id,
151 date: new Date(),
152 });
153 }
154 }
155}
156
157// tribute/services/auction.service.ts
158@Injectable()
159export class AuctionService {
160 constructor(
161 private auctionRepository: AuctionRepository,
162 private eventEmitter: EventEmitter2,
163 @InjectQueue('auction') private auctionQueue: Queue,
164 ) {}
165
166 async createAuction(tributeId: number, sellerId: number, startingPrice: number, duration: number) {
167 const auction = await this.auctionRepository.create({
168 tributeId,
169 sellerId,
170 startingPrice,
171 currentPrice: startingPrice,
172 endTime: new Date(Date.now() + duration * 1000),
173 status: 'ACTIVE',
174 });
175
176 // Schedule auction end
177 await this.auctionQueue.add(
178 'end-auction',
179 { auctionId: auction.id },
180 { delay: duration * 1000 }
181 );
182
183 this.eventEmitter.emit('auction.created', auction);
184 return auction;
185 }
186
187 async placeBid(auctionId: number, bidderId: number, amount: number) {
188 const auction = await this.auctionRepository.findById(auctionId);
189 
190 if (auction.status !== 'ACTIVE' || new Date() > auction.endTime) {
191 throw new BadRequestException('Auction is not active');
192 }
193
194 if (amount <= auction.currentPrice) {
195 throw new BadRequestException('Bid must be higher than current price');
196 }
197
198 // Anti-sniping: extend auction if bid in last 5 minutes
199 const timeLeft = auction.endTime.getTime() - Date.now();
200 if (timeLeft < 5 * 60 * 1000) {
201 auction.endTime = new Date(auction.endTime.getTime() + 5 * 60 * 1000);
202 }
203
204 auction.currentPrice = amount;
205 auction.currentBidderId = bidderId;
206 
207 await this.auctionRepository.save(auction);
208
209 this.eventEmitter.emit('auction.bid', {
210 auctionId,
211 bidderId,
212 amount,
213 timeLeft: Math.max(0, timeLeft),
214 });
215
216 return auction;
217 }
218
219 @OnEvent('auction.end')
220 async handleAuctionEnd(auctionId: number) {
221 const auction = await this.auctionRepository.findById(auctionId);
222
223 if (auction.currentBidderId) {
224 await this.transferTribute(auction.tributeId, auction.currentBidderId);
225 await this.transferFunds(auction.currentBidderId, auction.sellerId, auction.currentPrice);
226
227 auction.status = 'COMPLETED';
228 auction.winnerId = auction.currentBidderId;
229 } else {
230 auction.status = 'NO_BIDS';
231 }
232
233 await this.auctionRepository.save(auction);
234 this.eventEmitter.emit('auction.completed', auction);
235 }
236}

Zadania do realizacji

Etap 1: Podstawowa architektura (Tydzień 1)

  1. Setup projektu - konfiguracja NestJS, TypeORM, Redis
  2. Authentication system - JWT, refresh tokeny, role-based access
  3. Base entities - User, Legion, Cohort, Tribute podstawowe
  4. API endpoints - CRUD operations dla podstawowych encji
  5. Basic tests - unit testy dla serwisów

Etap 2: Funkcjonalności biznesowe (Tydzień 2)

  1. Campaign system - planowanie i wykonywanie kampanii
  2. Trading system - wymiana tributów między legionistami
  3. Legion management - zarządzanie legionami i umiejętnościami
  4. Notification system - powiadomienia w czasie rzeczywistym
  5. Advanced validation - complex business rules

Etap 3: Real-time i zaawansowane (Tydzień 3)

  1. WebSocket integration - real-time communication
  2. Auction system - licytacje tributów
  3. Analytics dashboard - statystyki i metryki
  4. Background jobs - przetwarzanie async zadań
  5. Performance optimization - caching, indexy, optymalizacje

Etap 4: Produkcja i zaawansowane (Tydzień 4)

  1. GraphQL implementation - alternatywne API
  2. Rate limiting - ochrona przed spam
  3. Monitoring - health checks, metrics, alerting
  4. Deployment - Docker, CI/CD, environment management
  5. Advanced security - security headers, CORS, data encryption

Kryteria oceny

Funkcjonalność (25%)

  • ✅ Wszystkie wymagane funkcje działają poprawnie
  • ✅ Kompleksowy system autoryzacji i uprawnień
  • ✅ Real-time communication między użytkownikami
  • ✅ Zaawansowane funkcje biznesowe (aukcje, misje, handel)

Jakość kodu (25%)

  • ✅ Czytelna architektura i struktura projektu
  • ✅ Właściwe użycie wzorców projektowych
  • ✅ Consistent code style i naming conventions
  • ✅ Proper error handling i validation

Performance i skalowalność (20%)

  • ✅ Optymalizacja zapytań do bazy danych
  • ✅ Effective caching strategies
  • ✅ Background job processing
  • ✅ Rate limiting i resource management

Testy (15%)

  • ✅ Comprehensive unit tests (>80% coverage)
  • ✅ Integration tests dla kluczowych flow
  • ✅ E2E tests dla głównych funkcjonalności
  • ✅ Performance tests

Dokumentacja (15%)

  • ✅ API documentation (Swagger/OpenAPI)
  • ✅ README z instrukcjami setup i deployment
  • ✅ Architecture documentation
  • ✅ Code comments gdzie potrzebne

Bonus Points

  • 🌟 GraphQL subscriptions dla real-time updates
  • 🌟 Machine learning predictions dla tribute values
  • 🌟 Microservices architecture z message queues
  • 🌟 Advanced monitoring z Prometheus/Grafana
  • 🌟 Mobile app komunikująca się z API

Przykładowe endpointy API

1// Legion Management
2GET /api/legions # Lista legionów
3POST /api/legions # Utwórz legion
4GET /api/legions/:id # Szczegóły legionu
5PUT /api/legions/:id # Aktualizuj legion
6DELETE /api/legions/:id # Usuń legion
7
8// Cohort Management
9GET /api/cohorts # Lista kohort
10POST /api/cohorts # Dodaj kohortę
11GET /api/cohorts/:id # Szczegóły kohorty
12PUT /api/cohorts/:id # Aktualizuj kohortę
13POST /api/cohorts/:id/assign-legionaries # Przypisz legionistów
14POST /api/cohorts/:id/campaigns # Utwórz kampanię
15
16// Tribute System
17GET /api/tributes # Lista tributów
18POST /api/tributes # Dodaj tribut
19GET /api/tributes/:id # Szczegóły tributu
20PUT /api/tributes/:id/transfer # Transfer tributu
21POST /api/tributes/:id/auction # Wystawienie na aukcję
22
23// Auctions
24GET /api/auctions # Aktywne aukcje
25POST /api/auctions/:id/bid # Złóż ofertę
26GET /api/auctions/:id/history # Historia licytacji
27
28// Analytics
29GET /api/analytics/legion/:id # Statystyki legionu
30GET /api/analytics/tribute-trends # Trendy wartości tributów
31GET /api/analytics/legion-performance # Wydajność legionów
32
33// Real-time WebSocket events
34cohort:message # Wiadomości w kohorcie
35legion:announcement # Ogłoszenia legionu
36auction:bid # Nowa oferta aukcji
37campaign:update # Update kampanii
38tribute:discovered # Znaleziony tribut

To największe wyzwanie w służbie Imperium Romanum! Powodzenia, legate - imperium liczy na Ciebie!

Vai a CodeWorlds