"""海报字段画像:统一约束不同险种、不同版式的内容范围。""" from copy import deepcopy _PROFILES = { ("savings", "single"): { "required": ["product_name", "company_name", "currency", "annual_premium", "premium_term"], "recommended": ["features", "benefit_milestone"], "optional": ["basic_sum_insured", "coverage_period", "insured_age"], "forbidden": ["full_benefit_table", "withdrawal_table"], "maxFeatureCount": 3, "milestoneYears": [20], }, ("savings", "long"): { "required": ["product_name", "company_name", "currency", "annual_premium", "premium_term"], "recommended": ["features", "total_premium", "benefit_milestones", "breakeven_hint"], "optional": ["first_year_amount_due", "withdrawal_plan", "coverage_period"], "forbidden": [], "maxFeatureCount": 6, "milestoneYears": [10, 20, 30], }, ("ci", "single"): { "required": ["product_name", "company_name", "currency", "sum_assured"], "recommended": ["annual_premium", "premium_term", "coverage_highlights", "waiting_period"], "optional": ["insured_age", "gender", "smoker"], "forbidden": ["breakeven_hint", "withdrawal_table"], "maxFeatureCount": 3, "milestoneYears": [], }, ("ci", "long"): { "required": ["product_name", "company_name", "currency", "sum_assured"], "recommended": ["coverage_highlights", "features", "waiting_period", "coverage_period"], "optional": ["premium_waiver", "death_benefit", "insured_age", "smoker"], "forbidden": ["breakeven_hint", "withdrawal_table"], "maxFeatureCount": 6, "milestoneYears": [], }, ("iul", "single"): { "required": ["product_name", "company_name", "currency", "sum_assured"], "recommended": ["target_premium", "premium_term", "index_account"], "optional": ["insured_age", "gender", "smoker"], "forbidden": ["unverified_return_promise", "withdrawal_table"], "maxFeatureCount": 3, "milestoneYears": [20], }, ("iul", "long"): { "required": ["product_name", "company_name", "currency", "sum_assured"], "recommended": ["target_premium", "minimum_premium", "index_accounts", "benefit_milestones"], "optional": ["withdrawal_notes", "fee_notes", "first_year_amount_due"], "forbidden": ["unverified_return_promise"], "maxFeatureCount": 6, "milestoneYears": [10, 20, 30], }, ("other", "single"): { "required": ["product_name", "company_name", "coverage_highlights", "disclaimer"], "recommended": ["features"], "optional": ["audience"], "forbidden": ["benefit_table", "return_metrics"], "maxFeatureCount": 3, "milestoneYears": [], }, ("other", "long"): { "required": ["product_name", "company_name", "coverage_highlights", "disclaimer"], "recommended": ["features", "audience"], "optional": ["coverage_period"], "forbidden": ["benefit_table", "return_metrics"], "maxFeatureCount": 6, "milestoneYears": [], }, } def get_field_profile(plan_type: str, output_mode: str) -> dict: """返回安全副本;未知险种和版式回退到保守画像。""" normalized_type = str(plan_type or "other").lower() if normalized_type not in {"savings", "ci", "iul"}: normalized_type = "other" normalized_mode = "long" if output_mode == "long" else "single" profile = deepcopy(_PROFILES[(normalized_type, normalized_mode)]) profile["planType"] = normalized_type profile["outputMode"] = normalized_mode return profile