79 Commits

Author SHA1 Message Date
maaz519 4f1df96b34 fix: add retry loop for database connection in entrypoint 2026-06-09 16:50:56 +05:30
maaz519 1b63f62ca0 fix: add retry loop for database connection in entrypoint 2026-06-09 16:47:54 +05:30
maaz519 e66f198785 fix: add retry loop for database connection in entrypoint 2026-06-09 16:41:47 +05:30
maaz519 d6da151d16 fix: add retry loop for database connection in entrypoint 2026-06-09 16:35:27 +05:30
maaz519 50026c8a95 fix: add retry loop for database connection in entrypoint 2026-06-09 16:29:46 +05:30
maaz519 9761564c22 fix: shrink images + fix prisma generate in runner 2026-06-09 16:21:55 +05:30
maaz519 9ac3e29a20 fix: add @prisma/client to root deps for Docker runner 2026-06-09 16:09:29 +05:30
maaz519 c8943e8d88 fix: use turbo build in worker Dockerfile for dependency resolution 2026-06-09 15:56:56 +05:30
maaz519 000a06fa0e fix: add prisma to dependencies for Docker build 2026-06-09 15:51:32 +05:30
maaz519 f9d5749dba added changes 2 2026-06-09 15:45:34 +05:30
maaz519 ff4d0f90e8 added changes 2026-06-09 15:33:21 +05:30
maaz519 249d759e6a good forst commit 2026-06-09 02:02:40 +05:30
maaz519 801c1d7121 fix: create new accounts with DISCONNECTED status so QR displays immediately 2026-05-29 11:57:42 +05:30
maaz519 afff6fdbdf feat: add POST /accounts endpoint to create new WhatsApp account records
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 11:50:01 +05:30
maaz519 2f88e883b2 feat: add AccountsList with Add Account form; proxy POST /accounts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 11:49:23 +05:30
maaz519 952a0e9b49 feat: pass JID on connect; extract startAccount() helper; poll 30s for new accounts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 11:44:54 +05:30
maaz519 e8aaae4188 feat: add Accounts page with QR code display for WhatsApp re-authentication
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 11:40:48 +05:30
maaz519 759b49159e feat: add Next.js proxy routes for accounts list and QR endpoints 2026-05-29 11:37:48 +05:30
maaz519 1dba77959d feat: add AccountsModule with list and QR endpoints
Implements GET /accounts (list all accounts) and GET /accounts/:id/qr
(returns QR code as base64 data URL) using the qrcode package.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 11:15:42 +05:30
maaz519 02dad1347c feat: thread QR/status callbacks through session pool; persist to DB in main
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 11:08:51 +05:30
maaz519 18edce7552 feat: add onQr/onStatus callbacks to session; auto-restart on loggedOut
Adds OnQrCallback and OnStatusCallback parameters to createWhatsAppSession,
broadcasts QR strings and connection status changes to callers, and clears
session files then restarts automatically when the socket is logged out.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 11:04:39 +05:30
maaz519 43f4133f1d feat: add qrCode field to Account for QR re-auth 2026-05-29 10:58:04 +05:30
maaz519 5d9df64849 fix(api): prevent self-loop routes, map P2003 to 400, forward DELETE error body
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 01:44:48 +05:30
maaz519 9d1799eab1 fix(api): export GroupSummary interface to fix TS4053 declaration emit error 2026-05-28 01:41:12 +05:30
maaz519 1389a65e18 feat(web): add groups page with RouteManager and route handler proxies
Implements the Groups & Routes admin page with a client-side RouteManager
component (add/delete sync routes via fetch), server-side groups page that
pre-fetches groups/routes from the API, and Next.js Route Handler proxies
for /api/routes (GET, POST) and /api/routes/[id] (DELETE). Adds a custom
jest environment that polyfills Node 18+ native fetch into the jsdom sandbox
so tests can use jest.spyOn(global, 'fetch').

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 01:37:13 +05:30
maaz519 71e2b0681c test(web): assert approvedAt date is rendered in SearchResults 2026-05-28 01:23:25 +05:30
maaz519 6ae1130585 feat(web): add search page with full-text message search UI 2026-05-28 01:19:23 +05:30
maaz519 f7b3ef5a7c feat(web): add sidebar nav layout and dashboard home page 2026-05-28 01:15:53 +05:30
maaz519 d92476f841 fix(api): use PrismaClientKnownRequestError instanceof, add ConflictException for duplicate routes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 01:13:05 +05:30
maaz519 6b4920ce41 feat(api): add RoutesModule with GET/POST/DELETE /routes endpoints
Implements RoutesService and RoutesController for SyncRoute CRUD, wires
GroupsModule and RoutesModule into AppModule; 11 new tests, all 31 pass.
2026-05-28 01:07:15 +05:30
maaz519 f4a40b573e fix(api): add clearAllMocks and explicit return type to GroupsModule
- Add jest.clearAllMocks() in beforeEach of both spec files to prevent
  call-history state from leaking between tests as the suites grow
- Define GroupSummary interface and use it as explicit return type for
  GroupsService.list() to satisfy TypeScript strict typing requirements

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 01:00:09 +05:30
maaz519 0e92b24bf0 feat(api): add GroupsModule with GET /groups endpoint
Implements TDD-driven GroupsService and GroupsController with full unit test coverage. GET /groups returns all groups ordered by name, selecting id, name, platform, platformId, isActive, and accountId fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 00:55:13 +05:30
maaz519 e73d39b798 fix(api): escape filter values, clamp pagination, remove redundant ConfigModule import
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 00:31:43 +05:30
maaz519 8ad5f737bd feat(api): add SearchModule with GET /search endpoint backed by Meilisearch
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 00:28:13 +05:30
maaz519 6f18433c67 fix(worker): throw on invalid approvedAt in index processor 2026-05-28 00:19:14 +05:30
maaz519 1e421c0073 feat(worker): add index queue and wire Meilisearch indexing after approval
Adds index.queue.ts and index.processor.ts to handle BullMQ indexing jobs,
updates main.ts to create a Meilisearch client, configure the index on startup,
and enqueue index + forward jobs from ApprovalResult after a star reaction.
2026-05-28 00:02:47 +05:30
maaz519 7d905b166e test(worker): assert indexDoc in sync-routes approval test 2026-05-27 23:58:44 +05:30
maaz519 6f71e5aee9 feat(worker): handleStarReaction returns ApprovalResult with indexDoc 2026-05-27 23:56:14 +05:30
maaz519 1d6e1fb4da fix(search): tighten mock type cast for better type safety
Replace `as any` cast with `as unknown as ReturnType<typeof createMeiliClient>`
in the mock client factory. This preserves type safety without requiring the mock
to implement the full SDK interface.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 23:53:32 +05:30
maaz519 dfa289d6b8 feat(search): add @tower/search package with Meilisearch client and helpers
Implements Task 2 of Plan 4 (Archive & Search): provides createMeiliClient,
configureIndex, indexMessage, and deleteMessage for use by the worker and API.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 23:51:12 +05:30
maaz519 480f748692 feat(types): add IndexJobData for Meilisearch indexing 2026-05-27 23:45:42 +05:30
maaz519 d33b4e40b8 fix: use type-only Baileys import and raw status code to fix Jest ESM issue
Replaces DisconnectReason enum import with type-only WASocket import and
uses 401 directly instead of DisconnectReason.loggedOut. Baileys is an ES
module that cannot be executed in Jest's CommonJS mode, so removing the
value import (keeping only type imports) prevents ts-jest from trying to
execute the module.

Also updated session-pool.test.ts to verify end() is called with the
expected Boom error object instead of undefined.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 17:40:24 +05:30
maaz519 06449acd96 fix: pass loggedOut reason in closeAll to prevent reconnect timers after shutdown 2026-05-27 17:38:37 +05:30
maaz519 41aabc4c0d fix: address code quality issues in session pool, approval, and main
- session.ts: add onReconnect callback so reconnected socket replaces stale pool entry
- session-pool.ts: pass onReconnect to update pool on reconnect; add closeAll() to gracefully end WebSocket connections on shutdown
- approval.ts: use approved flag so double-approval race (updateMany count=0) returns null instead of sending duplicate forward jobs
- main.ts: wrap pool.add() in try/catch to continue if one account fails; replace silent groupMap fallback with explicit error log and early return; call pool.closeAll() before BullMQ shutdown to prevent hanging sockets
- Tests: add closeAll() test to session-pool.test.ts; add double-approval race test to approval.test.ts (56 tests total, all passing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 17:35:52 +05:30
maaz519 9e3ee0cd38 feat(worker): wire multi-account pool, reactions → approval → forward pipeline
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 17:28:08 +05:30
maaz519 5ad33fd416 feat(worker): forward queue + processor with 20/min rate limiter 2026-05-27 17:23:08 +05:30
maaz519 57a06bc517 fix(worker): atomic approval via transaction, guard null targetGroup
Wrap message.update + approval.create in a $transaction using updateMany
with a PENDING status guard to prevent duplicate approvals and audit gaps.
Filter out null targetGroup routes to prevent runtime errors on DB inconsistency.
Add TODO comment for multi-platform support and fallback accountId comment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 17:21:17 +05:30
maaz519 a07f393373 feat(worker): handleStarReaction approval core with tests
Implement approval core logic for Task 5: when admin reacts to WhatsApp
message with , verify admin status, update message to APPROVED, create
Approval record, find active SyncRoutes from source group, and return
ForwardJobData[] for each target group. All 7 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 17:17:02 +05:30
maaz519 9cdc41e23e fix(worker): improve sendMessage error, add session-pool unit tests 2026-05-27 17:14:56 +05:30
maaz519 0f30af6018 feat(worker): WhatsAppSessionPool + group-sync accepts accountId 2026-05-27 17:11:19 +05:30