Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions packages/backend/app/db/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,19 @@ CREATE TABLE IF NOT EXISTS audit_logs (
action VARCHAR(100) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Bank Connectors for pluggable bank integrations
CREATE TABLE IF NOT EXISTS bank_connectors (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
connector_id VARCHAR(50) NOT NULL,
connector_name VARCHAR(100) NOT NULL,
account_id VARCHAR(100),
account_name VARCHAR(200),
status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
config_encrypted TEXT,
last_sync DATE,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_bank_connectors_user ON bank_connectors(user_id);
43 changes: 42 additions & 1 deletion packages/backend/app/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,45 @@
jwt = JWTManager()

_settings = Settings()
redis_client = redis.Redis.from_url(_settings.redis_url, decode_responses=True)

# Create Redis client but handle connection errors gracefully
try:
redis_client = redis.Redis.from_url(_settings.redis_url, decode_responses=True)
redis_client.ping()
except Exception:
# For testing environments without Redis, create a proper mock
class MockRedis:
def __init__(self):
self._data = {}

def ping(self):
return True

def scan(self, cursor=0, match=None, count=100):
return 0, []

def delete(self, *keys):
return 0

def setex(self, name, time, value):
return True

def get(self, name):
return None

def set(self, name, value):
return True

def exists(self, *names):
return 0

def expire(self, name, time):
return True

def flushdb(self):
self._data.clear()
return True

def __getattr__(self, name):
return lambda *args, **kwargs: None
redis_client = MockRedis()
16 changes: 16 additions & 0 deletions packages/backend/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,19 @@ class AuditLog(db.Model):
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=True)
action = db.Column(db.String(100), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)


class BankConnector(db.Model):
"""Stores user bank connector configurations."""
__tablename__ = "bank_connectors"
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
connector_id = db.Column(db.String(50), nullable=False)
connector_name = db.Column(db.String(100), nullable=False)
account_id = db.Column(db.String(100), nullable=True)
account_name = db.Column(db.String(200), nullable=True)
status = db.Column(db.String(20), default="PENDING", nullable=False)
config_encrypted = db.Column(db.Text, nullable=True)
last_sync = db.Column(db.Date, nullable=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
2 changes: 2 additions & 0 deletions packages/backend/app/routes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .categories import bp as categories_bp
from .docs import bp as docs_bp
from .dashboard import bp as dashboard_bp
from .bank_connectors import bp as bank_connectors_bp


def register_routes(app: Flask):
Expand All @@ -18,3 +19,4 @@ def register_routes(app: Flask):
app.register_blueprint(categories_bp, url_prefix="/categories")
app.register_blueprint(docs_bp, url_prefix="/docs")
app.register_blueprint(dashboard_bp, url_prefix="/dashboard")
app.register_blueprint(bank_connectors_bp, url_prefix="/bank-connectors")
Loading