0036_contact_messages.sql 1.3 KB

1234567891011121314151617181920212223242526272829
  1. -- 0036_contact_messages — public /contact form intake.
  2. -- The /contact marketing page writes one row per submission from an
  3. -- unauthenticated visitor. The sender's email is collected + stored
  4. -- here so an operator can reply privately — it is never rendered back
  5. -- to the website. Triaged out-of-band; `handled_at` is stamped once an
  6. -- operator has actioned the message. Lands on the control DB (Postgres).
  7. CREATE TABLE IF NOT EXISTS "contact_messages" (
  8. "id" text PRIMARY KEY NOT NULL,
  9. "name" text NOT NULL,
  10. -- Collected so the operator can reply privately. NEVER echoed back to
  11. -- the website in any state.
  12. "email" text NOT NULL,
  13. -- Routing hint chosen by the sender. Values: general | support | sales
  14. -- | security | privacy | other.
  15. "topic" text NOT NULL,
  16. "message" text NOT NULL,
  17. -- Abuse signals — hashed IP + raw user-agent, both nullable when the
  18. -- request arrives without them.
  19. "ip_hash" text,
  20. "user_agent" text,
  21. "created_at" timestamp with time zone DEFAULT now() NOT NULL,
  22. -- Stamped once an operator has actioned the message.
  23. "handled_at" timestamp with time zone
  24. );
  25. -- Triage queue: operator reviews newest-first.
  26. CREATE INDEX IF NOT EXISTS "contact_messages_created_idx"
  27. ON "contact_messages" USING btree ("created_at" DESC);