Skip to content

feat(crm): working Web-to-Lead public form example#1996

Merged
os-zhuang merged 1 commit into
mainfrom
feat/app-crm-web-to-lead-form
Jun 17, 2026
Merged

feat(crm): working Web-to-Lead public form example#1996
os-zhuang merged 1 commit into
mainfrom
feat/app-crm-web-to-lead-form

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

What

Add a working Web-to-Lead public-form example to app-crm.

The example previously demonstrated Web-to-Lead only via customer.portal anonymousEntry — a spec property with no runtime consumer (404, verified). So the canonical CRM example shipped a non-functional public form. This adds the mechanism that actually works and makes the example coherent.

  • lead.view.tsweb_to_lead form view with sharing.allowAnonymous → live GET/POST /api/v1/forms/contact-us (+ /submit).
  • sales-roles.tsGuestPortalProfile (isProfile, INSERT-only on crm_lead, keyed by the full object name — the anonymous permission path requires it).
  • lead.object.tsstatus gets defaultValue: 'new' so a minimal public create satisfies required (option-level default is only a UI preselect).
  • customer.portal.ts — drop the dead anonymousEntry routes; point to the working form view (re-add when the runtime mounts anonymousEntry).
  • security barrel + config: export + register the guest profile.

Why it matters

Builds against the workspace, so it's also a CI regression test for the public-form path — the #1989 flattened-metadata resolution bug would have been caught here.

Verified end-to-end (app-crm, no auth)

  • GET /api/v1/forms/contact-us200 (form spec)
  • POST /api/v1/forms/contact-us/submit → creates a crm_lead (status=new)
  • GET /api/v1/data/crm_lead401 (guests can't read — INSERT-only enforced)

validate ✓, app-crm tests 29/29. (Pre-existing example typecheck drift in unrelated files — UI/Cube/ApiEndpoint spec exports — is untouched.)

🤖 Generated with Claude Code

The app-crm example showed Web-to-Lead only via `customer.portal` `anonymousEntry`
— a spec property with NO runtime consumer, so it never worked (404). Add the
mechanism that actually does, and make the example coherent:

- lead.view.ts: `web_to_lead` form view with `sharing.allowAnonymous` →
  live `GET/POST /api/v1/forms/contact-us` (+ /submit).
- sales-roles.ts: `GuestPortalProfile` (isProfile, INSERT-only on crm_lead, keyed
  by FULL object name — the anonymous permission path requires it).
- lead.object.ts: `status` gets `defaultValue: 'new'` so a minimal public create
  satisfies `required` (the option-level `default` is only a UI preselect).
- customer.portal.ts: drop the dead `anonymousEntry` routes; point to the working
  form view instead (re-add when the runtime mounts anonymousEntry).
- security/index.ts + objectstack.config.ts: export + register the guest profile.

Doubles as a CI regression test for the public-form path (builds against the
workspace) — the #1989 flattened-metadata resolution bug would have been caught here.

Verified end-to-end (app-crm, no auth): GET /forms/contact-us → 200 form spec;
POST /forms/contact-us/submit → creates a crm_lead (status=new); GET /data/crm_lead
→ 401 (guests can't read).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@os-zhuang
os-zhuang merged commit 808487d into main Jun 17, 2026
1 of 2 checks passed
@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Building Building Preview, Comment Jun 17, 2026 1:50am

Request Review

@os-zhuang
os-zhuang deleted the feat/app-crm-web-to-lead-form branch June 17, 2026 01:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant