A product's application is published, not assumed

Featurekamo-shared-library
Shipped
September 5, 2026 at 8:31 PM UTC
Author
Kamo
Commit
1cb89df

`LeadVendorProduct` gains `applicationEnabled` and `webChatIntegrationId`. A product existing in the CRM is not a decision to publish a form the whole internet can submit to — it is an internal category. Deriving one from the other meant every mortgage product silently had a live public endpoint from the moment it was created, which nobody asked for and nobody could see they had. `webChatIntegrationId` is required to publish. A borrower filling in a mortgage application will have a question, and a form with no way to ask one is where they stop; making the chat part of switching the page on is what stops it being the thing nobody gets round to. A soft id, not a `@ManyToOne`: the integration lives in MediaService's half of the schema and an org may delete one, which a foreign key would make fail against a product in another service's aggregate. `setProductApplication` checks BOTH ids against the organization, not merely against each other — the vendor scoping alone would let anyone holding two matching ids edit another tenant's product — and verifies the chat integration belongs to the same org before storing it. An integration id is attacker-controlled, and a product pointing at another tenant's integration would route a borrower's conversation into that tenant's support queue. `WebChatIntegrationDTO` gains `hostedKeyReady`: the boolean, never the key. A settings screen needs to know whether attaching an integration to a page it does not host will work as-is; handing it a live credential for a list view would not help it do that.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing