class Category(Base): """ A representation of a plaid category object. """ __tablename__ = 'categories' plaid_id = db.Column(db.Integer, primary_key=True) plaid_type = db.Column(db.Text) # TODO: change to ARRAY type once Postgres test db in place plaid_hierarchy = db.Column(db.Text)
class UserProfile(TimestampBase): """Associated information with a User.""" __tablename__ = 'user_profiles' birthday = db.Column(db.Date, nullable=True) user = db.relationship('User', uselist=False)
class Account(Base): """ A representation of an financial Account object. A User has many Accounts but an Account has only one User. An Institution has many Accounts but an Account has only one Institution. An Account has many Transactions but a Transaction can have only one Account. A Goal has many Accounts and an Account has many Goals. """ __tablename__ = 'accounts' id = db.Column(db.String(50), primary_key=True) name = db.Column(db.Text, nullable=False) type = db.Column(db.Text, nullable=False) available_balance = db.Column(db.Float(scale=2), nullable=True) current_balance = db.Column(db.Float(scale=2), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) user = db.relationship('User', backref=db.backref('accounts', cascade='all, delete-orphan', lazy='dynamic')) institution_id = db.Column(db.Integer, db.ForeignKey('institutions.id'), nullable=False) institution = db.relationship('Institution', backref=db.backref( 'accounts', cascade='all, delete-orphan', lazy='dynamic'))
class Institution(PrimaryKeyIdBase): """ A representation of a basic Institution object. """ __tablename__ = 'institutions' name = db.Column(db.String(100), nullable=False, unique=True) @property def users(self): from matcha.models import AccessToken, User return User.query.filter( User.id.in_(self.access_tokens.with_entities(AccessToken.user_id)))
class User(TimestampBase): """A representation of a basic User object.""" __tablename__ = 'users' first_name = db.Column(db.String(50), nullable=False) last_name = db.Column(db.String(50), nullable=False) email = db.Column(db.String(255), nullable=False, unique=True) password_hash = db.Column(db.String(256), nullable=False) profile = db.relationship('UserProfile') profile_id = db.Column(db.ForeignKey('user_profiles.id'), nullable=True) @property def institutions(self): from matcha.models import AccessToken, Institution return Institution.query.filter( Institution.id.in_( self.access_tokens.with_entities(AccessToken.institution_id))) @classmethod def by_email(cls, email: str) -> 'User': return User.query.filter_by(email=email).first()
class Transaction(TimestampBase): """ A representation of a transaction object. Transactions are any USD payment or exchange. A User has many Transactions but a Transaction has only one User. An Institution has many Transactions but a Transaction has only one Institution. A Goal has many Transactions and a Transaction can have many Goals. A Transaction has many Categories and a Category has many Transactions. """ __tablename__ = 'transactions' name = db.Column(db.Text, nullable=False) amount = db.Column(db.Float(scale=2), nullable=False) pending = db.Column(db.Boolean, nullable=False) post_date = db.Column(db.DateTime, nullable=False) account_id = db.Column(db.Text, db.ForeignKey('accounts.id'), nullable=False) account = db.relationship('Account', backref=db.backref('transactions', cascade='all, delete-orphan', lazy='dynamic')) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) user = db.relationship('User', backref=db.backref('transactions', cascade='all, delete-orphan', lazy='dynamic')) institution_id = db.Column(db.Integer, db.ForeignKey('institutions.id'), nullable=False) institution = db.relationship('Institution', backref=db.backref( 'transactions', cascade='all, delete-orphan', lazy='dynamic')) def serialize(self): return { 'id': self.id, 'name': self.name, 'amount': self.amount, 'pending': self.pending, 'post_date': str(self.post_date) }
class Goal(TimestampBase): """ A representation of a basic goal object. Goals track a User defined financial progress over time. Goals can be periodic. A User has many Goals but a Goal has only one User. A Transaction has many Goals and a Goal has many Transactions. """ __tablename__ = 'goals' name = db.Column(db.Text, nullable=False) progress = db.Column(db.Integer, default=0) amount = db.Column(db.Integer, nullable=False) start_date = db.Column(db.DateTime, nullable=False) end_date = db.Column(db.DateTime, nullable=True) frequency = db.Column(db.Text, nullable=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) user = db.relationship('User', backref=db.backref('goals', cascade='all, delete-orphan', lazy='dynamic')) transactions = db.relationship('Transaction', secondary=goal_transactions, backref='goals') accounts = db.relationship('Account', secondary=goal_accounts, backref='goals') def serialize(self): return { 'id': self.id, 'amount': self.amount, 'name': self.name, 'start_date': self.start_date, 'end_date': self.end_date }
from matcha.database import db from matcha.models import TimestampBase goal_transactions = db.Table( 'goal_transactions', db.Column('goal_id', db.Integer, db.ForeignKey('goals.id')), db.Column('transaction_id', db.Integer, db.ForeignKey('transactions.id'))) goal_accounts = db.Table( 'goal_accounts', db.Column('goal_id', db.Integer, db.ForeignKey('goals.id')), db.Column('account_id', db.Text, db.ForeignKey('accounts.id'))) class Goal(TimestampBase): """ A representation of a basic goal object. Goals track a User defined financial progress over time. Goals can be periodic. A User has many Goals but a Goal has only one User. A Transaction has many Goals and a Goal has many Transactions. """ __tablename__ = 'goals' name = db.Column(db.Text, nullable=False) progress = db.Column(db.Integer, default=0) amount = db.Column(db.Integer, nullable=False) start_date = db.Column(db.DateTime, nullable=False) end_date = db.Column(db.DateTime, nullable=True) frequency = db.Column(db.Text, nullable=True)