@2byte/tgbot-framework 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +300 -300
  2. package/bin/2byte-cli.ts +97 -97
  3. package/package.json +55 -55
  4. package/src/cli/CreateBotCommand.ts +181 -181
  5. package/src/cli/GenerateCommand.ts +195 -195
  6. package/src/cli/InitCommand.ts +107 -107
  7. package/src/cli/TgAccountManager.ts +50 -50
  8. package/src/console/migrate.ts +82 -82
  9. package/src/core/ApiService.ts +20 -20
  10. package/src/core/ApiServiceManager.ts +63 -63
  11. package/src/core/App.ts +1157 -1143
  12. package/src/core/BotArtisan.ts +79 -79
  13. package/src/core/BotMigration.ts +30 -30
  14. package/src/core/BotSeeder.ts +66 -66
  15. package/src/core/Model.ts +84 -84
  16. package/src/core/utils.ts +2 -2
  17. package/src/illumination/Artisan.ts +149 -149
  18. package/src/illumination/InlineKeyboard.ts +61 -61
  19. package/src/illumination/Message2Byte.ts +255 -255
  20. package/src/illumination/Message2ByteLiveProgressive.ts +278 -278
  21. package/src/illumination/Message2bytePool.ts +107 -107
  22. package/src/illumination/Migration.ts +186 -186
  23. package/src/illumination/RunSectionRoute.ts +85 -85
  24. package/src/illumination/Section.ts +410 -410
  25. package/src/illumination/SectionComponent.ts +64 -64
  26. package/src/illumination/Telegraf2byteContext.ts +32 -32
  27. package/src/index.ts +42 -42
  28. package/src/libs/TelegramAccountControl.ts +1140 -1140
  29. package/src/libs/TgSender.ts +53 -53
  30. package/src/models/Model.ts +67 -67
  31. package/src/models/Proxy.ts +217 -217
  32. package/src/models/TgAccount.ts +362 -362
  33. package/src/models/index.ts +2 -2
  34. package/src/types.ts +191 -191
  35. package/src/user/UserModel.ts +297 -297
  36. package/src/user/UserStore.ts +119 -119
  37. package/src/workflow/services/MassSendApiService.ts +83 -80
  38. package/templates/bot/.env.example +33 -33
  39. package/templates/bot/artisan.ts +8 -8
  40. package/templates/bot/bot.ts +82 -82
  41. package/templates/bot/database/dbConnector.ts +4 -4
  42. package/templates/bot/database/migrate.ts +9 -9
  43. package/templates/bot/database/migrations/001_create_users.sql +18 -18
  44. package/templates/bot/database/migrations/007_proxy.sql +27 -27
  45. package/templates/bot/database/migrations/008_tg_accounts.sql +32 -32
  46. package/templates/bot/database/seed.ts +14 -14
  47. package/templates/bot/docs/CLI_SERVICES.md +536 -536
  48. package/templates/bot/docs/INPUT_SYSTEM.md +211 -211
  49. package/templates/bot/docs/MASS_SEND_SERVICE.md +327 -0
  50. package/templates/bot/docs/SERVICE_EXAMPLES.md +384 -384
  51. package/templates/bot/docs/TASK_SYSTEM.md +156 -156
  52. package/templates/bot/models/Model.ts +7 -7
  53. package/templates/bot/models/index.ts +1 -1
  54. package/templates/bot/package.json +30 -30
  55. package/templates/bot/sectionList.ts +9 -9
  56. package/templates/bot/sections/ExampleInputSection.ts +85 -85
  57. package/templates/bot/sections/ExampleLiveTaskerSection.ts +60 -60
  58. package/templates/bot/sections/HomeSection.ts +63 -63
  59. package/templates/bot/workflow/services/ExampleService.ts +23 -23
@@ -1,384 +1,384 @@
1
- # Примеры использования Service Generator
2
-
3
- ## Тестовые сценарии
4
-
5
- ### Сценарий 1: Создание простого сервиса
6
-
7
- ```bash
8
- cd your-bot-directory
9
- 2byte generate service Payment
10
- ```
11
-
12
- **Ожидаемый результат:**
13
- - Создан файл `workflow/services/PaymentService.ts`
14
- - Выведено: `✅ Created service PaymentService at workflow/services/PaymentService.ts`
15
-
16
- ### Сценарий 2: Создание с полным именем
17
-
18
- ```bash
19
- 2byte g service NotificationService
20
- ```
21
-
22
- **Ожидаемый результат:**
23
- - Создан файл `workflow/services/NotificationService.ts`
24
- - Суффикс Service не дублируется
25
-
26
- ### Сценарий 3: Попытка создать существующий сервис
27
-
28
- ```bash
29
- 2byte g service Payment # Второй раз
30
- ```
31
-
32
- **Ожидаемый результат:**
33
- - Ошибка: `❌ Service PaymentService already exists`
34
- - Файл не перезаписывается
35
-
36
- ### Сценарий 4: Создание нескольких сервисов
37
-
38
- ```bash
39
- 2byte g service Cache
40
- 2byte g service Logger
41
- 2byte g service EmailSender
42
- 2byte g service DatabaseConnector
43
- ```
44
-
45
- **Структура после создания:**
46
- ```
47
- workflow/
48
- └── services/
49
- ├── CacheService.ts
50
- ├── LoggerService.ts
51
- ├── EmailSenderService.ts
52
- └── DatabaseConnectorService.ts
53
- ```
54
-
55
- ## Проверка работы созданного сервиса
56
-
57
- ### 1. Создайте тестовый сервис
58
-
59
- ```bash
60
- 2byte g service Test
61
- ```
62
-
63
- ### 2. Измените сервис
64
-
65
- Откройте `workflow/services/TestService.ts` и добавьте логику:
66
-
67
- ```typescript
68
- import { App } from "@2byte/tgbot-framework";
69
- import { ApiService } from "@2byte/tgbot-framework";
70
-
71
- export default class TestService extends ApiService {
72
-
73
- constructor(
74
- protected app: App,
75
- public name: string = "TestService"
76
- ) {
77
- super(app, name);
78
- }
79
-
80
- public async setup(): Promise<void> {
81
- this.app.debugLog(`[${this.name}] Setting up test service`);
82
- return Promise.resolve();
83
- }
84
-
85
- public async unsetup(): Promise<void> {
86
- this.app.debugLog(`[${this.name}] Cleaning up test service`);
87
- return Promise.resolve();
88
- }
89
-
90
- public async run(): Promise<void> {
91
- this.app.debugLog(`[${this.name}] Test service is running!`);
92
-
93
- // Тестовая задача каждые 10 секунд
94
- setInterval(() => {
95
- this.app.debugLog(`[${this.name}] Heartbeat - ${new Date().toISOString()}`);
96
- }, 10000);
97
-
98
- return Promise.resolve();
99
- }
100
-
101
- // Кастомный метод для тестирования
102
- public getStatus(): string {
103
- return `TestService is active at ${new Date().toISOString()}`;
104
- }
105
- }
106
- ```
107
-
108
- ### 3. Запустите бота
109
-
110
- ```bash
111
- bun run index.ts
112
- ```
113
-
114
- **Ожидаемые логи:**
115
- ```
116
- [App] Registered API services: [ 'TestService', ... ]
117
- [TestService] Setting up test service
118
- [TestService] Service setup completed
119
- [TestService] Test service is running!
120
- [TestService] Heartbeat - 2025-10-29T...
121
- [TestService] Heartbeat - 2025-10-29T...
122
- ```
123
-
124
- ### 4. Используйте сервис в секции
125
-
126
- Создайте или откройте секцию:
127
-
128
- ```typescript
129
- import { Section } from "@2byte/tgbot-framework";
130
-
131
- export default class HomeSection extends Section {
132
- async index() {
133
- // Получаем наш тестовый сервис
134
- const testService = this.app.getService('TestService');
135
-
136
- if (testService) {
137
- const status = testService.getStatus();
138
-
139
- await this.message(`🤖 Bot Status\n\n${status}`)
140
- .send();
141
- }
142
- }
143
- }
144
- ```
145
-
146
- ## Интеграционные тесты
147
-
148
- ### Test 1: Автозагрузка сервиса
149
-
150
- ```bash
151
- # Создать сервис
152
- 2byte g service AutoLoad
153
-
154
- # Запустить бота
155
- bun run index.ts
156
-
157
- # Проверить логи
158
- # Должно быть: [App] Registered API services: [ 'AutoLoadService', ... ]
159
- ```
160
-
161
- ### Test 2: Использование в секциях
162
-
163
- ```typescript
164
- // В любой секции
165
- const service = this.app.getService('AutoLoadService');
166
- console.log('Service loaded:', service ? 'YES' : 'NO');
167
- ```
168
-
169
- ### Test 3: Жизненный цикл
170
-
171
- ```bash
172
- # Запустить бота
173
- bun run index.ts
174
- # Лог: [ServiceName] Service setup completed
175
-
176
- # Остановить бота (Ctrl+C)
177
- # Лог: [ServiceName] Service cleanup completed
178
- ```
179
-
180
- ## Примеры реальных сервисов
181
-
182
- ### Email Service
183
-
184
- ```bash
185
- 2byte g service Email
186
- ```
187
-
188
- ```typescript
189
- // workflow/services/EmailService.ts
190
- import { App, ApiService } from "@2byte/tgbot-framework";
191
- import nodemailer from 'nodemailer';
192
-
193
- export default class EmailService extends ApiService {
194
- private transporter: any;
195
-
196
- constructor(protected app: App, public name: string = "EmailService") {
197
- super(app, name);
198
- }
199
-
200
- public async setup(): Promise<void> {
201
- this.transporter = nodemailer.createTransport({
202
- host: process.env.SMTP_HOST,
203
- port: parseInt(process.env.SMTP_PORT || '587'),
204
- auth: {
205
- user: process.env.SMTP_USER,
206
- pass: process.env.SMTP_PASS
207
- }
208
- });
209
-
210
- this.app.debugLog(`[${this.name}] Email service ready`);
211
- }
212
-
213
- public async sendEmail(to: string, subject: string, text: string) {
214
- const info = await this.transporter.sendMail({
215
- from: process.env.EMAIL_FROM,
216
- to,
217
- subject,
218
- text
219
- });
220
-
221
- this.app.debugLog(`[${this.name}] Email sent: ${info.messageId}`);
222
- return info;
223
- }
224
- }
225
- ```
226
-
227
- ### Database Service
228
-
229
- ```bash
230
- 2byte g service Database
231
- ```
232
-
233
- ```typescript
234
- // workflow/services/DatabaseService.ts
235
- import { App, ApiService } from "@2byte/tgbot-framework";
236
- import { Database } from 'sqlite3';
237
-
238
- export default class DatabaseService extends ApiService {
239
- private db: Database | null = null;
240
-
241
- constructor(protected app: App, public name: string = "DatabaseService") {
242
- super(app, name);
243
- }
244
-
245
- public async setup(): Promise<void> {
246
- return new Promise((resolve, reject) => {
247
- this.db = new Database('./database.db', (err) => {
248
- if (err) {
249
- this.app.debugLog(`[${this.name}] DB connection failed`, err);
250
- reject(err);
251
- } else {
252
- this.app.debugLog(`[${this.name}] DB connected`);
253
- resolve();
254
- }
255
- });
256
- });
257
- }
258
-
259
- public async unsetup(): Promise<void> {
260
- return new Promise((resolve) => {
261
- this.db?.close(() => {
262
- this.app.debugLog(`[${this.name}] DB connection closed`);
263
- resolve();
264
- });
265
- });
266
- }
267
-
268
- public async query(sql: string, params: any[] = []): Promise<any> {
269
- return new Promise((resolve, reject) => {
270
- this.db?.all(sql, params, (err, rows) => {
271
- if (err) reject(err);
272
- else resolve(rows);
273
- });
274
- });
275
- }
276
- }
277
- ```
278
-
279
- ### Redis Cache Service
280
-
281
- ```bash
282
- 2byte g service RedisCache
283
- ```
284
-
285
- ```typescript
286
- // workflow/services/RedisCacheService.ts
287
- import { App, ApiService } from "@2byte/tgbot-framework";
288
- import Redis from 'ioredis';
289
-
290
- export default class RedisCacheService extends ApiService {
291
- private redis: Redis | null = null;
292
-
293
- constructor(protected app: App, public name: string = "RedisCacheService") {
294
- super(app, name);
295
- }
296
-
297
- public async setup(): Promise<void> {
298
- this.redis = new Redis({
299
- host: process.env.REDIS_HOST || 'localhost',
300
- port: parseInt(process.env.REDIS_PORT || '6379'),
301
- password: process.env.REDIS_PASSWORD
302
- });
303
-
304
- this.redis.on('connect', () => {
305
- this.app.debugLog(`[${this.name}] Redis connected`);
306
- });
307
- }
308
-
309
- public async unsetup(): Promise<void> {
310
- await this.redis?.quit();
311
- this.app.debugLog(`[${this.name}] Redis disconnected`);
312
- }
313
-
314
- public async get(key: string): Promise<string | null> {
315
- return this.redis?.get(key) || null;
316
- }
317
-
318
- public async set(key: string, value: string, ttl?: number): Promise<void> {
319
- if (ttl) {
320
- await this.redis?.setex(key, ttl, value);
321
- } else {
322
- await this.redis?.set(key, value);
323
- }
324
- }
325
-
326
- public async del(key: string): Promise<void> {
327
- await this.redis?.del(key);
328
- }
329
- }
330
- ```
331
-
332
- ## Troubleshooting Examples
333
-
334
- ### Проблема: Сервис не создается
335
-
336
- ```bash
337
- $ 2byte g service Test
338
- Error: EACCES: permission denied
339
- ```
340
-
341
- **Решение:**
342
- ```bash
343
- # Проверьте права доступа
344
- ls -la workflow/services/
345
-
346
- # Создайте директорию вручную если нужно
347
- mkdir -p workflow/services
348
- chmod 755 workflow/services
349
- ```
350
-
351
- ### Проблема: Сервис создан но не загружается
352
-
353
- **Проверка:**
354
- ```bash
355
- # Запустите бота с debug
356
- DEBUG=* bun run index.ts
357
-
358
- # Проверьте структуру файла
359
- cat workflow/services/TestService.ts
360
- ```
361
-
362
- **Типичные ошибки:**
363
- - Файл не экспортирует класс как default
364
- - Класс не наследуется от ApiService
365
- - Синтаксическая ошибка в коде
366
-
367
- ## Performance Tests
368
-
369
- ### Тест загрузки множества сервисов
370
-
371
- ```bash
372
- # Создать 10 сервисов
373
- for i in {1..10}; do
374
- 2byte g service Service$i
375
- done
376
-
377
- # Запустить и проверить время загрузки
378
- time bun run index.ts
379
- ```
380
-
381
- **Ожидаемый результат:**
382
- - Все 10 сервисов загружены
383
- - Время загрузки < 1 секунды
384
- - Нет ошибок в логах
1
+ # Примеры использования Service Generator
2
+
3
+ ## Тестовые сценарии
4
+
5
+ ### Сценарий 1: Создание простого сервиса
6
+
7
+ ```bash
8
+ cd your-bot-directory
9
+ 2byte generate service Payment
10
+ ```
11
+
12
+ **Ожидаемый результат:**
13
+ - Создан файл `workflow/services/PaymentService.ts`
14
+ - Выведено: `✅ Created service PaymentService at workflow/services/PaymentService.ts`
15
+
16
+ ### Сценарий 2: Создание с полным именем
17
+
18
+ ```bash
19
+ 2byte g service NotificationService
20
+ ```
21
+
22
+ **Ожидаемый результат:**
23
+ - Создан файл `workflow/services/NotificationService.ts`
24
+ - Суффикс Service не дублируется
25
+
26
+ ### Сценарий 3: Попытка создать существующий сервис
27
+
28
+ ```bash
29
+ 2byte g service Payment # Второй раз
30
+ ```
31
+
32
+ **Ожидаемый результат:**
33
+ - Ошибка: `❌ Service PaymentService already exists`
34
+ - Файл не перезаписывается
35
+
36
+ ### Сценарий 4: Создание нескольких сервисов
37
+
38
+ ```bash
39
+ 2byte g service Cache
40
+ 2byte g service Logger
41
+ 2byte g service EmailSender
42
+ 2byte g service DatabaseConnector
43
+ ```
44
+
45
+ **Структура после создания:**
46
+ ```
47
+ workflow/
48
+ └── services/
49
+ ├── CacheService.ts
50
+ ├── LoggerService.ts
51
+ ├── EmailSenderService.ts
52
+ └── DatabaseConnectorService.ts
53
+ ```
54
+
55
+ ## Проверка работы созданного сервиса
56
+
57
+ ### 1. Создайте тестовый сервис
58
+
59
+ ```bash
60
+ 2byte g service Test
61
+ ```
62
+
63
+ ### 2. Измените сервис
64
+
65
+ Откройте `workflow/services/TestService.ts` и добавьте логику:
66
+
67
+ ```typescript
68
+ import { App } from "@2byte/tgbot-framework";
69
+ import { ApiService } from "@2byte/tgbot-framework";
70
+
71
+ export default class TestService extends ApiService {
72
+
73
+ constructor(
74
+ protected app: App,
75
+ public name: string = "TestService"
76
+ ) {
77
+ super(app, name);
78
+ }
79
+
80
+ public async setup(): Promise<void> {
81
+ this.app.debugLog(`[${this.name}] Setting up test service`);
82
+ return Promise.resolve();
83
+ }
84
+
85
+ public async unsetup(): Promise<void> {
86
+ this.app.debugLog(`[${this.name}] Cleaning up test service`);
87
+ return Promise.resolve();
88
+ }
89
+
90
+ public async run(): Promise<void> {
91
+ this.app.debugLog(`[${this.name}] Test service is running!`);
92
+
93
+ // Тестовая задача каждые 10 секунд
94
+ setInterval(() => {
95
+ this.app.debugLog(`[${this.name}] Heartbeat - ${new Date().toISOString()}`);
96
+ }, 10000);
97
+
98
+ return Promise.resolve();
99
+ }
100
+
101
+ // Кастомный метод для тестирования
102
+ public getStatus(): string {
103
+ return `TestService is active at ${new Date().toISOString()}`;
104
+ }
105
+ }
106
+ ```
107
+
108
+ ### 3. Запустите бота
109
+
110
+ ```bash
111
+ bun run index.ts
112
+ ```
113
+
114
+ **Ожидаемые логи:**
115
+ ```
116
+ [App] Registered API services: [ 'TestService', ... ]
117
+ [TestService] Setting up test service
118
+ [TestService] Service setup completed
119
+ [TestService] Test service is running!
120
+ [TestService] Heartbeat - 2025-10-29T...
121
+ [TestService] Heartbeat - 2025-10-29T...
122
+ ```
123
+
124
+ ### 4. Используйте сервис в секции
125
+
126
+ Создайте или откройте секцию:
127
+
128
+ ```typescript
129
+ import { Section } from "@2byte/tgbot-framework";
130
+
131
+ export default class HomeSection extends Section {
132
+ async index() {
133
+ // Получаем наш тестовый сервис
134
+ const testService = this.app.getService('TestService');
135
+
136
+ if (testService) {
137
+ const status = testService.getStatus();
138
+
139
+ await this.message(`🤖 Bot Status\n\n${status}`)
140
+ .send();
141
+ }
142
+ }
143
+ }
144
+ ```
145
+
146
+ ## Интеграционные тесты
147
+
148
+ ### Test 1: Автозагрузка сервиса
149
+
150
+ ```bash
151
+ # Создать сервис
152
+ 2byte g service AutoLoad
153
+
154
+ # Запустить бота
155
+ bun run index.ts
156
+
157
+ # Проверить логи
158
+ # Должно быть: [App] Registered API services: [ 'AutoLoadService', ... ]
159
+ ```
160
+
161
+ ### Test 2: Использование в секциях
162
+
163
+ ```typescript
164
+ // В любой секции
165
+ const service = this.app.getService('AutoLoadService');
166
+ console.log('Service loaded:', service ? 'YES' : 'NO');
167
+ ```
168
+
169
+ ### Test 3: Жизненный цикл
170
+
171
+ ```bash
172
+ # Запустить бота
173
+ bun run index.ts
174
+ # Лог: [ServiceName] Service setup completed
175
+
176
+ # Остановить бота (Ctrl+C)
177
+ # Лог: [ServiceName] Service cleanup completed
178
+ ```
179
+
180
+ ## Примеры реальных сервисов
181
+
182
+ ### Email Service
183
+
184
+ ```bash
185
+ 2byte g service Email
186
+ ```
187
+
188
+ ```typescript
189
+ // workflow/services/EmailService.ts
190
+ import { App, ApiService } from "@2byte/tgbot-framework";
191
+ import nodemailer from 'nodemailer';
192
+
193
+ export default class EmailService extends ApiService {
194
+ private transporter: any;
195
+
196
+ constructor(protected app: App, public name: string = "EmailService") {
197
+ super(app, name);
198
+ }
199
+
200
+ public async setup(): Promise<void> {
201
+ this.transporter = nodemailer.createTransport({
202
+ host: process.env.SMTP_HOST,
203
+ port: parseInt(process.env.SMTP_PORT || '587'),
204
+ auth: {
205
+ user: process.env.SMTP_USER,
206
+ pass: process.env.SMTP_PASS
207
+ }
208
+ });
209
+
210
+ this.app.debugLog(`[${this.name}] Email service ready`);
211
+ }
212
+
213
+ public async sendEmail(to: string, subject: string, text: string) {
214
+ const info = await this.transporter.sendMail({
215
+ from: process.env.EMAIL_FROM,
216
+ to,
217
+ subject,
218
+ text
219
+ });
220
+
221
+ this.app.debugLog(`[${this.name}] Email sent: ${info.messageId}`);
222
+ return info;
223
+ }
224
+ }
225
+ ```
226
+
227
+ ### Database Service
228
+
229
+ ```bash
230
+ 2byte g service Database
231
+ ```
232
+
233
+ ```typescript
234
+ // workflow/services/DatabaseService.ts
235
+ import { App, ApiService } from "@2byte/tgbot-framework";
236
+ import { Database } from 'sqlite3';
237
+
238
+ export default class DatabaseService extends ApiService {
239
+ private db: Database | null = null;
240
+
241
+ constructor(protected app: App, public name: string = "DatabaseService") {
242
+ super(app, name);
243
+ }
244
+
245
+ public async setup(): Promise<void> {
246
+ return new Promise((resolve, reject) => {
247
+ this.db = new Database('./database.db', (err) => {
248
+ if (err) {
249
+ this.app.debugLog(`[${this.name}] DB connection failed`, err);
250
+ reject(err);
251
+ } else {
252
+ this.app.debugLog(`[${this.name}] DB connected`);
253
+ resolve();
254
+ }
255
+ });
256
+ });
257
+ }
258
+
259
+ public async unsetup(): Promise<void> {
260
+ return new Promise((resolve) => {
261
+ this.db?.close(() => {
262
+ this.app.debugLog(`[${this.name}] DB connection closed`);
263
+ resolve();
264
+ });
265
+ });
266
+ }
267
+
268
+ public async query(sql: string, params: any[] = []): Promise<any> {
269
+ return new Promise((resolve, reject) => {
270
+ this.db?.all(sql, params, (err, rows) => {
271
+ if (err) reject(err);
272
+ else resolve(rows);
273
+ });
274
+ });
275
+ }
276
+ }
277
+ ```
278
+
279
+ ### Redis Cache Service
280
+
281
+ ```bash
282
+ 2byte g service RedisCache
283
+ ```
284
+
285
+ ```typescript
286
+ // workflow/services/RedisCacheService.ts
287
+ import { App, ApiService } from "@2byte/tgbot-framework";
288
+ import Redis from 'ioredis';
289
+
290
+ export default class RedisCacheService extends ApiService {
291
+ private redis: Redis | null = null;
292
+
293
+ constructor(protected app: App, public name: string = "RedisCacheService") {
294
+ super(app, name);
295
+ }
296
+
297
+ public async setup(): Promise<void> {
298
+ this.redis = new Redis({
299
+ host: process.env.REDIS_HOST || 'localhost',
300
+ port: parseInt(process.env.REDIS_PORT || '6379'),
301
+ password: process.env.REDIS_PASSWORD
302
+ });
303
+
304
+ this.redis.on('connect', () => {
305
+ this.app.debugLog(`[${this.name}] Redis connected`);
306
+ });
307
+ }
308
+
309
+ public async unsetup(): Promise<void> {
310
+ await this.redis?.quit();
311
+ this.app.debugLog(`[${this.name}] Redis disconnected`);
312
+ }
313
+
314
+ public async get(key: string): Promise<string | null> {
315
+ return this.redis?.get(key) || null;
316
+ }
317
+
318
+ public async set(key: string, value: string, ttl?: number): Promise<void> {
319
+ if (ttl) {
320
+ await this.redis?.setex(key, ttl, value);
321
+ } else {
322
+ await this.redis?.set(key, value);
323
+ }
324
+ }
325
+
326
+ public async del(key: string): Promise<void> {
327
+ await this.redis?.del(key);
328
+ }
329
+ }
330
+ ```
331
+
332
+ ## Troubleshooting Examples
333
+
334
+ ### Проблема: Сервис не создается
335
+
336
+ ```bash
337
+ $ 2byte g service Test
338
+ Error: EACCES: permission denied
339
+ ```
340
+
341
+ **Решение:**
342
+ ```bash
343
+ # Проверьте права доступа
344
+ ls -la workflow/services/
345
+
346
+ # Создайте директорию вручную если нужно
347
+ mkdir -p workflow/services
348
+ chmod 755 workflow/services
349
+ ```
350
+
351
+ ### Проблема: Сервис создан но не загружается
352
+
353
+ **Проверка:**
354
+ ```bash
355
+ # Запустите бота с debug
356
+ DEBUG=* bun run index.ts
357
+
358
+ # Проверьте структуру файла
359
+ cat workflow/services/TestService.ts
360
+ ```
361
+
362
+ **Типичные ошибки:**
363
+ - Файл не экспортирует класс как default
364
+ - Класс не наследуется от ApiService
365
+ - Синтаксическая ошибка в коде
366
+
367
+ ## Performance Tests
368
+
369
+ ### Тест загрузки множества сервисов
370
+
371
+ ```bash
372
+ # Создать 10 сервисов
373
+ for i in {1..10}; do
374
+ 2byte g service Service$i
375
+ done
376
+
377
+ # Запустить и проверить время загрузки
378
+ time bun run index.ts
379
+ ```
380
+
381
+ **Ожидаемый результат:**
382
+ - Все 10 сервисов загружены
383
+ - Время загрузки < 1 секунды
384
+ - Нет ошибок в логах