@deadragdoll/tellymcp 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/.env.example.client +93 -0
  2. package/.env.example.gateway +120 -0
  3. package/CHANGELOG.md +155 -0
  4. package/LICENSE +21 -0
  5. package/README-ru.md +338 -0
  6. package/README.md +1262 -0
  7. package/STANDALONE-ru.md +266 -0
  8. package/STANDALONE.md +266 -0
  9. package/TOOLS.md +1296 -0
  10. package/config/templates/env.both.template +83 -0
  11. package/config/templates/env.client.template +60 -0
  12. package/config/templates/env.gateway.template +82 -0
  13. package/dist/cli.js +636 -0
  14. package/dist/index.js +17 -0
  15. package/dist/lib/logfeed/store.js +52 -0
  16. package/dist/lib/middlewares/tracer.js +172 -0
  17. package/dist/lib/mixins/db.js +267 -0
  18. package/dist/lib/mixins/logfeed.js +34 -0
  19. package/dist/lib/mixins/session.errors.js +142 -0
  20. package/dist/lib/moleculer.js +2 -0
  21. package/dist/lib/trace.js +147 -0
  22. package/dist/lib/traceContext.js +116 -0
  23. package/dist/moleculer.config.js +274 -0
  24. package/dist/services/features/telegram-mcp/approval.service.js +33 -0
  25. package/dist/services/features/telegram-mcp/browser.service.js +42 -0
  26. package/dist/services/features/telegram-mcp/collaboration.service.js +53 -0
  27. package/dist/services/features/telegram-mcp/ensuredb.service.js +337 -0
  28. package/dist/services/features/telegram-mcp/gateway-delivery.service.js +378 -0
  29. package/dist/services/features/telegram-mcp/gateway-loopback.js +10 -0
  30. package/dist/services/features/telegram-mcp/gateway-rmq.service.js +294 -0
  31. package/dist/services/features/telegram-mcp/gateway-socket.service.js +1463 -0
  32. package/dist/services/features/telegram-mcp/gateway.service.js +1141 -0
  33. package/dist/services/features/telegram-mcp/inbox.service.js +33 -0
  34. package/dist/services/features/telegram-mcp/mcp-http.service.js +76 -0
  35. package/dist/services/features/telegram-mcp/mcp-server.service.js +127 -0
  36. package/dist/services/features/telegram-mcp/notify.service.js +33 -0
  37. package/dist/services/features/telegram-mcp/pair.service.js +33 -0
  38. package/dist/services/features/telegram-mcp/runtime.service.js +36 -0
  39. package/dist/services/features/telegram-mcp/session-context.service.js +33 -0
  40. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +103 -0
  41. package/dist/services/features/telegram-mcp/src/app/config/env.js +317 -0
  42. package/dist/services/features/telegram-mcp/src/app/http.js +774 -0
  43. package/dist/services/features/telegram-mcp/src/app/index.js +2 -0
  44. package/dist/services/features/telegram-mcp/src/app/providers/mcp/server.js +13 -0
  45. package/dist/services/features/telegram-mcp/src/app/providers/redis/client.js +18 -0
  46. package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +740 -0
  47. package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +267 -0
  48. package/dist/services/features/telegram-mcp/src/app/webapp/relay.js +69 -0
  49. package/dist/services/features/telegram-mcp/src/app/webapp/tmux.js +9 -0
  50. package/dist/services/features/telegram-mcp/src/entities/auth/model/types.js +2 -0
  51. package/dist/services/features/telegram-mcp/src/entities/browser/model/types.js +2 -0
  52. package/dist/services/features/telegram-mcp/src/entities/collaboration/model/types.js +2 -0
  53. package/dist/services/features/telegram-mcp/src/entities/inbox/model/types.js +2 -0
  54. package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +545 -0
  55. package/dist/services/features/telegram-mcp/src/entities/request/model/types.js +2 -0
  56. package/dist/services/features/telegram-mcp/src/entities/session/model/types.js +2 -0
  57. package/dist/services/features/telegram-mcp/src/features/ask-user/model/askUserTelegram.js +33 -0
  58. package/dist/services/features/telegram-mcp/src/features/browser/model/browserClearLogsTool.js +28 -0
  59. package/dist/services/features/telegram-mcp/src/features/browser/model/browserClickTool.js +28 -0
  60. package/dist/services/features/telegram-mcp/src/features/browser/model/browserCloseTool.js +28 -0
  61. package/dist/services/features/telegram-mcp/src/features/browser/model/browserComputedStyleTool.js +28 -0
  62. package/dist/services/features/telegram-mcp/src/features/browser/model/browserConsoleTool.js +28 -0
  63. package/dist/services/features/telegram-mcp/src/features/browser/model/browserDomTool.js +28 -0
  64. package/dist/services/features/telegram-mcp/src/features/browser/model/browserErrorsTool.js +28 -0
  65. package/dist/services/features/telegram-mcp/src/features/browser/model/browserFillTool.js +28 -0
  66. package/dist/services/features/telegram-mcp/src/features/browser/model/browserNetworkFailuresTool.js +28 -0
  67. package/dist/services/features/telegram-mcp/src/features/browser/model/browserOpenTool.js +33 -0
  68. package/dist/services/features/telegram-mcp/src/features/browser/model/browserPressTool.js +28 -0
  69. package/dist/services/features/telegram-mcp/src/features/browser/model/browserReloadTool.js +28 -0
  70. package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +28 -0
  71. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +689 -0
  72. package/dist/services/features/telegram-mcp/src/features/browser/model/browserWaitForTool.js +28 -0
  73. package/dist/services/features/telegram-mcp/src/features/browser/model/browserWaitForUrlTool.js +28 -0
  74. package/dist/services/features/telegram-mcp/src/features/collaboration/model/backend.js +2 -0
  75. package/dist/services/features/telegram-mcp/src/features/collaboration/model/collaborationService.js +26 -0
  76. package/dist/services/features/telegram-mcp/src/features/collaboration/model/localCollaborationBackend.js +390 -0
  77. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +102 -0
  78. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileTool.js +33 -0
  79. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerNoteTool.js +33 -0
  80. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +69 -0
  81. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +657 -0
  82. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayReplyResolution.js +17 -0
  83. package/dist/services/features/telegram-mcp/src/features/inbox/model/deleteTelegramInboxMessageTool.js +33 -0
  84. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxCountTool.js +33 -0
  85. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxTool.js +33 -0
  86. package/dist/services/features/telegram-mcp/src/features/inbox/model/inboxService.js +77 -0
  87. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +93 -0
  88. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyTelegramTool.js +33 -0
  89. package/dist/services/features/telegram-mcp/src/features/pair-session/model/clearSessionPairingTool.js +33 -0
  90. package/dist/services/features/telegram-mcp/src/features/pair-session/model/createSessionPairCodeTool.js +33 -0
  91. package/dist/services/features/telegram-mcp/src/features/pair-session/model/generatePairCode.js +202 -0
  92. package/dist/services/features/telegram-mcp/src/features/session-context/model/clearSessionContextTool.js +33 -0
  93. package/dist/services/features/telegram-mcp/src/features/session-context/model/getSessionContextTool.js +33 -0
  94. package/dist/services/features/telegram-mcp/src/features/session-context/model/getTmuxTargetTool.js +33 -0
  95. package/dist/services/features/telegram-mcp/src/features/session-context/model/renameSessionTool.js +33 -0
  96. package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +409 -0
  97. package/dist/services/features/telegram-mcp/src/features/session-context/model/setSessionContextTool.js +33 -0
  98. package/dist/services/features/telegram-mcp/src/features/session-context/model/setTmuxTargetTool.js +33 -0
  99. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownService.js +123 -0
  100. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownTool.js +33 -0
  101. package/dist/services/features/telegram-mcp/src/processes/human-approval/model/orchestrator.js +243 -0
  102. package/dist/services/features/telegram-mcp/src/shared/api/storage/contract.js +2 -0
  103. package/dist/services/features/telegram-mcp/src/shared/api/tool-registry/registry.js +8 -0
  104. package/dist/services/features/telegram-mcp/src/shared/api/tool-registry/types.js +2 -0
  105. package/dist/services/features/telegram-mcp/src/shared/api/transport/contract.js +2 -0
  106. package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +86 -0
  107. package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +436 -0
  108. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/collabSemantics.js +21 -0
  109. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/collabUi.js +87 -0
  110. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/messageFormat.js +60 -0
  111. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/proxyFetch.js +46 -0
  112. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +6534 -0
  113. package/dist/services/features/telegram-mcp/src/shared/integrations/tmux/client.js +280 -0
  114. package/dist/services/features/telegram-mcp/src/shared/lib/ids/ids.js +34 -0
  115. package/dist/services/features/telegram-mcp/src/shared/lib/logger/logger.js +68 -0
  116. package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +223 -0
  117. package/dist/services/features/telegram-mcp/src/shared/lib/redact-secrets/redactSecrets.js +22 -0
  118. package/dist/services/features/telegram-mcp/src/shared/lib/truncate/truncate.js +12 -0
  119. package/dist/services/features/telegram-mcp/src/shared/lib/version/versionHandshake.js +124 -0
  120. package/dist/services/features/telegram-mcp/src/shared/types/common.js +2 -0
  121. package/dist/services/features/telegram-mcp/standalone-http.service.js +113 -0
  122. package/dist/services/features/telegram-mcp/tools-sync.service.js +33 -0
  123. package/package.json +110 -0
  124. package/scripts/postinstall.js +60 -0
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TELEGRAM_MCP_ENSUREDB_SERVICE_NAME = void 0;
4
+ const db_1 = require("../../../lib/mixins/db");
5
+ exports.TELEGRAM_MCP_ENSUREDB_SERVICE_NAME = "telegramMcp.ensuredb";
6
+ const DISTRIBUTED_MODE = process.env.DISTRIBUTED_MODE || "client";
7
+ const GATEWAY_ENABLED = DISTRIBUTED_MODE === "gateway" || DISTRIBUTED_MODE === "both";
8
+ const MCP_SCHEMA = process.env.DB_SCHEME || "mcp";
9
+ const TelegramMcpEnsureDbService = {
10
+ name: exports.TELEGRAM_MCP_ENSUREDB_SERVICE_NAME,
11
+ mixins: [db_1.DBMixin],
12
+ methods: {
13
+ async ensureGatewaySchema() {
14
+ await this.db.raw(`create schema if not exists "${MCP_SCHEMA}"`);
15
+ if (!(await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_clients"))) {
16
+ await this.db.schema.withSchema(MCP_SCHEMA).createTable("gateway_clients", (table) => {
17
+ table.uuid("client_uuid").primary();
18
+ table.text("client_label");
19
+ table.text("bot_token_fingerprint");
20
+ table.text("bot_username");
21
+ table.jsonb("meta").notNullable().defaultTo(this.db.raw(`'{}'::jsonb`));
22
+ table
23
+ .timestamp("created_at", { useTz: true })
24
+ .notNullable()
25
+ .defaultTo(this.db.fn.now());
26
+ table
27
+ .timestamp("updated_at", { useTz: true })
28
+ .notNullable()
29
+ .defaultTo(this.db.fn.now());
30
+ table.timestamp("last_seen_at", { useTz: true });
31
+ });
32
+ }
33
+ if (!(await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_projects"))) {
34
+ await this.db.schema.withSchema(MCP_SCHEMA).createTable("gateway_projects", (table) => {
35
+ table.uuid("project_uuid").primary();
36
+ table.text("name").notNullable();
37
+ table.text("invite_token").notNullable().unique();
38
+ table
39
+ .uuid("created_by_client_uuid")
40
+ .references("client_uuid")
41
+ .inTable(`${MCP_SCHEMA}.gateway_clients`)
42
+ .onDelete("RESTRICT");
43
+ table.bigInteger("owner_telegram_user_id");
44
+ table.text("owner_telegram_username");
45
+ table.text("owner_display_name");
46
+ table.boolean("is_active").notNullable().defaultTo(true);
47
+ table
48
+ .timestamp("created_at", { useTz: true })
49
+ .notNullable()
50
+ .defaultTo(this.db.fn.now());
51
+ table
52
+ .timestamp("updated_at", { useTz: true })
53
+ .notNullable()
54
+ .defaultTo(this.db.fn.now());
55
+ });
56
+ }
57
+ if (!(await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_project_members"))) {
58
+ await this.db.schema
59
+ .withSchema(MCP_SCHEMA)
60
+ .createTable("gateway_project_members", (table) => {
61
+ table.uuid("project_uuid").notNullable();
62
+ table.uuid("client_uuid").notNullable();
63
+ table.text("role").notNullable().defaultTo("member");
64
+ table.text("status").notNullable().defaultTo("active");
65
+ table.bigInteger("telegram_user_id");
66
+ table.text("telegram_username");
67
+ table.text("display_name");
68
+ table
69
+ .timestamp("joined_at", { useTz: true })
70
+ .notNullable()
71
+ .defaultTo(this.db.fn.now());
72
+ table.primary(["project_uuid", "client_uuid"]);
73
+ table
74
+ .foreign("project_uuid")
75
+ .references("project_uuid")
76
+ .inTable(`${MCP_SCHEMA}.gateway_projects`)
77
+ .onDelete("CASCADE");
78
+ table
79
+ .foreign("client_uuid")
80
+ .references("client_uuid")
81
+ .inTable(`${MCP_SCHEMA}.gateway_clients`)
82
+ .onDelete("CASCADE");
83
+ });
84
+ }
85
+ if (!(await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_sessions"))) {
86
+ await this.db.schema.withSchema(MCP_SCHEMA).createTable("gateway_sessions", (table) => {
87
+ table.uuid("session_uuid").primary();
88
+ table.uuid("project_uuid").notNullable();
89
+ table.uuid("client_uuid").notNullable();
90
+ table.text("local_session_id").notNullable();
91
+ table.text("label");
92
+ table.text("cwd");
93
+ table.text("tmux_session_name");
94
+ table.text("tmux_window_name");
95
+ table.integer("tmux_window_index");
96
+ table.text("tmux_pane_id");
97
+ table.integer("tmux_pane_index");
98
+ table.text("tmux_target");
99
+ table.text("status").notNullable().defaultTo("active");
100
+ table.jsonb("meta").notNullable().defaultTo(this.db.raw(`'{}'::jsonb`));
101
+ table
102
+ .timestamp("created_at", { useTz: true })
103
+ .notNullable()
104
+ .defaultTo(this.db.fn.now());
105
+ table
106
+ .timestamp("updated_at", { useTz: true })
107
+ .notNullable()
108
+ .defaultTo(this.db.fn.now());
109
+ table
110
+ .foreign("project_uuid")
111
+ .references("project_uuid")
112
+ .inTable(`${MCP_SCHEMA}.gateway_projects`)
113
+ .onDelete("CASCADE");
114
+ table
115
+ .foreign("client_uuid")
116
+ .references("client_uuid")
117
+ .inTable(`${MCP_SCHEMA}.gateway_clients`)
118
+ .onDelete("CASCADE");
119
+ table.unique(["project_uuid", "client_uuid", "local_session_id"], "gateway_sessions_project_client_local_unique");
120
+ table.index(["project_uuid"], "gateway_sessions_project_idx");
121
+ table.index(["client_uuid"], "gateway_sessions_client_idx");
122
+ });
123
+ }
124
+ const legacyConstraint = await this.db
125
+ .select("con.conname")
126
+ .from({ con: "pg_constraint" })
127
+ .join({ rel: "pg_class" }, "rel.oid", "con.conrelid")
128
+ .join({ nsp: "pg_namespace" }, "nsp.oid", "rel.relnamespace")
129
+ .where("nsp.nspname", MCP_SCHEMA)
130
+ .where("rel.relname", "gateway_sessions")
131
+ .where("con.contype", "u")
132
+ .whereRaw("pg_get_constraintdef(con.oid) = ?", [
133
+ "UNIQUE (client_uuid, local_session_id)",
134
+ ])
135
+ .first();
136
+ if (legacyConstraint?.conname) {
137
+ await this.db.raw(`ALTER TABLE "${MCP_SCHEMA}"."gateway_sessions" DROP CONSTRAINT "${legacyConstraint.conname}"`);
138
+ }
139
+ if ((await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_projects")) &&
140
+ !(await this.db.schema.withSchema(MCP_SCHEMA).hasColumn("gateway_projects", "owner_telegram_user_id"))) {
141
+ await this.db.schema.withSchema(MCP_SCHEMA).alterTable("gateway_projects", (table) => {
142
+ table.bigInteger("owner_telegram_user_id");
143
+ });
144
+ }
145
+ if ((await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_projects")) &&
146
+ !(await this.db.schema.withSchema(MCP_SCHEMA).hasColumn("gateway_projects", "owner_telegram_username"))) {
147
+ await this.db.schema.withSchema(MCP_SCHEMA).alterTable("gateway_projects", (table) => {
148
+ table.text("owner_telegram_username");
149
+ });
150
+ }
151
+ if ((await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_projects")) &&
152
+ !(await this.db.schema.withSchema(MCP_SCHEMA).hasColumn("gateway_projects", "owner_display_name"))) {
153
+ await this.db.schema.withSchema(MCP_SCHEMA).alterTable("gateway_projects", (table) => {
154
+ table.text("owner_display_name");
155
+ });
156
+ }
157
+ if ((await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_project_members")) &&
158
+ !(await this.db.schema.withSchema(MCP_SCHEMA).hasColumn("gateway_project_members", "telegram_user_id"))) {
159
+ await this.db.schema
160
+ .withSchema(MCP_SCHEMA)
161
+ .alterTable("gateway_project_members", (table) => {
162
+ table.bigInteger("telegram_user_id");
163
+ });
164
+ }
165
+ if ((await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_project_members")) &&
166
+ !(await this.db.schema.withSchema(MCP_SCHEMA).hasColumn("gateway_project_members", "telegram_username"))) {
167
+ await this.db.schema
168
+ .withSchema(MCP_SCHEMA)
169
+ .alterTable("gateway_project_members", (table) => {
170
+ table.text("telegram_username");
171
+ });
172
+ }
173
+ if ((await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_project_members")) &&
174
+ !(await this.db.schema.withSchema(MCP_SCHEMA).hasColumn("gateway_project_members", "display_name"))) {
175
+ await this.db.schema
176
+ .withSchema(MCP_SCHEMA)
177
+ .alterTable("gateway_project_members", (table) => {
178
+ table.text("display_name");
179
+ });
180
+ }
181
+ await this.db.raw(`
182
+ CREATE UNIQUE INDEX IF NOT EXISTS gateway_sessions_project_client_local_unique
183
+ ON "${MCP_SCHEMA}"."gateway_sessions" ("project_uuid", "client_uuid", "local_session_id")
184
+ `);
185
+ if (!(await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_session_links"))) {
186
+ await this.db.schema
187
+ .withSchema(MCP_SCHEMA)
188
+ .createTable("gateway_session_links", (table) => {
189
+ table.uuid("link_uuid").primary();
190
+ table.uuid("project_uuid").notNullable();
191
+ table.uuid("left_session_uuid").notNullable();
192
+ table.uuid("right_session_uuid").notNullable();
193
+ table.text("status").notNullable().defaultTo("active");
194
+ table
195
+ .timestamp("created_at", { useTz: true })
196
+ .notNullable()
197
+ .defaultTo(this.db.fn.now());
198
+ table
199
+ .foreign("project_uuid")
200
+ .references("project_uuid")
201
+ .inTable(`${MCP_SCHEMA}.gateway_projects`)
202
+ .onDelete("CASCADE");
203
+ table
204
+ .foreign("left_session_uuid")
205
+ .references("session_uuid")
206
+ .inTable(`${MCP_SCHEMA}.gateway_sessions`)
207
+ .onDelete("CASCADE");
208
+ table
209
+ .foreign("right_session_uuid")
210
+ .references("session_uuid")
211
+ .inTable(`${MCP_SCHEMA}.gateway_sessions`)
212
+ .onDelete("CASCADE");
213
+ table.unique(["left_session_uuid", "right_session_uuid"]);
214
+ table.index(["project_uuid"], "gateway_session_links_project_idx");
215
+ });
216
+ }
217
+ if (!(await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_messages"))) {
218
+ await this.db.schema.withSchema(MCP_SCHEMA).createTable("gateway_messages", (table) => {
219
+ table.uuid("message_uuid").primary();
220
+ table.uuid("project_uuid").notNullable();
221
+ table.uuid("from_session_uuid").notNullable();
222
+ table.uuid("to_session_uuid").notNullable();
223
+ table.text("kind").notNullable();
224
+ table.text("summary").notNullable();
225
+ table.text("body").notNullable();
226
+ table.text("expected_reply");
227
+ table.boolean("requires_reply").notNullable().defaultTo(false);
228
+ table.uuid("in_reply_to");
229
+ table.jsonb("meta").notNullable().defaultTo(this.db.raw(`'{}'::jsonb`));
230
+ table
231
+ .timestamp("created_at", { useTz: true })
232
+ .notNullable()
233
+ .defaultTo(this.db.fn.now());
234
+ table
235
+ .foreign("project_uuid")
236
+ .references("project_uuid")
237
+ .inTable(`${MCP_SCHEMA}.gateway_projects`)
238
+ .onDelete("CASCADE");
239
+ table
240
+ .foreign("from_session_uuid")
241
+ .references("session_uuid")
242
+ .inTable(`${MCP_SCHEMA}.gateway_sessions`)
243
+ .onDelete("CASCADE");
244
+ table
245
+ .foreign("to_session_uuid")
246
+ .references("session_uuid")
247
+ .inTable(`${MCP_SCHEMA}.gateway_sessions`)
248
+ .onDelete("CASCADE");
249
+ table
250
+ .foreign("in_reply_to")
251
+ .references("message_uuid")
252
+ .inTable(`${MCP_SCHEMA}.gateway_messages`)
253
+ .onDelete("SET NULL");
254
+ table.index(["to_session_uuid", "created_at"], "gateway_messages_target_idx");
255
+ });
256
+ }
257
+ if (!(await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_message_artifacts"))) {
258
+ await this.db.schema
259
+ .withSchema(MCP_SCHEMA)
260
+ .createTable("gateway_message_artifacts", (table) => {
261
+ table.uuid("artifact_uuid").primary();
262
+ table.uuid("message_uuid").notNullable();
263
+ table.text("original_name").notNullable();
264
+ table.text("mime_type");
265
+ table.bigInteger("size_bytes");
266
+ table.text("storage_ref");
267
+ table.text("public_url");
268
+ table.text("relative_path");
269
+ table.jsonb("meta").notNullable().defaultTo(this.db.raw(`'{}'::jsonb`));
270
+ table
271
+ .timestamp("created_at", { useTz: true })
272
+ .notNullable()
273
+ .defaultTo(this.db.fn.now());
274
+ table
275
+ .foreign("message_uuid")
276
+ .references("message_uuid")
277
+ .inTable(`${MCP_SCHEMA}.gateway_messages`)
278
+ .onDelete("CASCADE");
279
+ table.index(["message_uuid"], "gateway_message_artifacts_message_idx");
280
+ });
281
+ }
282
+ if (!(await this.db.schema.withSchema(MCP_SCHEMA).hasTable("gateway_deliveries"))) {
283
+ await this.db.schema.withSchema(MCP_SCHEMA).createTable("gateway_deliveries", (table) => {
284
+ table.uuid("delivery_uuid").primary();
285
+ table.uuid("message_uuid").notNullable();
286
+ table.uuid("target_client_uuid").notNullable();
287
+ table.uuid("target_session_uuid").notNullable();
288
+ table.text("status").notNullable().defaultTo("pending");
289
+ table.integer("attempt_count").notNullable().defaultTo(0);
290
+ table.text("last_error");
291
+ table
292
+ .timestamp("available_at", { useTz: true })
293
+ .notNullable()
294
+ .defaultTo(this.db.fn.now());
295
+ table.timestamp("delivered_at", { useTz: true });
296
+ table.timestamp("acked_at", { useTz: true });
297
+ table
298
+ .timestamp("created_at", { useTz: true })
299
+ .notNullable()
300
+ .defaultTo(this.db.fn.now());
301
+ table
302
+ .foreign("message_uuid")
303
+ .references("message_uuid")
304
+ .inTable(`${MCP_SCHEMA}.gateway_messages`)
305
+ .onDelete("CASCADE");
306
+ table
307
+ .foreign("target_client_uuid")
308
+ .references("client_uuid")
309
+ .inTable(`${MCP_SCHEMA}.gateway_clients`)
310
+ .onDelete("CASCADE");
311
+ table
312
+ .foreign("target_session_uuid")
313
+ .references("session_uuid")
314
+ .inTable(`${MCP_SCHEMA}.gateway_sessions`)
315
+ .onDelete("CASCADE");
316
+ table.index(["target_client_uuid", "status", "available_at"], "gateway_deliveries_poll_idx");
317
+ });
318
+ }
319
+ },
320
+ },
321
+ async started() {
322
+ if (!GATEWAY_ENABLED) {
323
+ this.logger.info("Skipping telegram_mcp gateway database bootstrap", {
324
+ mode: DISTRIBUTED_MODE,
325
+ });
326
+ return;
327
+ }
328
+ this.logger.info("Ensuring telegram_mcp gateway database schema", {
329
+ schema: MCP_SCHEMA,
330
+ });
331
+ await this.ensureGatewaySchema?.();
332
+ this.logger.info("telegram_mcp gateway database schema is ready", {
333
+ schema: MCP_SCHEMA,
334
+ });
335
+ },
336
+ };
337
+ exports.default = TelegramMcpEnsureDbService;