mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-25 03:44:39 +02:00
feat(packages): add @manacore/bot-services shared package
Introduces a new shared package containing transport-agnostic business logic services for Matrix bots and the Gateway. This enables: - Individual bots to import shared services - A unified Gateway bot to combine all features - Code reuse without duplication Services included: - TodoService: Task management with projects, priorities, dates - CalendarService: Events, calendars, reminders - AiService: Ollama LLM integration, chat sessions, vision - ClockService: Timers, alarms, world clocks (API client) - Placeholder modules for Nutrition, Quotes, Stats, Docs Key features: - Pluggable storage providers (file-based, in-memory, custom) - German natural language input parsing - NestJS module system with dependency injection - Fully testable in isolation https://claude.ai/code/session_015bwcqVRiFmSydYTjvDJGTc
This commit is contained in:
parent
bea066c7f8
commit
68a6c7a8d6
28 changed files with 2492 additions and 0 deletions
71
packages/bot-services/src/shared/storage.ts
Normal file
71
packages/bot-services/src/shared/storage.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import { Logger } from '@nestjs/common';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { StorageProvider } from './types';
|
||||
|
||||
/**
|
||||
* File-based JSON storage provider
|
||||
* Used for local GDPR-compliant data storage
|
||||
*/
|
||||
export class FileStorageProvider<T> implements StorageProvider<T> {
|
||||
private readonly logger = new Logger(FileStorageProvider.name);
|
||||
private readonly filePath: string;
|
||||
private readonly defaultData: T;
|
||||
|
||||
constructor(filePath: string, defaultData: T) {
|
||||
this.filePath = filePath;
|
||||
this.defaultData = defaultData;
|
||||
}
|
||||
|
||||
async load(): Promise<T> {
|
||||
try {
|
||||
const dir = path.dirname(this.filePath);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
|
||||
if (fs.existsSync(this.filePath)) {
|
||||
const content = fs.readFileSync(this.filePath, 'utf-8');
|
||||
return JSON.parse(content);
|
||||
} else {
|
||||
await this.save(this.defaultData);
|
||||
return this.defaultData;
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to load data from ${this.filePath}:`, error);
|
||||
return this.defaultData;
|
||||
}
|
||||
}
|
||||
|
||||
async save(data: T): Promise<void> {
|
||||
try {
|
||||
const dir = path.dirname(this.filePath);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
fs.writeFileSync(this.filePath, JSON.stringify(data, null, 2));
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to save data to ${this.filePath}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In-memory storage provider (for testing)
|
||||
*/
|
||||
export class MemoryStorageProvider<T> implements StorageProvider<T> {
|
||||
private data: T;
|
||||
|
||||
constructor(defaultData: T) {
|
||||
this.data = defaultData;
|
||||
}
|
||||
|
||||
async load(): Promise<T> {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
async save(data: T): Promise<void> {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue