Commit Graph

86 Commits

Author SHA1 Message Date
dependabot[bot]
f9c1d91024
chore(deps): bump next-intl from 4.13.2 to 4.13.4
Bumps [next-intl](https://github.com/amannn/next-intl) from 4.13.2 to 4.13.4.
- [Release notes](https://github.com/amannn/next-intl/releases)
- [Changelog](https://github.com/amannn/next-intl/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amannn/next-intl/compare/v4.13.2...v4.13.4)

---
updated-dependencies:
- dependency-name: next-intl
  dependency-version: 4.13.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-27 10:35:34 +00:00
Arnas Donauskas
b18b5fa8e0
Merge pull request #380 from ArnasDon/dependabot/npm_and_yarn/dev-dependencies-b44e82a8cb
chore(deps-dev): bump the dev-dependencies group with 4 updates
2026-07-17 13:36:02 +03:00
Arnas Donauskas
3e4ed3714d
Merge pull request #382 from ArnasDon/dependabot/npm_and_yarn/recharts-3.9.2
chore(deps): bump recharts from 3.8.1 to 3.9.2
2026-07-17 13:35:49 +03:00
dependabot[bot]
eb3c6fdc20
chore(deps): bump next-intl from 4.13.1 to 4.13.2
Bumps [next-intl](https://github.com/amannn/next-intl) from 4.13.1 to 4.13.2.
- [Release notes](https://github.com/amannn/next-intl/releases)
- [Changelog](https://github.com/amannn/next-intl/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amannn/next-intl/compare/v4.13.1...v4.13.2)

---
updated-dependencies:
- dependency-name: next-intl
  dependency-version: 4.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-13 10:36:42 +00:00
dependabot[bot]
0ec5de789a
chore(deps): bump recharts from 3.8.1 to 3.9.2
Bumps [recharts](https://github.com/recharts/recharts) from 3.8.1 to 3.9.2.
- [Release notes](https://github.com/recharts/recharts/releases)
- [Changelog](https://github.com/recharts/recharts/blob/main/CHANGELOG.md)
- [Commits](https://github.com/recharts/recharts/compare/v3.8.1...v3.9.2)

---
updated-dependencies:
- dependency-name: recharts
  dependency-version: 3.9.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-13 10:36:33 +00:00
dependabot[bot]
d9c1f5cc4a
chore(deps-dev): bump the dev-dependencies group with 4 updates
---
updated-dependencies:
- dependency-name: "@tailwindcss/postcss"
  dependency-version: 4.3.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: "@types/node"
  dependency-version: 26.1.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: prettier
  dependency-version: 3.9.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: vitest
  dependency-version: 4.1.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-13 10:35:52 +00:00
Arnas Donauskas
b0194dfc27 feat(ai): polish auto-reply — inbox controls, real handoff, usage logging
Makes the AI auto-reply bot visible and controllable from the inbox,
completes the handoff, and records token spend. Builds on the existing
lib/ai engine rather than replacing it.

Track A — user-facing
- messages.ai_generated flag → small "AI" badge on bot-generated bubbles
- "Take over" / "Resume AI" banner per conversation
  (POST /api/ai/autoreply/[id]) — take-over pauses + assigns to the agent
- handoff now assigns to a configurable target (agent or unassigned
  queue) and writes an internal note summarizing the exchange; the
  existing on_conversation_assigned trigger notifies the assignee
- Settings → AI: "Hand off to" target picker

Track B — observability + safety
- providers return normalized token usage; logged per run to ai_usage_log
  (admin-readable) from both auto-reply and draft
- account-wide auto-reply rate limit (30/min) on top of the
  per-conversation cap

Migration: 033_ai_reply_polish.sql (messages.ai_generated,
ai_configs.handoff_agent_id, conversations.ai_handoff_summary,
ai_usage_log). Tests + typecheck + lint pass (607 tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 14:03:33 +03:00
Arnas Donauskas
79565c1fbe
Merge pull request #328 from ivanmercedes/feat/i18n-support
feat: integrate next-intl for i18n support
2026-07-07 12:57:04 +03:00
Arnas Donauskas
10d31bcfc8 feat: AI Agents sidebar section (setup + playground)
Promotes the AI assistant out of Settings into a first-class "AI Agents"
sidebar area.

- Sidebar: new "AI Agents" item → /agents.
- /agents page with two tabs:
  - Playground — a test chat (POST /api/ai/playground) that runs the
    real auto-reply path (KB retrieval + provider, auto_reply prompt,
    multi-turn, shows handoff). loadAiConfig gains requireActive so you
    can test before enabling.
  - Setup — the existing provider/key + knowledge-base config, relocated.
- Removed the AI section from Settings (settings-sections + page); same
  account config, new home. No migration.

Tests +6 (query, loadAiConfig requireActive). 593 pass; typecheck, lint,
build green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 18:20:18 +03:00
Arnas Donauskas
ce1fa4705d feat: AI knowledge base (RAG grounding)
Grounds the AI assistant (0.5.0) in the account's own content so it can
answer instead of handing off.

- Hybrid retrieval: Postgres full-text search for every account; optional
  semantic search (pgvector + OpenAI text-embedding-3-small) when an
  embeddings key is set. Semantic-primary, topped up with FTS.
- src/lib/ai: chunk, embeddings, knowledge (ingest + retrieve), query;
  buildSystemPrompt gains a knowledge block; config carries an
  (optional) embeddings key.
- Wired into /api/ai/draft and the auto-reply bot (best-effort — never
  blocks a reply).
- KB API (/api/ai/knowledge CRUD + /reindex) and a Settings → AI
  Assistant knowledge-base manager + embeddings-key field.
- Migration 030: pgvector, ai_knowledge_documents, ai_knowledge_chunks
  (fts + embedding), match RPCs, ai_configs.embeddings_api_key.

Migration required: supabase/migrations/030_ai_knowledge.sql.
Stacked on feat/ai-reply-assistant (#329).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 17:06:09 +03:00
Arnas Donauskas
2748028c1d feat: AI reply assistant (bring-your-own-key)
Adds an AI reply assistant powered by the account's own OpenAI or
Anthropic key (stored AES-256-GCM-encrypted; no per-seat AI fee).

- AI-drafted replies in the inbox composer (✨ button, agent+), via
  read-only POST /api/ai/draft.
- Optional auto-reply bot on inbound messages that no Flow consumed and
  no agent owns, with a per-conversation cap and clean [[HANDOFF]] to a
  human. Stands down when a message-level automation would also reply.
- Settings → AI Assistant (admin+): provider/model, key, business
  context, toggles, and a Test-key button that verifies before saving.
- Provider layer (src/lib/ai) with OpenAI + Anthropic adapters behind
  one interface; migration 029 (ai_configs + per-conversation columns +
  atomic claim_ai_reply_slot RPC).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 12:56:04 +03:00
Ivan Mercedes
8327c0906d feat(i18n): setup next-intl and migrate login page
This introduces the base i18n setup using next-intl without routing. It adds the default messages/en.json and sets up the app layout and next.config.ts to consume the locale from the environment. The login page has been migrated as a first example.
2026-07-01 17:46:00 -04:00
Arnas Donauskas
c0f390c401 feat(api): outbound event webhooks — /api/v1/webhooks (#245)
Completes the public API roadmap (#245): register HTTPS endpoints to be
POSTed to when things happen in an account, so automations can react to
inbound activity instead of polling.

- Migration 028: account-scoped webhook_endpoints (secret stored
  AES-GCM-encrypted) + an atomic record_webhook_failure() function.
- Scope webhooks:manage; management API GET/POST /api/v1/webhooks and
  GET/PATCH/DELETE /api/v1/webhooks/{id} (secret returned once).
- Events message.received / conversation.created / message.status_updated
  dispatched from the inbound webhook handler's after() block.
- Signed delivery (X-Wacrm-Signature = HMAC-SHA256 over t.body), single
  best-effort attempt, auto-disable after consecutive failures.
- Versioned 0.4.0; docs/public-api.md Webhooks section; CHANGELOG.

Fixes from the adversarial code review of this diff:
- SSRF: block private/loopback/link-local (incl. cloud metadata) targets
  at delivery time + redirect:'manual' so a public URL can't bounce
  internal (src/lib/webhooks/ssrf.ts).
- Status mirror UPDATE no longer uses .select().maybeSingle() (message_id
  is non-unique); account resolved via a bounded limit(1) read.
- Atomic failure counter via SQL RPC (was a racy read-modify-write).
- conversation.created emitted before the reaction short-circuit.
- Per-delivery id added for receiver dedupe; docs state at-least-once /
  unordered delivery.
- Signature verify tolerates hex case / header whitespace.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 14:53:18 +03:00
Arnas Donauskas
8cb5792823 feat(api): public REST API v1 — messages, contacts, conversations, broadcasts (#245)
Complete the public API roadmap on top of the existing key-auth layer
(#290). Re-lands POST /api/v1/messages (lost when the stacked #291 never
reached main) by extracting the dashboard send route's core into
`sendMessageToConversation`, then adds:

- Contacts: GET/POST /api/v1/contacts, GET/PATCH /api/v1/contacts/{id}
- Conversations: GET list + /{id} + /{id}/messages
- Broadcasts: POST /api/v1/broadcasts + GET /{id} (persist rows, fan out
  in after(), poll for status)

All list endpoints share one keyset-pagination contract
({ data, meta: { next_cursor } }). No migration required — scopes and
tables already exist. Versioned as 0.3.0 (folded into [Unreleased]);
docs/public-api.md updated; outbound webhooks left as the sole roadmap
item. API stays v1 (additive).

Includes fixes from an adversarial code review: cursor validation
against filter injection, broadcast counts deferred to the DB aggregate
trigger, terminal broadcast status reflects failures, duplicate-phone
de-dup, up-front send-param validation (no orphan conversations),
PATCH null-clear semantics, error-checked tag sync, bounded tag filter,
unified audit-user attribution, and a maxDuration on the broadcast
fan-out.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 14:10:19 +03:00
Arnas Donauskas
6fb71d21d2
Merge pull request #247 from ArnasDon/dependabot/npm_and_yarn/supabase-76c1b082ed
chore(deps): bump the supabase group across 1 directory with 2 updates
2026-07-01 12:00:13 +03:00
Arnas Donauskas
1e05ba028c
Merge pull request #282 from ArnasDon/dependabot/npm_and_yarn/base-ui/react-1.6.0
chore(deps): bump @base-ui/react from 1.5.0 to 1.6.0
2026-07-01 11:24:02 +03:00
Arnas Donauskas
1229de52d2
Merge pull request #315 from ArnasDon/dependabot/npm_and_yarn/dev-dependencies-d62044d6eb
chore(deps-dev): bump prettier from 3.8.4 to 3.9.1 in the dev-dependencies group
2026-07-01 11:21:14 +03:00
Arnas Donauskas
493cf4195a
Merge pull request #316 from ArnasDon/dependabot/npm_and_yarn/types/node-26.0.1
chore(deps-dev): bump @types/node from 25.9.3 to 26.0.1
2026-07-01 11:14:46 +03:00
dependabot[bot]
979372c7cd
chore(deps): bump lucide-react from 1.18.0 to 1.22.0
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.18.0 to 1.22.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.22.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-29 10:35:27 +00:00
dependabot[bot]
71852d38d3
chore(deps-dev): bump @types/node from 25.9.3 to 26.0.1
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.3 to 26.0.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 26.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-29 10:35:15 +00:00
dependabot[bot]
2de40e39a3
chore(deps): bump the supabase group across 1 directory with 2 updates
Bumps the supabase group with 1 update in the / directory: [@supabase/ssr](https://github.com/supabase/ssr).


Updates `@supabase/ssr` from 0.10.3 to 0.12.0
- [Release notes](https://github.com/supabase/ssr/releases)
- [Changelog](https://github.com/supabase/ssr/blob/main/CHANGELOG.md)
- [Commits](https://github.com/supabase/ssr/compare/v0.10.3...v0.12.0)

Updates `@supabase/supabase-js` from 2.107.0 to 2.108.2
- [Release notes](https://github.com/supabase/supabase-js/releases)
- [Changelog](https://github.com/supabase/supabase-js/blob/master/packages/core/supabase-js/CHANGELOG.md)
- [Commits](https://github.com/supabase/supabase-js/commits/v2.108.2/packages/core/supabase-js)

---
updated-dependencies:
- dependency-name: "@supabase/ssr"
  dependency-version: 0.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: supabase
- dependency-name: "@supabase/supabase-js"
  dependency-version: 2.108.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: supabase
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-29 10:35:09 +00:00
dependabot[bot]
0e7c42b7ef
chore(deps-dev): bump prettier in the dev-dependencies group
Bumps the dev-dependencies group with 1 update: [prettier](https://github.com/prettier/prettier).


Updates `prettier` from 3.8.4 to 3.9.1
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.8.4...3.9.1)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.9.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-29 10:35:06 +00:00
dependabot[bot]
7560167312
chore(deps): bump @base-ui/react from 1.5.0 to 1.6.0
Bumps [@base-ui/react](https://github.com/mui/base-ui/tree/HEAD/packages/react) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/mui/base-ui/releases)
- [Changelog](https://github.com/mui/base-ui/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mui/base-ui/commits/v1.6.0/packages/react)

---
updated-dependencies:
- dependency-name: "@base-ui/react"
  dependency-version: 1.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-22 10:35:25 +00:00
Arnas Donauskas
453336e280
fix(security): patch transitive vulns (hono, js-yaml, @babel/core)
Pin patched versions via overrides to clear open Dependabot alerts:

- hono ^4.12.25 (was 4.12.23) — fixes GHSA CORS wildcard-with-
  credentials reflection (high), serve-static %5C path traversal,
  Lambda/ALB Set-Cookie & header dropping, and body-limit bypass
  (alerts #31–#35)
- js-yaml ^4.2.0 (was 4.1.1) — fixes quadratic-complexity DoS in
  merge-key alias handling (alert #30)
- @babel/core ^7.29.6 (was 7.29.0) — fixes arbitrary file read via
  sourceMappingURL comment (alert #29)

All three are transitive (build/lint/tooling) deps; bumps are
patch/minor. npm audit clean, typecheck + lint + 421 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:50:41 +03:00
Arnas Donauskas
4fa29b7a45
refactor(inbox): record voice notes client-side, drop server ffmpeg
Follow-up to #259. Voice notes are encoded to Ogg/Opus in the browser via
opus-recorder (small WASM encoder, lazy-loaded on record), so there's no
server-side transcode and nothing to provision on the host. The server
stores the .ogg like any other attachment; WhatsApp renders it as a voice
note.

- Composer: MediaRecorder + /api/whatsapp/transcode-audio replaced with
  opus-recorder. Encoder worker vendored at public/opus/encoderWorker.min.js
  (no install-time download to fail), ignored by eslint + prettier.
- Removed the transcode route, the audio-transcode lib + tests, the
  ffmpeg-static dep + ambient types, the FFMPEG_PATH env doc, and the
  unused transcodeAudio rate limit.
- Added opus-recorder ambient types.

Still behind the 'chat_media' beta flag with per-kind size caps.
typecheck/lint/build green; 414 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 11:27:12 +03:00
Arnas Donauskas
312683ca05
feat(inbox): send photo, video, document & voice in chat (#213)
Agents can now attach a photo/video/document or record a voice note in
the inbox composer and send it live in a 1:1 thread — previously media
could only be received from customers or sent via the Flows builder.

- 023_chat_media.sql: new account-scoped `chat-media` Storage bucket
  (mirrors flow-media RLS from 020) plus Meta-accepted audio MIME types.
- meta-api: sendMediaMessage gains an `audio` kind (link-only — Meta
  rejects caption/filename on audio; WhatsApp renders OGG/Opus as a
  voice note).
- /api/whatsapp/send: media branch reusing the phone-variant retry loop.
- /api/whatsapp/transcode-audio: Node-runtime route remuxing the
  WebM/Opus that Chromium's MediaRecorder produces to OGG/Opus via
  ffmpeg-static (Firefox/Safari record accepted formats and skip it).
- composer: attach menu, file pickers, voice recorder + auto-transcode,
  preview with caption; thread: optimistic handleSendMedia.
- shared uploadAccountMedia helper (flows form refactored onto it).
- next.config: allow microphone=(self) (was fully blocked) + CSP
  media-src; document optional FFMPEG_PATH override.

Tests: meta-api audio payload shape, buildMediaPath, audio-transcode
helpers (14 new). typecheck/lint/build green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 10:07:16 +03:00
dependabot[bot]
5733b62898
chore(deps-dev): bump the dev-dependencies group across 1 directory with 4 updates
Bumps the dev-dependencies group with 4 updates in the / directory: [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss), [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [prettier](https://github.com/prettier/prettier) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `@tailwindcss/postcss` from 4.3.0 to 4.3.1
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.1/packages/@tailwindcss-postcss)

Updates `@types/node` from 25.9.2 to 25.9.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `prettier` from 3.8.3 to 3.8.4
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.8.3...3.8.4)

Updates `vitest` from 4.1.8 to 4.1.9
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/vitest)

---
updated-dependencies:
- dependency-name: "@tailwindcss/postcss"
  dependency-version: 4.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: "@types/node"
  dependency-version: 25.9.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: prettier
  dependency-version: 3.8.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: vitest
  dependency-version: 4.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-16 08:43:33 +00:00
Arnas Donauskas
c58d5cb952
Merge pull request #249 from ArnasDon/dependabot/npm_and_yarn/shadcn-4.11.0
chore(deps): bump shadcn from 4.10.0 to 4.11.0
2026-06-16 11:40:41 +03:00
dependabot[bot]
aa38cb4aa3
chore(deps): bump lucide-react from 1.17.0 to 1.18.0
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.17.0 to 1.18.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.18.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-15 10:36:56 +00:00
dependabot[bot]
fd2640c89a
chore(deps): bump shadcn from 4.10.0 to 4.11.0
Bumps [shadcn](https://github.com/shadcn-ui/ui/tree/HEAD/packages/shadcn) from 4.10.0 to 4.11.0.
- [Release notes](https://github.com/shadcn-ui/ui/releases)
- [Changelog](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/CHANGELOG.md)
- [Commits](https://github.com/shadcn-ui/ui/commits/shadcn@4.11.0/packages/shadcn)

---
updated-dependencies:
- dependency-name: shadcn
  dependency-version: 4.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-15 10:36:41 +00:00
Arnas Donauskas
64eae5e0ab
Merge pull request #225 from ArnasDon/dependabot/npm_and_yarn/date-fns-4.4.0
chore(deps): bump date-fns from 4.3.0 to 4.4.0
2026-06-08 13:42:29 +03:00
dependabot[bot]
13e03ab937
chore(deps): bump date-fns from 4.3.0 to 4.4.0
Bumps [date-fns](https://github.com/date-fns/date-fns) from 4.3.0 to 4.4.0.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Commits](https://github.com/date-fns/date-fns/compare/v4.3.0...v4.4.0)

---
updated-dependencies:
- dependency-name: date-fns
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-08 10:35:38 +00:00
dependabot[bot]
926fa4d043
chore(deps): bump @supabase/supabase-js in the supabase group
Bumps the supabase group with 1 update: [@supabase/supabase-js](https://github.com/supabase/supabase-js/tree/HEAD/packages/core/supabase-js).


Updates `@supabase/supabase-js` from 2.106.2 to 2.107.0
- [Release notes](https://github.com/supabase/supabase-js/releases)
- [Changelog](https://github.com/supabase/supabase-js/blob/master/packages/core/supabase-js/CHANGELOG.md)
- [Commits](https://github.com/supabase/supabase-js/commits/v2.107.0/packages/core/supabase-js)

---
updated-dependencies:
- dependency-name: "@supabase/supabase-js"
  dependency-version: 2.107.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: supabase
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-08 10:35:14 +00:00
Arnas Donauskas
0a2abc4290
fix(security): bump vulnerable transitive deps (hono, qs, brace-expansion)
Resolves all 6 open Dependabot alerts (#23-#28), all moderate severity:

- hono 4.12.19 -> 4.12.23 (>=4.12.21 fixes #25-#28: Set-Cookie injection,
  app.mount() path decoding, IPv6 deny-rule bypass, JWT scheme validation).
  Bumps the existing `hono` override floor to ^4.12.21.
- qs 6.15.1 -> 6.15.2 (fixes #24: stringify DoS on null/undefined comma-array entries).
- brace-expansion 5.0.5 -> 5.0.6 (fixes #23: large numeric range defeats max DoS protection).

All transitive (lockfile-only) deps. typecheck + 370 tests pass; npm audit clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 15:13:07 +03:00
Arnas Donauskas
80b4639c60
Merge pull request #195 from ArnasDon/dependabot/npm_and_yarn/dev-dependencies-4825ac1e2e
chore(deps-dev): bump vitest from 4.1.7 to 4.1.8 in the dev-dependencies group
2026-06-04 16:50:09 +03:00
Arnas Donauskas
11efb8a785
Merge pull request #197 from ArnasDon/dependabot/npm_and_yarn/shadcn-4.10.0
chore(deps): bump shadcn from 4.2.0 to 4.10.0
2026-06-04 16:48:17 +03:00
Arnas Donauskas
5c262ae3ee
Merge pull request #198 from ArnasDon/dependabot/npm_and_yarn/lucide-react-1.17.0
chore(deps): bump lucide-react from 1.16.0 to 1.17.0
2026-06-04 16:45:22 +03:00
dependabot[bot]
438cb28162
chore(deps): bump @xyflow/react from 12.10.2 to 12.11.0
Bumps [@xyflow/react](https://github.com/xyflow/xyflow/tree/HEAD/packages/react) from 12.10.2 to 12.11.0.
- [Release notes](https://github.com/xyflow/xyflow/releases)
- [Changelog](https://github.com/xyflow/xyflow/blob/main/packages/react/CHANGELOG.md)
- [Commits](https://github.com/xyflow/xyflow/commits/@xyflow/react@12.11.0/packages/react)

---
updated-dependencies:
- dependency-name: "@xyflow/react"
  dependency-version: 12.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 07:07:33 +00:00
dependabot[bot]
972762a9dd
chore(deps): bump lucide-react from 1.16.0 to 1.17.0
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.16.0 to 1.17.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.17.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 07:07:22 +00:00
dependabot[bot]
0bff06b8e6
chore(deps): bump shadcn from 4.2.0 to 4.10.0
Bumps [shadcn](https://github.com/shadcn-ui/ui/tree/HEAD/packages/shadcn) from 4.2.0 to 4.10.0.
- [Release notes](https://github.com/shadcn-ui/ui/releases)
- [Changelog](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/CHANGELOG.md)
- [Commits](https://github.com/shadcn-ui/ui/commits/shadcn@4.10.0/packages/shadcn)

---
updated-dependencies:
- dependency-name: shadcn
  dependency-version: 4.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 07:07:10 +00:00
dependabot[bot]
47439660aa
chore(deps-dev): bump vitest in the dev-dependencies group
Bumps the dev-dependencies group with 1 update: [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `vitest` from 4.1.7 to 4.1.8
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.8/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-version: 4.1.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 07:06:49 +00:00
Arnas Donauskas
2fbeeee3ac
Revert "feat(i18n): re-attempt next-intl with hardened artifact tracing" 2026-05-31 21:05:34 +03:00
Arnas Donauskas
0fa06d8b14
feat(i18n): harden build artifact tracing for Hostinger deploy
Re-applies PR #182's next-intl scaffold with defensive measures aimed
at the most-likely-but-unconfirmed causes of the 503 that hit prod
after that PR merged. PR #183 reverted #182 to restore service; this
branch carries the same i18n payload plus the safeguards below.

Defensive changes vs PR #182:

1. **`outputFileTracingRoot: __dirname`** in next.config.ts.
   Builds were warning that Next.js inferred the workspace root as
   the parent GHWebhosting directory (because of a stray lockfile
   there). With the wrong root, file tracing for the production
   artifact can include the wrong files or skip ours. Pinning the
   root to the wacrm directory silences the warning and makes tracing
   deterministic across local / CI / Hostinger.

2. **`outputFileTracingIncludes: { "/**/*": ["./messages/**/*.json"] }`**.
   Belt-and-suspenders: explicitly force the i18n message dictionaries
   into the production artifact even if static-import tracing somehow
   misses them in Hostinger's build environment.

3. **Static locale import map in `src/i18n/request.ts`**.
   Replaces `import(\`../../messages/\${locale}.json\`)` with an
   explicit `{ en: () => import(...), es: ..., lt: ... }` map.
   Template-literal dynamic imports are well-supported by Turbopack's
   tracer but the static form leaves zero room for the tracer to
   skip a locale.

4. **Try/catch around the intl middleware call**.
   If `intlMiddleware(request)` ever throws at runtime, fall through
   to auth-only handling and log the error rather than 503-ing every
   page request behind a single bad call.

5. **Try/catch around `LOADERS[locale]()`** with English fallback.
   Same idea: a missing locale bundle at runtime returns English
   content instead of crashing the render path.

6. **`engines.node: ">=20.10.0"`** (was `>=20.0.0`). Next 16.2's
   actual minimum. Tells Hostinger's Node.js app picker not to land
   us on a too-old subversion.

Verified locally:
- npm run lint → 0 errors (same 18 pre-existing warnings)
- npm run typecheck → clean
- npm run test → 366 passing
- npm run build → 62 prerendered pages across en/es/lt; workspace
  root warning gone; messages bundled into `.next/server/chunks/ssr/
  messages_{en,es,lt}_json_[json]_cjs_*.js`
- npm start probes:
    /              → 307 → /en
    /en/login      → 200
    /es/login      → 200
    /lt/login      → 200
    /en/dashboard  → 307 → /en/login (signed out)
    /api/whatsapp/templates → 401

If 503 reappears in prod after this lands, the local repro is clean,
so the next step is hPanel build/runtime logs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-31 21:01:13 +03:00
Arnas Donauskas
8124640d80
Revert "Merge pull request #183 from ArnasDon/revert/i18n-pr-182"
This reverts commit 872f751c07, reversing
changes made to 5e8076cee9.
2026-05-31 20:56:54 +03:00
Arnas Donauskas
a30f04b5a4
Revert "Merge pull request #182 from ArnasDon/feat/i18n-next-intl"
This reverts commit 5e8076cee9, reversing
changes made to 962e4fb27d.
2026-05-31 20:42:14 +03:00
Arnas Donauskas
fa5f3d51cc
fix(i18n): pin @swc/helpers >=0.5.17 via overrides to satisfy npm ci
Next 16's package metadata is self-contradictory: it declares
@swc/helpers@0.5.15 as a direct dependency, but also lists
@swc/helpers >=0.5.17 as a (non-optional now) peer dependency. With
only Next in the tree this slid by because the peer was marked
optional, but next-intl pulls in @swc/core which has the same peer
constraint without the optional flag.

Local npm 11 auto-resolved the conflict by hoisting the higher
version. CI runs npm 10 (bundled with Node 20 per .github/workflows/
ci.yml) and refused with `Missing: @swc/helpers@0.5.23 from lock
file`.

Adding @swc/helpers to the overrides block forces a single resolved
version (0.5.23 — current latest matching ^0.5.17) across the tree.
Verified locally with a clean `rm -rf node_modules && npm ci` plus
the full CI pipeline (lint, typecheck, test, build).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-31 20:28:17 +03:00
Arnas Donauskas
8a8758a487
feat(i18n): scaffold next-intl with [locale] routing + extract auth/layout
Introduces an internationalization layer so wacrm can ship in multiple
languages — initially en (canonical), es, lt (untranslated mirrors of
en, ready for translators).

Foundation
- next-intl ^4.13 (Next 16 + React 19 compatible)
- src/i18n/{routing,navigation,request}.ts — locale config, locale-aware
  Link/router/redirect, server-side message loader
- next.config.ts wired with `createNextIntlPlugin`
- src/app/* moved under src/app/[locale]/ (excluding /api and globals.css)
- [locale]/layout.tsx is now the root layout: <html lang={locale}>,
  hasLocale guard, setRequestLocale, NextIntlClientProvider,
  generateStaticParams for build-time prerendering of all locales
- middleware.ts composes next-intl's createMiddleware with the existing
  Supabase auth check: intl middleware runs first to handle locale
  prefix; auth redirects retain the active locale (e.g. signed-out user
  on /es/dashboard → /es/login); intl cookies (NEXT_LOCALE) are carried
  onto auth-issued responses so the sticky preference survives

Strings extracted (~80 keys across en/es/lt.json)
- common, nav (sidebar + header), roles (Owner/Admin/Agent/Viewer chips)
- auth.login, auth.signup, auth.forgotPassword (all forms + success states)
- join (all four UI states: loading, fail, accept, sign-up CTA + conflict modal)
- localeSwitcher

UI
- New `<LocaleSwitcher />` in the header — globe icon + locale dropdown
  using next-intl's useLocale + locale-aware useRouter

Out of scope for this PR (intentional — keeps diff reviewable)
- Dashboard feature pages (dashboard, inbox, contacts, pipelines,
  broadcasts, automations, flows, settings) and their components/
  namespaces still have hardcoded English; they continue to render
  fine because next/link redirects through the locale middleware
- Shared UI a11y strings (dialog close, etc.)
- Translating es.json / lt.json — they currently mirror en.json so the
  app runs in any locale without crashes (English fallback)
- Renaming middleware.ts → proxy.ts per Next 16 deprecation

Verification
- npm run build → 62 static pages prerendered across en/es/lt
- npm run typecheck → clean
- npm run test → 366 passing
- npm run lint → 0 errors (18 pre-existing warnings untouched)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-31 20:17:49 +03:00
Arnas Donauskas
bf90c370fc
feat(dashboard): adopt Tremor for charts — first integration
Brings Tremor (Apache-2.0) in as the project's chart component
library and converts the response-time chart as the first
integration. Tremor is distributed copy-paste ("Tremor Raw") so
the components live under `src/components/tremor/`; the only
runtime peer dependency added is `recharts`. Two small local
adaptations to the vendored `BarChart`:

- `cx` (Tremor's `clsx`+`twMerge` helper) → our `cn` from
  `@/lib/utils`, aliased locally to keep diff vs upstream minimal.
- `@remixicon/react` legend-slider icons →
  `lucide-react`'s `ChevronLeft` / `ChevronRight`, since
  `lucide-react` is already a project dep.
- `ChartTooltipProps.label` widened from `string` to
  `string | number | undefined` to match recharts 3.x (Tremor's
  source still types it for recharts 2.x).

Why Tremor and not a wider switch (Mantine, HeroUI):
- The dashboard ships ~700 lines of hand-rolled SVG across three
  chart files — a focused charting library is the highest-ROI
  addition without touching the wider component surface.
- Tremor is Tailwind-native and built on the same Radix/Base UI
  layer as the existing `src/components/ui/*`, so it composes
  rather than displaces.
- Apache-2.0 + copy-paste distribution means no upgrade lock-in.

What this PR does
- Adds `src/components/tremor/{bar-chart.tsx,chart-colors.ts,
  get-y-axis-domain.ts,use-on-window-resize.ts}` (vendored from
  tremorlabs/tremor with the adaptations above).
- Installs `recharts@^3.8.1` (React 19 + Next.js 16 compatible).
- Rewrites `src/components/dashboard/response-time-chart.tsx`:
  drops 130 lines of bespoke SVG math (axis scaling, bar
  positioning, grid lines, tooltip rendering), reuses the same
  card/header/empty-state shell.

Deferred (own follow-up PRs)
- `pipeline-donut.tsx` — has user-customisable per-stage hex
  colours; Tremor's palette would override them. Needs either a
  small upstream patch or a `colors` override path.
- `conversations-chart.tsx` — area-chart conversion (largest of
  the three, 341 lines).
- The previous hand-rolled bar chart drew a horizontal dashed
  "target N minutes" reference line. Tremor BarChart doesn't
  expose Recharts primitives, so for now the target is promoted
  to a header pill (`target 5m`). On-chart reference line is a
  follow-up — either via a positioned overlay or an upstream
  `referenceLines` prop.

Verification
- `npm run lint`   → 0 errors (same 20 pre-existing warnings).
- `npm run typecheck` → clean.
- `npm test`       → 319/319 pass.
- `npm run build`  → succeeds, dashboard remains a static route.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-31 14:42:10 +03:00
Arnas Donauskas
bc859bcbcd
feat(flows): canvas / mind-map view (PR 1 of 3 — read-only)
The second half of the user feedback that drove send_media: the
linear-list editor reads as a checklist, not a branching flow, which
made conversational structures hard to understand at a glance. This
introduces a canvas view alongside the list — boxes + arrows, drag-
zoom-pan, labeled edges per branch slot. Canvas is the new default;
the list stays as a fallback toggle (per-browser preference,
persisted to localStorage).

PR 1 scope is intentionally read-only: render, don't edit. The
foundation is testable in isolation before adding drag-to-persist,
side-panel editing, and drag-to-connect (PR 2) and polish like
keyboard shortcuts, mobile fallback, and validator integration
(PR 3).

Pieces:
  - New @xyflow/react (~30 KB gz) + @dagrejs/dagre (auto-layout for
    pre-existing flows whose position_x / position_y are all zero —
    flow_nodes already reserved those columns in migration 010
    precisely for this).
  - Shared module src/components/flows/shared.tsx lifts NodeType,
    BuilderNode, NODE_META, summarizeNode, truncate so both views
    render nodes identically.
  - Pure helpers (no React, fully unit-tested):
      src/lib/flows/edges.ts   — derive labeled canvas edges per
                                 outgoing slot (button, list row,
                                 condition branch)
      src/lib/flows/layout.ts  — dagre wrapper + shouldAutoLayout
                                 guard so manually-positioned flows
                                 never get rearranged on open
  - FlowCanvas — client component, custom node renderer matching the
    list view's collapsed-card styling, MiniMap + Controls, attribution
    hidden.
  - FlowEditorShell — owns the Canvas / List toggle, conditionally
    mounts the right view.

21 new unit tests (layout + edges); existing 271 still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 19:41:37 +02:00
Arnas Donauskas
78e0f25911
docs(changelog): 0.2.2 — send_media flow node + migration 016
New users / self-hosters pulling this version need to apply migration
016 before deploying — the entry flags it under "Migration required"
and explains exactly what it does (CHECK constraint + storage bucket
+ RLS policies) so the operator knows why each piece exists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 19:22:22 +02:00