

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
12345# Telegram Search - Architecture & Development Guide67## 项目概述89这是一个把 Telegram 消息导入、导出到数据库中并提供搜索的服务。支持向量搜索和语义匹配,基于 OpenAI 的语义向量技术。1011## Monorepo 结构1213项目采用 pnpm workspace 管理,包含以下包:1415### Apps1617- **[apps/web](mdc:apps/web)**: 前端应用18 - Vue 3 + Pinia + Vue Router19 - 支持浏览器模式(PGlite)和服务器模式(PostgreSQL)20 - 主入口:[apps/web/src/main.ts](mdc:apps/web/src/main.ts)21 - 布局:[apps/web/src/layouts/default.vue](mdc:apps/web/src/layouts/default.vue)2223- **[apps/server](mdc:apps/server)**: WebSocket 服务器24 - 实时双向通信25 - 事件路由和会话管理26 - WebSocket 实现:[apps/server/src/ws](mdc:apps/server/src/ws)2728### Packages2930- **[packages/core](mdc:packages/core)**: 核心业务逻辑31 - CoreContext 事件总线:[packages/core/src/context.ts](mdc:packages/core/src/context.ts)32 - 事件处理器:[packages/core/src/event-handlers](mdc:packages/core/src/event-handlers)33 - 服务层:[packages/core/src/services](mdc:packages/core/src/services)34 - 消息解析器:[packages/core/src/message-resolvers](mdc:packages/core/src/message-resolvers)35 - 数据库模型:[packages/core/src/models](mdc:packages/core/src/models)36 - 数据库 Schema:[packages/core/src/schemas](mdc:packages/core/src/schemas)3738- **[packages/client](mdc:packages/client)**: 客户端集成层39 - WebSocket 适配器:[packages/client/src/adapters/websocket.ts](mdc:packages/client/src/adapters/websocket.ts)40 - Core Bridge 适配器:[packages/client/src/adapters/core-bridge.ts](mdc:packages/client/src/adapters/core-bridge.ts)41 - 客户端事件处理器:[packages/client/src/event-handlers](mdc:packages/client/src/event-handlers)42 - Pinia Stores:[packages/client/src/stores](mdc:packages/client/src/stores)43 - 组合式函数:[packages/client/src/composables](mdc:packages/client/src/composables)4445- **[packages/common](mdc:packages/common)**: 共享工具46 - 日志封装:使用 @guiiai/logg47 - 通用工具函数4849## 核心架构模式5051### 事件驱动架构5253整个系统基于事件驱动架构,使用 EventEmitter3 作为核心:5455#### CoreContext([packages/core/src/context.ts](mdc:packages/core/src/context.ts))5657- **ToCoreEvent**: 发送到核心系统的事件(如 `auth:login`, `message:query`)58- **FromCoreEvent**: 从核心系统发出的事件(如 `message:data`, `auth:status`)59- **Event Wrapping**: 自动错误处理和日志记录60- **Session Management**: 每个客户端会话有独立的 CoreContext 实例6162#### 事件流程6364```65Frontend (Vue Component)66 ↓ 用户操作67Client Store (Pinia)68 ↓ sendEvent via WebSocket Adapter69WebSocket Server70 ↓ 路由事件71CoreContext (Event Bus)72 ↓ 分发到对应的73Event Handler74 ↓ 调用75Service (Business Logic)76 ↓ 执行操作(Telegram API / Database)77 ↓ emit 结果事件78CoreContext79 ↓ 通过 WebSocket80Client Event Handler81 ↓ 更新82Client Store83 ↓ 响应式更新84Frontend (UI Update)85```8687### 核心事件处理器8889位于 [packages/core/src/event-handlers](mdc:packages/core/src/event-handlers):9091- **auth.ts**: 认证流程(登录、验证码、密码)92- **message.ts**: 消息查询和处理93- **dialog.ts**: 对话列表管理94- **storage.ts**: 消息同步和存储95- **entity.ts**: 用户、频道、群组信息96- **config.ts**: 配置管理97- **session.ts**: 会话管理98- **gram-events.ts**: Telegram 事件监听99- **message-resolver.ts**: 消息解析协调100- **takeout.ts**: 大量数据导出101102### 服务层103104位于 [packages/core/src/services](mdc:packages/core/src/services):105106每个服务对应一个事件处理器,处理具体的业务逻辑。服务通过 CoreContext 发送和接收事件。107108### 消息处理管道109110位于 [packages/core/src/message-resolvers](mdc:packages/core/src/message-resolvers):111112- **embedding-resolver.ts**: 生成向量嵌入(OpenAI/Ollama)113- **jieba-resolver.ts**: 中文分词114- **link-resolver.ts**: 链接提取和处理115- **media-resolver.ts**: 媒体文件处理116- **user-resolver.ts**: 用户引用处理117118消息通过多个 resolver 流式处理,每个 resolver 负责一个特定方面。119120## 数据库121122### ORM 和迁移123124- **ORM**: Drizzle ORM125- **Schema 定义**: [packages/core/src/schemas](mdc:packages/core/src/schemas)126- **迁移文件**: [drizzle](mdc:drizzle)127- **配置**: [drizzle.config.ts](mdc:drizzle.config.ts)128129### 数据库支持1301311. **PostgreSQL + pgvector**: 生产环境,完整向量搜索1322. **PGlite**: 浏览器模式,实验性功能133134### 主要表135136- `chat_messages`: 消息主表137- `chat_message_stats`: 消息统计138- `joined_chats`: 已加入的聊天139- `photos`: 照片资源140- `stickers`: 贴纸141- `sticker_packs`: 贴纸包142- `recent_sent_stickers`: 最近发送的贴纸143144## Telegram 集成145146### 客户端管理147148使用 [packages/core/src/context.ts](mdc:packages/core/src/context.ts) 进行 Telegram 客户端的上下文管理:149150```typescript151// 设置客户端152ctx.setClient(telegramClient)153154// 获取客户端(确保已设置)155const client = ctx.getClient()156```157158### 重要细节159160- **Message ID**: 递增的,优先使用 Message ID 而不是时间戳161- **Telegram API**: 使用 gram.js 库162- **事件监听**: 通过 GramEventsHandler 监听 Telegram 实时事件163164## 日志系统165166使用 @guiiai/logg,在 [packages/common](mdc:packages/common) 封装。167168### 使用方式169170```typescript171import { useLogger } from '@guiiai/logg'172173// 基本日志174useLogger().log('Message')175176// 带字段177useLogger().withFields({ userId: 123 }).log('User action')178179// 错误日志180useLogger().withError(error).error('Operation failed')181```182183## 包管理184185### 工具186187- **包管理器**: pnpm188- **Workspace**: pnpm workspace189- **快捷命令**: 可使用 `ni` 和 `nr` (如果安装了 ni 工具)190191### 常用脚本192193查看 [package.json](mdc:package.json) 中的 scripts:194195```bash196# 开发模式197pnpm run dev # 浏览器模式(带 Core)198pnpm run web:dev # 仅前端199pnpm run server:dev # 仅后端200201# 启动完整服务202pnpm run start # 后端 + 前端预览203204# 构建205pnpm run build # 构建前端(浏览器模式)206pnpm run web:build # 构建前端(服务器模式)207pnpm run packages:build # 构建所有 packages208209# 数据库210pnpm run db:generate # 生成迁移文件211212# 代码质量213pnpm run lint # ESLint 检查214pnpm run lint:fix # 自动修复215pnpm run typecheck # 类型检查216pnpm run test run # 运行测试217```218219## 配置文件220221### 环境配置222223- **浏览器模式**: `.env` 文件224 - `VITE_TELEGRAM_API_ID`225 - `VITE_TELEGRAM_API_HASH`226227- **服务器模式**: 通过环境变量配置,由 `.env` / `.env.local` 加载并通过 dotenvx 注入 `apps/server`228 - `TELEGRAM_API_ID`, `TELEGRAM_API_HASH`229 - `DATABASE_TYPE`, `DATABASE_URL`230 - `PROXY_URL`, `PROXY_MT_PROXY` 等代理相关配置231232> [!NOTE]233> Embedding / LLM 相关设置现在在应用内按账号配置(设置 → API)。234> 环境变量如 `EMBEDDING_API_KEY`, `EMBEDDING_MODEL` 等已废弃,仅保留向后兼容,不推荐新增依赖。235236## 开发规范237238### TypeScript239240- 所有代码使用 TypeScript241- 严格的类型检查242- 优先使用接口和类型定义243244### 代码风格245246- ESLint 配置:[eslint.config.ts](mdc:eslint.config.ts)247- 使用 @unbird/eslint-config248- 自动格式化:运行 `pnpm run lint:fix`249250### 命名规范251252- **文件名**: kebab-case(如 `user-service.ts`)253- **组件**: PascalCase(如 `UserProfile.vue`)254- **函数/变量**: camelCase(如 `getUserData`)255- **类型/接口**: PascalCase(如 `UserData`)256- **常量**: UPPER_SNAKE_CASE(如 `API_BASE_URL`)257258### 事件命名259260- 格式:`<domain>:<action>`261- 示例:`auth:login`, `message:query`, `dialog:fetch`262- ToCore 事件:客户端 → 核心263- FromCore 事件:核心 → 客户端264265## 性能优化266267### 消息处理268269- 使用流式处理,避免一次性加载大量数据270- Message Resolver 可并行处理271- 数据库查询优化:使用索引和向量索引272273### 前端优化274275- 虚拟列表:[packages/client/src/composables/useVirtualList.ts](mdc:packages/client/src/composables/useVirtualList.ts)276- 分页:[packages/common/src/pagination.ts](mdc:packages/common/src/pagination.ts)277- 懒加载组件278279## 测试280281### 测试框架282283- Vitest284- 测试文件:`*.spec.ts` 或 `*.test.ts`285286### 运行测试287288```bash289pnpm run test run290```291292## Docker 部署293294### Docker Compose295296[docker-compose.yml](mdc:docker-compose.yml) 包含:297- PostgreSQL + pgvector298- 应用服务299300### Dockerfile301302[Dockerfile](mdc:Dockerfile) 用于构建生产镜像。303304## 常见问题305306### Message ID 处理307308Message ID 是递增的,涉及 Message 处理时:309- ✅ 优先使用 Message ID310- ❌ 避免仅依赖时间戳311312### 错误处理313314使用 CoreContext 的 `withError` 方法:315316```typescript317ctx.withError(error, 'Description')318```319320会自动:321- 处理 FloodWaitError322- 处理 RpcError323- 记录日志324- 发送 `core:error` 事件325326### 日志记录327328所有关键操作都应记录日志:329330```typescript331useLogger().withFields({ context }).debug('Debug info')332useLogger().withFields({ context }).log('Info')333useLogger().withFields({ context }).warn('Warning')334useLogger().withError(error).error('Error')335```336337## 相关文档338339- [README.md](mdc:README.md): 主要文档340- [README_CN.md](mdc:docs/README_CN.md): 中文文档341- [README_JA.md](mdc:docs/README_JA.md): 日文文档342- [CONTRIBUTING.md](mdc:CONTRIBUTING.md): 贡献指南343- [LICENSE](mdc:LICENSE): 许可证344
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| groupultra/telegram-search.cursor/rules/client.mdc · 4.1k | Cursor rules | stylearchtypesdependencies+1 | 60/100 | 14 days ago | |
| groupultra/telegram-search.cursor/rules/testing.mdc · 4.1k | Cursor rules | teststyletesting-strategydatabase | 55/100 | 14 days ago | |
| groupultra/telegram-search.cursor/rules/tooling.mdc · 4.1k | Cursor rules | buildlint-formatstyledeployment+1 | 67/100 | 14 days ago | |
| groupultra/telegram-search.github/copilot-instructions.md · 4.1k | Copilot instructions | teststyleagent-behaviour | 76/100 | 14 days ago | |
| groupultra/telegram-searchAGENTS.md · 4.1k | AGENTS.md | setupbuildtestlint-format+10 | 83/100 | 14 days ago | |
| groupultra/telegram-search.cursor/rules/backend-server.mdc · 4.1k | Cursor rules | setupsecuritymonorepo | 52/100 | 14 days ago | |
| groupultra/telegram-search.cursor/rules/contributing.mdc · 4.1k | Cursor rules | styletypesgit | 56/100 | 14 days ago | |
| groupultra/telegram-search.cursor/rules/core.mdc · 4.1k | Cursor rules | stylearchdependenciesdatabase+1 | 60/100 | 14 days ago | |
| groupultra/telegram-search.cursor/rules/db.mdc · 4.1k | Cursor rules | styletypesdatabaseperformance | 59/100 | 14 days ago | |
| groupultra/telegram-search.cursor/rules/events.mdc · 4.1k | Cursor rules | style | 60/100 | 14 days ago | |
| groupultra/telegram-search.cursor/rules/frontend-web.mdc · 4.1k | Cursor rules | stylesecurityuimonorepo | 56/100 | 14 days ago | |
| groupultra/telegram-search.cursor/rules/pglite-inspector.mdc · 4.1k | Cursor rules | securityapi | 47/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 46 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 14 days ago | |
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 14 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 14 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 46 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/groupultra-telegram-search-cursor-rules-architecture)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.