Move Resos API key to central Settings service; add sidebar scrollbar styling
Removes the standalone resos_api_key from the forecasting app's own system_config table. All credential fetches now go through central_settings.get_resos_credentials() / get_resos_credentials_sync() which pull from the Settings app (LXC 116) via the internal integration endpoint — the same pattern already used for NewBook. The Resos API Config section is removed from the forecasting Settings page; users manage the key in the central Settings app instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9057d764fa
commit
3650c92175
7 changed files with 51 additions and 282 deletions
|
|
@ -76,29 +76,10 @@ def load_newbook_credentials(db) -> dict:
|
|||
|
||||
|
||||
def load_resos_credentials(db) -> dict:
|
||||
"""Load Resos API credentials from database config."""
|
||||
import base64
|
||||
|
||||
def decrypt(value: str) -> str:
|
||||
"""Decrypt base64 encoded value"""
|
||||
if not value:
|
||||
return None
|
||||
try:
|
||||
return base64.b64decode(value.encode()).decode()
|
||||
except:
|
||||
return value
|
||||
|
||||
# Get API key (may be encrypted)
|
||||
api_key_result = db.execute(
|
||||
text("SELECT config_value, is_encrypted FROM system_config WHERE config_key = 'resos_api_key'")
|
||||
)
|
||||
api_key_row = api_key_result.fetchone()
|
||||
|
||||
api_key = None
|
||||
if api_key_row and api_key_row.config_value:
|
||||
api_key = decrypt(api_key_row.config_value) if api_key_row.is_encrypted else api_key_row.config_value
|
||||
|
||||
return {'api_key': api_key}
|
||||
"""Load Resos API credentials from central Settings service."""
|
||||
from services.central_settings import get_resos_credentials_sync
|
||||
creds = get_resos_credentials_sync()
|
||||
return creds or {'api_key': None}
|
||||
|
||||
|
||||
def load_gl_config(db) -> tuple:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ Pattern: Replicates newbook bookings sync but adapted for Resos covers/stats
|
|||
"""
|
||||
import json
|
||||
import logging
|
||||
import base64
|
||||
from datetime import date, datetime, timedelta
|
||||
from typing import Optional, Tuple, List, Dict, Any
|
||||
|
||||
|
|
@ -20,27 +19,6 @@ logger = logging.getLogger(__name__)
|
|||
VALID_STATUSES = ('approved', 'arrived', 'seated', 'left')
|
||||
|
||||
|
||||
def get_config_value(db, key: str) -> Optional[str]:
|
||||
"""Get a configuration value from system_config table."""
|
||||
result = db.execute(
|
||||
text("SELECT config_value, is_encrypted FROM system_config WHERE config_key = :key"),
|
||||
{"key": key}
|
||||
)
|
||||
row = result.fetchone()
|
||||
if not row or not row.config_value:
|
||||
return None
|
||||
|
||||
# Decrypt if encrypted
|
||||
if row.is_encrypted:
|
||||
try:
|
||||
return base64.b64decode(row.config_value.encode()).decode()
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to decrypt {key}: {e}")
|
||||
return row.config_value
|
||||
|
||||
return row.config_value
|
||||
|
||||
|
||||
def load_resos_custom_field_mappings(db) -> Dict[str, Dict[str, Any]]:
|
||||
"""
|
||||
Load custom field mappings from resos_custom_field_mapping table.
|
||||
|
|
@ -194,11 +172,13 @@ async def sync_resos_bookings_data(
|
|||
)
|
||||
db.commit()
|
||||
|
||||
# Load Resos API key
|
||||
api_key = get_config_value(db, 'resos_api_key')
|
||||
# Load Resos API key from central Settings service
|
||||
from services.central_settings import get_resos_credentials_sync
|
||||
_resos_creds = get_resos_credentials_sync()
|
||||
api_key = _resos_creds["api_key"] if _resos_creds else None
|
||||
|
||||
if not api_key:
|
||||
raise Exception("Resos API key not configured")
|
||||
raise Exception("Resos API key not configured in central Settings")
|
||||
|
||||
# Load mappings
|
||||
cf_mappings = load_resos_custom_field_mappings(db)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue