wacrm/src/lib/whatsapp
Arnas Donauskas a2100a3076
feat(templates): edit / resubmit / delete lifecycle endpoints
Adds the missing lifecycle operations so users can manage existing
templates without leaving wacrm.

API surface
-----------

PATCH /api/whatsapp/templates/[id]
  Edits (and re-submits) an existing Meta-side template. Used by
  the "Edit" action on APPROVED rows and "Resubmit" on REJECTED /
  PAUSED rows — same operation, different UI labels. Meta replaces
  components wholesale and flips status back to PENDING for
  re-review. Status guard rejects edits on PENDING / DISABLED /
  IN_APPEAL / PENDING_DELETION and on local-only (no
  meta_template_id) rows. Honors WHATSAPP_TEMPLATES_DRY_RUN.

DELETE /api/whatsapp/templates/[id]
  Calls Meta `DELETE /{waba_id}/message_templates?name=X&hsm_id=Y`
  when meta_template_id is set — hsm_id is critical, without it
  Meta deletes EVERY language variant of the same name. Treats
  Meta 404 as a no-op (template already gone). Always removes the
  local row.

New Meta helpers
----------------

src/lib/whatsapp/meta-api.ts gains editMessageTemplate and
deleteMessageTemplate following the established named-args +
throwMetaError pattern. Eleven new fetch-mock tests assert the
exact wire shape — especially that hsm_id always rides along when
provided, which is the difference between "delete one variant"
and "delete every variant."

UI changes
----------

src/components/settings/template-manager.tsx:
  * Edit (pencil) button visible for APPROVED rows
  * Resubmit (rotate) button visible for REJECTED / PAUSED rows
    — same flow as Edit, different label
  * Delete now calls the route handler (so Meta gets the call too)
    with a spinner during the in-flight request
  * Dialog pre-fills form from the row when opened in edit mode
  * Dialog title / CTA / description switch between "New Message
    Template" + "Submit for Approval" and "Edit Message Template"
    + "Save & Resubmit"
  * Name + language inputs are disabled in edit mode (Meta keys
    templates by id; changing either is effectively a new template)
  * Closing the dialog clears editingId so the next open starts
    fresh

Design decision
---------------

One PATCH endpoint instead of the two endpoints the plan called
for (PATCH for edit, POST for resubmit). The Meta call is the same
operation either way — the difference is UI semantics, handled in
the component. Cuts duplication; easy to split later if needed.

Out of scope (final PR remaining in the sequence):
  * Webhook handler for real-time status (PR 5)
  * sendTemplateMessage media + button param support (PR 6)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 15:57:24 +02:00
..
encryption.test.ts test: foundational Vitest suite for security + critical pure logic 2026-05-18 16:06:02 +03:00
encryption.ts security: switch WhatsApp token encryption from AES-CBC to AES-GCM 2026-04-20 20:25:48 +03:00
meta-api.test.ts feat(flows): foundation for interactive WhatsApp messages (PR 1/4) 2026-05-22 13:12:27 +03:00
meta-api.ts feat(templates): edit / resubmit / delete lifecycle endpoints 2026-05-29 15:57:24 +02:00
phone-utils.test.ts test: foundational Vitest suite for security + critical pure logic 2026-05-18 16:06:02 +03:00
phone-utils.ts feat: auto-retry with phone variants on Meta "not in allowed list" 2026-04-16 21:34:53 +03:00
template-components.test.ts feat(templates): submit-to-Meta endpoint + component-based form builder 2026-05-29 15:34:58 +02:00
template-components.ts feat(templates): submit-to-Meta endpoint + component-based form builder 2026-05-29 15:34:58 +02:00
template-lifecycle.test.ts feat(templates): edit / resubmit / delete lifecycle endpoints 2026-05-29 15:57:24 +02:00
template-status-normalize.test.ts feat(templates): submit-to-Meta endpoint + component-based form builder 2026-05-29 15:34:58 +02:00
template-status-normalize.ts feat(templates): submit-to-Meta endpoint + component-based form builder 2026-05-29 15:34:58 +02:00
template-validators.test.ts feat(templates): submit-to-Meta endpoint + component-based form builder 2026-05-29 15:34:58 +02:00
template-validators.ts feat(templates): submit-to-Meta endpoint + component-based form builder 2026-05-29 15:34:58 +02:00
webhook-signature.test.ts test: foundational Vitest suite for security + critical pure logic 2026-05-18 16:06:02 +03:00
webhook-signature.ts fix(webhook): require META_APP_SECRET, fail closed 2026-04-20 18:54:52 +03:00