| return await dependant.call(**values) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/workspace/bulkmailer/app/api/routers/campaigns.py", line 338, in preview_campaign | res = engine.substitute(tpl.body_html, rec, g, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/workspace/bulkmailer/app/services/variable_engine.py", line 142, in substitute | pool = dict(recipient) | ^^^^^^^^^^^^^^^ | TypeError: 'Recipient' object is not iterable -- return await dependant.call(**values) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/workspace/bulkmailer/app/api/routers/campaigns.py", line 338, in preview_campaign res = engine.substitute(tpl.body_html, rec, g, === 201:async def materialize_campaign(db: AsyncSession, campaign: Campaign, recipient_rows: Sequence[Recipient], 201:async def materialize_campaign(db: AsyncSession, campaign: Campaign, recipient_rows: Sequence[Recipient], 202- preview: bool = False, preview_size: int = 0) -> dict: 203- """Create CampaignRecipient rows with generated values & assignments. 204- 205- This is the core deterministic plan: which subject/template/phone/account each recipient gets, 206- plus generated invoice numbers (unique per campaign), amounts, shipping. 207- """ 208- subjects, templates, phones, accounts = await get_campaign_entities(db, campaign) 209- 210- var_cfg = dict(campaign.variable_config or {}) 211- engine = VariableEngine(var_cfg) 212- 213- subj_sel = SubjectSelector(subjects, campaign.subject_rotation)