From 2b979d554819aa45680bca419812cab937ecf226 Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:50:48 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20migrate=20all?= =?UTF-8?q?=20remaining=20bots=20to=20shared=20services?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Completed migration of all Matrix bots to @manacore/bot-services: **SessionService (11 bots migrated):** - matrix-chat-bot (with conversation/model mapping via setSessionData) - matrix-contacts-bot - matrix-skilltree-bot - matrix-presi-bot - matrix-questions-bot - matrix-storage-bot - matrix-planta-bot - matrix-manadeck-bot - matrix-nutriphi-bot (with pendingImage via setSessionData) - matrix-picture-bot (previous commit) - matrix-zitare-bot (previous commit) **TranscriptionService (5 bots migrated):** - matrix-todo-bot (previous commit) - matrix-clock-bot (previous commit) - matrix-zitare-bot (previous commit) - matrix-nutriphi-bot - matrix-project-doc-bot **Code Reduction:** - Deleted 22 local module files (session + transcription) - ~1100 lines of duplicate code removed total - All bots now share identical auth and STT logic **Special handling:** - matrix-chat-bot: Extended methods converted to setSessionData/getSessionData - matrix-nutriphi-bot: pendingImage state via setSessionData - matrix-project-doc-bot: TranscriptionService used by MediaService Co-Authored-By: Claude Opus 4.5 --- docs/MATRIX_BOT_ARCHITECTURE.md | 10 +- packages/bot-services/CLAUDE.md | 17 +- pnpm-lock.yaml | 708 +++++++++++++----- services/matrix-chat-bot/package.json | 1 + .../matrix-chat-bot/src/bot/bot.module.ts | 4 +- .../matrix-chat-bot/src/bot/matrix.service.ts | 93 ++- .../src/session/session.module.ts | 8 - .../src/session/session.service.ts | 142 ---- services/matrix-contacts-bot/package.json | 1 + .../matrix-contacts-bot/src/bot/bot.module.ts | 4 +- .../src/bot/matrix.service.ts | 2 +- .../src/session/session.module.ts | 8 - .../src/session/session.service.ts | 90 --- services/matrix-manadeck-bot/package.json | 1 + .../matrix-manadeck-bot/src/app.module.ts | 2 - .../matrix-manadeck-bot/src/bot/bot.module.ts | 4 +- .../src/bot/matrix.service.ts | 2 +- .../src/session/session.module.ts | 8 - .../src/session/session.service.ts | 90 --- services/matrix-nutriphi-bot/package.json | 1 + .../matrix-nutriphi-bot/src/bot/bot.module.ts | 5 +- .../src/bot/matrix.service.ts | 21 +- .../src/session/session.module.ts | 8 - .../src/session/session.service.ts | 152 ---- .../src/transcription/transcription.module.ts | 8 - .../transcription/transcription.service.ts | 54 -- services/matrix-planta-bot/package.json | 1 + services/matrix-planta-bot/src/app.module.ts | 2 - .../matrix-planta-bot/src/bot/bot.module.ts | 4 +- .../src/bot/matrix.service.ts | 2 +- .../src/session/session.module.ts | 8 - .../src/session/session.service.ts | 90 --- services/matrix-presi-bot/package.json | 1 + services/matrix-presi-bot/src/app.module.ts | 2 - .../matrix-presi-bot/src/bot/bot.module.ts | 4 +- .../src/bot/matrix.service.ts | 2 +- .../src/session/session.module.ts | 8 - .../src/session/session.service.ts | 86 --- services/matrix-project-doc-bot/package.json | 1 + .../src/media/media.module.ts | 4 +- .../src/media/media.service.ts | 2 +- .../src/transcription/transcription.module.ts | 8 - .../transcription/transcription.service.ts | 47 -- services/matrix-questions-bot/package.json | 1 + .../matrix-questions-bot/src/app.module.ts | 2 - .../src/bot/bot.module.ts | 4 +- .../src/bot/matrix.service.ts | 2 +- .../src/session/session.module.ts | 8 - .../src/session/session.service.ts | 90 --- services/matrix-skilltree-bot/package.json | 1 + .../matrix-skilltree-bot/src/app.module.ts | 2 - .../src/bot/bot.module.ts | 4 +- .../src/bot/matrix.service.ts | 2 +- .../src/session/session.module.ts | 8 - .../src/session/session.service.ts | 86 --- services/matrix-storage-bot/package.json | 1 + services/matrix-storage-bot/src/app.module.ts | 2 - .../matrix-storage-bot/src/bot/bot.module.ts | 4 +- .../src/bot/matrix.service.ts | 2 +- .../src/session/session.module.ts | 8 - .../src/session/session.service.ts | 90 --- 61 files changed, 640 insertions(+), 1393 deletions(-) delete mode 100644 services/matrix-chat-bot/src/session/session.module.ts delete mode 100644 services/matrix-chat-bot/src/session/session.service.ts delete mode 100644 services/matrix-contacts-bot/src/session/session.module.ts delete mode 100644 services/matrix-contacts-bot/src/session/session.service.ts delete mode 100644 services/matrix-manadeck-bot/src/session/session.module.ts delete mode 100644 services/matrix-manadeck-bot/src/session/session.service.ts delete mode 100644 services/matrix-nutriphi-bot/src/session/session.module.ts delete mode 100644 services/matrix-nutriphi-bot/src/session/session.service.ts delete mode 100644 services/matrix-nutriphi-bot/src/transcription/transcription.module.ts delete mode 100644 services/matrix-nutriphi-bot/src/transcription/transcription.service.ts delete mode 100644 services/matrix-planta-bot/src/session/session.module.ts delete mode 100644 services/matrix-planta-bot/src/session/session.service.ts delete mode 100644 services/matrix-presi-bot/src/session/session.module.ts delete mode 100644 services/matrix-presi-bot/src/session/session.service.ts delete mode 100644 services/matrix-project-doc-bot/src/transcription/transcription.module.ts delete mode 100644 services/matrix-project-doc-bot/src/transcription/transcription.service.ts delete mode 100644 services/matrix-questions-bot/src/session/session.module.ts delete mode 100644 services/matrix-questions-bot/src/session/session.service.ts delete mode 100644 services/matrix-skilltree-bot/src/session/session.module.ts delete mode 100644 services/matrix-skilltree-bot/src/session/session.service.ts delete mode 100644 services/matrix-storage-bot/src/session/session.module.ts delete mode 100644 services/matrix-storage-bot/src/session/session.service.ts diff --git a/docs/MATRIX_BOT_ARCHITECTURE.md b/docs/MATRIX_BOT_ARCHITECTURE.md index f0327fd0e..b8f0f4c81 100644 --- a/docs/MATRIX_BOT_ARCHITECTURE.md +++ b/docs/MATRIX_BOT_ARCHITECTURE.md @@ -204,10 +204,12 @@ export { parseGermanDateKeyword } from './shared/date-parser'; Die folgenden Services wurden aus den einzelnen Bots konsolidiert: -| Service | Vorher | Nachher | Bots | -|---------|--------|---------|------| -| `SessionService` | 11x dupliziert | 1x in bot-services | picture, contacts, chat, zitare, ... | -| `TranscriptionService` | 6x dupliziert | 1x in bot-services | todo, clock, zitare, nutriphi, ... | +| Service | Vorher | Nachher | Migrierte Bots | +|---------|--------|---------|----------------| +| `SessionService` | 11x dupliziert | 1x in bot-services | picture, contacts, chat, zitare, skilltree, presi, questions, storage, planta, manadeck, nutriphi | +| `TranscriptionService` | 6x dupliziert | 1x in bot-services | todo, clock, zitare, nutriphi, project-doc | + +**Status: Vollständig migriert** - Alle 11 Bots mit SessionService und alle 5 Bots mit TranscriptionService nutzen jetzt die gemeinsamen Services aus `@manacore/bot-services`. ### 3.2 TodoService diff --git a/packages/bot-services/CLAUDE.md b/packages/bot-services/CLAUDE.md index 6ac473294..ea18337c1 100644 --- a/packages/bot-services/CLAUDE.md +++ b/packages/bot-services/CLAUDE.md @@ -309,8 +309,15 @@ rm -rf src/transcription/ | matrix-picture-bot | ✅ | - | | matrix-clock-bot | - | ✅ | | matrix-zitare-bot | ✅ | ✅ | -| matrix-chat-bot | TODO | - | -| matrix-contacts-bot | TODO | - | -| matrix-nutriphi-bot | TODO | TODO | -| matrix-project-doc-bot | - | TODO | -| ... | ... | ... | +| matrix-chat-bot | ✅ | - | +| matrix-contacts-bot | ✅ | - | +| matrix-nutriphi-bot | ✅ | ✅ | +| matrix-project-doc-bot | - | ✅ | +| matrix-skilltree-bot | ✅ | - | +| matrix-presi-bot | ✅ | - | +| matrix-questions-bot | ✅ | - | +| matrix-storage-bot | ✅ | - | +| matrix-planta-bot | ✅ | - | +| matrix-manadeck-bot | ✅ | - | + +**All bots with SessionService and TranscriptionService have been migrated.** diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bfff99bbc..4dac649d6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -137,7 +137,7 @@ importers: devDependencies: '@nestjs/cli': specifier: ^10.4.9 - version: 10.4.9 + version: 10.4.9(esbuild@0.19.12) '@nestjs/schematics': specifier: ^10.2.3 version: 10.2.3(chokidar@3.6.0)(typescript@5.9.3) @@ -185,10 +185,10 @@ importers: version: 0.5.21 ts-jest: specifier: ^29.2.5 - version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) ts-loader: specifier: ^9.5.1 - version: 9.5.4(typescript@5.9.3)(webpack@5.100.2) + version: 9.5.4(typescript@5.9.3)(webpack@5.97.1(esbuild@0.19.12)) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3) @@ -212,14 +212,14 @@ importers: version: link:../../../../packages/shared-landing-ui astro: specifier: ^5.16.0 - version: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) + version: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) typescript: specifier: ^5.9.2 version: 5.9.3 devDependencies: '@astrojs/tailwind': specifier: ^6.0.2 - version: 6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3)) + version: 6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3)) '@tailwindcss/typography': specifier: ^0.5.18 version: 0.5.19(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1)) @@ -228,13 +228,13 @@ importers: version: 20.19.25 eslint: specifier: ^9.0.0 - version: 9.39.1(jiti@2.6.1) + version: 9.39.1(jiti@1.21.7) eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.2(eslint@9.39.1(jiti@2.6.1)) + version: 9.1.2(eslint@9.39.1(jiti@1.21.7)) eslint-plugin-astro: specifier: ^1.0.0 - version: 1.5.0(eslint@9.39.1(jiti@2.6.1)) + version: 1.5.0(eslint@9.39.1(jiti@1.21.7)) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -609,19 +609,19 @@ importers: version: 18.3.27 '@typescript-eslint/eslint-plugin': specifier: ^7.7.0 - version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) '@typescript-eslint/parser': specifier: ^7.7.0 - version: 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) + version: 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) dotenv: specifier: ^16.4.7 version: 16.6.1 eslint: specifier: ^9.39.1 - version: 9.39.1(jiti@1.21.7) + version: 9.39.1(jiti@2.6.1) eslint-config-universe: specifier: ^12.0.1 - version: 12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2)(typescript@5.3.3) + version: 12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2)(typescript@5.3.3) prettier: specifier: ^3.2.5 version: 3.6.2 @@ -2333,7 +2333,7 @@ importers: version: 0.5.21 ts-jest: specifier: ^29.2.5 - version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) ts-loader: specifier: ^9.5.1 version: 9.5.4(typescript@5.9.3)(webpack@5.100.2) @@ -5208,7 +5208,7 @@ importers: version: 1.57.0 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)) + version: 29.7.0(@types/node@24.10.1) vitest: specifier: ^3.0.0 version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.2.0)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1) @@ -5340,7 +5340,7 @@ importers: version: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)) ts-jest: specifier: ^29.2.5 - version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3) @@ -5500,7 +5500,7 @@ importers: version: 7.1.4 ts-jest: specifier: ^29.2.5 - version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) ts-loader: specifier: ^9.5.1 version: 9.5.4(typescript@5.9.3)(webpack@5.100.2) @@ -5612,7 +5612,7 @@ importers: version: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)) ts-jest: specifier: ^29.2.5 - version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3) @@ -5712,7 +5712,7 @@ importers: version: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)) ts-jest: specifier: ^29.2.5 - version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3) @@ -5785,7 +5785,7 @@ importers: version: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)) ts-jest: specifier: ^29.2.5 - version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3) @@ -5832,6 +5832,9 @@ importers: services/matrix-chat-bot: dependencies: + '@manacore/bot-services': + specifier: workspace:* + version: link:../../packages/bot-services '@nestjs/common': specifier: ^10.4.15 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -5903,6 +5906,9 @@ importers: services/matrix-contacts-bot: dependencies: + '@manacore/bot-services': + specifier: workspace:* + version: link:../../packages/bot-services '@nestjs/common': specifier: ^10.4.15 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -5974,6 +5980,9 @@ importers: services/matrix-manadeck-bot: dependencies: + '@manacore/bot-services': + specifier: workspace:* + version: link:../../packages/bot-services '@nestjs/common': specifier: ^10.4.15 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -6008,6 +6017,9 @@ importers: services/matrix-nutriphi-bot: dependencies: + '@manacore/bot-services': + specifier: workspace:* + version: link:../../packages/bot-services '@nestjs/common': specifier: ^10.4.15 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -6119,6 +6131,9 @@ importers: services/matrix-planta-bot: dependencies: + '@manacore/bot-services': + specifier: workspace:* + version: link:../../packages/bot-services '@nestjs/common': specifier: ^10.4.15 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -6153,6 +6168,9 @@ importers: services/matrix-presi-bot: dependencies: + '@manacore/bot-services': + specifier: workspace:* + version: link:../../packages/bot-services '@nestjs/common': specifier: ^10.4.15 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -6193,6 +6211,9 @@ importers: '@aws-sdk/s3-request-presigner': specifier: ^3.721.0 version: 3.940.0 + '@manacore/bot-services': + specifier: workspace:* + version: link:../../packages/bot-services '@nestjs/common': specifier: ^10.4.15 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -6245,6 +6266,9 @@ importers: services/matrix-questions-bot: dependencies: + '@manacore/bot-services': + specifier: workspace:* + version: link:../../packages/bot-services '@nestjs/common': specifier: ^10.4.15 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -6279,6 +6303,9 @@ importers: services/matrix-skilltree-bot: dependencies: + '@manacore/bot-services': + specifier: workspace:* + version: link:../../packages/bot-services '@nestjs/common': specifier: ^10.4.15 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -6359,6 +6386,9 @@ importers: services/matrix-storage-bot: dependencies: + '@manacore/bot-services': + specifier: workspace:* + version: link:../../packages/bot-services '@nestjs/common': specifier: ^10.4.15 version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -8861,7 +8891,7 @@ packages: '@expo/bunyan@4.0.1': resolution: {integrity: sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==} - engines: {node: '>=0.10.0'} + engines: {'0': node >=0.10.0} '@expo/cli@0.22.26': resolution: {integrity: sha512-I689wc8Fn/AX7aUGiwrh3HnssiORMJtR2fpksX+JIe8Cj/EDleblYMSwRPd0025wrwOV9UN1KM/RuEt/QjCS3Q==} @@ -23311,6 +23341,16 @@ snapshots: transitivePeerDependencies: - ts-node + '@astrojs/tailwind@6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))': + dependencies: + astro: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) + autoprefixer: 10.4.22(postcss@8.5.6) + postcss: 8.5.6 + postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3)) + tailwindcss: 3.4.18(tsx@4.20.6)(yaml@2.8.1) + transitivePeerDependencies: + - ts-node + '@astrojs/tailwind@6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))': dependencies: astro: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) @@ -26380,7 +26420,7 @@ snapshots: wrap-ansi: 7.0.0 ws: 8.18.3 optionalDependencies: - expo-router: 6.0.15(vmxlpuhz6xqbe2ee7fdabyqx3y) + expo-router: 6.0.15(7mqaurqidri6vkknnsci36yp4e) react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0) transitivePeerDependencies: - '@modelcontextprotocol/sdk' @@ -27688,7 +27728,7 @@ snapshots: jest-util: 30.2.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))': + '@jest/core@29.7.0': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -27702,7 +27742,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)) + jest-config: 29.7.0(@types/node@22.19.1) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -27723,7 +27763,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3))': + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -27737,7 +27777,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)) + jest-config: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -28276,6 +28316,32 @@ snapshots: - uglify-js - webpack-cli + '@nestjs/cli@10.4.9(esbuild@0.19.12)': + dependencies: + '@angular-devkit/core': 17.3.11(chokidar@3.6.0) + '@angular-devkit/schematics': 17.3.11(chokidar@3.6.0) + '@angular-devkit/schematics-cli': 17.3.11(chokidar@3.6.0) + '@nestjs/schematics': 10.2.3(chokidar@3.6.0)(typescript@5.7.2) + chalk: 4.1.2 + chokidar: 3.6.0 + cli-table3: 0.6.5 + commander: 4.1.1 + fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.19.12)) + glob: 10.4.5 + inquirer: 8.2.6 + node-emoji: 1.11.0 + ora: 5.4.1 + tree-kill: 1.2.2 + tsconfig-paths: 4.2.0 + tsconfig-paths-webpack-plugin: 4.2.0 + typescript: 5.7.2 + webpack: 5.97.1(esbuild@0.19.12) + webpack-node-externals: 3.0.0 + transitivePeerDependencies: + - esbuild + - uglify-js + - webpack-cli + '@nestjs/cli@10.4.9(esbuild@0.27.0)': dependencies: '@angular-devkit/core': 17.3.11(chokidar@3.6.0) @@ -31871,6 +31937,19 @@ snapshots: picocolors: 1.1.1 pretty-format: 27.5.1 + '@testing-library/react-native@13.3.3(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react-test-renderer@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + jest-matcher-utils: 30.2.0 + picocolors: 1.1.1 + pretty-format: 30.2.0 + react: 19.1.0 + react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0) + react-test-renderer: 19.1.0(react@19.1.0) + redent: 3.0.0 + optionalDependencies: + jest: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)) + optional: true + '@testing-library/react-native@13.3.3(jest@30.2.0(@types/node@20.19.25)(esbuild-register@3.6.0(esbuild@0.27.0)))(react-native@0.81.4(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react-test-renderer@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: jest-matcher-utils: 30.2.0 @@ -32441,16 +32520,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)': + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) - '@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) + '@typescript-eslint/type-utils': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.4.3 - eslint: 9.39.1(jiti@1.21.7) + eslint: 9.39.1(jiti@2.6.1) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -32499,15 +32578,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) + '@typescript-eslint/parser': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) - '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) + '@typescript-eslint/type-utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) + '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) '@typescript-eslint/visitor-keys': 7.18.0 - eslint: 9.39.1(jiti@1.21.7) + eslint: 9.39.1(jiti@2.6.1) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -32599,14 +32678,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)': + '@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.4.3 - eslint: 9.39.1(jiti@1.21.7) + eslint: 9.39.1(jiti@2.6.1) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: @@ -32638,14 +32717,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)': + '@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 7.18.0 debug: 4.4.3 - eslint: 9.39.1(jiti@1.21.7) + eslint: 9.39.1(jiti@2.6.1) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: @@ -32771,12 +32850,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)': + '@typescript-eslint/type-utils@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)': dependencies: '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) - '@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) debug: 4.4.3 - eslint: 9.39.1(jiti@1.21.7) + eslint: 9.39.1(jiti@2.6.1) ts-api-utils: 1.4.3(typescript@5.3.3) optionalDependencies: typescript: 5.3.3 @@ -32807,12 +32886,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)': + '@typescript-eslint/type-utils@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)': dependencies: '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3) - '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) + '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) debug: 4.4.3 - eslint: 9.39.1(jiti@1.21.7) + eslint: 9.39.1(jiti@2.6.1) ts-api-utils: 1.4.3(typescript@5.3.3) optionalDependencies: typescript: 5.3.3 @@ -32994,15 +33073,15 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)': + '@typescript-eslint/utils@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) '@types/json-schema': 7.0.15 '@types/semver': 7.7.1 '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) - eslint: 9.39.1(jiti@1.21.7) + eslint: 9.39.1(jiti@2.6.1) semver: 7.7.3 transitivePeerDependencies: - supports-color @@ -33033,13 +33112,13 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)': + '@typescript-eslint/utils@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3) - eslint: 9.39.1(jiti@1.21.7) + eslint: 9.39.1(jiti@2.6.1) transitivePeerDependencies: - supports-color - typescript @@ -33938,6 +34017,108 @@ snapshots: transitivePeerDependencies: - supports-color + astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): + dependencies: + '@astrojs/compiler': 2.13.0 + '@astrojs/internal-helpers': 0.7.5 + '@astrojs/markdown-remark': 6.3.9 + '@astrojs/telemetry': 3.3.0 + '@capsizecss/unpack': 3.0.1 + '@oslojs/encoding': 1.1.0 + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + acorn: 8.15.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + boxen: 8.0.1 + ci-info: 4.3.1 + clsx: 2.1.1 + common-ancestor-path: 1.0.1 + cookie: 1.1.0 + cssesc: 3.0.0 + debug: 4.4.3 + deterministic-object-hash: 2.0.2 + devalue: 5.5.0 + diff: 5.2.0 + dlv: 1.1.3 + dset: 3.1.4 + es-module-lexer: 1.7.0 + esbuild: 0.25.12 + estree-walker: 3.0.3 + flattie: 1.1.1 + fontace: 0.3.1 + github-slugger: 2.0.0 + html-escaper: 3.0.3 + http-cache-semantics: 4.2.0 + import-meta-resolve: 4.2.0 + js-yaml: 4.1.1 + magic-string: 0.30.21 + magicast: 0.5.1 + mrmime: 2.0.1 + neotraverse: 0.6.18 + p-limit: 6.2.0 + p-queue: 8.1.1 + package-manager-detector: 1.5.0 + piccolore: 0.1.3 + picomatch: 4.0.3 + prompts: 2.4.2 + rehype: 13.0.2 + semver: 7.7.3 + shiki: 3.15.0 + smol-toml: 1.5.2 + svgo: 4.0.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tsconfck: 3.1.6(typescript@5.9.3) + ultrahtml: 1.6.0 + unifont: 0.6.0 + unist-util-visit: 5.0.0 + unstorage: 1.17.3(@netlify/blobs@10.4.1)(ioredis@5.9.2) + vfile: 6.0.3 + vite: 6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1) + vitefu: 1.1.1(vite@6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)) + xxhash-wasm: 1.1.0 + yargs-parser: 21.1.1 + yocto-spinner: 0.2.3 + zod: 3.25.76 + zod-to-json-schema: 3.25.0(zod@3.25.76) + zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76) + optionalDependencies: + sharp: 0.34.5 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@types/node' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - idb-keyval + - ioredis + - jiti + - less + - lightningcss + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - uploadthing + - yaml + astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): dependencies: '@astrojs/compiler': 2.13.0 @@ -35224,13 +35405,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)): + create-jest@29.7.0(@types/node@24.10.1): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)) + jest-config: 29.7.0(@types/node@24.10.1) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -36334,6 +36515,11 @@ snapshots: escape-string-regexp@5.0.0: {} + eslint-compat-utils@0.6.5(eslint@9.39.1(jiti@1.21.7)): + dependencies: + eslint: 9.39.1(jiti@1.21.7) + semver: 7.7.3 + eslint-compat-utils@0.6.5(eslint@9.39.1(jiti@2.6.1)): dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -36344,9 +36530,9 @@ snapshots: '@typescript-eslint/eslint-plugin': 8.48.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.1(jiti@2.6.1) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-expo: 1.0.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-react-hooks: 5.2.0(eslint@9.39.1(jiti@2.6.1)) globals: 16.5.0 @@ -36361,9 +36547,9 @@ snapshots: '@typescript-eslint/eslint-plugin': 8.48.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3) '@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3) eslint: 9.39.1(jiti@2.6.1) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-expo: 0.1.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-react-hooks: 5.2.0(eslint@9.39.1(jiti@2.6.1)) globals: 16.5.0 @@ -36381,14 +36567,14 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@1.21.7)): - dependencies: - eslint: 9.39.1(jiti@1.21.7) - eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@2.6.1)): dependencies: eslint: 9.39.1(jiti@2.6.1) + eslint-config-prettier@9.1.2(eslint@9.39.1(jiti@1.21.7)): + dependencies: + eslint: 9.39.1(jiti@1.21.7) + eslint-config-prettier@9.1.2(eslint@9.39.1(jiti@2.6.1)): dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -36413,17 +36599,17 @@ snapshots: - supports-color - typescript - eslint-config-universe@12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2)(typescript@5.3.3): + eslint-config-universe@12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2)(typescript@5.3.3): dependencies: - '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) - '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) - eslint: 9.39.1(jiti@1.21.7) - eslint-config-prettier: 8.10.2(eslint@9.39.1(jiti@1.21.7)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7)) - eslint-plugin-node: 11.1.0(eslint@9.39.1(jiti@1.21.7)) - eslint-plugin-prettier: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@1.21.7)))(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2) - eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@1.21.7)) - eslint-plugin-react-hooks: 4.6.2(eslint@9.39.1(jiti@1.21.7)) + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) + eslint: 9.39.1(jiti@2.6.1) + eslint-config-prettier: 8.10.2(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-node: 11.1.0(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-prettier: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2) + eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-react-hooks: 4.6.2(eslint@9.39.1(jiti@2.6.1)) optionalDependencies: prettier: 3.6.2 transitivePeerDependencies: @@ -36461,7 +36647,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 @@ -36472,7 +36658,22 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)) + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3 + eslint: 9.39.1(jiti@2.6.1) + get-tsconfig: 4.13.0 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.15 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -36486,12 +36687,12 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@1.21.7)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) - eslint: 9.39.1(jiti@1.21.7) + '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) + eslint: 9.39.1(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color @@ -36506,25 +36707,39 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3) eslint: 9.39.1(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.1(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)) + transitivePeerDependencies: + - supports-color + + eslint-plugin-astro@1.5.0(eslint@9.39.1(jiti@1.21.7)): + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7)) + '@jridgewell/sourcemap-codec': 1.5.5 + '@typescript-eslint/types': 8.48.0 + astro-eslint-parser: 1.2.2 + eslint: 9.39.1(jiti@1.21.7) + eslint-compat-utils: 0.6.5(eslint@9.39.1(jiti@1.21.7)) + globals: 16.5.0 + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 transitivePeerDependencies: - supports-color @@ -36548,12 +36763,6 @@ snapshots: eslint-utils: 2.1.0 regexpp: 3.2.0 - eslint-plugin-es@3.0.1(eslint@9.39.1(jiti@1.21.7)): - dependencies: - eslint: 9.39.1(jiti@1.21.7) - eslint-utils: 2.1.0 - regexpp: 3.2.0 - eslint-plugin-es@3.0.1(eslint@9.39.1(jiti@2.6.1)): dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -36607,7 +36816,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -36616,9 +36825,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.39.1(jiti@1.21.7) + eslint: 9.39.1(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@1.21.7)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -36630,7 +36839,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -36665,7 +36874,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -36676,7 +36885,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.1(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -36694,7 +36903,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -36705,7 +36914,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.1(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -36733,16 +36942,6 @@ snapshots: resolve: 1.22.11 semver: 6.3.1 - eslint-plugin-node@11.1.0(eslint@9.39.1(jiti@1.21.7)): - dependencies: - eslint: 9.39.1(jiti@1.21.7) - eslint-plugin-es: 3.0.1(eslint@9.39.1(jiti@1.21.7)) - eslint-utils: 2.1.0 - ignore: 5.3.2 - minimatch: 3.1.2 - resolve: 1.22.11 - semver: 6.3.1 - eslint-plugin-node@11.1.0(eslint@9.39.1(jiti@2.6.1)): dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -36773,16 +36972,6 @@ snapshots: '@types/eslint': 9.6.1 eslint-config-prettier: 8.10.2(eslint@8.57.1) - eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@1.21.7)))(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2): - dependencies: - eslint: 9.39.1(jiti@1.21.7) - prettier: 3.6.2 - prettier-linter-helpers: 1.0.0 - synckit: 0.11.11 - optionalDependencies: - '@types/eslint': 9.6.1 - eslint-config-prettier: 8.10.2(eslint@9.39.1(jiti@1.21.7)) - eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2): dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -36807,10 +36996,6 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-react-hooks@4.6.2(eslint@9.39.1(jiti@1.21.7)): - dependencies: - eslint: 9.39.1(jiti@1.21.7) - eslint-plugin-react-hooks@4.6.2(eslint@9.39.1(jiti@2.6.1)): dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -36841,28 +37026,6 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-react@7.37.5(eslint@9.39.1(jiti@1.21.7)): - dependencies: - array-includes: 3.1.9 - array.prototype.findlast: 1.2.5 - array.prototype.flatmap: 1.3.3 - array.prototype.tosorted: 1.1.4 - doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 - eslint: 9.39.1(jiti@1.21.7) - estraverse: 5.3.0 - hasown: 2.0.2 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.9 - object.fromentries: 2.0.8 - object.values: 1.2.1 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 - string.prototype.matchall: 4.0.12 - string.prototype.repeat: 1.0.0 - eslint-plugin-react@7.37.5(eslint@9.39.1(jiti@2.6.1)): dependencies: array-includes: 3.1.9 @@ -38005,6 +38168,53 @@ snapshots: - react-native - supports-color + expo-router@6.0.15(7mqaurqidri6vkknnsci36yp4e): + dependencies: + '@expo/metro-runtime': 6.1.2(expo@54.0.25)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + '@expo/schema-utils': 0.1.7 + '@radix-ui/react-slot': 1.2.0(@types/react@19.2.7)(react@19.1.0) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@react-navigation/bottom-tabs': 7.8.6(@react-navigation/native@7.1.21(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + '@react-navigation/native': 7.1.21(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + '@react-navigation/native-stack': 7.8.0(@react-navigation/native@7.1.21(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + client-only: 0.0.1 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + expo: 54.0.25(@babel/core@7.28.5)(@expo/metro-runtime@6.1.2)(expo-router@6.0.15)(react-native-webview@13.12.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + expo-constants: 18.0.10(expo@54.0.25)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0)) + expo-linking: 8.0.9(expo@54.0.25)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + expo-server: 1.0.4 + fast-deep-equal: 3.1.3 + invariant: 2.2.4 + nanoid: 3.3.11 + query-string: 7.1.3 + react: 19.1.0 + react-fast-compare: 3.2.2 + react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0) + react-native-is-edge-to-edge: 1.2.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + react-native-safe-area-context: 5.6.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + react-native-screens: 4.16.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + semver: 7.6.3 + server-only: 0.0.1 + sf-symbols-typescript: 2.1.0 + shallowequal: 1.1.0 + use-latest-callback: 0.2.6(react@19.1.0) + vaul: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + optionalDependencies: + '@react-navigation/drawer': 7.7.4(@react-navigation/native@7.1.21(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-gesture-handler@2.28.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-reanimated@4.1.5(@babel/core@7.28.5)(react-native-worklets@0.6.1(@babel/core@7.28.5)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + '@testing-library/react-native': 13.3.3(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react-test-renderer@19.1.0(react@19.1.0))(react@19.1.0) + react-dom: 19.1.0(react@19.1.0) + react-native-gesture-handler: 2.28.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + react-native-reanimated: 4.1.5(@babel/core@7.28.5)(react-native-worklets@0.6.1(@babel/core@7.28.5)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0) + react-native-web: 0.21.2(encoding@0.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react-server-dom-webpack: 19.0.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(webpack@5.97.1(esbuild@0.19.12)) + transitivePeerDependencies: + - '@react-native-masked-view/masked-view' + - '@types/react' + - '@types/react-dom' + - supports-color + optional: true + expo-router@6.0.15(k2muy65dii4k2uiuhg4mwyy6ki): dependencies: '@expo/metro-runtime': 6.1.2(expo@54.0.25)(react-dom@19.1.0(react@18.3.1))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) @@ -39127,6 +39337,23 @@ snapshots: forever-agent@0.6.1: {} + fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.19.12)): + dependencies: + '@babel/code-frame': 7.27.1 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 8.3.6(typescript@5.7.2) + deepmerge: 4.3.1 + fs-extra: 10.1.0 + memfs: 3.5.3 + minimatch: 3.1.2 + node-abort-controller: 3.1.1 + schema-utils: 3.3.0 + semver: 7.7.3 + tapable: 2.3.0 + typescript: 5.7.2 + webpack: 5.97.1(esbuild@0.19.12) + fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.27.0)): dependencies: '@babel/code-frame': 7.27.1 @@ -40582,16 +40809,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)): + jest-cli@29.7.0(@types/node@24.10.1): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)) + '@jest/core': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)) + create-jest: 29.7.0(@types/node@24.10.1) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)) + jest-config: 29.7.0(@types/node@24.10.1) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -40679,6 +40906,36 @@ snapshots: - ts-node optional: true + jest-config@29.7.0(@types/node@22.19.1): + dependencies: + '@babel/core': 7.28.5 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.28.5) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.19.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-config@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)): dependencies: '@babel/core': 7.28.5 @@ -40710,38 +40967,7 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)): - dependencies: - '@babel/core': 7.28.5 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.28.5) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 22.19.1 - ts-node: 10.9.2(@types/node@24.10.1)(typescript@5.9.3) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-config@29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)): + jest-config@29.7.0(@types/node@24.10.1): dependencies: '@babel/core': 7.28.5 '@jest/test-sequencer': 29.7.0 @@ -40767,7 +40993,6 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 24.10.1 - ts-node: 10.9.2(@types/node@24.10.1)(typescript@5.9.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -41354,12 +41579,12 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)): + jest@29.7.0(@types/node@24.10.1): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)) + '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)) + jest-cli: 29.7.0(@types/node@24.10.1) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -45733,6 +45958,16 @@ snapshots: webpack-sources: 3.3.3 optional: true + react-server-dom-webpack@19.0.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(webpack@5.97.1(esbuild@0.19.12)): + dependencies: + acorn-loose: 8.5.2 + neo-async: 2.6.2 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + webpack: 5.97.1(esbuild@0.19.12) + webpack-sources: 3.3.3 + optional: true + react-style-singleton@2.2.3(@types/react@18.3.27)(react@18.3.1): dependencies: get-nonce: 1.0.1 @@ -47194,6 +47429,17 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 + terser-webpack-plugin@5.3.14(esbuild@0.19.12)(webpack@5.97.1(esbuild@0.19.12)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + terser: 5.44.1 + webpack: 5.97.1(esbuild@0.19.12) + optionalDependencies: + esbuild: 0.19.12 + terser-webpack-plugin@5.3.14(esbuild@0.27.0)(webpack@5.100.2(esbuild@0.27.0)): dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -47394,6 +47640,27 @@ snapshots: ts-interface-checker@0.1.13: {} + ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.8 + jest: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.3 + type-fest: 4.41.0 + typescript: 5.9.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.28.5 + '@jest/transform': 30.2.0 + '@jest/types': 30.2.0 + babel-jest: 30.2.0(@babel/core@7.28.5) + esbuild: 0.19.12 + jest-util: 30.2.0 + ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.27.0)(jest-util@30.2.0)(jest@30.2.0(@types/node@22.19.1)(esbuild-register@3.6.0(esbuild@0.27.0))(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 @@ -47436,26 +47703,6 @@ snapshots: esbuild: 0.27.0 jest-util: 30.2.0 - ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3): - dependencies: - bs-logger: 0.2.6 - fast-json-stable-stringify: 2.1.0 - handlebars: 4.7.8 - jest: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)) - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.7.3 - type-fest: 4.41.0 - typescript: 5.9.3 - yargs-parser: 21.1.1 - optionalDependencies: - '@babel/core': 7.28.5 - '@jest/transform': 30.2.0 - '@jest/types': 30.2.0 - babel-jest: 30.2.0(@babel/core@7.28.5) - jest-util: 30.2.0 - ts-loader@9.5.4(typescript@5.9.3)(webpack@5.100.2(esbuild@0.27.0)): dependencies: chalk: 4.1.2 @@ -47476,6 +47723,16 @@ snapshots: typescript: 5.9.3 webpack: 5.100.2 + ts-loader@9.5.4(typescript@5.9.3)(webpack@5.97.1(esbuild@0.19.12)): + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.18.3 + micromatch: 4.0.8 + semver: 7.7.3 + source-map: 0.7.6 + typescript: 5.9.3 + webpack: 5.97.1(esbuild@0.19.12) + ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -48156,6 +48413,23 @@ snapshots: lightningcss: 1.30.2 terser: 5.44.1 + vite@6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.3 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 20.19.25 + fsevents: 2.3.3 + jiti: 1.21.7 + lightningcss: 1.30.2 + terser: 5.44.1 + tsx: 4.20.6 + yaml: 2.8.1 + vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.12 @@ -48259,6 +48533,10 @@ snapshots: tsx: 4.20.6 yaml: 2.8.1 + vitefu@1.1.1(vite@6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)): + optionalDependencies: + vite: 6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1) + vitefu@1.1.1(vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)): optionalDependencies: vite: 6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1) @@ -48713,6 +48991,36 @@ snapshots: - esbuild - uglify-js + webpack@5.97.1(esbuild@0.19.12): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.15.0 + browserslist: 4.28.0 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.3 + es-module-lexer: 1.7.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.14(esbuild@0.19.12)(webpack@5.97.1(esbuild@0.19.12)) + watchpack: 2.4.4 + webpack-sources: 3.3.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + webpack@5.97.1(esbuild@0.27.0): dependencies: '@types/eslint-scope': 3.7.7 diff --git a/services/matrix-chat-bot/package.json b/services/matrix-chat-bot/package.json index 838da8d09..c39648bdc 100644 --- a/services/matrix-chat-bot/package.json +++ b/services/matrix-chat-bot/package.json @@ -22,6 +22,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { + "@manacore/bot-services": "workspace:*", "@nestjs/common": "^10.4.15", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.4.15", diff --git a/services/matrix-chat-bot/src/bot/bot.module.ts b/services/matrix-chat-bot/src/bot/bot.module.ts index 3aef8b8d3..2a6e51cb8 100644 --- a/services/matrix-chat-bot/src/bot/bot.module.ts +++ b/services/matrix-chat-bot/src/bot/bot.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; import { MatrixService } from './matrix.service'; import { ChatModule } from '../chat/chat.module'; -import { SessionModule } from '../session/session.module'; +import { SessionModule } from '@manacore/bot-services'; @Module({ - imports: [ChatModule, SessionModule], + imports: [ChatModule, SessionModule.forRoot()], providers: [MatrixService], exports: [MatrixService], }) diff --git a/services/matrix-chat-bot/src/bot/matrix.service.ts b/services/matrix-chat-bot/src/bot/matrix.service.ts index ed0232776..01cac0c31 100644 --- a/services/matrix-chat-bot/src/bot/matrix.service.ts +++ b/services/matrix-chat-bot/src/bot/matrix.service.ts @@ -7,7 +7,7 @@ import { RichReply, } from 'matrix-bot-sdk'; import { ChatService, Model, Conversation, Message } from '../chat/chat.service'; -import { SessionService } from '../session/session.service'; +import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE, BRANCH_ICONS } from '../config/configuration'; @Injectable() @@ -22,6 +22,43 @@ export class MatrixService implements OnModuleInit { private sessionService: SessionService ) {} + // Session data helper methods (wrapping the generic setSessionData/getSessionData) + private getCurrentConversation(sender: string): string | null { + return this.sessionService.getSessionData(sender, 'currentConversationId'); + } + + private setCurrentConversation(sender: string, conversationId: string | null): void { + this.sessionService.setSessionData(sender, 'currentConversationId', conversationId); + } + + private getSelectedModel(sender: string): string | null { + return this.sessionService.getSessionData(sender, 'selectedModelId'); + } + + private setSelectedModel(sender: string, modelId: string): void { + this.sessionService.setSessionData(sender, 'selectedModelId', modelId); + } + + private setConversationMapping(sender: string, ids: string[]): void { + this.sessionService.setSessionData(sender, 'conversationMapping', ids); + } + + private getConversationId(sender: string, number: number): string | null { + const ids = this.sessionService.getSessionData(sender, 'conversationMapping'); + if (!ids || number < 1 || number > ids.length) return null; + return ids[number - 1]; + } + + private setModelMapping(sender: string, ids: string[]): void { + this.sessionService.setSessionData(sender, 'modelMapping', ids); + } + + private getModelId(sender: string, number: number): string | null { + const ids = this.sessionService.getSessionData(sender, 'modelMapping'); + if (!ids || number < 1 || number > ids.length) return null; + return ids[number - 1]; + } + async onModuleInit() { const homeserverUrl = this.configService.get('matrix.homeserverUrl'); const accessToken = this.configService.get('matrix.accessToken'); @@ -200,8 +237,8 @@ export class MatrixService implements OnModuleInit { private handleStatus(sender: string): string { const isLoggedIn = this.sessionService.isLoggedIn(sender); - const currentConv = this.sessionService.getCurrentConversation(sender); - const selectedModel = this.sessionService.getSelectedModel(sender); + const currentConv = this.getCurrentConversation(sender); + const selectedModel = this.getSelectedModel(sender); let status = `**Bot Status**\n`; status += `- Angemeldet: ${isLoggedIn ? 'Ja' : 'Nein'}\n`; @@ -232,7 +269,7 @@ export class MatrixService implements OnModuleInit { return 'Keine AI-Modelle verfuegbar.'; } - const selectedModelId = this.sessionService.getSelectedModel(sender); + const selectedModelId = this.getSelectedModel(sender); const modelId = selectedModelId || modelsResult.data.find((m) => m.isDefault)?.id || modelsResult.data[0].id; const result = await this.chatService.createCompletion( @@ -265,7 +302,7 @@ export class MatrixService implements OnModuleInit { return 'Keine AI-Modelle verfuegbar.'; } - const selectedModelId = this.sessionService.getSelectedModel(sender); + const selectedModelId = this.getSelectedModel(sender); const modelId = selectedModelId || modelsResult.data.find((m) => m.isDefault)?.id || modelsResult.data[0].id; const convTitle = title || `Matrix Chat ${new Date().toLocaleDateString('de-DE')}`; @@ -279,7 +316,7 @@ export class MatrixService implements OnModuleInit { return `Fehler: ${result.error}`; } - this.sessionService.setCurrentConversation(sender, result.data!.id); + this.setCurrentConversation(sender, result.data!.id); return `Neues Gespraech erstellt: **${result.data!.title}**\nNutze \`!senden [nachricht]\` um zu chatten.`; } @@ -305,12 +342,12 @@ export class MatrixService implements OnModuleInit { }); // Store mapping - this.sessionService.setConversationMapping( + this.setConversationMapping( sender, sorted.map((c) => c.id) ); - const currentId = this.sessionService.getCurrentConversation(sender); + const currentId = this.getCurrentConversation(sender); let response = '**Deine Gespraeche:**\n\n'; sorted.forEach((conv, index) => { @@ -332,7 +369,7 @@ export class MatrixService implements OnModuleInit { if (!numberStr) { // Show current conversation - const currentId = this.sessionService.getCurrentConversation(sender); + const currentId = this.getCurrentConversation(sender); if (!currentId) { return 'Kein Gespraech ausgewaehlt. Nutze `!gespraeche` und dann `!gespraech [nr]`'; } @@ -350,7 +387,7 @@ export class MatrixService implements OnModuleInit { return 'Bitte eine gueltige Nummer angeben.'; } - const conversationId = this.sessionService.getConversationId(sender, number); + const conversationId = this.getConversationId(sender, number); if (!conversationId) { return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.'; } @@ -360,7 +397,7 @@ export class MatrixService implements OnModuleInit { return `Fehler: ${result.error}`; } - this.sessionService.setCurrentConversation(sender, conversationId); + this.setCurrentConversation(sender, conversationId); return `Gespraech ausgewaehlt: **${result.data!.title}**\n\n${this.formatConversationDetails(result.data!)}`; } @@ -388,7 +425,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht return 'Bitte zuerst anmelden mit `!login email passwort`'; } - const conversationId = this.sessionService.getCurrentConversation(sender); + const conversationId = this.getCurrentConversation(sender); if (!conversationId) { return 'Kein Gespraech ausgewaehlt. Nutze `!gespraeche` und `!gespraech [nr]` oder `!neu [titel]`'; } @@ -434,12 +471,12 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht return 'Bitte zuerst anmelden mit `!login email passwort`'; } - let conversationId = this.sessionService.getCurrentConversation(sender); + let conversationId = this.getCurrentConversation(sender); if (numberStr) { const number = parseInt(numberStr, 10); if (!isNaN(number)) { - const id = this.sessionService.getConversationId(sender, number); + const id = this.getConversationId(sender, number); if (id) conversationId = id; } } @@ -489,7 +526,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht return 'Bitte eine gueltige Nummer angeben.'; } - const conversationId = this.sessionService.getConversationId(sender, number); + const conversationId = this.getConversationId(sender, number); if (!conversationId) { return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.'; } @@ -517,7 +554,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht return 'Bitte eine gueltige Nummer angeben.'; } - const conversationId = this.sessionService.getConversationId(sender, number); + const conversationId = this.getConversationId(sender, number); if (!conversationId) { return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.'; } @@ -546,7 +583,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht } // Store mapping for restore - this.sessionService.setConversationMapping( + this.setConversationMapping( sender, result.data.map((c) => c.id) ); @@ -576,7 +613,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht return 'Bitte eine gueltige Nummer angeben.'; } - const conversationId = this.sessionService.getConversationId(sender, number); + const conversationId = this.getConversationId(sender, number); if (!conversationId) { return 'Ungueltige Nummer. Nutze `!archiviert` fuer eine aktuelle Liste.'; } @@ -604,7 +641,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht return 'Bitte eine gueltige Nummer angeben.'; } - const conversationId = this.sessionService.getConversationId(sender, number); + const conversationId = this.getConversationId(sender, number); if (!conversationId) { return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.'; } @@ -632,7 +669,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht return 'Bitte eine gueltige Nummer angeben.'; } - const conversationId = this.sessionService.getConversationId(sender, number); + const conversationId = this.getConversationId(sender, number); if (!conversationId) { return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.'; } @@ -660,7 +697,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht return 'Bitte eine gueltige Nummer angeben.'; } - const conversationId = this.sessionService.getConversationId(sender, number); + const conversationId = this.getConversationId(sender, number); if (!conversationId) { return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.'; } @@ -675,8 +712,8 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht } // Clear current conversation if it was the deleted one - if (this.sessionService.getCurrentConversation(sender) === conversationId) { - this.sessionService.setCurrentConversation(sender, null); + if (this.getCurrentConversation(sender) === conversationId) { + this.setCurrentConversation(sender, null); } return `Gespraech **${title}** geloescht.`; @@ -696,12 +733,12 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht const activeModels = result.data.filter((m) => m.isActive); // Store mapping - this.sessionService.setModelMapping( + this.setModelMapping( sender, activeModels.map((m) => m.id) ); - const selectedModelId = this.sessionService.getSelectedModel(sender); + const selectedModelId = this.getSelectedModel(sender); let response = '**Verfuegbare AI-Modelle:**\n\n'; activeModels.forEach((model, index) => { @@ -718,7 +755,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht private async handleSelectModel(sender: string, numberStr: string): Promise { if (!numberStr) { - const selectedModelId = this.sessionService.getSelectedModel(sender); + const selectedModelId = this.getSelectedModel(sender); if (!selectedModelId) { return 'Kein Modell ausgewaehlt (Standard wird verwendet). Nutze `!modelle` und `!modell [nr]`'; } @@ -737,7 +774,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht return 'Bitte eine gueltige Nummer angeben.'; } - const modelId = this.sessionService.getModelId(sender, number); + const modelId = this.getModelId(sender, number); if (!modelId) { return 'Ungueltige Nummer. Nutze `!modelle` fuer eine aktuelle Liste.'; } @@ -747,7 +784,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht return `Fehler: ${result.error}`; } - this.sessionService.setSelectedModel(sender, modelId); + this.setSelectedModel(sender, modelId); const icon = BRANCH_ICONS[result.data!.provider] || BRANCH_ICONS.default; return `Modell gewaehlt: ${icon} **${result.data!.name}**\nWird fuer neue Gespraeche und Quick-Chat verwendet.`; } diff --git a/services/matrix-chat-bot/src/session/session.module.ts b/services/matrix-chat-bot/src/session/session.module.ts deleted file mode 100644 index 834b715eb..000000000 --- a/services/matrix-chat-bot/src/session/session.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { SessionService } from './session.service'; - -@Module({ - providers: [SessionService], - exports: [SessionService], -}) -export class SessionModule {} diff --git a/services/matrix-chat-bot/src/session/session.service.ts b/services/matrix-chat-bot/src/session/session.service.ts deleted file mode 100644 index 37871ea3a..000000000 --- a/services/matrix-chat-bot/src/session/session.service.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -interface UserSession { - token: string; - email: string; - expiresAt: Date; - currentConversationId?: string; - selectedModelId?: string; -} - -@Injectable() -export class SessionService { - private readonly logger = new Logger(SessionService.name); - private sessions: Map = new Map(); - private authUrl: string; - - // Store conversation list mappings per user - private conversationMappings: Map = new Map(); - private modelMappings: Map = new Map(); - - constructor(private configService: ConfigService) { - this.authUrl = this.configService.get('auth.url') || 'http://localhost:3001'; - } - - async login( - matrixUserId: string, - email: string, - password: string - ): Promise<{ success: boolean; error?: string }> { - try { - const response = await fetch(`${this.authUrl}/api/v1/auth/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email, password }), - }); - - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - return { - success: false, - error: errorData.message || 'Authentifizierung fehlgeschlagen', - }; - } - - const data = await response.json(); - const token = data.accessToken || data.token; - - if (!token) { - return { success: false, error: 'Kein Token erhalten' }; - } - - this.sessions.set(matrixUserId, { - token, - email, - expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), - }); - - this.logger.log(`User ${matrixUserId} logged in as ${email}`); - return { success: true }; - } catch (error) { - this.logger.error(`Login failed for ${matrixUserId}:`, error); - return { - success: false, - error: 'Verbindung zum Auth-Server fehlgeschlagen', - }; - } - } - - logout(matrixUserId: string): void { - this.sessions.delete(matrixUserId); - this.conversationMappings.delete(matrixUserId); - this.modelMappings.delete(matrixUserId); - this.logger.log(`User ${matrixUserId} logged out`); - } - - getToken(matrixUserId: string): string | null { - const session = this.sessions.get(matrixUserId); - if (!session) return null; - if (session.expiresAt < new Date()) { - this.sessions.delete(matrixUserId); - return null; - } - return session.token; - } - - isLoggedIn(matrixUserId: string): boolean { - return this.getToken(matrixUserId) !== null; - } - - getSessionCount(): number { - return this.sessions.size; - } - - // Current conversation management - setCurrentConversation(matrixUserId: string, conversationId: string | null): void { - const session = this.sessions.get(matrixUserId); - if (session) { - session.currentConversationId = conversationId || undefined; - } - } - - getCurrentConversation(matrixUserId: string): string | null { - const session = this.sessions.get(matrixUserId); - return session?.currentConversationId || null; - } - - // Selected model management - setSelectedModel(matrixUserId: string, modelId: string): void { - const session = this.sessions.get(matrixUserId); - if (session) { - session.selectedModelId = modelId; - } - } - - getSelectedModel(matrixUserId: string): string | null { - const session = this.sessions.get(matrixUserId); - return session?.selectedModelId || null; - } - - // Conversation number mapping - setConversationMapping(matrixUserId: string, ids: string[]): void { - this.conversationMappings.set(matrixUserId, ids); - } - - getConversationId(matrixUserId: string, number: number): string | null { - const ids = this.conversationMappings.get(matrixUserId); - if (!ids || number < 1 || number > ids.length) return null; - return ids[number - 1]; - } - - // Model number mapping - setModelMapping(matrixUserId: string, ids: string[]): void { - this.modelMappings.set(matrixUserId, ids); - } - - getModelId(matrixUserId: string, number: number): string | null { - const ids = this.modelMappings.get(matrixUserId); - if (!ids || number < 1 || number > ids.length) return null; - return ids[number - 1]; - } -} diff --git a/services/matrix-contacts-bot/package.json b/services/matrix-contacts-bot/package.json index ee3cfb542..34d018d45 100644 --- a/services/matrix-contacts-bot/package.json +++ b/services/matrix-contacts-bot/package.json @@ -22,6 +22,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { + "@manacore/bot-services": "workspace:*", "@nestjs/common": "^10.4.15", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.4.15", diff --git a/services/matrix-contacts-bot/src/bot/bot.module.ts b/services/matrix-contacts-bot/src/bot/bot.module.ts index b85318815..f25106807 100644 --- a/services/matrix-contacts-bot/src/bot/bot.module.ts +++ b/services/matrix-contacts-bot/src/bot/bot.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; import { MatrixService } from './matrix.service'; import { ContactsModule } from '../contacts/contacts.module'; -import { SessionModule } from '../session/session.module'; +import { SessionModule } from '@manacore/bot-services'; @Module({ - imports: [ContactsModule, SessionModule], + imports: [ContactsModule, SessionModule.forRoot()], providers: [MatrixService], exports: [MatrixService], }) diff --git a/services/matrix-contacts-bot/src/bot/matrix.service.ts b/services/matrix-contacts-bot/src/bot/matrix.service.ts index a401e5622..fff7dbcfd 100644 --- a/services/matrix-contacts-bot/src/bot/matrix.service.ts +++ b/services/matrix-contacts-bot/src/bot/matrix.service.ts @@ -8,7 +8,7 @@ import { LogLevel, } from 'matrix-bot-sdk'; import { ContactsService, Contact } from '../contacts/contacts.service'; -import { SessionService } from '../session/session.service'; +import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; // Natural language keywords diff --git a/services/matrix-contacts-bot/src/session/session.module.ts b/services/matrix-contacts-bot/src/session/session.module.ts deleted file mode 100644 index 834b715eb..000000000 --- a/services/matrix-contacts-bot/src/session/session.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { SessionService } from './session.service'; - -@Module({ - providers: [SessionService], - exports: [SessionService], -}) -export class SessionModule {} diff --git a/services/matrix-contacts-bot/src/session/session.service.ts b/services/matrix-contacts-bot/src/session/session.service.ts deleted file mode 100644 index f1bed7852..000000000 --- a/services/matrix-contacts-bot/src/session/session.service.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -interface UserSession { - token: string; - email: string; - expiresAt: Date; -} - -@Injectable() -export class SessionService { - private readonly logger = new Logger(SessionService.name); - private sessions: Map = new Map(); - private authUrl: string; - - constructor(private configService: ConfigService) { - this.authUrl = this.configService.get('auth.url') || 'http://localhost:3001'; - } - - async login( - matrixUserId: string, - email: string, - password: string - ): Promise<{ success: boolean; error?: string }> { - try { - const response = await fetch(`${this.authUrl}/api/v1/auth/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email, password }), - }); - - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - return { - success: false, - error: errorData.message || 'Authentifizierung fehlgeschlagen', - }; - } - - const data = await response.json(); - const token = data.accessToken || data.token; - - if (!token) { - return { success: false, error: 'Kein Token erhalten' }; - } - - // Store session (7 days expiry) - this.sessions.set(matrixUserId, { - token, - email, - expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), - }); - - this.logger.log(`User ${matrixUserId} logged in as ${email}`); - return { success: true }; - } catch (error) { - this.logger.error(`Login failed for ${matrixUserId}:`, error); - return { - success: false, - error: 'Verbindung zum Auth-Server fehlgeschlagen', - }; - } - } - - logout(matrixUserId: string): void { - this.sessions.delete(matrixUserId); - this.logger.log(`User ${matrixUserId} logged out`); - } - - getToken(matrixUserId: string): string | null { - const session = this.sessions.get(matrixUserId); - - if (!session) return null; - - if (session.expiresAt < new Date()) { - this.sessions.delete(matrixUserId); - return null; - } - - return session.token; - } - - isLoggedIn(matrixUserId: string): boolean { - return this.getToken(matrixUserId) !== null; - } - - getSessionCount(): number { - return this.sessions.size; - } -} diff --git a/services/matrix-manadeck-bot/package.json b/services/matrix-manadeck-bot/package.json index 2c5a35e3d..71e3126f1 100644 --- a/services/matrix-manadeck-bot/package.json +++ b/services/matrix-manadeck-bot/package.json @@ -22,6 +22,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { + "@manacore/bot-services": "workspace:*", "@nestjs/common": "^10.4.15", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.4.15", diff --git a/services/matrix-manadeck-bot/src/app.module.ts b/services/matrix-manadeck-bot/src/app.module.ts index 76f39ffd8..897a4ebe2 100644 --- a/services/matrix-manadeck-bot/src/app.module.ts +++ b/services/matrix-manadeck-bot/src/app.module.ts @@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config'; import { HealthController } from './health.controller'; import { BotModule } from './bot/bot.module'; import { ManadeckModule } from './manadeck/manadeck.module'; -import { SessionModule } from './session/session.module'; import configuration from './config/configuration'; @Module({ @@ -14,7 +13,6 @@ import configuration from './config/configuration'; }), BotModule, ManadeckModule, - SessionModule, ], controllers: [HealthController], }) diff --git a/services/matrix-manadeck-bot/src/bot/bot.module.ts b/services/matrix-manadeck-bot/src/bot/bot.module.ts index 8878a4a3c..e7afd5d44 100644 --- a/services/matrix-manadeck-bot/src/bot/bot.module.ts +++ b/services/matrix-manadeck-bot/src/bot/bot.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; import { MatrixService } from './matrix.service'; import { ManadeckModule } from '../manadeck/manadeck.module'; -import { SessionModule } from '../session/session.module'; +import { SessionModule } from '@manacore/bot-services'; @Module({ - imports: [ManadeckModule, SessionModule], + imports: [ManadeckModule, SessionModule.forRoot()], providers: [MatrixService], exports: [MatrixService], }) diff --git a/services/matrix-manadeck-bot/src/bot/matrix.service.ts b/services/matrix-manadeck-bot/src/bot/matrix.service.ts index 2ec4aaa8e..ab7447fd4 100644 --- a/services/matrix-manadeck-bot/src/bot/matrix.service.ts +++ b/services/matrix-manadeck-bot/src/bot/matrix.service.ts @@ -6,7 +6,7 @@ import { AutojoinRoomsMixin, } from 'matrix-bot-sdk'; import { ManadeckService, Deck, Card } from '../manadeck/manadeck.service'; -import { SessionService } from '../session/session.service'; +import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @Injectable() diff --git a/services/matrix-manadeck-bot/src/session/session.module.ts b/services/matrix-manadeck-bot/src/session/session.module.ts deleted file mode 100644 index 834b715eb..000000000 --- a/services/matrix-manadeck-bot/src/session/session.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { SessionService } from './session.service'; - -@Module({ - providers: [SessionService], - exports: [SessionService], -}) -export class SessionModule {} diff --git a/services/matrix-manadeck-bot/src/session/session.service.ts b/services/matrix-manadeck-bot/src/session/session.service.ts deleted file mode 100644 index f1bed7852..000000000 --- a/services/matrix-manadeck-bot/src/session/session.service.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -interface UserSession { - token: string; - email: string; - expiresAt: Date; -} - -@Injectable() -export class SessionService { - private readonly logger = new Logger(SessionService.name); - private sessions: Map = new Map(); - private authUrl: string; - - constructor(private configService: ConfigService) { - this.authUrl = this.configService.get('auth.url') || 'http://localhost:3001'; - } - - async login( - matrixUserId: string, - email: string, - password: string - ): Promise<{ success: boolean; error?: string }> { - try { - const response = await fetch(`${this.authUrl}/api/v1/auth/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email, password }), - }); - - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - return { - success: false, - error: errorData.message || 'Authentifizierung fehlgeschlagen', - }; - } - - const data = await response.json(); - const token = data.accessToken || data.token; - - if (!token) { - return { success: false, error: 'Kein Token erhalten' }; - } - - // Store session (7 days expiry) - this.sessions.set(matrixUserId, { - token, - email, - expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), - }); - - this.logger.log(`User ${matrixUserId} logged in as ${email}`); - return { success: true }; - } catch (error) { - this.logger.error(`Login failed for ${matrixUserId}:`, error); - return { - success: false, - error: 'Verbindung zum Auth-Server fehlgeschlagen', - }; - } - } - - logout(matrixUserId: string): void { - this.sessions.delete(matrixUserId); - this.logger.log(`User ${matrixUserId} logged out`); - } - - getToken(matrixUserId: string): string | null { - const session = this.sessions.get(matrixUserId); - - if (!session) return null; - - if (session.expiresAt < new Date()) { - this.sessions.delete(matrixUserId); - return null; - } - - return session.token; - } - - isLoggedIn(matrixUserId: string): boolean { - return this.getToken(matrixUserId) !== null; - } - - getSessionCount(): number { - return this.sessions.size; - } -} diff --git a/services/matrix-nutriphi-bot/package.json b/services/matrix-nutriphi-bot/package.json index 8e63a104a..08ad583ee 100644 --- a/services/matrix-nutriphi-bot/package.json +++ b/services/matrix-nutriphi-bot/package.json @@ -27,6 +27,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { + "@manacore/bot-services": "workspace:*", "@nestjs/common": "^10.4.15", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.4.15", diff --git a/services/matrix-nutriphi-bot/src/bot/bot.module.ts b/services/matrix-nutriphi-bot/src/bot/bot.module.ts index 683c06e3f..773ba3b1e 100644 --- a/services/matrix-nutriphi-bot/src/bot/bot.module.ts +++ b/services/matrix-nutriphi-bot/src/bot/bot.module.ts @@ -1,11 +1,10 @@ import { Module } from '@nestjs/common'; import { MatrixService } from './matrix.service'; import { NutriPhiModule } from '../nutriphi/nutriphi.module'; -import { SessionModule } from '../session/session.module'; -import { TranscriptionModule } from '../transcription/transcription.module'; +import { SessionModule, TranscriptionModule } from '@manacore/bot-services'; @Module({ - imports: [NutriPhiModule, SessionModule, TranscriptionModule], + imports: [NutriPhiModule, SessionModule.forRoot(), TranscriptionModule.forRoot()], providers: [MatrixService], exports: [MatrixService], }) diff --git a/services/matrix-nutriphi-bot/src/bot/matrix.service.ts b/services/matrix-nutriphi-bot/src/bot/matrix.service.ts index 735c7b9ea..4563396a7 100644 --- a/services/matrix-nutriphi-bot/src/bot/matrix.service.ts +++ b/services/matrix-nutriphi-bot/src/bot/matrix.service.ts @@ -13,8 +13,7 @@ import { DailySummary, WeeklyStats, } from '../nutriphi/nutriphi.service'; -import { SessionService } from '../session/session.service'; -import { TranscriptionService } from '../transcription/transcription.service'; +import { SessionService, TranscriptionService } from '@manacore/bot-services'; import { HELP_MESSAGE, MEAL_TYPE_LABELS } from '../config/configuration'; // Natural language keywords that trigger commands (German + English) @@ -136,11 +135,10 @@ Sag "hilfe" fur alle Befehle!`; // Handle image messages if (content.msgtype === 'm.image' && content.url) { - this.sessionService.setPendingImage( - event.sender, - content.url, - content.info?.mimetype || 'image/png' - ); + this.sessionService.setSessionData(event.sender, 'pendingImage', { + url: content.url, + mimeType: content.info?.mimetype || 'image/png', + }); this.logger.log(`Image received from ${event.sender}`); await this.sendMessage( roomId, @@ -298,7 +296,10 @@ Sag "hilfe" fur alle Befehle!`; return; } - const pendingImage = this.sessionService.getPendingImage(sender); + const pendingImage = this.sessionService.getSessionData<{ url: string; mimeType: string }>( + sender, + 'pendingImage' + ); // If no image and no description, show help if (!pendingImage && !description.trim()) { @@ -319,7 +320,7 @@ Sag "hilfe" fur alle Befehle!`; await this.sendMessage(roomId, 'Analysiere Bild...'); const imageData = await this.downloadMatrixImage(pendingImage.url); result = await this.nutriphiService.analyzePhoto(imageData, pendingImage.mimeType, token); - this.sessionService.clearPendingImage(sender); + this.sessionService.setSessionData(sender, 'pendingImage', null); } else { // Analyze text await this.sendMessage(roomId, `Analysiere: "${description}"...`); @@ -634,7 +635,7 @@ Sag "hilfe" fur alle Befehle!`; const backendHealthy = await this.nutriphiService.checkHealth(); const isLoggedIn = this.sessionService.isLoggedIn(sender); const sessionCount = this.sessionService.getSessionCount(); - const loggedInCount = this.sessionService.getLoggedInCount(); + const loggedInCount = this.sessionService.getActiveSessionCount(); const statusText = `**NutriPhi Bot Status** diff --git a/services/matrix-nutriphi-bot/src/session/session.module.ts b/services/matrix-nutriphi-bot/src/session/session.module.ts deleted file mode 100644 index 834b715eb..000000000 --- a/services/matrix-nutriphi-bot/src/session/session.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { SessionService } from './session.service'; - -@Module({ - providers: [SessionService], - exports: [SessionService], -}) -export class SessionModule {} diff --git a/services/matrix-nutriphi-bot/src/session/session.service.ts b/services/matrix-nutriphi-bot/src/session/session.service.ts deleted file mode 100644 index 1b84fab9a..000000000 --- a/services/matrix-nutriphi-bot/src/session/session.service.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -export interface UserSession { - matrixUserId: string; - jwtToken?: string; - tokenExpiry?: Date; - pendingImage?: { url: string; mimeType: string }; - lastActivity: Date; -} - -export interface LoginResult { - success: boolean; - token?: string; - error?: string; -} - -@Injectable() -export class SessionService { - private readonly logger = new Logger(SessionService.name); - private sessions: Map = new Map(); - private readonly authUrl: string; - private readonly devBypass: boolean; - private readonly devUserId: string; - - constructor(private configService: ConfigService) { - this.authUrl = this.configService.get('auth.url') || 'http://localhost:3001'; - this.devBypass = this.configService.get('auth.devBypass') || false; - this.devUserId = this.configService.get('auth.devUserId') || ''; - } - - getSession(matrixUserId: string): UserSession { - if (!this.sessions.has(matrixUserId)) { - this.sessions.set(matrixUserId, { - matrixUserId, - lastActivity: new Date(), - }); - } - const session = this.sessions.get(matrixUserId)!; - session.lastActivity = new Date(); - return session; - } - - isLoggedIn(matrixUserId: string): boolean { - if (this.devBypass && this.devUserId) { - return true; - } - - const session = this.sessions.get(matrixUserId); - if (!session?.jwtToken || !session.tokenExpiry) { - return false; - } - - // Check if token is expired (with 5 minute buffer) - const now = new Date(); - const expiryBuffer = new Date(session.tokenExpiry.getTime() - 5 * 60 * 1000); - return now < expiryBuffer; - } - - getToken(matrixUserId: string): string | null { - if (this.devBypass && this.devUserId) { - // In dev mode, return a mock token (the backend should also bypass auth) - return 'dev-bypass-token'; - } - - const session = this.sessions.get(matrixUserId); - if (!session?.jwtToken || !this.isLoggedIn(matrixUserId)) { - return null; - } - return session.jwtToken; - } - - async login(matrixUserId: string, email: string, password: string): Promise { - try { - const response = await fetch(`${this.authUrl}/api/v1/auth/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email, password }), - }); - - if (!response.ok) { - const error = await response.text(); - this.logger.warn(`Login failed for ${matrixUserId}: ${response.status}`); - return { success: false, error: `Login fehlgeschlagen: ${error}` }; - } - - const data = await response.json(); - const { accessToken, expiresIn } = data; - - if (!accessToken) { - return { success: false, error: 'Kein Token erhalten' }; - } - - // Calculate expiry time (expiresIn is in seconds) - const expiryTime = expiresIn - ? new Date(Date.now() + expiresIn * 1000) - : new Date(Date.now() + 7 * 24 * 60 * 60 * 1000); // Default: 7 days - - const session = this.getSession(matrixUserId); - session.jwtToken = accessToken; - session.tokenExpiry = expiryTime; - - this.logger.log(`User ${matrixUserId} logged in successfully`); - return { success: true, token: accessToken }; - } catch (error) { - this.logger.error(`Login error for ${matrixUserId}:`, error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unbekannter Fehler', - }; - } - } - - logout(matrixUserId: string): void { - const session = this.sessions.get(matrixUserId); - if (session) { - session.jwtToken = undefined; - session.tokenExpiry = undefined; - } - this.logger.log(`User ${matrixUserId} logged out`); - } - - setPendingImage(matrixUserId: string, url: string, mimeType: string): void { - const session = this.getSession(matrixUserId); - session.pendingImage = { url, mimeType }; - } - - getPendingImage(matrixUserId: string): { url: string; mimeType: string } | undefined { - return this.sessions.get(matrixUserId)?.pendingImage; - } - - clearPendingImage(matrixUserId: string): void { - const session = this.sessions.get(matrixUserId); - if (session) { - session.pendingImage = undefined; - } - } - - getSessionCount(): number { - return this.sessions.size; - } - - getLoggedInCount(): number { - let count = 0; - for (const [userId] of this.sessions) { - if (this.isLoggedIn(userId)) { - count++; - } - } - return count; - } -} diff --git a/services/matrix-nutriphi-bot/src/transcription/transcription.module.ts b/services/matrix-nutriphi-bot/src/transcription/transcription.module.ts deleted file mode 100644 index fb5aeeaf1..000000000 --- a/services/matrix-nutriphi-bot/src/transcription/transcription.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TranscriptionService } from './transcription.service'; - -@Module({ - providers: [TranscriptionService], - exports: [TranscriptionService], -}) -export class TranscriptionModule {} diff --git a/services/matrix-nutriphi-bot/src/transcription/transcription.service.ts b/services/matrix-nutriphi-bot/src/transcription/transcription.service.ts deleted file mode 100644 index 85296cf98..000000000 --- a/services/matrix-nutriphi-bot/src/transcription/transcription.service.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -interface SttResponse { - text: string; - language?: string; - model?: string; -} - -@Injectable() -export class TranscriptionService { - private readonly logger = new Logger(TranscriptionService.name); - private readonly sttUrl: string; - - constructor(private configService: ConfigService) { - this.sttUrl = this.configService.get('stt.url') || 'http://localhost:3020'; - this.logger.log(`STT Service URL: ${this.sttUrl}`); - } - - async transcribe(audioBuffer: Buffer, language: string = 'de'): Promise { - const formData = new FormData(); - const blob = new Blob([new Uint8Array(audioBuffer)], { type: 'audio/ogg' }); - formData.append('file', blob, 'audio.ogg'); - formData.append('language', language); - - try { - const response = await fetch(`${this.sttUrl}/transcribe`, { - method: 'POST', - body: formData, - }); - - if (!response.ok) { - const errorText = await response.text(); - throw new Error(`STT service error: ${response.status} - ${errorText}`); - } - - const result: SttResponse = await response.json(); - this.logger.log(`Transcription completed: ${result.text.substring(0, 50)}...`); - return result.text; - } catch (error) { - this.logger.error('Transcription failed:', error); - throw error; - } - } - - async checkHealth(): Promise { - try { - const response = await fetch(`${this.sttUrl}/health`); - return response.ok; - } catch { - return false; - } - } -} diff --git a/services/matrix-planta-bot/package.json b/services/matrix-planta-bot/package.json index ac4b0f54f..f2a530aba 100644 --- a/services/matrix-planta-bot/package.json +++ b/services/matrix-planta-bot/package.json @@ -22,6 +22,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { + "@manacore/bot-services": "workspace:*", "@nestjs/common": "^10.4.15", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.4.15", diff --git a/services/matrix-planta-bot/src/app.module.ts b/services/matrix-planta-bot/src/app.module.ts index e5ea0e3d1..9267ec11c 100644 --- a/services/matrix-planta-bot/src/app.module.ts +++ b/services/matrix-planta-bot/src/app.module.ts @@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config'; import { HealthController } from './health.controller'; import { BotModule } from './bot/bot.module'; import { PlantaModule } from './planta/planta.module'; -import { SessionModule } from './session/session.module'; import configuration from './config/configuration'; @Module({ @@ -14,7 +13,6 @@ import configuration from './config/configuration'; }), BotModule, PlantaModule, - SessionModule, ], controllers: [HealthController], }) diff --git a/services/matrix-planta-bot/src/bot/bot.module.ts b/services/matrix-planta-bot/src/bot/bot.module.ts index c6e26a634..6935dc829 100644 --- a/services/matrix-planta-bot/src/bot/bot.module.ts +++ b/services/matrix-planta-bot/src/bot/bot.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; import { MatrixService } from './matrix.service'; import { PlantaModule } from '../planta/planta.module'; -import { SessionModule } from '../session/session.module'; +import { SessionModule } from '@manacore/bot-services'; @Module({ - imports: [PlantaModule, SessionModule], + imports: [PlantaModule, SessionModule.forRoot()], providers: [MatrixService], exports: [MatrixService], }) diff --git a/services/matrix-planta-bot/src/bot/matrix.service.ts b/services/matrix-planta-bot/src/bot/matrix.service.ts index 9ca6a7173..705ca7574 100644 --- a/services/matrix-planta-bot/src/bot/matrix.service.ts +++ b/services/matrix-planta-bot/src/bot/matrix.service.ts @@ -6,7 +6,7 @@ import { AutojoinRoomsMixin, } from 'matrix-bot-sdk'; import { PlantaService, Plant } from '../planta/planta.service'; -import { SessionService } from '../session/session.service'; +import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @Injectable() diff --git a/services/matrix-planta-bot/src/session/session.module.ts b/services/matrix-planta-bot/src/session/session.module.ts deleted file mode 100644 index 834b715eb..000000000 --- a/services/matrix-planta-bot/src/session/session.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { SessionService } from './session.service'; - -@Module({ - providers: [SessionService], - exports: [SessionService], -}) -export class SessionModule {} diff --git a/services/matrix-planta-bot/src/session/session.service.ts b/services/matrix-planta-bot/src/session/session.service.ts deleted file mode 100644 index f1bed7852..000000000 --- a/services/matrix-planta-bot/src/session/session.service.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -interface UserSession { - token: string; - email: string; - expiresAt: Date; -} - -@Injectable() -export class SessionService { - private readonly logger = new Logger(SessionService.name); - private sessions: Map = new Map(); - private authUrl: string; - - constructor(private configService: ConfigService) { - this.authUrl = this.configService.get('auth.url') || 'http://localhost:3001'; - } - - async login( - matrixUserId: string, - email: string, - password: string - ): Promise<{ success: boolean; error?: string }> { - try { - const response = await fetch(`${this.authUrl}/api/v1/auth/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email, password }), - }); - - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - return { - success: false, - error: errorData.message || 'Authentifizierung fehlgeschlagen', - }; - } - - const data = await response.json(); - const token = data.accessToken || data.token; - - if (!token) { - return { success: false, error: 'Kein Token erhalten' }; - } - - // Store session (7 days expiry) - this.sessions.set(matrixUserId, { - token, - email, - expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), - }); - - this.logger.log(`User ${matrixUserId} logged in as ${email}`); - return { success: true }; - } catch (error) { - this.logger.error(`Login failed for ${matrixUserId}:`, error); - return { - success: false, - error: 'Verbindung zum Auth-Server fehlgeschlagen', - }; - } - } - - logout(matrixUserId: string): void { - this.sessions.delete(matrixUserId); - this.logger.log(`User ${matrixUserId} logged out`); - } - - getToken(matrixUserId: string): string | null { - const session = this.sessions.get(matrixUserId); - - if (!session) return null; - - if (session.expiresAt < new Date()) { - this.sessions.delete(matrixUserId); - return null; - } - - return session.token; - } - - isLoggedIn(matrixUserId: string): boolean { - return this.getToken(matrixUserId) !== null; - } - - getSessionCount(): number { - return this.sessions.size; - } -} diff --git a/services/matrix-presi-bot/package.json b/services/matrix-presi-bot/package.json index 5044daad2..44c6a434f 100644 --- a/services/matrix-presi-bot/package.json +++ b/services/matrix-presi-bot/package.json @@ -22,6 +22,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { + "@manacore/bot-services": "workspace:*", "@nestjs/common": "^10.4.15", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.4.15", diff --git a/services/matrix-presi-bot/src/app.module.ts b/services/matrix-presi-bot/src/app.module.ts index 7babeca70..3bcdfa5fa 100644 --- a/services/matrix-presi-bot/src/app.module.ts +++ b/services/matrix-presi-bot/src/app.module.ts @@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config'; import { HealthController } from './health.controller'; import { BotModule } from './bot/bot.module'; import { PresiModule } from './presi/presi.module'; -import { SessionModule } from './session/session.module'; import configuration from './config/configuration'; @Module({ @@ -14,7 +13,6 @@ import configuration from './config/configuration'; }), BotModule, PresiModule, - SessionModule, ], controllers: [HealthController], }) diff --git a/services/matrix-presi-bot/src/bot/bot.module.ts b/services/matrix-presi-bot/src/bot/bot.module.ts index 0c3b493aa..fd11bd01e 100644 --- a/services/matrix-presi-bot/src/bot/bot.module.ts +++ b/services/matrix-presi-bot/src/bot/bot.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; import { MatrixService } from './matrix.service'; import { PresiModule } from '../presi/presi.module'; -import { SessionModule } from '../session/session.module'; +import { SessionModule } from '@manacore/bot-services'; @Module({ - imports: [PresiModule, SessionModule], + imports: [PresiModule, SessionModule.forRoot()], providers: [MatrixService], exports: [MatrixService], }) diff --git a/services/matrix-presi-bot/src/bot/matrix.service.ts b/services/matrix-presi-bot/src/bot/matrix.service.ts index 383d7422e..417b657e0 100644 --- a/services/matrix-presi-bot/src/bot/matrix.service.ts +++ b/services/matrix-presi-bot/src/bot/matrix.service.ts @@ -6,7 +6,7 @@ import { AutojoinRoomsMixin, } from 'matrix-bot-sdk'; import { PresiService, Deck, Theme, SlideContent } from '../presi/presi.service'; -import { SessionService } from '../session/session.service'; +import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @Injectable() diff --git a/services/matrix-presi-bot/src/session/session.module.ts b/services/matrix-presi-bot/src/session/session.module.ts deleted file mode 100644 index 834b715eb..000000000 --- a/services/matrix-presi-bot/src/session/session.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { SessionService } from './session.service'; - -@Module({ - providers: [SessionService], - exports: [SessionService], -}) -export class SessionModule {} diff --git a/services/matrix-presi-bot/src/session/session.service.ts b/services/matrix-presi-bot/src/session/session.service.ts deleted file mode 100644 index 504b9951d..000000000 --- a/services/matrix-presi-bot/src/session/session.service.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -interface UserSession { - token: string; - email: string; - expiresAt: Date; -} - -@Injectable() -export class SessionService { - private readonly logger = new Logger(SessionService.name); - private sessions: Map = new Map(); - private authUrl: string; - - constructor(private configService: ConfigService) { - this.authUrl = this.configService.get('auth.url') || 'http://localhost:3001'; - } - - async login( - matrixUserId: string, - email: string, - password: string - ): Promise<{ success: boolean; error?: string }> { - try { - const response = await fetch(`${this.authUrl}/api/v1/auth/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email, password }), - }); - - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - return { - success: false, - error: errorData.message || 'Authentifizierung fehlgeschlagen', - }; - } - - const data = await response.json(); - const token = data.accessToken || data.token; - - if (!token) { - return { success: false, error: 'Kein Token erhalten' }; - } - - this.sessions.set(matrixUserId, { - token, - email, - expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), - }); - - this.logger.log(`User ${matrixUserId} logged in as ${email}`); - return { success: true }; - } catch (error) { - this.logger.error(`Login failed for ${matrixUserId}:`, error); - return { - success: false, - error: 'Verbindung zum Auth-Server fehlgeschlagen', - }; - } - } - - logout(matrixUserId: string): void { - this.sessions.delete(matrixUserId); - this.logger.log(`User ${matrixUserId} logged out`); - } - - getToken(matrixUserId: string): string | null { - const session = this.sessions.get(matrixUserId); - if (!session) return null; - if (session.expiresAt < new Date()) { - this.sessions.delete(matrixUserId); - return null; - } - return session.token; - } - - isLoggedIn(matrixUserId: string): boolean { - return this.getToken(matrixUserId) !== null; - } - - getSessionCount(): number { - return this.sessions.size; - } -} diff --git a/services/matrix-project-doc-bot/package.json b/services/matrix-project-doc-bot/package.json index 5df3805a6..3a965047d 100644 --- a/services/matrix-project-doc-bot/package.json +++ b/services/matrix-project-doc-bot/package.json @@ -27,6 +27,7 @@ "db:studio": "drizzle-kit studio" }, "dependencies": { + "@manacore/bot-services": "workspace:*", "@nestjs/common": "^10.4.15", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.4.15", diff --git a/services/matrix-project-doc-bot/src/media/media.module.ts b/services/matrix-project-doc-bot/src/media/media.module.ts index 7d62a4e77..2acb1d09f 100644 --- a/services/matrix-project-doc-bot/src/media/media.module.ts +++ b/services/matrix-project-doc-bot/src/media/media.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; import { MediaService } from './media.service'; import { StorageService } from './storage.service'; -import { TranscriptionModule } from '../transcription/transcription.module'; +import { TranscriptionModule } from '@manacore/bot-services'; @Module({ - imports: [TranscriptionModule], + imports: [TranscriptionModule.forRoot()], providers: [MediaService, StorageService], exports: [MediaService, StorageService], }) diff --git a/services/matrix-project-doc-bot/src/media/media.service.ts b/services/matrix-project-doc-bot/src/media/media.service.ts index d545b2d5c..b319be90d 100644 --- a/services/matrix-project-doc-bot/src/media/media.service.ts +++ b/services/matrix-project-doc-bot/src/media/media.service.ts @@ -2,7 +2,7 @@ import { Injectable, Inject, Logger } from '@nestjs/common'; import { DATABASE_CONNECTION } from '../database/database.module'; import { projectItems } from '../database/schema'; import { StorageService } from './storage.service'; -import { TranscriptionService } from '../transcription/transcription.service'; +import { TranscriptionService } from '@manacore/bot-services'; import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import type * as schema from '../database/schema'; diff --git a/services/matrix-project-doc-bot/src/transcription/transcription.module.ts b/services/matrix-project-doc-bot/src/transcription/transcription.module.ts deleted file mode 100644 index fb5aeeaf1..000000000 --- a/services/matrix-project-doc-bot/src/transcription/transcription.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TranscriptionService } from './transcription.service'; - -@Module({ - providers: [TranscriptionService], - exports: [TranscriptionService], -}) -export class TranscriptionModule {} diff --git a/services/matrix-project-doc-bot/src/transcription/transcription.service.ts b/services/matrix-project-doc-bot/src/transcription/transcription.service.ts deleted file mode 100644 index d2cfcd858..000000000 --- a/services/matrix-project-doc-bot/src/transcription/transcription.service.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -interface SttResponse { - text: string; - language?: string; - model?: string; -} - -@Injectable() -export class TranscriptionService { - private readonly logger = new Logger(TranscriptionService.name); - private readonly sttUrl: string; - - constructor(private configService: ConfigService) { - this.sttUrl = this.configService.get('stt.url') || 'http://localhost:3020'; - this.logger.log(`STT Service URL: ${this.sttUrl}`); - } - - async transcribe(audioBuffer: Buffer, language: string = 'de'): Promise { - const formData = new FormData(); - const blob = new Blob([new Uint8Array(audioBuffer)], { type: 'audio/ogg' }); - formData.append('file', blob, 'audio.ogg'); - formData.append('language', language); - - try { - const response = await fetch(`${this.sttUrl}/transcribe`, { - method: 'POST', - body: formData, - }); - - if (!response.ok) { - const errorText = await response.text(); - throw new Error(`STT service error: ${response.status} - ${errorText}`); - } - - const result: SttResponse = await response.json(); - this.logger.log( - `Transcription completed (${result.model || 'whisper'}): ${result.text.substring(0, 50)}...` - ); - return result.text; - } catch (error) { - this.logger.error('Transcription failed:', error); - throw error; - } - } -} diff --git a/services/matrix-questions-bot/package.json b/services/matrix-questions-bot/package.json index 149e9c372..e3ff432fb 100644 --- a/services/matrix-questions-bot/package.json +++ b/services/matrix-questions-bot/package.json @@ -22,6 +22,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { + "@manacore/bot-services": "workspace:*", "@nestjs/common": "^10.4.15", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.4.15", diff --git a/services/matrix-questions-bot/src/app.module.ts b/services/matrix-questions-bot/src/app.module.ts index 8042c3990..11facf21d 100644 --- a/services/matrix-questions-bot/src/app.module.ts +++ b/services/matrix-questions-bot/src/app.module.ts @@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config'; import { HealthController } from './health.controller'; import { BotModule } from './bot/bot.module'; import { QuestionsModule } from './questions/questions.module'; -import { SessionModule } from './session/session.module'; import configuration from './config/configuration'; @Module({ @@ -14,7 +13,6 @@ import configuration from './config/configuration'; }), BotModule, QuestionsModule, - SessionModule, ], controllers: [HealthController], }) diff --git a/services/matrix-questions-bot/src/bot/bot.module.ts b/services/matrix-questions-bot/src/bot/bot.module.ts index 76c464e96..d72b37216 100644 --- a/services/matrix-questions-bot/src/bot/bot.module.ts +++ b/services/matrix-questions-bot/src/bot/bot.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; import { MatrixService } from './matrix.service'; import { QuestionsModule } from '../questions/questions.module'; -import { SessionModule } from '../session/session.module'; +import { SessionModule } from '@manacore/bot-services'; @Module({ - imports: [QuestionsModule, SessionModule], + imports: [QuestionsModule, SessionModule.forRoot()], providers: [MatrixService], exports: [MatrixService], }) diff --git a/services/matrix-questions-bot/src/bot/matrix.service.ts b/services/matrix-questions-bot/src/bot/matrix.service.ts index 8c38eb07c..7c56688e5 100644 --- a/services/matrix-questions-bot/src/bot/matrix.service.ts +++ b/services/matrix-questions-bot/src/bot/matrix.service.ts @@ -6,7 +6,7 @@ import { AutojoinRoomsMixin, } from 'matrix-bot-sdk'; import { QuestionsService, Question, Collection, Answer } from '../questions/questions.service'; -import { SessionService } from '../session/session.service'; +import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @Injectable() diff --git a/services/matrix-questions-bot/src/session/session.module.ts b/services/matrix-questions-bot/src/session/session.module.ts deleted file mode 100644 index 834b715eb..000000000 --- a/services/matrix-questions-bot/src/session/session.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { SessionService } from './session.service'; - -@Module({ - providers: [SessionService], - exports: [SessionService], -}) -export class SessionModule {} diff --git a/services/matrix-questions-bot/src/session/session.service.ts b/services/matrix-questions-bot/src/session/session.service.ts deleted file mode 100644 index f1bed7852..000000000 --- a/services/matrix-questions-bot/src/session/session.service.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -interface UserSession { - token: string; - email: string; - expiresAt: Date; -} - -@Injectable() -export class SessionService { - private readonly logger = new Logger(SessionService.name); - private sessions: Map = new Map(); - private authUrl: string; - - constructor(private configService: ConfigService) { - this.authUrl = this.configService.get('auth.url') || 'http://localhost:3001'; - } - - async login( - matrixUserId: string, - email: string, - password: string - ): Promise<{ success: boolean; error?: string }> { - try { - const response = await fetch(`${this.authUrl}/api/v1/auth/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email, password }), - }); - - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - return { - success: false, - error: errorData.message || 'Authentifizierung fehlgeschlagen', - }; - } - - const data = await response.json(); - const token = data.accessToken || data.token; - - if (!token) { - return { success: false, error: 'Kein Token erhalten' }; - } - - // Store session (7 days expiry) - this.sessions.set(matrixUserId, { - token, - email, - expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), - }); - - this.logger.log(`User ${matrixUserId} logged in as ${email}`); - return { success: true }; - } catch (error) { - this.logger.error(`Login failed for ${matrixUserId}:`, error); - return { - success: false, - error: 'Verbindung zum Auth-Server fehlgeschlagen', - }; - } - } - - logout(matrixUserId: string): void { - this.sessions.delete(matrixUserId); - this.logger.log(`User ${matrixUserId} logged out`); - } - - getToken(matrixUserId: string): string | null { - const session = this.sessions.get(matrixUserId); - - if (!session) return null; - - if (session.expiresAt < new Date()) { - this.sessions.delete(matrixUserId); - return null; - } - - return session.token; - } - - isLoggedIn(matrixUserId: string): boolean { - return this.getToken(matrixUserId) !== null; - } - - getSessionCount(): number { - return this.sessions.size; - } -} diff --git a/services/matrix-skilltree-bot/package.json b/services/matrix-skilltree-bot/package.json index 866e0dd3a..5b5b96014 100644 --- a/services/matrix-skilltree-bot/package.json +++ b/services/matrix-skilltree-bot/package.json @@ -22,6 +22,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { + "@manacore/bot-services": "workspace:*", "@nestjs/common": "^10.4.15", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.4.15", diff --git a/services/matrix-skilltree-bot/src/app.module.ts b/services/matrix-skilltree-bot/src/app.module.ts index f76ada916..e37fea52a 100644 --- a/services/matrix-skilltree-bot/src/app.module.ts +++ b/services/matrix-skilltree-bot/src/app.module.ts @@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config'; import { HealthController } from './health.controller'; import { BotModule } from './bot/bot.module'; import { SkilltreeModule } from './skilltree/skilltree.module'; -import { SessionModule } from './session/session.module'; import configuration from './config/configuration'; @Module({ @@ -14,7 +13,6 @@ import configuration from './config/configuration'; }), BotModule, SkilltreeModule, - SessionModule, ], controllers: [HealthController], }) diff --git a/services/matrix-skilltree-bot/src/bot/bot.module.ts b/services/matrix-skilltree-bot/src/bot/bot.module.ts index bdf211146..e5e7d6758 100644 --- a/services/matrix-skilltree-bot/src/bot/bot.module.ts +++ b/services/matrix-skilltree-bot/src/bot/bot.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; import { MatrixService } from './matrix.service'; import { SkilltreeModule } from '../skilltree/skilltree.module'; -import { SessionModule } from '../session/session.module'; +import { SessionModule } from '@manacore/bot-services'; @Module({ - imports: [SkilltreeModule, SessionModule], + imports: [SkilltreeModule, SessionModule.forRoot()], providers: [MatrixService], exports: [MatrixService], }) diff --git a/services/matrix-skilltree-bot/src/bot/matrix.service.ts b/services/matrix-skilltree-bot/src/bot/matrix.service.ts index 0bcf669d5..6684a0bdd 100644 --- a/services/matrix-skilltree-bot/src/bot/matrix.service.ts +++ b/services/matrix-skilltree-bot/src/bot/matrix.service.ts @@ -6,7 +6,7 @@ import { AutojoinRoomsMixin, } from 'matrix-bot-sdk'; import { SkilltreeService, Skill, SkillBranch } from '../skilltree/skilltree.service'; -import { SessionService } from '../session/session.service'; +import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @Injectable() diff --git a/services/matrix-skilltree-bot/src/session/session.module.ts b/services/matrix-skilltree-bot/src/session/session.module.ts deleted file mode 100644 index 834b715eb..000000000 --- a/services/matrix-skilltree-bot/src/session/session.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { SessionService } from './session.service'; - -@Module({ - providers: [SessionService], - exports: [SessionService], -}) -export class SessionModule {} diff --git a/services/matrix-skilltree-bot/src/session/session.service.ts b/services/matrix-skilltree-bot/src/session/session.service.ts deleted file mode 100644 index 504b9951d..000000000 --- a/services/matrix-skilltree-bot/src/session/session.service.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -interface UserSession { - token: string; - email: string; - expiresAt: Date; -} - -@Injectable() -export class SessionService { - private readonly logger = new Logger(SessionService.name); - private sessions: Map = new Map(); - private authUrl: string; - - constructor(private configService: ConfigService) { - this.authUrl = this.configService.get('auth.url') || 'http://localhost:3001'; - } - - async login( - matrixUserId: string, - email: string, - password: string - ): Promise<{ success: boolean; error?: string }> { - try { - const response = await fetch(`${this.authUrl}/api/v1/auth/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email, password }), - }); - - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - return { - success: false, - error: errorData.message || 'Authentifizierung fehlgeschlagen', - }; - } - - const data = await response.json(); - const token = data.accessToken || data.token; - - if (!token) { - return { success: false, error: 'Kein Token erhalten' }; - } - - this.sessions.set(matrixUserId, { - token, - email, - expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), - }); - - this.logger.log(`User ${matrixUserId} logged in as ${email}`); - return { success: true }; - } catch (error) { - this.logger.error(`Login failed for ${matrixUserId}:`, error); - return { - success: false, - error: 'Verbindung zum Auth-Server fehlgeschlagen', - }; - } - } - - logout(matrixUserId: string): void { - this.sessions.delete(matrixUserId); - this.logger.log(`User ${matrixUserId} logged out`); - } - - getToken(matrixUserId: string): string | null { - const session = this.sessions.get(matrixUserId); - if (!session) return null; - if (session.expiresAt < new Date()) { - this.sessions.delete(matrixUserId); - return null; - } - return session.token; - } - - isLoggedIn(matrixUserId: string): boolean { - return this.getToken(matrixUserId) !== null; - } - - getSessionCount(): number { - return this.sessions.size; - } -} diff --git a/services/matrix-storage-bot/package.json b/services/matrix-storage-bot/package.json index 71fda589d..705e43503 100644 --- a/services/matrix-storage-bot/package.json +++ b/services/matrix-storage-bot/package.json @@ -22,6 +22,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { + "@manacore/bot-services": "workspace:*", "@nestjs/common": "^10.4.15", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.4.15", diff --git a/services/matrix-storage-bot/src/app.module.ts b/services/matrix-storage-bot/src/app.module.ts index d67fe2f63..7fd59e6d0 100644 --- a/services/matrix-storage-bot/src/app.module.ts +++ b/services/matrix-storage-bot/src/app.module.ts @@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config'; import { HealthController } from './health.controller'; import { BotModule } from './bot/bot.module'; import { StorageModule } from './storage/storage.module'; -import { SessionModule } from './session/session.module'; import configuration from './config/configuration'; @Module({ @@ -14,7 +13,6 @@ import configuration from './config/configuration'; }), BotModule, StorageModule, - SessionModule, ], controllers: [HealthController], }) diff --git a/services/matrix-storage-bot/src/bot/bot.module.ts b/services/matrix-storage-bot/src/bot/bot.module.ts index cf0c6aea1..47308a4b8 100644 --- a/services/matrix-storage-bot/src/bot/bot.module.ts +++ b/services/matrix-storage-bot/src/bot/bot.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; import { MatrixService } from './matrix.service'; import { StorageModule } from '../storage/storage.module'; -import { SessionModule } from '../session/session.module'; +import { SessionModule } from '@manacore/bot-services'; @Module({ - imports: [StorageModule, SessionModule], + imports: [StorageModule, SessionModule.forRoot()], providers: [MatrixService], exports: [MatrixService], }) diff --git a/services/matrix-storage-bot/src/bot/matrix.service.ts b/services/matrix-storage-bot/src/bot/matrix.service.ts index 30673b9e8..f8af7b7b3 100644 --- a/services/matrix-storage-bot/src/bot/matrix.service.ts +++ b/services/matrix-storage-bot/src/bot/matrix.service.ts @@ -6,7 +6,7 @@ import { AutojoinRoomsMixin, } from 'matrix-bot-sdk'; import { StorageService, StorageFile, Folder, ShareLink, TrashItem } from '../storage/storage.service'; -import { SessionService } from '../session/session.service'; +import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; type ListItem = StorageFile | Folder; diff --git a/services/matrix-storage-bot/src/session/session.module.ts b/services/matrix-storage-bot/src/session/session.module.ts deleted file mode 100644 index 834b715eb..000000000 --- a/services/matrix-storage-bot/src/session/session.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { SessionService } from './session.service'; - -@Module({ - providers: [SessionService], - exports: [SessionService], -}) -export class SessionModule {} diff --git a/services/matrix-storage-bot/src/session/session.service.ts b/services/matrix-storage-bot/src/session/session.service.ts deleted file mode 100644 index f1bed7852..000000000 --- a/services/matrix-storage-bot/src/session/session.service.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -interface UserSession { - token: string; - email: string; - expiresAt: Date; -} - -@Injectable() -export class SessionService { - private readonly logger = new Logger(SessionService.name); - private sessions: Map = new Map(); - private authUrl: string; - - constructor(private configService: ConfigService) { - this.authUrl = this.configService.get('auth.url') || 'http://localhost:3001'; - } - - async login( - matrixUserId: string, - email: string, - password: string - ): Promise<{ success: boolean; error?: string }> { - try { - const response = await fetch(`${this.authUrl}/api/v1/auth/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email, password }), - }); - - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - return { - success: false, - error: errorData.message || 'Authentifizierung fehlgeschlagen', - }; - } - - const data = await response.json(); - const token = data.accessToken || data.token; - - if (!token) { - return { success: false, error: 'Kein Token erhalten' }; - } - - // Store session (7 days expiry) - this.sessions.set(matrixUserId, { - token, - email, - expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), - }); - - this.logger.log(`User ${matrixUserId} logged in as ${email}`); - return { success: true }; - } catch (error) { - this.logger.error(`Login failed for ${matrixUserId}:`, error); - return { - success: false, - error: 'Verbindung zum Auth-Server fehlgeschlagen', - }; - } - } - - logout(matrixUserId: string): void { - this.sessions.delete(matrixUserId); - this.logger.log(`User ${matrixUserId} logged out`); - } - - getToken(matrixUserId: string): string | null { - const session = this.sessions.get(matrixUserId); - - if (!session) return null; - - if (session.expiresAt < new Date()) { - this.sessions.delete(matrixUserId); - return null; - } - - return session.token; - } - - isLoggedIn(matrixUserId: string): boolean { - return this.getToken(matrixUserId) !== null; - } - - getSessionCount(): number { - return this.sessions.size; - } -}