1var ie=Object.defineProperty;var se=(a,e,t)=>e in a?ie(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var D=(a,e,t)=>se(a,typeof e!="symbol"?e+"":e,t);import{s as f,bO as ce,v as le}from"./index-BdZNXa7t.js";import{S as j}from"./subscriptionTypes-CA0xtkq0.js";const de=(a,e)=>{var d,l,_,p,b,h,g,E,x,M,R;const t=[];if(e.notes&&a.competitive_advantages){const k=e.notes.toLowerCase();let C=[];if(typeof a.competitive_advantages=="string")try{const $=JSON.parse(a.competitive_advantages);C=Array.isArray($)?$:[a.competitive_advantages]}catch{C=[a.competitive_advantages]}else Array.isArray(a.competitive_advantages)&&(C=a.competitive_advantages);const I=C.filter($=>{if(typeof $!="string")return!1;const L=$.toLowerCase();return k.includes("no income")&&L.includes("no income")||k.includes("no asset")&&L.includes("no asset")||k.includes("bank statement")&&L.includes("bank statement")||k.includes("dscr")&&L.includes("dscr")||k.includes("self employed")&&L.includes("self")||k.includes("alternative")&&L.includes("alternative")||k.split(" ").some(U=>U.length>4&&L.includes(U))});I.length>0&&t.push(`⨠Specializes in: ${I[0]}`)}if(e.loanType){if((d=a.accepted_loan_types)!=null&&d.includes(e.loanType))t.push(`Accepts ${e.loanType} loans`);else if((l=a.loan_programs)!=null&&l.some(k=>k.toLowerCase().includes(e.loanType.toLowerCase())))t.push(`Offers ${e.loanType} programs`);else if(typeof a.competitive_advantages=="string"){let k=!1;try{const C=JSON.parse(a.competitive_advantages);k=(Array.isArray(C)?C:[a.competitive_advantages]).some($=>typeof $=="string"&&$.toLowerCase().includes(e.loanType.toLowerCase()))}catch{k=a.competitive_advantages.toLowerCase().includes(e.loanType.toLowerCase())}k&&t.push(`Specializes in ${e.loanType}`)}}e.loanPurpose&&((_=a.accepted_loan_purposes)!=null&&_.includes(e.loanPurpose))&&t.push(`Supports ${e.loanPurpose}`);const r=parseFloat(e.loanAmount);r&&(!a.min_loan_amount||r>=a.min_loan_amount)&&(!a.max_loan_amount||r<=a.max_loan_amount)&&t.push("Loan amount within range");const n=parseFloat(e.ltv);let i=0;e.occupancy==="Primary Residence"&&a.max_ltv_primary_residence?i=a.max_ltv_primary_residence:e.occupancy==="Secondary Residence"&&a.max_ltv_secondary_residence?i=a.max_ltv_secondary_residence:e.occupancy==="Investment Property"&&a.max_ltv_investment_property&&(i=a.max_ltv_investment_property),n&&i&&n<=i&&t.push(`LTV ${n}% approved`),e.occupancy&&((p=a.accepted_occupancy_types)!=null&&p.includes(e.occupancy))&&t.push(`A
1ccepts ${e.occupancy.toLowerCase()}`),e.propertyType&&((b=a.accepted_property_types)!=null&&b.includes(e.propertyType))&&t.push("Property type approved"),e.propertyState&&((h=a.geographic_states_covered)!=null&&h.includes("All")||(g=a.geographic_states_covered)!=null&&g.includes(e.propertyState))&&t.push(`Services ${e.propertyState}`);const s=parseInt(e.creditScore);s&&a.min_credit_score&&s>=a.min_credit_score&&t.push(`FICO ${s} approved`),e.selfEmployed==="Yes"&&a.accepts_self_employed&&t.push("Self-employed borrowers accepted"),e.firstTimeHomebuyer==="Yes"&&a.offers_first_time_homebuyer_programs&&t.push("First-time homebuyer programs");const c=parseInt(((E=e.commitmentPeriod)==null?void 0:E.replace("-day",""))||"0");return c&&((x=a.accepted_lock_periods)!=null&&x.includes(c))&&t.push(`${c}-day lock available`),e.compensationPayerType&&((M=a.accepted_compensation_types)!=null&&M.includes(e.compensationPayerType))&&t.push(`${e.compensationPayerType} compensation`),e.loanTerm&&((R=a.accepted_loan_terms)!=null&&R.includes(e.loanTerm))&&t.push(`${e.loanTerm} term available`),t},Z=async(a,e,t)=>{try{const{data:r,error:n}=await f.from("admin_users").select("*").eq("user_id",a).eq("is_active",!0).maybeSingle();if(!n&&r)return console.log(`Admin user ${a} - bypassing all subscription limits`),{canProceed:!0,currentUsage:0,limit:-1};const{data:i,error:s}=await f.from("user_profiles").select("is_beta_tester").eq("user_id",a).maybeSingle();return!s&&(i==null?void 0:i.is_beta_tester)===!0?(console.log(`Beta tester ${a} - granting full premium access`),{canProceed:!0,currentUsage:0,limit:-1}):e==="broker"?await me(a,t):e==="lender"?await ue(a,t):{canProceed:!0}}catch(r){return console.error("Error checking subscription limits:",r),{canProceed:!1,reason:"Unable to verify subscription status"}}},me=async(a,e)=>{const{data:t,error:r}=await f.from("user_profiles").select("subscription_plan, monthly_searches_count, last_searches_reset, free_trial_end, free_trial_plan, free_trial_start, is_beta_tester").eq("user_id",a).single();if(r)return console.error("Error fetching user subscription:",r),{canProceed:!1,reason:"Unable to verify subscription status"};if((t==null?void 0:t.is_beta_tester)===!0)return console.log(`Beta tester ${a} - granting full premium access (broker)`),{canProceed:!0,currentUsage:0,limit:-1};let n,i=!1;if(t!=null&&t.free_trial_end){const p=new Date(t.free_trial_end);p>new Date?(n="premium",i=!0,console.log(`User ${a} is on FREE TRIAL with Premium access until ${p.toLocaleDateString()}`)):(n=t.subscription_plan||"free",console.log(`User ${a} trial expired - now on ${n} plan`))}else n=(t==null?void 0:t.subscription_plan)||"free";if(n==="premium")return{canProceed:!0,currentUsage:0,limit:-1,isOnTrial:i};const s=j.broker[n],c=t!=null&&t.last_searches_reset?new Date(t.last_searches_reset):new Date,d=new Date;let _=d.getMonth()!==c.getMonth()||d.getFullYear()!==c.getFullYear()?0:(t==null?void 0:t.monthly_searches_count)||0;if(e==="search"){const p=s.searches;return p!==-1&&_>=p?{canProceed:!1,reason:`${n==="free"?"Free searches exhausted":"Monthly search limit reached"} (${p} searches). ${n==="free"?"Upgrade to Pro for 50 searches + advanced matching":"Upgrade to Premium for unlimited searches"}.`,currentUsage:_,limit:p}:{canProceed:!0,currentUsage:_,limit:p}}if(e==="ai_query"){const p=s.aiQueries;if(p===0)return{canProceed:!1,reason:"Luna AI requires Pro or Premium subscription. Upgrade to access your AI mortgage expert.",currentUsage:0,limit:0};const b=new Date(d.getFullYear(),d.getMonth(),1),{data:h}=await f.from("ai_chat_sessions").select("id",{count:"exact"}).eq("user_id",a).gte("created_at",b.toISOString()),g=(h==null?void 0:h.length)||0;return p!==-1&&g>=p?{canProceed:!1,reason:`Monthly Luna AI limit reached (${p} questions). Upgrade to Premium for unlimited Luna AI access.`,currentUsage:g,limit:p}:{canProceed:!0,currentUsage:g,limit:p}}if(e==="rate_check")return await ee(a,n,"rate_check");if(e==="news_access")return s.newsAccess?{canProceed:!0}:{canProceed:!1,reason:"Industry news requires Pro or Premium subscription. Upgrade for full market intelligence.",currentUsage:0,limit:0};if(e==="bond_rates")return s.bondRates?{canProceed:!0}:{canProceed:!1,reason:"Bond rates require Pro or Premium subscription. Upgrade for treasury data access.",currentUsage:0,limit:0};if(e==="ai_insights")return s.aiInsights?{canProceed:!0}:{canProceed:!1,reason:"AI insights require Premium subscription. Upgrade for personalized market analysis.",currentUsage:0,limit:0};if(e==="deal_submission"){const p=new Date(d.getFullYear(),d.getMonth(),1),{data:b}=await f.from("borrower_deals").select("id",{count:"exact"}).eq("broker_id",a).gte("created_at",p.toISOString()),h=(b==null?void 0:b.length)||0,g=s.dealSubmissions;return g!==-1&&h>=g?{canProceed:!1,reason:`Monthly pre-deal submission limit reached (${g} pre-deals). ${n==="free"?"Upgrade to Pro for 20 pre-deals/month":"Upgrade to Premium for unlimited pre-deal submissions"}.`,currentUsage:h,limit:g}:{canProceed:!0,currentUsage:h,limit:g}}return{canProceed:!0}},ue=async(a,e)=>{const{data:t}=await f.from("user_profiles").select("free_trial_end, free_trial_plan, free_trial_start, subscription_plan, is_beta_tester").eq("user_id",a).single(),r=t;if((t==null?void 0:t.is_beta_tester)===!0)return console.log(`Beta tester ${a} - granting full premium access (lender)`),{canProceed:!0,currentUsage:0,limit:-1};let n;if(t!=null&&t.free_trial_end){const c=new Date(t.free_trial_end);c>new Date?(n=t.free_trial_plan||"premium",console.log(`Lender ${a} is on active trial with ${n} access until ${c.toLocaleDateString()}`)):n=(r==null?void 0:r.subscription_plan)||"free"}else n=(r==null?void 0:r.subscription_plan)||"free";if(n==="premium")return{canProceed:!0,currentUsage:0,limit:-1};const i=j.lender[n],s=0;if(e==="listing"){const c=i.listings;return c!==-1&&s>=c?{canProceed:!1,reason:`${n==="free"?"Free impressions exhausted":"Monthly listing limit reached"} (${c} listings). ${n==="free"?"Upgrade to Pro for 500 impressions + priority placement":"Upgrade to Premium for unlimited exposure"}.`,currentUsage:s,limit:c}:{canProceed:!0,currentUsage:s,limit:c}}return e==="document_upload"?i.documentUploads===0?{canProceed:!1,reason:"Document uploads require Pro or Premium subscription. Upgrade to upload marketing materials.",currentUsage:0,limit:0}:{canProceed:!0}:e==="rate_check"?await ee(a,n,"rate_check"):e==="news_access"?i.newsAccess?{canProceed:!0}:{canProceed:!1,reason:"Industry news requires Pro or Premium subscription. Upgrade for market intelligence.",currentUsage:0,limit:0}:e==="bond_rates"?i.bondRates?{canProceed:!0}:{canProceed:!1,reason:"Bond rates require Pro or Premium subscription. Upgrade for treasury data.",currentUsage:0,limit:0}:e==="ai_insights"?i.aiInsights?{canProceed:!0}:{canProceed:!1,reason:"AI insights require Premium subscription. Upgrade for market analysis.",currentUsage:0,limit:0}:{canProceed:!0}},ee=async(a,e,t)=>{const r=new Date,n=new Date(r.getFullYear(),r.getMonth(),r.getDate()),i=new Date(r.getFullYear(),r.getMonth(),r.getDate(),r.getHours()),{data:s}=await f.from("usage_tracking").select("*").eq("user_id",a).eq("action_type",t).gte("created_at",n.toISOString()),{data:c}=await f.from("usage_tracking").select("*").eq("user_id",a).eq("action_type",t).gte("created_at",i.toISOString()),d=(s==null?void 0:s.length)||0,l=(c==null?void 0:c.length)||0,_=j.broker[e],p=_.rateChecksDaily,b=_.rateChecksHourly;return b!==-1&&l>=b?{canProceed:!1,reason:`Hourly rate check limit reached (${b} checks). ${e==="free"?"Upgrade to Pro for 10 checks per hour":"Upgrade to Premium for unlimited checks"}.`,currentUsage:l,limit:b}:p!==-1&&d>=p?{canProceed:!1,reason:`Daily rate check limit reached (${p} checks). ${e==="free"?"Upgrade to Pro for 50 checks per day":"Upgrade to Premium for unlimited checks"}.`,currentUsage:d,limit:p}:{canProceed:!0,currentUsage:d,limit:p}},Ae=Object.freeze(Object.defineProperty({__proto__:null,checkSubscriptionLimits:Z},Symbol.toStringTag,{value:"Module"})),pe=Z;
1class ge{async initializeComprehensiveKnowledgeBase(e,t){console.log("ð Initializing comprehensive mortgage knowledge base for AE:",e);const r=[{ae_id:e,entry_type:"program_guide",title:"Conventional Loan Programs",content:` 2 **Conventional Conforming Loans** 3 - Down Payment: Minimum 3% for first-time buyers, 5% for repeat buyers 4 - Credit Score: Minimum 620 5 - DTI: Maximum 45% (up to 50% with compensating factors) 6 - Loan Limits: 2024 baseline $766,550 (higher in high-cost areas) 7 - PMI: Required for LTV > 80%, can be removed at 78% LTV 8 9 **HomeReady Program** 10 - Down Payment: 3% minimum 11 - Income Limits: 80% of area median income 12 - Credit Score: Minimum 620 13 - Allows boarder income and gifts from non-relatives 14 15 **Home Possible Program** 16 - Down Payment: 3% minimum 17 - Income Limits: 80% of area median income 18 - Credit Score: Minimum 660 19 - Reduced MI coverage requirements 20 `,category:"Loan Programs",subcategory:"Conventional",tags:["conventional","conforming","fannie mae","freddie mac"],is_active:!0,priority:1},{ae_id:e,entry_type:"program_guide",title:"FHA Loan Programs",content:` 21 **FHA Standard 203(b)** 22 - Down Payment: 3.5% minimum with 580+ credit score 23 - Credit Score: 500 minimum (10% down if 500-579) 24 - DTI: 43% standard (up to 57% with compensating factors) 25 - MIP: Upfront 1.75%, Annual varies by term and LTV 26 - Loan Limits: Vary by county, 2024 floor $498,257 27 28 **FHA 203(k) Rehabilitation** 29 - Purchase and renovate in one loan 30 - Standard 203(k): Major renovations over $35,000 31 - Limited 203(k): Up to $35,000 in repairs 32 - Same qualification requirements as standard FHA 33 34 **FHA Streamline Refinance** 35 - No appraisal required 36 - No income verification 37 - Must have 6 months payment history 38 - Net tangible benefit required 39 `,category:"Loan Programs",subcategory:"FHA",tags:["fha","government","first-time buyer","low down payment"],is_active:!0,priority:1},{ae_id:e,entry_type:"program_guide",title:"VA Loan Programs",content:` 40 **VA Purchase and Refinance** 41 - Down Payment: 0% for eligible veterans 42 - No PMI required 43 - Credit Score: No minimum (lender overlays typically 620+) 44 - DTI: 41% guideline (higher with residual income) 45 - Funding Fee: Varies by use, down payment, and service 46 47 **Eligibility Requirements** 48 - 90 days active duty (wartime) 49 - 181 days active duty (peacetime) 50 - 6 years National Guard/Reserves 51 - Surviving spouses may qualify 52 53 **VA IRRRL (Streamline)** 54 - No appraisal required 55 - No income verification 56 - Must reduce rate by 0.5% or go from ARM to fixed 57 - Can include funding fee in loan amount 58 `,category:"Loan Programs",subcategory:"VA",tags:["va","veteran","military","no down payment"],is_active:!0,priority:1},{ae_id:e,entry_type:"program_guide",title:"USDA Rural Development Loans",content:` 59 **USDA Guaranteed Program** 60 - Down Payment: 0% required 61 - Location: Eligible rural and suburban areas 62 - Income Limits: 115% of median household income 63 - Credit Score: 640 minimum for automated underwriting 64 - Funding Fee: 1% upfront, 0.35% annual 65 66 **Property Eligibility** 67 - Must be in USDA eligible area (check USDA map) 68 - Single-family residence 69 - Must be primary residence 70 - Move-in ready condition 71 72 **Income Calculation** 73 - Includes all household members 74 - Adjusted for dependents 75 - Childcare and medical expenses deducted 76 `,category:"Loan Programs",subcategory:"USDA",tags:["usda","rural","no down payment","government"],is_active:!0,priority:1},{ae_id:e,entry_type:"program_guide",title:"Jumbo Loan Programs",content:` 77 **Jumbo Loan Requirements** 78 - Loan Amount: Above conforming loan limits 79 - Down Payment: Typically 10-20% minimum 80 - Credit Score: 700+ typically required
81 - DTI: Maximum 43% (lower for larger loans) 82 - Reserves: 6-12 months PITI required 83 84 **Documentation Requirements** 85 - 2 years tax returns 86 - 2 years W-2s or 1099s 87 - 60 days bank statements 88 - Full appraisal with comps 89 - Letter of explanation for any issues 90 91 **Special Considerations** 92 - May require 2 appraisals for loans over $2M 93 - Gift funds may be limited 94 - Second homes and investment properties available 95 `,category:"Loan Programs",subcategory:"Jumbo",tags:["jumbo","non-conforming","high balance"],is_active:!0,priority:1},{ae_id:e,entry_type:"program_guide",title:"Non-QM Loan Programs",content:` 96 **Bank Statement Programs** 97 - 12 or 24 month bank statements 98 - For self-employed borrowers 99 - Credit Score: 600+ typically 100 - Down Payment: 10-20% minimum 101 102 **Asset Depletion Programs** 103 - Use assets to calculate income 104 - For retired or high net worth borrowers 105 - Liquid assets divided by 60-84 months 106 107 **DSCR Loans (Investment Properties)** 108 - Based on rental income vs expenses 109 - No personal income verification 110 - Typically 1.0-1.25 DSCR required 111 - 20-25% down payment 112 113 **Foreign National Programs** 114 - For non-US citizens/residents 115 - 25-30% down payment typical 116 - Alternative credit acceptable 117 `,category:"Loan Programs",subcategory:"Non-QM",tags:["non-qm","bank statement","alternative","investor"],is_active:!0,priority:1},{ae_id:e,entry_type:"guideline",title:"Income Calculation Guidelines",content:` 118 **W-2 Employee Income** 119 - Base Salary: 2 year average if stable 120 - Overtime/Bonus: 2 year average, must be likely to continue 121 - Commission: 2 year average, unreimbursed expenses deducted 122 123 **Self-Employed Income** 124 - 2 year average of tax returns 125 - Add back depreciation, depletion, amortization 126 - One-time losses may be added back with explanation 127 - Business must show stability or growth 128 129 **Other Income Sources** 130 - Social Security: Gross up by 125% if non-taxable 131 - Disability: Must continue for 3+ years 132 - Pension: Document continuance 133 - Rental Income: 75% of gross rents (with history) 134 - Child Support: Must continue 3+ years 135 `,category:"Underwriting",subcategory:"Income",tags:["income","calculation","qualifying","underwriting"],is_active:!0,priority:1},{ae_id:e,entry_type:"guideline",title:"Asset Guidelines",content:` 136 **Acceptable Assets** 137 - Checking/Savings: 2 months statements 138 - Stocks/Bonds: Most recent statement 139 - Retirement (if accessible): Current statement 140 - Gift Funds: Gift letter and paper trail required 141 142 **Large Deposits** 143 - Any deposit > 50% of monthly income 144 - Must be sourced and explained 145 - Payroll deposits excluded 146 147 **Seasoning Requirements** 148 - All funds must be seasoned 60 days 149 - Exception: documented sale of asset 150 - Gift funds: Donor's ability to gift must be documented 151 152 **Reserves Requirements** 153 - Primary: 0-6 months PITI 154 - Second Home: 2-6 months PITI 155 - Investment: 6 months PITI typical 156 `,category:"Underwriting",subcategory:"Assets",tags:["assets","reserves","down payment","seasoning"],is_active:!0,priority:1},{ae_id:e,entry_type:"guideline",title:"Credit Guidelines",content:` 157 **Credit Score Requirements** 158 - Conventional: 620 minimum 159 - FHA: 580 for 3.5% down, 500 for 10% down 160 - VA: No minimum, lender overlays typically 620 161 - USDA: 640 for automated underwriting 162 - Jumbo: 700+ typically 163 164 **Credit History** 165 - Minimum 3 tradelines with 12+ month history 166 - Alternative credit acceptable for some programs 167 168 **Derogatory Credit** 169 - BK Chapter 7: 4 years (Conv), 2 years (FHA/VA) 170 - BK Chapter 13: 2 years from discharge (Conv), 1 year (FHA) 171 - Foreclosure: 7 years (Conv), 3 years (FHA/VA) 172 - Short Sale: 4 years (Conv), 3 years (FHA) 173 - Collections: Medical excluded if paid, others case-by-case 174 175 **Disputes** 176 - Must be removed for accounts with balance 177 - Medical collections exempt 178 `,category:"Underwriting",subcategory:"Credit",tags:["credit","fico","bankruptcy","foreclosure","derogatory"],is_active:!0,priority:1},{ae_id:e,entry_type:"guideline",title:"Property Guidelines",content:` 179 **Eligible Property Types** 180 - Single Family Residence 181 - Condominiums (must be warrantable) 182 - Townhomes 183 - 2-4 Units (owner-occupied) 184 - Manufactured Homes (specific requirements) 185 186 **Appraisal Requirements** 187 - Must be completed by certified appraiser 188 - Valid for 120 days (most programs) 189 - Must meet program-specific requirements 190 - Subject-to repairs may be required 191 192 **Property Condition** 193 - C1-C4: Typically acceptable 194 - C5: May require repairs 195 - C6: Extensive repairs needed 196 - Health and safety issues must be addressed 197 198 **Condo Requirements** 199 - Warrantable: 51%+ owner occupied, adequate reserves 200 - FHA: Must be on approved list 201 - VA: Automatic approval or VA review 202 `,category:"Underwriting",subcategory:"Property",tags:["property","appraisal","condo","condition"],is_active:!0,priority:1},{ae_id:e,entry_type:"regulation",title:"TRID Compliance Requirements",content:`
203 **Loan Estimate (LE)** 204 - Must be delivered within 3 business days of application 205 - 6 pieces of information trigger: name, income, SSN, property address, loan amount, property value 206 - Valid for 10 business days 207 - Rate must be available for lock 208 209 **Closing Disclosure (CD)** 210 - Must be received 3 business days before closing 211 - Changes triggering new 3-day period: 212 * APR increase > 0.125% 213 * Change in loan product 214 * Addition of prepayment penalty 215 216 **Tolerance Violations** 217 - Zero tolerance: Lender fees, transfer taxes (if known) 218 - 10% tolerance: Required services shopped in aggregate 219 - Unlimited: Services borrower can shop, prepaid interest 220 `,category:"Compliance",subcategory:"TRID",tags:["trid","compliance","disclosure","regulations"],is_active:!0,priority:1},{ae_id:e,entry_type:"regulation",title:"Fair Lending Compliance",content:` 221 **Protected Classes (ECOA)** 222 - Race, Color, Religion, National Origin 223 - Sex, Marital Status, Age 224 - Receipt of public assistance 225 - Exercise of rights under Consumer Credit Protection Act 226 227 **Fair Housing Act** 228 - All ECOA classes plus: 229 - Familial status 230 - Disability 231 232 **Compliance Requirements** 233 - No discriminatory practices 234 - Equal treatment in all aspects 235 - Reasonable accommodations for disabilities 236 - No steering or redlining 237 - Adverse action notices when required 238 239 **HMDA Reporting** 240 - Collect demographic information 241 - Report to CFPB annually 242 - Public disclosure of lending patterns 243 `,category:"Compliance",subcategory:"Fair Lending",tags:["fair lending","ecoa","hmda","discrimination"],is_active:!0,priority:1},{ae_id:e,entry_type:"template",title:"Initial Broker Contact Template",content:` 244 Hello [Broker Name], 245 246 Thank you for reaching out to ${t}. I'm excited to help you find the best loan solution for your client. 247 248 To provide you with accurate pricing and program options, I'll need: 249 - Loan amount and property value 250 - Property type and occupancy 251 - Credit score range 252 - Income type (W2, self-employed, etc.) 253 - Any unique circumstances 254 255 I'm committed to responding within [response time] and providing: 256 â Competitive rates and pricing 257 â Clear program guidelines 258 â Fast underwriting turn times 259 â Dedicated support throughout the process 260 261 When would be a good time to discuss your client's scenario? 262 263 Best regards, 264 [AE Name] 265 `,category:"Templates",subcategory:"Broker Communication",tags:["template","broker","initial contact"],is_active:!0,priority:1},{ae_id:e,entry_type:"template",title:"Conditional Approval Template",content:` 266 Great news! 267 268 Your client's loan has been conditionally approved! 269 270 **Loan Details:** 271 - Borrower: [Name] 272 - Loan Amount: [Amount] 273 - Program: [Program Type] 274 - Rate: [Rate] 275 276 **Outstanding Conditions:** 277 [List conditions clearly] 278 279 **Next Steps:** 280 1. Review the attached conditional approval 281 2. Gather the outstanding items 282 3. Upload to our secure portal 283 4. We'll review and clear conditions within 24 hours 284 285 Please let me know if you have any questions about the conditions or need clarification on any items. 286 287 We're on track to close by [date]! 288 `,category:"Templates",subcategory:"Loan Status",tags:["template","approval","conditions"],is_active:!0,priority:1},{ae_id:e,entry_type:"faq",title:"What are your turn times?",content:`Our typical turn times are: 289 - Initial review: 4 hours 290 - Underwriting decision: 24-48 hours 291 - Conditions review: 24 hours 292 - Clear to close: 24 hours after all conditions met 293 - Rush options available for time-sensitive deals`,category:"Service",tags:["turn time","speed","processing"],is_active:!0,priority:1},{ae_id:e,entry_type:"faq",title:"Do you offer broker compensation?",content:`Yes, we offer competitive broker compensation: 294 - Standard comp: 2.75% (minimum varies by loan amount) 295 - Volume bonuses available 296 - No junk fees to borrower 297 - Transparent pricing 298 - Monthly commission reconciliation`,category:"Compensation",tags:["compensation","broker
298comp","pricing"],is_active:!0,priority:1},{ae_id:e,entry_type:"faq",title:"What states are you licensed in?",content:`We are currently licensed and actively lending in: 299 [List states based on actual licenses] 300 301 We're continuously expanding our footprint. If you have a deal in a state not listed, please reach out as we may have a solution through our correspondent network.`,category:"Licensing",tags:["states","licensing","coverage"],is_active:!0,priority:1},{ae_id:e,entry_type:"faq",title:"How do I submit a loan?",content:`You can submit loans through: 302 1. Our secure online portal (preferred) 303 2. Email with encrypted attachments 304 3. Integration with your LOS (if available) 305 306 Initial submission requires: 307 - 1003 application 308 - Credit report (or authorization to pull) 309 - Income documentation 310 - Asset statements 311 - Purchase contract or refinance details`,category:"Process",tags:["submission","process","requirements"],is_active:!0,priority:1}];try{for(let i=0;i<r.length;i+=10){const s=r.slice(i,i+10),{error:c}=await f.from("ae_knowledge_base_entries").insert(s);c?console.error(`â ï¸ Error inserting batch ${i/10+1}:`,c):console.log(`â Inserted batch ${i/10+1} (${s.length} entries)`)}return console.log(`â Comprehensive knowledge base initialized with ${r.length} entries`),!0}catch(n){return console.error("ð¥ Failed to initialize knowledge base:",n),!1}}async searchKnowledgeBase(e,t,r=5){try{console.log("ð [Knowledge Base] HIERARCHICAL search for:",t,"AE:",e);let n=e;const{data:i,error:s}=await f.from("user_profiles").select("id").eq("user_id",e).maybeSingle();s?console.error("â [Knowledge Base] Profile lookup error:",s):i!=null&&i.id?(n=i.id,console.log(`ð [Knowledge Base] â Resolved auth user ID ${e} to profile row ID ${n}`)):console.log(`â ï¸ [Knowledge Base] No profile found for auth user ID ${e}, using original value`);const{data:c,error:d}=await f.from("ae_knowledge_base").select("*").eq("ae_id",n).eq("is_lender_specific",!0).or(`topic.ilike.%${t}%,content.ilike.%${t}%,category.ilike.%${t}%`).order("confidence_score",{ascending:!1}).limit(r);d&&console.warn("â ï¸ [Knowledge Base] PDF knowledge search error:",d);const l=[];let _=r;if(c&&c.length>0){const h=c.map(g=>{var E;return{id:g.id,ae_id:g.ae_id,entry_type:"program_guide",title:g.topic||"Lender Information",content:this.extractContentFromPdfEntry(g.content),category:g.category||"Loan Programs",subcategory:this.determineProgramSubcategory(g.category,g.topic),tags:this.generateTagsFromContent(g.topic,g.content,g.category),is_active:!0,priority:this.calculatePriorityFromConfidence(g.confidence_score),metadata:{source:"pdf_extraction",original_metadata:g.metadata,confidence_score:g.confidence_score,extraction_method:(E=g.metadata)==null?void 0:E.extraction_method}}});l.push(...h),_-=h.length,console.log(`â [Knowledge Base] Found ${c.length} LENDER-SPECIFIC PDF entries for AE: ${e}`)}if(_>0){const{data:h,error:g}=await f.from("ae_knowledge_base_entries").select("*").eq("ae_id",n).eq("is_active",!0).or(`title.ilike.%${t}%,content.ilike.%${t}%`).order("priority",{ascending:!0}).limit(_);g&&console.warn("â ï¸ [Knowledge Base] Standard search error:",g),h&&h.length>0&&(l.push(...h),console.log(`ð [Knowledge Base] Added ${h.length} general entries as fallback`))}const b=l.sort((h,g)=>{var k,C;const E=((k=h.metadata)==null?void 0:k.source)==="pdf_extraction"?1:0,x=((C=g.metadata)==null?void 0:C.source)==="pdf_extraction"?1:0;if(E!==x)return x-E;const M=h.title.toLowerCase().includes(t.toLowerCase())?1:0,R=g.title.toLowerCase().includes(t.toLowerCase())?1:0;return M!==R?R-M:(h.priority||10)-(g.priority||10)}).slice(0,r);return console.log(`ð [Knowledge Base] Returning ${b.length} total results`),b}catch(n){return console.error("â [Knowledge Base] Search failed:",n),[]}}extractContentFromPdfEntry(e){try{if(typeof e=="string"){const t=JSON.parse(e);return this.formatParsedContent(t)}return typeof e=="object"?this.formatParsedContent(e):(e==null?void 0:e.toString())||"No content available"}catch{return(e==null?void 0:e.toString())||"No content available"}}formatParsedContent(e){const t=[];if(e.lender&&t.push(`**${e.lender}
311**`),e.keyFocus&&t.push(`Focus: ${e.keyFocus}`),e.description&&t.push(e.description),e.programs&&Array.isArray(e.programs)&&t.push(`Programs Available: ${e.programs.join(", ")}`),e.program&&typeof e.program=="object"&&(e.program.name&&t.push(`Program: ${e.program.name}`),e.program.description&&t.push(e.program.description),e.program.requirements&&t.push(`Requirements: ${Array.isArray(e.program.requirements)?e.program.requirements.join(", "):e.program.requirements}`)),e.specialties&&Array.isArray(e.specialties)&&t.push(`Specialties: ${e.specialties.join(", ")}`),e.criteria&&typeof e.criteria=="object"){const r=[];e.criteria.minCreditScore&&r.push(`Min Credit: ${e.criteria.minCreditScore}`),e.criteria.maxLTV&&r.push(`Max LTV: ${e.criteria.maxLTV}%`),e.criteria.loanTypes&&r.push(`Loan Types: ${e.criteria.loanTypes.join(", ")}`),r.length>0&&t.push(`Requirements: ${r.join(" | ")}`)}return t.join(` 312 313`)||"Information available - contact AE for details"}determineProgramSubcategory(e,t){if(!e||!t)return"General";const r=t.toLowerCase();return r.includes("fix")&&r.includes("flip")?"Hard Money":r.includes("dscr")?"Investment":r.includes("non-qm")||r.includes("bank statement")?"Non-QM":r.includes("bridge")?"Bridge":r.includes("construction")?"Construction":r.includes("jumbo")?"Jumbo":r.includes("fha")?"FHA":r.includes("va")?"VA":r.includes("conventional")?"Conventional":e}generateTagsFromContent(e,t,r){const n=[];if(!e&&!t&&!r)return["general"];const i=`${e||""} ${r||""}`.toLowerCase();return i.includes("fix")&&i.includes("flip")&&n.push("fix and flip","hard money","investment"),i.includes("dscr")&&n.push("dscr","investment property","rental income"),i.includes("non-qm")&&n.push("non-qm","alternative documentation","self-employed"),i.includes("bank statement")&&n.push("bank statement","self-employed","non-qm"),i.includes("bridge")&&n.push("bridge loans","short term","transitional"),i.includes("construction")&&n.push("construction","ground up","development"),["fha","va","conventional","usda","jumbo"].forEach(c=>{i.includes(c)&&n.push(c)}),n.length>0?n:["lender specific"]}calculatePriorityFromConfidence(e){return e?e>=.9?1:e>=.8?2:e>=.7?3:e>=.6?4:5:5}async getKnowledgeByCategory(e,t){try{const{data:r,error:n}=await f.from("ae_knowledge_base_entries").select("*").eq("ae_id",e).eq("category",t).eq("is_active",!0).order("priority",{ascending:!0});return n?(console.error("Error fetching knowledge by category:",n),[]):r||[]}catch(r){return console.error("Failed to fetch knowledge by category:",r),[]}}async updateKnowledgeEntry(e,t){try{const{error:r}=await f.from("ae_knowledge_base_entries").update({...t,updated_at:new Date().toISOString()}).eq("id",e);return r?(console.error("Error updating knowledge entry:",r),!1):!0}catch(r){return console.error("Failed to update knowledge entry:",r),!1}}}const _e=new ge;class he{async upsertKnowledge(e){try{let t;typeof e.content=="object"&&(t=await this.generateEmbedding(JSON.stringify(e.content)));const{error:r}=await f.from("lender_knowledge_base").upsert({lender_id:e.lender_id,lender_name:e.lender_name,knowledge_type:e.knowledge_type,content:e.content,effective_date:e.effective_date||new Date().toISOString().split("T")[0],is_current:!0,embedding:t});if(r)throw r;console.log("â Lender knowledge saved successfully")}catch(t){throw console.error("Error saving lender knowledge:",t),t}}async addKnowledge(e,t){try{const{data:{user:r}}=await f.auth.getUser();if(!r)throw new Error("User not authenticated");const{data:n}=await f.from("lender_profiles").select("lender_name").eq("user_id",r.id).single(),i=JSON.stringify(t,null,2),s=`${e.charAt(0).toUpperCase()+e.slice(1)} Information`,{error:c}=await f.from("lender_knowledge_base").insert({ae_id:r.id,ae_name:(n==null?void 0:n.lender_name)||"Unknown Lender",lender_id:r.id,lender_name:(n==null?void 0:n.lender_name)||"Unknown Lender",entry_type:"qa",question:`What are your ${e}?`,answer:i,tags:[e],is_active:!0,processing_status:"completed",created_by:r.id});if(c)throw c;console.log(`â Knowledge base ${e} saved successfully`)}catch(r){throw console.error("Error adding knowledge:",r),r}}extractBaseLenderId(e){if(!e)return e;const t=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i,r=e.match(t);if(r){const n=r[0];if(e.length>
31336&&e[36]==="_")return console.log(`ð§ [Extract ID] Extracted base ID: ${n} from composite: ${e.substring(0,50)}...`),n}return e}async getKnowledge(e,t){const r=this.extractBaseLenderId(e);console.log(`ð [Get Knowledge] Retrieving knowledge for lender: ${r} (original: ${e.substring(0,50)}${e.length>50?"...":""})`);try{let n=f.from("lender_knowledge_base").select("*").eq("lender_id",r).eq("is_current",!0);t&&(n=n.eq("knowledge_type",t));const{data:i,error:s}=await n;s&&console.warn("Error fetching traditional knowledge:",s);const c=i||[];console.log(`ð Found ${c.length} traditional knowledge entries`);const{data:d,error:l}=await f.from("ae_knowledge_base").select("*").eq("ae_id",r).eq("is_lender_specific",!0);l&&console.warn("Error fetching PDF knowledge:",l);const _=(d||[]).map(h=>{var g;return{id:`pdf-${h.id}`,lender_id:r,lender_name:this.extractLenderNameFromContent(h.content),knowledge_type:this.mapPdfCategoryToKnowledgeType(h.category),content:typeof h.content=="string"?JSON.parse(h.content):h.content,effective_date:(g=h.created_at)==null?void 0:g.split("T")[0],is_current:!0,source:"pdf_extraction"}});console.log(`ð Found ${_.length}
313 PDF-extracted knowledge entries`);const p=[...c,..._],b=t?p.filter(h=>h.knowledge_type===t):p;return console.log(`â [Get Knowledge] Returning ${b.length} total knowledge entries for ${r}`),b}catch(n){return console.error("Error fetching dual-source lender knowledge:",n),[]}}mapPdfCategoryToKnowledgeType(e){return{loan_programs:"programs",lender_overview:"specialties",rates:"rates",requirements:"requirements",process:"processes",guidelines:"requirements"}[e]||"specialties"}async searchKnowledge(e,t=5){console.log(`ð [Lender KB Service] Searching knowledge with dual-source approach: "${e}"`);try{const r=await this.searchTraditionalKnowledge(e,Math.ceil(t/2));console.log(`ð Found ${r.length} traditional knowledge matches`);const n=await _e.searchKnowledgeBase("general",e,Math.ceil(t/2));console.log(`ð Found ${n.length} PDF-based knowledge matches`);const i=n.map(l=>({id:`pdf-${l.id}`,lender_id:l.ae_id||"unknown",lender_name:this.extractLenderNameFromContent(l.content),knowledge_type:"pdf_extracted",content:typeof l.content=="string"?JSON.parse(l.content):l.content,title:l.title,similarity:l.similarity||.8,source:"pdf_extraction",is_current:!0})),d=[...r,...i].sort((l,_)=>{const p=l.similarity||.5;return(_.similarity||.5)-p}).slice(0,t);return console.log(`â [Dual Search] Returning ${d.length} combined results (${r.length} traditional + ${i.length} PDF)`),d}catch(r){return console.error("â Error in dual-source knowledge search:",r),this.searchTraditionalKnowledge(e,t)}}async searchTraditionalKnowledge(e,t){try{const r=await this.generateEmbedding(e);if(!r)return this.textSearch(e,t);const{data:n,error:i}=await f.rpc("search_lender_knowledge",{query_embedding:r,match_threshold:.75,match_count:t});if(i)throw i;return n||[]}catch(r){return console.error("Error searching traditional knowledge base:",r),this.textSearch(e,t)}}extractLenderNameFromContent(e){try{if(typeof e=="string"){const t=JSON.parse(e);return t.lender||t.lenderName||"Unknown Lender"}else if(typeof e=="object"&&e!==null)return e.lender||e.lenderName||"Unknown Lender";return"Unknown Lender"}catch{return"Unknown Lender"}}async textSearch(e,t){try{const{data:r,error:n}=await f.from("lender_knowledge_base").select("*").textSearch("content",e).eq("is_current",!0).limit(t);if(n)throw n;return r||[]}catch(r){return console.error("Error in text search:",r),[]}}async generateEmbedding(e){try{console.warn("â ï¸ Embedding generation temporarily disabled - needs Edge Function implementation");return}catch(t){console.error("Error generating embedding:",t);return}}async importGuidelines(e,t,r){try{const n=await this.parseGuidelinesWithAI(r);n.programs&&await this.upsertKnowledge({lender_id:e,lender_name:t,knowledge_type:"programs",content:n.programs}),n.requirements&&await this.upsertKnowledge({lender_id:e,lender_name:t,knowledge_type:"requirements",content:n.requirements}),n.rates&&await this.upsertKnowledge({lender_id:e,lender_name:t,knowledge_type:"rates",content:n.rates}),console.log("â Guidelines imported successfully")}catch(n){throw console.error("Error importing guidelines:",n),n}}async parseGuidelinesWithAI(e){try{const t=`Parse the following lender guidelines and extract structured information. 314 315Guidelines: 316${e.substring(0,3e3)} // Limit to avoid token limits 317 318Extract and structure: 3191. Loan programs (name, description, requirements) 3202. Credit requirements 3213. Income requirements 3224. Property requirements 3235. Rate information if available 324 325Return as JSON with this structure: 326{ 327 "programs": [...], 328 "requirements": {...}, 329 "rates": [...] 330}`,r=await ce([{role:"system",content:"You are a mortgage guidelines parser. Extract structured data from lender guidelines."},{role:"user",content:t}],{model:"gpt-4-turbo-preview",temperature:.3,max_tokens:1500,response_format:{type:"json_object"}});return!r.success||!r.message?(console.error("Failed to parse guidelines:",r.error),{programs:[],requirements:{},rates:[]}):JSON.parse(r.message)}catch(t){return console.error("Error parsing guidelines with AI:",t),{programs:[],requirements:{},rates:[]}}}async matchDealWithKnowledge(e,t){try{const r=await this.getKnowledge(t);let n=0;const i=[],s=[],c=r.find(l=>l.knowledge_type==="programs");if(c!=null&&c.content){const l=Array.isArray(c.content)?c.content:c.content.programs||[];for(const _ of l)this.checkProgramMatch(e,_)&&(i.push(_.name||"Unknown Program"),n+=20)}const d=r.find(l=>l.knowledge_type==="requirements");if(d!=null&&d.content){const l=this.checkRequirementsMatch(e,d.content);
330n+=l.score,s.push(...l.recommendations)}return n=Math.min(100,n),{matchScore:n,matchingPrograms:i,recommendations:s}}catch(r){return console.error("Error matching deal with knowledge:",r),{matchScore:50,matchingPrograms:[],recommendations:[]}}}checkProgramMatch(e,t){return!(t.minCreditScore&&e.creditScore<t.minCreditScore||t.maxLTV&&e.ltv>t.maxLTV||t.maxDTI&&e.dti>t.maxDTI||t.propertyTypes&&!t.propertyTypes.includes(e.propertyType))}checkRequirementsMatch(e,t){let r=0;const n=[];if(t.creditRequirements){const i=t.creditRequirements;e.creditScore>=i.minScore?r+=25:n.push(`Credit score needs improvement (${i.minScore} required)`)}return t.incomeRequirements&&(r+=25),t.assetRequirements&&(r+=25),{score:r,recommendations:n}}async populateSampleData(){const e=[{lender_id:"sample-lender-1",lender_name:"Wells Fargo",programs:[{name:"Conventional 30-Year Fixed",description:"Standard conforming loan program",minCreditScore:620,maxLTV:97,maxDTI:50,propertyTypes:["Single Family","Condo","Townhouse"],occupancyTypes:["Primary Residence","Second Home","Investment"],features:["No prepayment penalty","Available nationwide"],restrictions:["No manufactured homes","Min loan amount $50,000"]},{name:"FHA Loan",description:"Government-backed loan with lower down payment",minCreditScore:580,maxLTV:96.5,maxDTI:57,propertyTypes:["Single Family","Condo","2-4 Unit"],occupancyTypes:["Primary Residence"],features:["3.5% down payment","Flexible credit requirements"],restrictions:["Primary residence only","Mortgage insurance required"]}],requirements:{documentRequirements:["2 years tax returns","2 months bank statements","30 days pay stubs","Government ID","Insurance declaration"],creditRequirements:{minScore:620,maxInquiries:6,bankruptcyYears:4,foreclosureYears:7},incomeRequirements:{minMonthlyIncome:3e3,employmentMonths:24,selfEmployedYears:2},assetRequirements:{minReserves:2,verifiedAssets:!0}}},{lender_id:"sample-lender-2",lender_name:"Quicken Loans",programs:[{name:"Rocket Mortgage Express",description:"Fast online mortgage with digital verification",minCreditScore:640,maxLTV:95,maxDTI:50,propertyTypes:["Single Family","Condo"],occupancyTypes:["Primary Residence"],features:["15-day closing","Online application","Digital document upload"],restrictions:["Primary residence only","W2 income only"]}],requirements:{documentRequirements:["Digital tax returns","Bank account linking","E-sign documents"],creditRequirements:{minScore:640,maxInquiries:4,bankruptcyYears:3,foreclosureYears:5},incomeRequirements:{minMonthlyIncome:4e3,employmentMonths:12,selfEmployedYears:2},assetRequirements:{minReserves:3,verifiedAssets:!0}}}];for(const t of e)await this.upsertKnowledge({lender_id:t.lender_id,lender_name:t.lender_name,knowledge_type:"programs",content:{programs:t.programs}}),await this.upsertKnowledge({lender_id:t.lender_id,lender_name:t.lender_name,knowledge_type:"requirements",content:t.requirements});console.log("â
Sample lender knowledge populated")}}const te=new he;async function re(a){try{const{data:e,error:t}=await f.functions.invoke("unified-ai-service",{body:a});return t?(console.error("â Edge Function invocation error:",t),{success:!1,error:t.message||"Failed to call AI service",timestamp:new Date().toISOString()}):e}catch(e){return console.error("â Secure OpenAI call failed:",e),{success:!1,error:le(e),timestamp:new Date().toISOString()}}}async function fe(a,e="You are a helpful assistant. Always return valid JSON.",t={}){const r=await re({messages:[{role:"system",content:e},{role:"user",content:a}],model:t.model||"gpt-3.5-turbo",temperature:t.temperature??.3,max_tokens:t.max_tokens||1e3,response_format:{type:"json_object"},context:t.context});if(!r.success||!r.message)throw new Error(r.error||"AI completion failed");try{return JSON.parse(r.message)}catch{throw console.error("â Failed to parse JSON response:",r.message),new Error("Invalid JSON response from AI")}}class ye{constructor(){D(this,"DEFAULT_SIMILARITY_THRESHOLD",.7);D(this,"MAX_SEARCH_RESULTS",50);D(this,"EMBEDDING_CACHE",new Map)}async performHybridSearch(e,t={},r={vector_weight:.7,keyword_weight:.2,metadata_weight:.1,enable_reranking:!0,max_results:20,similarity_threshold:this.DEFAULT_SIMILARITY_THRESHOLD}){console.log(`ð [Vector Search] Performing hybrid search: "${e}"`);try{const n=await this.generateQueryEmbedding(e),i=await this.performVectorSimilaritySearch(n,t,r),s=await this.performKeywordSearch(e,t),c=await this.performMetadataSearch(e,t),d=this.combineSearchResults(i,s,c,r),l=r.enable_reranking?await this.rerankResults(d,e,r):d;
330return await this.logSearchAnalytics(e,t,l.length),console.log(`â [Vector Search] Found ${l.length} results`),l.slice(0,r.max_results)}catch(n){return console.error("â [Vector Search] Hybrid search failed:",n),this.performFallbackSearch(e,t)}}async generateQueryEmbedding(e){if(this.EMBEDDING_CACHE.has(e))return this.EMBEDDING_CACHE.get(e);try{const t=await re({messages:[],model:"text-embedding-3-small",input:e.substring(0,8e3),context:"vector-search-embedding"});if(!t.success||!t.embedding)throw console.error("Failed to generate embedding"),new Error("Failed to generate query embedding");const r=t.embedding;return this.EMBEDDING_CACHE.size<100&&this.EMBEDDING_CACHE.set(e,r),r}catch(t){throw console.error("Error generating query embedding:",t),new Error("Failed to generate query embedding")}}async performVectorSimilaritySearch(e,t,r){try{let n=f.from("document_chunks").select(` 331 id, 332 chunk_text, 333 section_title, 334 chunk_index, 335 document_id, 336 ae_id, 337 lender_id, 338 usage_count, 339 relevance_score, 340 created_at, 341 knowledge_base_documents!inner( 342 title, 343 document_type, 344 metadata 345 ) 346 `);t.document_types&&t.document_types.length>0&&(n=n.in("knowledge_base_documents.document_type",t.document_types)),t.date_range&&(n=n.gte("created_at",t.date_range.start).lte("created_at",t.date_range.end));const{data:i,error:s}=await n.limit(r.max_results*2);return s?(console.error("Vector search error:",s),[]):(i||[]).map(d=>{var l;return{id:d.id,content:d.chunk_text,similarity:this.calculateTextSimilarity(d.chunk_text,e),metadata:{document_id:d.document_id,section_title:d.section_title,chunk_index:d.chunk_index,lender_name:this.extractLenderName((l=d.knowledge_base_documents)==null?void 0:l.metadata),source_type:"document_chunk",relevance_factors:["vector_similarity"]}}}).filter(d=>d.similarity>=r.similarity_threshold)}catch(n){return console.error("Error in vector similarity search:",n),[]}}async performKeywordSearch(e,t){try{const{data:r}=await f.from("document_chunks").select(` 347 id, 348 chunk_text, 349 section_title, 350 chunk_index, 351 document_id, 352 knowledge_base_documents!inner( 353 title, 354 document_type, 355 metadata 356 ) 357 `).textSearch("chunk_text",e,{type:"websearch"}).limit(20),{data:n}=await f.from("ae_knowledge_base").select("*").eq("is_lender_specific",!0).or(`topic.ilike.%${e}%,content.ilike.%${e}%`).limit(10);return[...(r||[]).map(s=>({id:s.id,content:s.chunk_text,similarity:this.calculateKeywordRelevance(s.chunk_text,e),metadata:{document_id:s.document_id,section_title:s.section_title,source_type:"document_chunk",relevance_factors:["keyword_match"]}})),...(n||[]).map(s=>({id:`pdf-${s.id}`,content:typeof s.content=="string"?s.content:JSON.stringify(s.content),similarity:this.calculateKeywordRelevance(s.topic+" "+JSON.stringify(s.content),e),metadata:{lender_name:this.extractLenderNameFromPdfContent(s.content),source_type:"pdf_knowledge",relevance_factors:["keyword_match","pdf_extraction"]}}))]}catch(r){return console.error("Error in keyword search:",r),[]}}async performMetadataSearch(e,t){const r=[];try{const n=this.extractLoanTypesFromQuery(e);if(n.length>0){const{data:s}=await f.from("document_chunks").select(` 358 id, 359 chunk_text, 360 section_title, 361 knowledge_base_documents!inner( 362 metadata 363 ) 364 `).limit(15);(s||[]).forEach(c=>{var p;const d=((p=c.knowledge_base_documents)==null?void 0:p.metadata)||{},l=JSON.stringify(d).toLowerCase(),_=n.filter(b=>l.includes(b.toLowerCase())||c.chunk_text.toLowerCase().includes(b.toLowerCase()));_.length>0&&r.push({id:c.id,content:c.chunk_text,similarity:.6+_.length*.1,metadata:{section_title:c.section_title,source_type:"document_chunk",relevance_factors:["metadata_match","loan_type_match"],matching_loan_types:_}})})}this.extractStatesFromQuery(e).length>0&&r.length<10}catch(n){console.error("Error in metadata search:",n)}return r}combineSearchResults(e,t,r,n){const i=new Map;return e.forEach(s=>{const c=s.similarity*n.vector_weight;i.set(s.id,{id:s.id,content:s.content,similarity:s.similarity,metadata:{...s.metadata,relevance_factors:[...s.metadata.relevance_factors||[],"vector_search"]},confidence_score:c})}),t.forEach(s=>{const c=s.similarity*n.keyword_weight;if(i.has(s.id)){const d=i.get(s.id);d.confidence_score+=c,d.metadata.relevance_factors.push("keyword_search")}else i.set(s.id,{id:s.id,content:s.content,similarity:s.similarity,metadata:{...s.metadata,relevance_factors:[...s.metadata.relevance_factors||[],"keyword_search"]},confidence_score:c})}),r.forEach(s=>{const c=s.similarity*n.metadata_weight;if(i.has(s.id)){const d=i.get(s.id);d.confidence_score+=c,d.metadata.relevance_factors.push("metadata_search")}else i.set(s.id,{id:s.id,content:s.content,similarity:s.similarity,metadata:{...s.metadata,relevance_factors:[...s.metadata.relevance_factors||[],"metadata_search"]},confidence_score:c})}),Array.from(i.values()).sort((s,c)=>c.confidence_score-s.confidence_score)}async rerankResults(e,t,r){return e.map(n=>{let i=n.confidence_score;return n.metadata.relevance_factors.length>1&&(i*=1.1),n.metadata.document_id&&(i*=1.05),n.metadata.source_type==="document_chunk"&&(i*=1.02),{...n,c
364onfidence_score:Math.min(i,1)}}).sort((n,i)=>i.confidence_score-n.confidence_score)}async performFallbackSearch(e,t){console.log("â ï¸ [Vector Search] Using fallback search");try{return(await this.performKeywordSearch(e,t)).map(n=>({id:n.id,content:n.content,similarity:n.similarity,metadata:{...n.metadata,relevance_factors:["fallback_search"]},confidence_score:n.similarity*.7}))}catch(r){return console.error("Fallback search also failed:",r),[]}}calculateTextSimilarity(e,t){const n=e.toLowerCase().split(/\s+/).length;return Math.min(n/10,1)}calculateKeywordRelevance(e,t){const r=e.toLowerCase(),n=t.toLowerCase().split(/\s+/);let i=0,s=n.length;return n.forEach(c=>{r.includes(c)&&(i+=1)}),i/s}extractLenderName(e){return e&&(e.lender_name||e.lenderName||e.company_name)||"Unknown Lender"}extractLenderNameFromPdfContent(e){try{if(typeof e=="string"){const t=JSON.parse(e);return t.lender||t.lenderName||"Unknown Lender"}else if(typeof e=="object"&&e!==null)return e.lender||e.lenderName||"Unknown Lender"}catch{}return"Unknown Lender"}extractLoanTypesFromQuery(e){const t=["conventional","fha","va","usda","jumbo","fix and flip","hard money","bridge","dscr","non-qm","bank statement","investment"],r=e.toLowerCase();return t.filter(n=>r.includes(n))}extractStatesFromQuery(e){const t=["FL","CA","TX","NY","Florida","California","Texas"],r=e.toUpperCase();return t.filter(n=>r.includes(n))}async logSearchAnalytics(e,t,r){try{console.log(`ð [Search Analytics] Query: "${e}", Results: ${r}`)}catch(n){console.error("Error logging search analytics:",n)}}clearEmbeddingCache(){this.EMBEDDING_CACHE.clear(),console.log("ð§¹ Embedding cache cleared")}}const we=new ye;class ve{constructor(){D(this,"CONFIDENCE_THRESHOLD_LOW",.6);D(this,"CONFIDENCE_THRESHOLD_HIGH",.85);D(this,"MAX_LEARNING_QUEUE_SIZE",1e3)}async captureBrokerFeedback(e,t,r){console.log(`ð [Learning] Capturing feedback from broker ${e}`);try{const n=this.calculateFeedbackConfidence(t),i=this.determinePriority(t,n),s={event_type:"search_feedback",user_id:e,user_type:"broker",context:{original_query:t.query,search_results:t.results,selected_results:this.extractSelectedResults(t),user_satisfaction:this.mapSatisfactionLevel(t),improvement_suggestions:this.extractImprovementSuggestions(t),deal_context:r},confidence_score:n,processing_priority:i};await this.addToLearningQueue(s),(i==="critical"||i==="high")&&await this.processLearningEvent(s),await this.updateUserPreferences(e,t),console.log("â [Learning] Feedback captured and queued for processing")}catch(n){console.error("â [Learning] Error capturing feedback:",n)}}async captureMatchingFeedback(e,t,r,n,i){try{const s={query:this.generateQueryFromDeal(t),results:r,user_action:n?"contacted":"dismissed",deal_outcome:i},c=this.calculateMatchQuality(t,r,n),d={event_type:"matching_feedback",user_id:e,user_type:"broker",context:{original_query:s.query,search_results:r,selected_results:n?[n]:[],user_satisfaction:i==="successful"?"positive":i==="failed"?"negative":"neutral",deal_context:t},confidence_score:c,processing_priority:i==="failed"?"high":"normal"};await this.addToLearningQueue(d),(i==="failed"||c<this.CONFIDENCE_THRESHOLD_LOW)&&await this.processLearningEvent(d)}catch(s){console.error("â [Learning] Error capturing matching feedback:",s)}}async captureExtractionFeedback(e,t,r,n,i){try{const s={event_type:"extraction_feedback",user_id:e,user_type:"admin",context:{original_query:`Document extraction for ${t}`,search_results:[r],selected_results:n?[n]:[],user_satisfaction:n?"negative":"positive",improvement_suggestions:n?["Improve extraction accuracy"]:[]},confidence_score:i||.5,processing_priority:n?"high":"normal"};await this.addToLearningQueue(s),n&&await this.processExtractionCorrection(r,n)}catch(s){console.error("â [Learning] Error capturing extraction feedback:",s)}}async addToLearningQueue(e){try{await this.maintainLearningQueue();const{error:t}=await f.from("ae_learning_queue").insert({ae_id:e.user_id,user_question:e.context.original_query||"System learning event",ai_response:JSON.stringify(e.context),confidence_score:e.confidence_score,knowledge_sources:this.extractKnowledgeSources(e),deal_context:e.context.deal_context,status:"pending",review_priority:e.processing_priority,response_helpful:e.context.user_satisfaction==="positive"});t&&console.error("Error adding to learning queue:",t)}catch(t){console.error("Error managing learning queue:",t)}}async processLearningEvent(e){console.log("ð¤ [Learning] Processing high-priority learning event");try{const t=await this.analyzeFeedbackWithAI(e);t.immediate_actions&&await this.applyImmediateImprovements(t.immediate_actions),t.knowledge_updates&&await this.updateKnowledgeBase(t.knowledge_updates),t.search_adjustments&&await this.adjustSearchParameters(t.search_adjustments)}catch(t){console.error("Error processing learning event:",t)}}async analyzeFeedbackWithAI(e){try{const t=` 365 Analyze this user feedback from our mortgage lending platform: 366 367 Event Type: ${e.event_type} 368 User Type: ${e.user_type} 369 Query: ${e.context.original_query} 370 Satisfaction: ${e.context.user_satisfaction} 371 Confidence Score: ${e.confidence_score} 372 373 Context: ${JSON.stringify(e.context,null,2)} 374 375 Please provide: 376 1. Root cause analysis of any issues 377 2. Immediate actions to improve user experience 378 3. Knowledge base updates needed 379 4. Search parameter adjustments 380 5. Long-term learning recommendations 381 382 Return as structured JSON. 383 `;return await fe(t,"You are an AI learning specialist for a mortgage platform. Analyze user feedback to improve system performance.",{model:"gpt-4-turbo-preview",temperature:.3,max_tokens:1e3,context:"learning-feedback-analysis"})||{}}catch(t){return console.error("Error in AI feedback analysis:",t),{}}}async applyImmediateImprovements(e){for(const t of e)try{switch(t.type){case"update_search_weights":break;case"add_synonym":break;case"boost_result":break;default:console.log(`Unknown immediate action type: ${t.type}`)}}catch(r){console.error("Error applying immediate improvement:",r)}}async generateLearningInsights(e="week"){try{const t=new Date,r=new Date;switch(e){case"day":r.setDate(t.getDate()-1);break;case"week":r.setDate(t.getDate()-7);break;case"month":r.setMonth(t.getMonth()-1);break}const{data:n}=await f.from("ae_learning_queue").select("*").gte("created_at",r.toISOString()).order("created_at",{ascending:!1}),i=this.analyzeLearningPatterns(n||[]),s=this.generateRecommendations(i),c=this.calculateLearningMetrics(n||[]);return{patterns:i,recommendations:s,metrics:c}}catch(t){return console.error("Error generating learning insights:",t),{patterns:{successful_queries:[],failed_queries:[],user_preferences:{},performance_trends:{}},recommendations:{knowledge_gaps:[],search_improvements:[],extraction_refinements:[],priority_actions:[]},metrics:{avg_confidence:0,user_satisfaction_rate:0,improvement_rate:0,learning_queue_size:0}}}}async updateUserPreferences(e,t){try{console.log(`ð [Learning] Updating preferences for user ${e}`)}catch(r){console.error("Error updating user preferences:",r)}}calculateFeedbackConfidence(e){let t=.5;return e.user_action==="contacted"&&(t+=.3),e.satisfaction_rating&&e.satisfaction_rating>=4&&(t+=.2),e.deal_outcome==="successful"&&(t+=.2),e.user_action==="dism
383issed"&&(t-=.2),e.satisfaction_rating&&e.satisfaction_rating<=2&&(t-=.3),e.deal_outcome==="failed"&&(t-=.3),Math.max(0,Math.min(1,t))}determinePriority(e,t){return e.deal_outcome==="failed"?"critical":t<this.CONFIDENCE_THRESHOLD_LOW||e.satisfaction_rating&&e.satisfaction_rating<=2?"high":t>this.CONFIDENCE_THRESHOLD_HIGH?"low":"normal"}extractSelectedResults(e){return e.user_action==="contacted"&&e.results.length>0?[e.results[0]]:[]}mapSatisfactionLevel(e){return e.deal_outcome==="successful"?"positive":e.deal_outcome==="failed"?"negative":e.satisfaction_rating&&e.satisfaction_rating>=4?"positive":e.satisfaction_rating&&e.satisfaction_rating<=2?"negative":"neutral"}extractImprovementSuggestions(e){const t=[];return e.user_action==="refined_search"&&t.push("Initial search results were not satisfactory"),e.explicit_feedback&&t.push(e.explicit_feedback),t}generateQueryFromDeal(e){const t=[];return e.loanType&&t.push(e.loanType),e.propertyState&&t.push(e.propertyState),e.loanAmount&&t.push(`$${e.loanAmount}`),e.creditScore&&t.push(`${e.creditScore} credit`),t.join(" ")}calculateMatchQuality(e,t,r){return t.length===0?.1:r&&t.includes(r)?.8:.6}extractKnowledgeSources(e){return["user_feedback",e.event_type]}async maintainLearningQueue(){try{const{data:e}=await f.from("ae_learning_queue").select("id",{count:"exact",head:!0});e&&e.length>this.MAX_LEARNING_QUEUE_SIZE&&await f.from("ae_learning_queue").delete().eq("status","reviewed").lte("created_at",new Date(Date.now()-30*24*60*60*1e3).toISOString())}catch(e){console.error("Error maintaining learning queue:",e)}}async processExtractionCorrection(e,t){console.log("ð§ [Learning] Processing extraction correction")}async updateKnowledgeBase(e){console.log("ð [Learning] Applying knowledge base updates")}async adjustSearchParameters(e){console.log("âï¸ [Learning] Adjusting search parameters")}analyzeLearningPatterns(e){return{successful_queries:[],failed_queries:[],user_preferences:{},performance_trends:{}}}generateRecommendations(e){return{knowledge_gaps:[],search_improvements:[],extraction_refinements:[],priority_actions:[]}}calculateLearningMetrics(e){const t=e.filter(n=>n.response_helpful).length;return{avg_confidence:e.reduce((n,i)=>n+i.confidence_score,0)/e.length||0,user_satisfaction_rate:t/e.length||0,improvement_rate:.85,learning_queue_size:e.length}}}const Se=new ve,be=async a=>{try{const{data:e,error:t}=await f.from("lender_knowledge_base").select("keywords, title, content").eq("lender_id",a).eq("is_active",!0).limit(5);if(t||!e||e.length===0)return"Full service lender";const r=["lender","lending","guidelines","programs","loan"],n=[];if(e.forEach(c=>{c.keywords&&Array.isArray(c.keywords)&&c.keywords.forEach(d=>{const l=d.toLowerCase().trim();!r.some(_=>l.includes(_))&&l.length>2&&n.push(d)})}),n.length>0)return[...new Set(n)].slice(0,3).map(l=>l.charAt(0).toUpperCase()+l.slice(1)).join(", ");const{data:i,error:s}=await f.from("ae_knowledge_base").select("topic, category").eq("ae_id",a).eq("is_lender_specific",!0).eq("status","approved").limit(3);if(!s&&i&&i.length>0){const c=i.map(d=>d.topic).filter(Boolean);if(c.length>0)return c.join(", ")}return"Full service lender"}catch(e){return console.error("Error extracting program focus:",e),"Full service lender"}},xe=async(a,e,t={})=>{var s,c,d;const{page:r=1,perPage:n=10,maxResults:i=100}=t;try{if(console.log("ð findMatchingLenders called with:",a),console.log("ð Broker ID:",e),console.log("ð Submission details:",{loanType:a.loanType,propertyState:a.propertyState,occupancy:a.occupancy,notes:a.notes,creditScore:a.creditScore,ltv:a.ltv,loanAmount:a.loanAmount}),e){const o=await pe(e,"broker","search");if(!o.canProceed)throw console.error("Search limit exceeded:",o.reason),new Error(`Search limit exceeded: ${o.reason}`)}const{data:l,error:_}=await f.from("lender_profiles").select("id, company_name, lender_name").limit(5);console.log("ð Test query results:",{count:(l==null?void 0:l.length)||0,error:_,sample:l==null?void 0:l[0]});const{data:p,error:b}=await f.from("lender_profiles").select(` 384 user_id, id, lender_id, lender_name, name, company_name, profile_description,
385 contact_ae_name, contact_phone, contact_email, key_program_focus, 386 accepted_loan_types, accepted_loan_purposes, min_loan_amount, 387 max_loan_amount, max_ltv_ratio, max_ltv_primary_residence, 388 max_ltv_secondary_residence, max_ltv_investment_property, 389 accepted_occupancy_types, accepted_property_types, 390 geographic_states_covered, custom_geographic_areas, 391 custom_loan_programs, custom_property_types, 392 program_specific_criteria, min_credit_score, max_dti_ratio, 393 accepts_self_employed, offers_first_time_homebuyer_programs, 394 accepted_compensation_types, escrow_waiver_available, 395 subscription_plan, competitive_advantages, loan_programs, 396 special_programs, competitive_advantages_embedding 397 `);if(b)throw console.error("Error fetching lender_profiles:",b),new Error(`Failed to fetch lender profiles: ${b.message}`);console.log(`â Found ${(p==null?void 0:p.length)||0} lenders in lender_profiles`);const{data:h,error:g}=await f.from("user_profiles").select("user_id, email, company_name, company_logo").eq("user_type","lender");if(g)throw console.error("Error fetching user_profiles:",g),new Error(`Failed to fetch user profiles: ${g.message}`);console.log(`â Found ${(h==null?void 0:h.length)||0} user_profiles for lenders`);const E=new Map;(h||[]).forEach(o=>{const m={user_id:o.user_id,company_logo:o.company_logo||null};o.email&&E.set(o.email.toLowerCase(),m),o.company_name&&E.set(o.company_name.toLowerCase(),m)});const x=(p||[]).map(o=>{let m;return o.contact_email&&(m=E.get(o.contact_email.toLowerCase())),!m&&o.lender_name&&(m=E.get(o.lender_name.toLowerCase())),!m&&o.company_name&&(m=E.get(o.company_name.toLowerCase())),{...o,user_id:(m==null?void 0:m.user_id)||o.user_id,company_logo:(m==null?void 0:m.company_logo)||null,email:o.contact_email,phone:o.contact_phone}}).filter(o=>o.user_id);if(console.log(`â Mapped ${x.length} lenders to valid user_id values`),console.log(`â Raw query returned ${(x==null?void 0:x.length)||0} lenders`),x&&x.length>0){console.log("â Sample of lenders fetched:",x.slice(0,3).map(m=>{var w,P,T;return{name:m.lender_name||m.company_name,user_id:m.user_id,states:(w=m.geographic_states_covered)==null?void 0:w.slice(0,3),loan_types:(P=m.accepted_loan_types)==null?void 0:P.slice(0,3),competitive_advantages:(T=m.competitive_advantages)==null?void 0:T.slice(0,2),id:m.id}}));const o=x.find(m=>m.company_name==="QEW Lending"||m.lender_name==="QEW Lending");o?console.log("ð QEW Lending found in raw results:",{name:o.company_name||o.lender_name,accepted_loan_types:o.accepted_loan_types,competitive_advantages:o.competitive_advantages,states:o.geographic_states_covered}):console.log("â ï¸ QEW Lending NOT found in raw database results")}else console.log("â No lenders returned from database query");const M=x||[],R=!0;let k=[];R&&(k=M.filter(o=>o.user_id?!0:(console.warn(`Skipping lender without user_id: ${o.lender_name||o.company_name}`),!1)),console.log(`DEMO MODE: ${k.length} of ${M.length} lenders eligible (all with valid user_id)`));const C=[];console.log(`Processing ${k.length} eligible lenders for matching`),console.log("Submission criteria:",{loanType:a.loanType,state:a.propertyState,creditScore:a.creditScore,ltv:a.ltv,loanAmount:a.loanAmount,propertyType:a.propertyType,occupancy:a.occupancy});for(const o of k){console.log(` 398ð Processing lender: ${o.lender_name||o.company_name}`),console.log("ð Lender data:",{subscription_plan:o.subscription_plan,accepted_loan_types:o.accepted_loan_types,geographic_states_covered:o.geographic_states_covered,accepted_occupancy_types:o.accepted_occupancy_types,competitive_advantages:o.competitive_advantages,competitive_advantages_type:typeof o.competitive_advantages});const m=[];let w=0;if(a.notes&&o.competitive_advantages){const y=a.notes.toLowerCase();console.log(`ð Broker notes (lower): "${y}"`);let S=[];try{if(typeof o.competitive_advantages=="string"){const u=o.competitive_advantages.trim();if(u.startsWith("{")&&u.endsWith("}")&&u.includes('"'))S=u.slice(1,-1).split(/","|","/).map(A=>A.replace(/^"|"$/g,"").replace(/\\"/g,'"').trim()),console.log("ð Parsed PostgreSQL array literal:",S);else if(u.startsWith("[")||u.startsWith("{"))try{const v=JSON.parse(u);Array.isArray(v)?S=v:typeof v=="object"?S=Object.values(v):S=[u],console.log("ð Parsed JSON:",S)}
398catch{S=[u],console.log("ð Treated as single string:",S)}else S=[u],console.log("ð Plain string:",S)}else Array.isArray(o.competitive_advantages)?(S=o.competitive_advantages,console.log("ð Already an array:",S)):(S=[o.competitive_advantages].filter(Boolean),console.log("ð Wrapped in array:",S))}catch(u){console.warn("Failed to parse competitive_advantages:",u),S=[String(o.competitive_advantages)].filter(Boolean)}console.log(`ð¯ Lender: ${o.company_name||o.lender_name}, Advantages:`,S);for(const u of S){if(typeof u!="string")continue;const v=u.toLowerCase(),A={hasNoIncome:y.includes("no income")||y.includes("no-income")||y.includes("no doc")||y.includes("stated income"),hasNoAsset:y.includes("no asset")||y.includes("no-asset")||y.includes("no doc"),hasBankStatement:y.includes("bank statement")||y.includes("bank-statement"),hasDSCR:y.includes("dscr"),hasAlternative:y.includes("alternative")||y.includes("non-qm")||y.includes("non qm")||y.includes("nonqm"),hasSelfEmployed:y.includes("self employed")||y.includes("self-employed")},q={hasNoIncome:v.includes("no income")||v.includes("no-income")||v.includes("no doc")||v.includes("stated income"),hasNoAsset:v.includes("no asset")||v.includes("no-asset")||v.includes("no doc"),hasBankStatement:v.includes("bank statement")||v.includes("bank-statement"),hasDSCR:v.includes("dscr"),hasAlternative:v.includes("alternative")||v.includes("non-qm")||v.includes("non qm")||v.includes("nonqm"),hasSelfEmployed:v.includes("self employed")||v.includes("self-employed")};A.hasNoIncome&&A.hasNoAsset&&q.hasNoIncome&&q.hasNoAsset?(m.push(u),w+=1e3,console.log("ð¯ PERFECT MATCH FOUND - Both No Income AND No Asset!")):A.hasBankStatement&&q.hasBankStatement?(m.push(u),w+=1e3,console.log("ð¯ PERFECT MATCH FOUND - Bank Statement Loan!")):A.hasDSCR&&q.hasDSCR?(m.push(u),w+=1e3,console.log("ð¯ PERFECT MATCH FOUND - DSCR Loan!")):A.hasNoIncome&&q.hasNoIncome||A.hasNoAsset&&q.hasNoAsset?(m.push(u),w+=200,console.log("⨠Strong Match - Partial term match")):A.hasAlternative&&q.hasAlternative?(m.push(u),w+=150,console.log("⨠Strong Match - Alternative/Non-QM")):A.hasSelfEmployed&&q.hasSelfEmployed&&(m.push(u),w+=100,console.log("⨠Strong Match - Self Employed"))}}const P=[{field:o.loan_programs,name:"Loan Programs",weight:80},{field:o.special_programs,name:"Special Programs",weight:80},{field:o.key_program_focus,name:"Key Focus",weight:70},{field:o.profile_description,name:"Profile",weight:60},{field:o.program_specific_criteria,name:"Program Criteria",weight:60},{field:o.custom_loan_programs,name:"Custom Programs",weight:70}];if(a.notes){const y=a.notes.toLowerCase(),S=["no income","no asset","bank statement","dscr","self employed","alternative","non-qm"];for(const{field:u,name:v,weight:A}of P)if(u){const q=Array.isArray(u)?u.join(" ").toLowerCase():(typeof u=="object"?JSON.stringify(u):String(u)).toLowerCase();for(const B of S)if(y.includes(B)&&q.includes(B)){const oe=B.charAt(0).toUpperCase()+B.slice(1);m.push(oe),w+=A;break}}}if(a.loanType){const y=a.loanType.toLowerCase();console.log(`ð Checking loan type "${a.loanType}" against lender programs...`),(s=o.accepted_loan_types)!=null&&s.some(u=>u.toLowerCase().includes(y))?(console.log(`â
MATCH FOUND: accepted_loan_types contains "${a.loanType}"`),m.push(`${a.loanType} loans`),w+=80):console.log("â No match in accepted_loan_types:",o.accepted_loan_types),(c=o.loan_programs)!=null&&c.some(u=>u.toLowerCase().includes(y))?(console.log(`â
MATCH FOUND: loan_programs contains "${a.loanType}"`),m.push(`${a.loanType} programs`),w+=60):console.log("â No match in loan_programs:",o.loan_programs),(d=o.special_programs)!=null&&d.some(u=>u.toLowerCase().includes(y))?(console.log(`â
MATCH FOUND: special_programs contains "${a.loanType}"`),m.push(`Special ${a.loanType} programs`),w+=60):console.log("â No match in special_programs:",o.special_programs);const S=(()=>{try{if(typeof o.competitive_advantages=="string"){const u=o.competitive_advantages.trim();if(u.startsWith("{")&&u.endsWith("}"))return u.slice(1,-1).split('","').map(A=>A.replace(/^"|"$/g,"").trim());try{const v=JSON.parse(u);return Array.isArray(v)?v:typeof v=="object"?Object.values(v):[u]}catch{return[u]}}return o.competitive_advantages||[]}
398catch{return[String(o.competitive_advantages)].filter(Boolean)}})();S.some(u=>u.toLowerCase().includes(y)&&!m.some(v=>v.includes(u)))?(console.log(`â
MATCH FOUND: competitive_advantages contains "${a.loanType}"`),m.push(`${a.loanType} specialist`),w+=50):console.log("â No match in competitive_advantages:",S)}const T=de(o,a);for(const y of T)m.some(S=>S.includes(y))||(m.push(y),w+=10);const F=w>=30,N=F;if(console.log(`ð FINAL DECISION for ${o.company_name||o.lender_name}:`),console.log(` Match Score: ${w}`),console.log(` Has Strong Match: ${F}`),console.log(` Should Include: ${N}`),console.log(` Matches Found: ${m.length>0?m.join(", "):"None"}`),N){console.log(`â
INCLUDING lender ${o.company_name||o.lender_name} - Score: ${w}, Matches:`,m);const y=o.user_id,S=o.contact_ae_name||o.name||o.full_name||"Account Executive",u=o.contact_email||o.email||"",v=`${y}_${S.replace(/\s+/g,"_")}_${u.replace("@","_at_").replace(".","_")}`,A=await be(y);C.push({lender_id:v,base_lender_id:y,lender_name:o.lender_name||o.name||o.company_name||"Lender",profile_description:o.profile_description||"Mortgage lending services",contact_ae_name:S,contact_phone:o.contact_phone||o.phone||"",contact_email:u,key_program_focus:A,keyMatches:m,subscription_plan:o.subscription_plan||"free",min_credit_score:o.min_credit_score,max_ltv_ratio:o.max_ltv_ratio||o.max_ltv_primary_residence||100,accepted_loan_types:o.accepted_loan_types||["Conventional","FHA","VA"],matchScore:w,competitive_advantages:o.competitive_advantages||[]})}}C.sort((o,m)=>{const w=o.matchScore||0,P=m.matchScore||0,T=u=>{switch(u==null?void 0:u.toLowerCase()){case"premium":return 3;case"pro":return 2;case"free":return 1;default:return 0}},F=T(o.subscription_plan),N=T(m.subscription_plan),y=w>=1e3,S=P>=1e3;return y&&S?F!==N?N-F:P-w:y&&!S?-1:!y&&S?1:F!==N?N-F:P-w}),console.log(`â
Matched ${C.length} lenders after filtering and sorting`),C.length>0?console.log("â
Top 5 lenders after sorting:",C.slice(0,5).map(o=>({name:o.lender_name,subscription:o.subscription_plan,score:o.matchScore,isPerfect:(o.matchScore||0)>=1e3,matches:o.keyMatches}))):console.log("â No lenders matched the criteria"),console.log("ð¤ Enhancing matches with AI and knowledge base...");const I=a.notes||"",$=I?`${I} ${a.loanType} ${a.propertyState}`.trim():`${a.loanType} loan ${a.loanAmount} ${a.propertyType} ${a.propertyState} credit score ${a.creditScore} LTV ${a.ltv}`.trim();console.log("ð Knowledge base search query:",$);let L=[];try{L=(await we.performHybridSearch($,{loan_type:a.loanType,property_type:a.propertyType,state:a.propertyState,credit_score_min:Math.max(300,a.creditScore-50),credit_score_max:Math.min(850,a.creditScore+50),ltv_max:a.ltv+10},{vector_weight:.7,keyword_weight:.2,metadata_weight:.1,limit:200,min_score:.6})).map(m=>({id:m.chunk_id,lender_id:m.ae_id,content:m.chunk_text,similarity_score:m.combined_score,confidence:m.confidence_score})),console.log(`ð Enhanced vector search found ${L.length} high-quality matches`),console.log(`ð Average confidence: ${L.length>0?(L.reduce((m,w)=>m+(w.confidence||0),0)/L.length).toFixed(2):"N/A"}`)}catch(o){console.warn("Enhanced vector search failed, falling back to basic search:",o);try{L=await te.searchKnowledge($,200),console.log(`ð Fallback: Found ${L.length} knowledge base matches from basic search`)}catch(m){console.warn("All knowledge base searches failed, continuing without it:",m)}}const U=C.filter(o=>o.subscription_plan==="premium"||o.subscription_plan==="pro"),V=C.filter(o=>!o.subscription_plan||o.subscription_plan==="free");console.log(`â¡ Performance: ${U.length} Premium/Pro lenders (AI scoring), ${V.length} Free lenders (basic scoring)`);let W=[];U.length>0&&(W=await ke(U,a,L));const ne=V.map(o=>{const m=L.filter(T=>T.lender_id===o.lender_id);let w=75;const P=["Criteria match"];return m.length>0&&(w+=5,P.push("Has knowledge base")),o.keyMatches&&o.keyMatches.length>5&&(w+=5,P.push("Strong criteria match")),{...o,aiScore:w,aiConfidence:70,aiReasons:P,hasKnowledgeBase:m.length>0,knowledgeMatchCount:m.length,aiPrograms:[],aiNextSteps:[]}}),Q=[...W,...ne];console.log("ð Performing confidence-based quality assurance...");const K=.75,O=Q.filter(o=>(o.aiConfidence||0)<K*100);if(O.length>0){console.log(`â ï¸ Found ${O.length} low confidence matches (< ${K*100}
398%). Triggering escalation.`);try{await Se.captureBrokerFeedback(a.brokerId,{feedback_type:"system_escalation",confidence_score:Math.min(...O.map(o=>o.aiConfidence||0))/100,feedback_text:`System detected ${O.length} matches with confidence below ${K*100}%. Manual review recommended.`,recommended_action:"human_review"},{query:$,low_confidence_matches:O.map(o=>({lender_name:o.lender_name,confidence:o.aiConfidence,reasons:o.aiReasons})),escalation_priority:O.length>3?"high":"normal"}),console.log("â
Low confidence escalation captured for human review")}catch(o){console.warn("Failed to capture confidence escalation:",o)}}else console.log("â
All matches meet confidence threshold");const H=Q.sort((o,m)=>{if(o.aiScore&&m.aiScore){const T=m.aiScore-o.aiScore;if(Math.abs(T)>5)return T}const w=o.subscription_plan||"free",P=m.subscription_plan||"free";return w==="premium"&&P!=="premium"?-1:P==="premium"&&w!=="premium"?1:w==="pro"&&P==="free"?-1:P==="pro"&&w==="free"?1:0});console.log(`Found ${H.length} matching lenders (AI-enhanced and sorted)`);const G=H.slice(0,i),J=G.length,z=Math.ceil(J/n),Y=(r-1)*n,ae=Y+n,X=G.slice(Y,ae);return console.log(`ð Returning page ${r} of ${z} (${X.length} lenders)`),H.length===0?(console.log("No matches found with criteria"),{lenders:[],totalCount:0,currentPage:r,totalPages:0,perPage:n}):{lenders:X,totalCount:J,currentPage:r,totalPages:z,perPage:n}}catch(l){return console.error("Error in findMatchingLenders:",l),{lenders:[],totalCount:0,currentPage:1,totalPages:0,perPage:n}}};async function ke(a,e,t){console.log(`ð Batch AI scoring ${a.length} Premium/Pro lenders in ONE call...`);const r=new Map;await Promise.all(a.map(async i=>{try{const s=await te.getKnowledge(i.lender_id);r.set(i.lender_id,s)}catch{r.set(i.lender_id,[])}}));const n=a.map(i=>{const s=r.get(i.lender_id)||[],c=t.filter(l=>l.lender_id===i.lender_id),d=s.map(l=>({type:l.knowledge_type||l.category||"general",topic:l.topic||"Information",content:typeof l.content=="string"?l.content:JSON.stringify(l.content).substring(0,500)}));return{id:i.id,lender_id:i.lender_id,company_name:i.company_name||i.lender_name,lender_name:i.lender_name,competitive_advantages:i.competitive_advantages,key_program_focus:i.key_program_focus,knowledge_base:d,semantic_matches:c.map(l=>{var _;return{content:(_=l.content)==null?void 0:_.substring(0,200),similarity:l.similarity_score||l.confidence}}),hasKnowledgeBase:s.length>0,knowledgeMatchCount:c.length}});try{const{data:i,error:s}=await f.functions.invoke("ai-lender-matching",{body:{submission:{loanType:e.loanType,propertyState:e.propertyState,creditScore:e.creditScore,loanAmount:e.loanAmount,ltv:e.ltv,propertyType:e.propertyType,occupancy:e.occupancy,loanPurpose:e.loanPurpose,notes:e.notes},lenders:n,isBatch:!0}});if(s||!(i!=null&&i.success))return console.error("Batch AI scoring failed:",s),a.map((d,l)=>({...d,aiScore:80+Math.random()*15,aiConfidence:75,aiReasons:["Premium lender (AI unavailable)"],hasKnowledgeBase:n[l].hasKnowledgeBase,knowledgeMatchCount:n[l].knowledgeMatchCount,aiPrograms:[],aiNextSteps:[]}));const c=i.results||[];return console.log(`â
Batch AI scoring complete: ${c.length} lenders analyzed in ONE call`),a.map((d,l)=>{const _=c[l]||{},p=n[l];return{...d,aiScore:_.score||80,aiConfidence:_.confidence||75,aiReasons:_.reasons||["Premium lender match"],aiPrograms:_.programs||[],aiNextSteps:_.nextSteps||[],aiKeyInsights:_.keyInsights,hasKnowledgeBase:p.hasKnowledgeBase,knowledgeMatchCount:p.knowledgeMatchCount}})}catch(i){return console.error("Batch AI scoring error:",i),a.map((s,c)=>{const d=n[c];return{...s,aiScore:80+Math.random()*15,aiConfidence:75,aiReasons:["Premium lender (AI temporarily unavailable)"],hasKnowledgeBase:d.hasKnowledgeBase,knowledgeMatchCount:d.knowledgeMatchCount,aiPrograms:[],aiNextSteps:[]}})}}export{re as c,xe as f,fe as g,_e as m,Ae as s};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.