mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-27 04:56:20 +02:00
* feat(landing): add Contact Sales page and inquiry endpoint (MUL-2493) Adds a public `/contact-sales` marketing page with a needs-discovery form modelled on the design reference attached to MUL-2493 — first/last name, business email (with free-provider rejection), company name + size, country/region, intended use case, and a free-text goals field, plus the two consent checkboxes from the reference. Submissions hit a new public `POST /api/contact-sales` endpoint with per-IP rate limiting (Redis-backed via the existing RateLimit middleware, configurable through `RATE_LIMIT_CONTACT_SALES`) and a per-email hourly cap so a single business address can't be used as a flood channel after one valid pass. The inquiry is stored in a new `contact_sales_inquiry` table; analytics fires a `contact_sales_submitted` PostHog event with only the closed-enum dimensions (size, country, use case) — the free-text goals stay in the DB and are never broadcast. The page is linked from the landing header (md+) and the footer's Company column, in both English and Simplified Chinese. The reserved-slug list is updated so a workspace named `contact-sales` can't shadow the route. Co-authored-by: multica-agent <github@multica.ai> * fix(landing): canonicalize business email and tighten contact-sales form (MUL-2493) - Parse the submitted email with net/mail and run the free-email block-list against the canonical addr.Address, so a display-name form like `Ada <ada@gmail.com>` can no longer slip past the gate (the raw string had domain `gmail.com>`, which wasn't blocked). Adds regression tests covering the display-name bypass and the canonicalization helper. - Drop noValidate from the contact-sales form so the browser's native required / email / select checks fire before submit; the JS-side free-email warning still runs as a UX guard. - Update success copy ("respond within three business days") in EN and ZH plus the page metadata. Co-authored-by: multica-agent <github@multica.ai> --------- Co-authored-by: multica-agent <github@multica.ai>
27 lines
1.2 KiB
SQL
27 lines
1.2 KiB
SQL
-- Contact-sales inquiries submitted from the public marketing site.
|
|
--
|
|
-- The endpoint is unauthenticated so the row has no user_id / workspace_id.
|
|
-- Spam mitigation is handled by per-IP rate limiting + business-email
|
|
-- validation at the handler layer. We store the IP only so the abuse signal
|
|
-- survives a process restart; we never expose it back through the API.
|
|
|
|
CREATE TABLE contact_sales_inquiry (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
first_name TEXT NOT NULL,
|
|
last_name TEXT NOT NULL,
|
|
business_email TEXT NOT NULL,
|
|
company_name TEXT NOT NULL,
|
|
company_size TEXT NOT NULL,
|
|
country_region TEXT NOT NULL,
|
|
use_case TEXT NOT NULL,
|
|
goals TEXT NOT NULL DEFAULT '',
|
|
consent_outreach BOOLEAN NOT NULL DEFAULT false,
|
|
consent_updates BOOLEAN NOT NULL DEFAULT false,
|
|
submitter_ip INET,
|
|
user_agent TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_contact_sales_inquiry_created ON contact_sales_inquiry(created_at DESC);
|
|
CREATE INDEX idx_contact_sales_inquiry_email_created ON contact_sales_inquiry(business_email, created_at DESC);
|