sammy786 commited on
Commit
809681b
·
verified ·
1 Parent(s): e514fa3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +178 -51
app.py CHANGED
@@ -146,6 +146,112 @@ from utils.api_client import RewardPilotClient
146
  from utils.llm_explainer import get_llm_explainer
147
  import config
148
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
150
  def get_recommendation_with_agent(user_id, merchant, category, amount):
151
  import httpx
@@ -210,60 +316,81 @@ def get_recommendation_with_agent(user_id, merchant, category, amount):
210
  }
211
  card_name = card_name_map.get(card_id, card_id.replace('c_', '').replace('_', ' ').title())
212
 
213
- # ========== CARD DATABASE (FALLBACK) ==========
214
- # If API doesn't provide card_details, use this database
215
- CARD_DATABASE = {
216
- 'c_citi_custom_cash': {
217
- 'reward_rate': 5.0,
218
- 'monthly_cap': 500,
219
- 'base_rate': 1.0,
220
- 'annual_fee': 0,
221
- 'cap_type': 'monthly'
222
- },
223
- 'c_amex_gold': {
224
- 'reward_rate': 4.0,
225
- 'annual_cap': 25000,
226
- 'base_rate': 1.0,
227
- 'annual_fee': 250,
228
- 'cap_type': 'annual'
229
- },
230
- 'c_chase_sapphire_reserve': {
231
- 'reward_rate': 3.0,
232
- 'monthly_cap': None,
233
- 'base_rate': 3.0,
234
- 'annual_fee': 550,
235
- 'cap_type': 'none'
236
- },
237
- 'c_chase_freedom_unlimited': {
238
- 'reward_rate': 1.5,
239
- 'monthly_cap': None,
240
- 'base_rate': 1.5,
241
- 'annual_fee': 0,
242
- 'cap_type': 'none'
243
- },
244
- 'c_chase_sapphire_preferred': {
245
- 'reward_rate': 2.0,
246
- 'monthly_cap': None,
247
- 'base_rate': 2.0,
248
- 'annual_fee': 95,
249
- 'cap_type': 'none'
250
- }
251
- }
252
-
253
- # ========== GET CARD DETAILS (API OR FALLBACK) ==========
 
 
 
 
 
 
 
254
  card_details = result.get('card_details', {})
255
 
256
  if not card_details or not card_details.get('reward_rate'):
257
- # Use fallback database
258
- card_details = CARD_DATABASE.get(card_id, {
259
- 'reward_rate': 1.0,
260
- 'monthly_cap': None,
261
- 'annual_cap': None,
262
- 'base_rate': 1.0,
263
- 'annual_fee': 0,
264
- 'cap_type': 'none'
265
- })
266
- print(f"⚠️ Using fallback card details for {card_id}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
 
268
  reward_rate_value = card_details.get('reward_rate', 1.0)
269
  monthly_cap = card_details.get('monthly_cap', None)
 
146
  from utils.llm_explainer import get_llm_explainer
147
  import config
148
 
149
+ # ===================== CARD DATABASE LOADER =====================
150
+ import json
151
+ import os
152
+
153
+ # Path to cards.json
154
+ CARDS_FILE = os.path.join(os.path.dirname(__file__), "data", "cards.json")
155
+
156
+ def load_card_database() -> dict:
157
+ """Load card database from local cards.json"""
158
+ try:
159
+ with open(CARDS_FILE, 'r') as f:
160
+ cards = json.load(f)
161
+ print(f"✅ Loaded {len(cards)} cards from database")
162
+ return cards
163
+ except FileNotFoundError:
164
+ print(f"⚠️ cards.json not found at {CARDS_FILE}")
165
+ return {}
166
+ except json.JSONDecodeError as e:
167
+ print(f"❌ Error parsing cards.json: {e}")
168
+ return {}
169
+
170
+ # Load at startup
171
+ CARD_DATABASE = load_card_database()
172
+
173
+ def get_card_details(card_id: str, mcc: str = None) -> dict:
174
+ """
175
+ Get card details from database
176
+
177
+ Args:
178
+ card_id: Card identifier (e.g., "c_citi_custom_cash")
179
+ mcc: Optional MCC code to get specific reward rate
180
+
181
+ Returns:
182
+ dict: Card details including name, reward rate, caps, etc.
183
+ """
184
+ if card_id not in CARD_DATABASE:
185
+ print(f"⚠️ Card {card_id} not found in database, using fallback")
186
+ return {
187
+ "name": card_id.replace("c_", "").replace("_", " ").title(),
188
+ "issuer": "Unknown",
189
+ "reward_rate": 1.0,
190
+ "annual_fee": 0,
191
+ "spending_caps": {},
192
+ "benefits": []
193
+ }
194
+
195
+ card = CARD_DATABASE[card_id]
196
+
197
+ # Get reward rate for specific MCC (if provided)
198
+ reward_rate = 1.0
199
+ if mcc and "reward_structure" in card:
200
+ reward_structure = card["reward_structure"]
201
+
202
+ # Check exact MCC match
203
+ if mcc in reward_structure:
204
+ reward_rate = reward_structure[mcc]
205
+ else:
206
+ # Check MCC ranges (e.g., "3001-3999")
207
+ try:
208
+ mcc_int = int(mcc)
209
+ for key, rate in reward_structure.items():
210
+ if "-" in str(key):
211
+ start, end = str(key).split("-")
212
+ if int(start) <= mcc_int <= int(end):
213
+ reward_rate = rate
214
+ break
215
+ except (ValueError, AttributeError):
216
+ pass
217
+
218
+ # Use default if no match found
219
+ if reward_rate == 1.0 and "default" in reward_structure:
220
+ reward_rate = reward_structure["default"]
221
+
222
+ # Extract spending cap info
223
+ spending_caps = card.get("spending_caps", {})
224
+ cap_info = {}
225
+
226
+ if "monthly_bonus" in spending_caps:
227
+ cap_info = {
228
+ "type": "monthly",
229
+ "limit": spending_caps["monthly_bonus"],
230
+ "display": f"${spending_caps['monthly_bonus']}/month"
231
+ }
232
+ elif "quarterly_bonus" in spending_caps:
233
+ cap_info = {
234
+ "type": "quarterly",
235
+ "limit": spending_caps["quarterly_bonus"],
236
+ "display": f"${spending_caps['quarterly_bonus']}/quarter"
237
+ }
238
+ elif "annual_bonus" in spending_caps:
239
+ cap_info = {
240
+ "type": "annual",
241
+ "limit": spending_caps["annual_bonus"],
242
+ "display": f"${spending_caps['annual_bonus']}/year"
243
+ }
244
+
245
+ return {
246
+ "name": card.get("name", "Unknown Card"),
247
+ "issuer": card.get("issuer", "Unknown"),
248
+ "reward_rate": reward_rate,
249
+ "annual_fee": card.get("annual_fee", 0),
250
+ "spending_caps": cap_info,
251
+ "benefits": card.get("benefits", [])
252
+ }
253
+ # ===================== END CARD DATABASE =====================
254
+
255
 
256
  def get_recommendation_with_agent(user_id, merchant, category, amount):
257
  import httpx
 
316
  }
317
  card_name = card_name_map.get(card_id, card_id.replace('c_', '').replace('_', ' ').title())
318
 
319
+ # # ========== CARD DATABASE (FALLBACK) ==========
320
+ # # If API doesn't provide card_details, use this database
321
+ # CARD_DATABASE = {
322
+ # 'c_citi_custom_cash': {
323
+ # 'reward_rate': 5.0,
324
+ # 'monthly_cap': 500,
325
+ # 'base_rate': 1.0,
326
+ # 'annual_fee': 0,
327
+ # 'cap_type': 'monthly'
328
+ # },
329
+ # 'c_amex_gold': {
330
+ # 'reward_rate': 4.0,
331
+ # 'annual_cap': 25000,
332
+ # 'base_rate': 1.0,
333
+ # 'annual_fee': 250,
334
+ # 'cap_type': 'annual'
335
+ # },
336
+ # 'c_chase_sapphire_reserve': {
337
+ # 'reward_rate': 3.0,
338
+ # 'monthly_cap': None,
339
+ # 'base_rate': 3.0,
340
+ # 'annual_fee': 550,
341
+ # 'cap_type': 'none'
342
+ # },
343
+ # 'c_chase_freedom_unlimited': {
344
+ # 'reward_rate': 1.5,
345
+ # 'monthly_cap': None,
346
+ # 'base_rate': 1.5,
347
+ # 'annual_fee': 0,
348
+ # 'cap_type': 'none'
349
+ # },
350
+ # 'c_chase_sapphire_preferred': {
351
+ # 'reward_rate': 2.0,
352
+ # 'monthly_cap': None,
353
+ # 'base_rate': 2.0,
354
+ # 'annual_fee': 95,
355
+ # 'cap_type': 'none'
356
+ # }
357
+ # }
358
+
359
+ # ========== GET CARD DETAILS (FROM cards.json) ==========
360
+ # Get MCC from transaction
361
+ transaction_mcc = result.get('mcc', MCC_CATEGORIES.get(category, "5999"))
362
+
363
+ # Load card details from our database
364
+ card_details_from_db = get_card_details(card_id, transaction_mcc)
365
+
366
+ # Use API card_details if available, otherwise use our database
367
  card_details = result.get('card_details', {})
368
 
369
  if not card_details or not card_details.get('reward_rate'):
370
+ # Convert our database format to the format expected by the rest of the code
371
+ reward_structure = CARD_DATABASE.get(card_id, {}).get('reward_structure', {})
372
+
373
+ # Get reward rate for this MCC
374
+ if transaction_mcc in reward_structure:
375
+ reward_rate_value = reward_structure[transaction_mcc]
376
+ else:
377
+ reward_rate_value = reward_structure.get('default', 1.0)
378
+
379
+ # Get spending caps
380
+ spending_caps_db = CARD_DATABASE.get(card_id, {}).get('spending_caps', {})
381
+
382
+ card_details = {
383
+ 'reward_rate': reward_rate_value,
384
+ 'monthly_cap': spending_caps_db.get('monthly_bonus'),
385
+ 'annual_cap': spending_caps_db.get('annual_bonus'),
386
+ 'quarterly_cap': spending_caps_db.get('quarterly_bonus'),
387
+ 'base_rate': reward_structure.get('default', 1.0),
388
+ 'annual_fee': CARD_DATABASE.get(card_id, {}).get('annual_fee', 0),
389
+ 'cap_type': 'monthly' if 'monthly_bonus' in spending_caps_db else
390
+ 'annual' if 'annual_bonus' in spending_caps_db else
391
+ 'quarterly' if 'quarterly_bonus' in spending_caps_db else 'none'
392
+ }
393
+ print(f"✅ Using cards.json details for {card_id}")
394
 
395
  reward_rate_value = card_details.get('reward_rate', 1.0)
396
  monthly_cap = card_details.get('monthly_cap', None)