diff --git a/brewman/alembic/versions/0363f582ab28_rename_auth.py b/brewman/alembic/versions/0363f582ab28_rename_auth.py
new file mode 100644
index 00000000..eb446d00
--- /dev/null
+++ b/brewman/alembic/versions/0363f582ab28_rename_auth.py
@@ -0,0 +1,71 @@
+"""rename auth
+
+Revision ID: 0363f582ab28
+Revises: ad8b2d208492
+Create Date: 2021-09-11 05:32:56.683107
+
+"""
+import sqlalchemy as sa
+
+from alembic import op
+from sqlalchemy.dialects import postgresql
+
+
+# revision identifiers, used by Alembic.
+revision = "0363f582ab28"
+down_revision = "ad8b2d208492"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.rename_table("auth_clients", "clients")
+    op.drop_constraint("uq_auth_clients_code", "clients", type_="unique")
+    op.drop_constraint("uq_auth_clients_name", "clients", type_="unique")
+    op.create_unique_constraint(op.f("uq_clients_code"), "clients", ["code"])
+    op.create_unique_constraint(op.f("uq_clients_name"), "clients", ["name"])
+
+    op.rename_table("auth_login_history", "login_history")
+    op.drop_constraint("uq_auth_login_history_user_id", "login_history", type_="unique")
+    op.create_unique_constraint(op.f("uq_login_history_user_id"), "login_history", ["user_id", "client_id", "date"])
+
+    op.rename_table("auth_permissions", "permissions")
+    op.drop_constraint("uq_auth_permissions_name", "permissions", type_="unique")
+    op.create_unique_constraint(op.f("uq_permissions_name"), "permissions", ["name"])
+
+    op.rename_table("auth_roles", "roles")
+    op.drop_constraint("uq_auth_roles_name", "roles", type_="unique")
+    op.create_unique_constraint(op.f("uq_roles_name"), "roles", ["name"])
+
+    op.rename_table("auth_users", "users")
+    op.drop_constraint("uq_auth_users_username", "users", type_="unique")
+    op.create_unique_constraint(op.f("uq_users_username"), "users", ["username"])
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+
+    op.rename_table("users", "auth_users")
+    op.drop_constraint(op.f("uq_users_username"), "users", type_="unique")
+    op.create_unique_constraint("uq_auth_users_username", "users", ["username"])
+
+    op.rename_table("roles", "auth_roles")
+    op.drop_constraint(op.f("uq_roles_name"), "roles", type_="unique")
+    op.create_unique_constraint("uq_auth_roles_name", "roles", ["name"])
+
+    op.rename_table("permissions", "auth_permissions")
+    op.drop_constraint(op.f("uq_permissions_name"), "permissions", type_="unique")
+    op.create_unique_constraint("uq_auth_permissions_name", "permissions", ["name"])
+
+    op.rename_table("login_history", "auth_login_history")
+    op.drop_constraint(op.f("uq_login_history_user_id"), "login_history", type_="unique")
+    op.create_unique_constraint("uq_auth_login_history_user_id", "login_history", ["user_id", "client_id", "date"])
+
+    op.rename_table("clients", "auth_clients")
+    op.drop_constraint(op.f("uq_clients_name"), "clients", type_="unique")
+    op.drop_constraint(op.f("uq_clients_code"), "clients", type_="unique")
+    op.create_unique_constraint("uq_auth_clients_name", "clients", ["name"])
+    op.create_unique_constraint("uq_auth_clients_code", "clients", ["code"])
+    # ### end Alembic commands ###
diff --git a/brewman/brewman/models/attendance.py b/brewman/brewman/models/attendance.py
index 6f52248d..8b93c739 100644
--- a/brewman/brewman/models/attendance.py
+++ b/brewman/brewman/models/attendance.py
@@ -27,7 +27,7 @@ class Attendance(Base):
     attendance_type = Column("attendance_type", Integer)
     amount = Column("amount", Numeric(precision=5, scale=2))
     creation_date = Column("creation_date", DateTime())
-    user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id"))
+    user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("users.id"))
     is_valid = Column("is_valid", Boolean)
 
     user = relationship("User", primaryjoin="User.id==Attendance.user_id")
diff --git a/brewman/brewman/models/client.py b/brewman/brewman/models/client.py
index 85a320b8..3b704ad1 100644
--- a/brewman/brewman/models/client.py
+++ b/brewman/brewman/models/client.py
@@ -16,7 +16,7 @@ from .meta import Base
 
 
 class Client(Base):
-    __tablename__ = "auth_clients"
+    __tablename__ = "clients"
 
     id = Column("client_id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
     code = Column("code", Integer, unique=True, nullable=False)
diff --git a/brewman/brewman/models/login_history.py b/brewman/brewman/models/login_history.py
index f890d99d..f6cf9ff3 100644
--- a/brewman/brewman/models/login_history.py
+++ b/brewman/brewman/models/login_history.py
@@ -13,14 +13,14 @@ from .meta import Base
 
 
 class LoginHistory(Base):
-    __tablename__ = "auth_login_history"
+    __tablename__ = "login_history"
     __table_args__ = (UniqueConstraint("user_id", "client_id", "date"),)
     id = Column("login_history_id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
-    user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id"), nullable=False)
+    user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
     client_id = Column(
         "client_id",
         UUID(as_uuid=True),
-        ForeignKey("auth_clients.client_id"),
+        ForeignKey("clients.client_id"),
         nullable=False,
     )
     date = Column("date", DateTime(), nullable=False)
diff --git a/brewman/brewman/models/permission.py b/brewman/brewman/models/permission.py
index d42062b3..980d423b 100644
--- a/brewman/brewman/models/permission.py
+++ b/brewman/brewman/models/permission.py
@@ -14,7 +14,7 @@ from .role_permission import role_permission
 
 
 class Permission(Base):
-    __tablename__ = "auth_permissions"
+    __tablename__ = "permissions"
 
     id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
     name = Column("name", Unicode(255), unique=True)
diff --git a/brewman/brewman/models/rate_contract.py b/brewman/brewman/models/rate_contract.py
new file mode 100644
index 00000000..1d4f8066
--- /dev/null
+++ b/brewman/brewman/models/rate_contract.py
@@ -0,0 +1,124 @@
+import uuid
+
+from sqlalchemy import (
+    Boolean,
+    Column,
+    ForeignKey,
+    Integer,
+    Numeric,
+    Unicode,
+    UniqueConstraint,
+    case,
+    func,
+    select,
+)
+from sqlalchemy.dialects.postgresql import UUID
+from sqlalchemy.ext.hybrid import hybrid_property
+from sqlalchemy.orm import Session, relationship
+
+from .meta import Base
+
+
+class Product(Base):
+    __tablename__ = "products"
+    __table_args__ = (UniqueConstraint("name", "units"),)
+
+    id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
+    code = Column("code", Integer, unique=True)
+    name = Column("name", Unicode(255), nullable=False)
+    units = Column("units", Unicode(255), nullable=False)
+    fraction = Column("fraction", Numeric(precision=15, scale=5), nullable=False)
+    fraction_units = Column("fraction_units", Unicode(255), nullable=False)
+    product_yield = Column("product_yield", Numeric(precision=15, scale=5), nullable=False)
+    product_group_id = Column(
+        "product_group_id",
+        UUID(as_uuid=True),
+        ForeignKey("product_groups.id"),
+        nullable=False,
+    )
+    account_id = Column("account_id", UUID(as_uuid=True), ForeignKey("accounts.id"), nullable=False)
+    price = Column("cost_price", Numeric(precision=15, scale=2), nullable=False)
+    sale_price = Column("sale_price", Numeric(precision=15, scale=2), nullable=False)
+    is_active = Column("is_active", Boolean, nullable=False)
+    is_fixture = Column("is_fixture", Boolean, nullable=False)
+    is_purchased = Column("is_purchased", Boolean, nullable=False)
+    is_sold = Column("is_sold", Boolean, nullable=False)
+
+    product_group = relationship("ProductGroup", back_populates="products")
+    batches = relationship("Batch", back_populates="product")
+    inventories = relationship("Inventory", back_populates="product")
+    recipes = relationship("Recipe", back_populates="product")
+    account = relationship("Account", primaryjoin="Account.id==Product.account_id", back_populates="products")
+
+    def __init__(
+        self,
+        code=None,
+        name=None,
+        units=None,
+        fraction=None,
+        fraction_units=None,
+        product_yield=None,
+        product_group_id=None,
+        account_id=None,
+        price=None,
+        sale_price=None,
+        is_active=None,
+        is_purchased=None,
+        is_sold=None,
+        id_=None,
+        is_fixture=False,
+    ):
+        self.code = code
+        self.name = name
+        self.units = units
+        self.fraction = fraction
+        self.fraction_units = fraction_units
+        self.product_yield = product_yield
+        self.product_group_id = product_group_id
+        self.account_id = account_id
+        self.price = price
+        self.sale_price = sale_price
+        self.is_active = is_active
+        self.is_purchased = is_purchased
+        self.is_sold = is_sold
+        self.id = id_
+        self.is_fixture = is_fixture
+
+    @hybrid_property
+    def full_name(self):
+        return f"{self.name} ({self.units})" if self.units else self.name
+
+    @full_name.expression
+    def full_name(cls):
+        return cls.name + case([(cls.units != "", " (" + cls.units + ")")], else_="")
+
+    def create(self, db: Session):
+        self.code = db.execute(select(func.coalesce(func.max(Product.code), 0) + 1)).scalar_one()
+        db.add(self)
+        return self
+
+    def can_delete(self, advanced_delete: bool):
+        if self.is_fixture:
+            return False, f"{self.name} is a fixture and cannot be edited or deleted."
+        if self.is_active:
+            return False, "Product is active"
+        if len(self.inventories) > 0 and not advanced_delete:
+            return False, "Product has entries"
+        return True, ""
+
+    @classmethod
+    def query(cls, q, is_purchased: bool = None, active: bool = None, db: Session = None):
+        query_ = select(cls)
+        if active is not None:
+            query_ = query_.filter(cls.is_active == active)
+        if is_purchased is not None:
+            query_ = query_.filter(cls.is_purchased == is_purchased)
+        if q is not None:
+            for item in q.split():
+                if item.strip() != "":
+                    query_ = query_.filter(cls.name.ilike(f"%{item}%"))
+        return db.execute(query_).scalars().all()
+
+    @classmethod
+    def suspense(cls):
+        return uuid.UUID("aa79a643-9ddc-4790-ac7f-a41f9efb4c15")
diff --git a/brewman/brewman/models/rate_contract_item.py b/brewman/brewman/models/rate_contract_item.py
new file mode 100644
index 00000000..441ed14a
--- /dev/null
+++ b/brewman/brewman/models/rate_contract_item.py
@@ -0,0 +1,119 @@
+import uuid
+
+from sqlalchemy import (
+    Boolean,
+    Column,
+    ForeignKey,
+    Integer,
+    Numeric,
+    Unicode,
+    UniqueConstraint,
+    case,
+    func,
+    select, DateTime, Date,
+)
+from sqlalchemy.dialects.postgresql import UUID
+from sqlalchemy.ext.hybrid import hybrid_property
+from sqlalchemy.orm import Session, relationship
+
+from .meta import Base
+
+
+class RateContract(Base):
+    __tablename__ = "rate_contracts"
+    __table_args__ = (UniqueConstraint("name", "units"),)
+
+    id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
+
+    user = relationship("User", primaryjoin="User.id==Voucher.user_id", cascade=None)
+    creation_date = Column("creation_date", DateTime(), nullable=False)
+    last_edit_date = Column("last_edit_date", DateTime(), nullable=False)
+
+    vendor_id = Column("vendor_id", UUID(as_uuid=True), ForeignKey("accounts.id"), nullable=False)
+
+    # product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False)
+    # price = Column("cost_price", Numeric(precision=15, scale=2), nullable=False)
+
+    valid_from = Column("valid_from", Date(), nullable=True)
+    valid_till = Column("valid_till", Date(), nullable=True)
+
+    user = relationship("User")
+    vendor = relationship("Account", back_populates="rate_contracts")
+
+    # batches = relationship("Batch", back_populates="product")
+    # inventories = relationship("Inventory", back_populates="product")
+    # recipes = relationship("Recipe", back_populates="product")
+    # account = relationship("Account", primaryjoin="Account.id==Product.account_id", back_populates="products")
+
+    def __init__(
+        self,
+        code=None,
+        name=None,
+        units=None,
+        fraction=None,
+        fraction_units=None,
+        product_yield=None,
+        product_group_id=None,
+        account_id=None,
+        price=None,
+        sale_price=None,
+        is_active=None,
+        is_purchased=None,
+        is_sold=None,
+        id_=None,
+        is_fixture=False,
+    ):
+        self.code = code
+        self.name = name
+        self.units = units
+        self.fraction = fraction
+        self.fraction_units = fraction_units
+        self.product_yield = product_yield
+        self.product_group_id = product_group_id
+        self.account_id = account_id
+        self.price = price
+        self.sale_price = sale_price
+        self.is_active = is_active
+        self.is_purchased = is_purchased
+        self.is_sold = is_sold
+        self.id = id_
+        self.is_fixture = is_fixture
+
+    @hybrid_property
+    def full_name(self):
+        return f"{self.name} ({self.units})" if self.units else self.name
+
+    @full_name.expression
+    def full_name(cls):
+        return cls.name + case([(cls.units != "", " (" + cls.units + ")")], else_="")
+
+    def create(self, db: Session):
+        self.code = db.execute(select(func.coalesce(func.max(Product.code), 0) + 1)).scalar_one()
+        db.add(self)
+        return self
+
+    def can_delete(self, advanced_delete: bool):
+        if self.is_fixture:
+            return False, f"{self.name} is a fixture and cannot be edited or deleted."
+        if self.is_active:
+            return False, "Product is active"
+        if len(self.inventories) > 0 and not advanced_delete:
+            return False, "Product has entries"
+        return True, ""
+
+    @classmethod
+    def query(cls, q, is_purchased: bool = None, active: bool = None, db: Session = None):
+        query_ = select(cls)
+        if active is not None:
+            query_ = query_.filter(cls.is_active == active)
+        if is_purchased is not None:
+            query_ = query_.filter(cls.is_purchased == is_purchased)
+        if q is not None:
+            for item in q.split():
+                if item.strip() != "":
+                    query_ = query_.filter(cls.name.ilike(f"%{item}%"))
+        return db.execute(query_).scalars().all()
+
+    @classmethod
+    def suspense(cls):
+        return uuid.UUID("aa79a643-9ddc-4790-ac7f-a41f9efb4c15")
diff --git a/brewman/brewman/models/role.py b/brewman/brewman/models/role.py
index fd5dc4c8..a5667ca6 100644
--- a/brewman/brewman/models/role.py
+++ b/brewman/brewman/models/role.py
@@ -11,7 +11,7 @@ from .role_permission import role_permission
 
 
 class Role(Base):
-    __tablename__ = "auth_roles"
+    __tablename__ = "roles"
 
     id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
     name = Column("name", Unicode(255), unique=True)
diff --git a/brewman/brewman/models/role_permission.py b/brewman/brewman/models/role_permission.py
index 678fd6fb..b388812d 100644
--- a/brewman/brewman/models/role_permission.py
+++ b/brewman/brewman/models/role_permission.py
@@ -13,6 +13,6 @@ role_permission = Table(
     "role_permissions",
     Base.metadata,
     Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4),
-    Column("permission_id", UUID(as_uuid=True), ForeignKey("auth_permissions.id")),
-    Column("role_id", UUID(as_uuid=True), ForeignKey("auth_roles.id")),
+    Column("permission_id", UUID(as_uuid=True), ForeignKey("permissions.id")),
+    Column("role_id", UUID(as_uuid=True), ForeignKey("roles.id")),
 )
diff --git a/brewman/brewman/models/user.py b/brewman/brewman/models/user.py
index 04154880..88c4e6de 100644
--- a/brewman/brewman/models/user.py
+++ b/brewman/brewman/models/user.py
@@ -20,7 +20,7 @@ def encrypt(val):
 
 
 class User(Base):
-    __tablename__ = "auth_users"
+    __tablename__ = "users"
 
     id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
     name = Column("username", Unicode(255), unique=True)
diff --git a/brewman/brewman/models/user_role.py b/brewman/brewman/models/user_role.py
index 540a6413..49b20ca4 100644
--- a/brewman/brewman/models/user_role.py
+++ b/brewman/brewman/models/user_role.py
@@ -13,6 +13,6 @@ user_role = Table(
     "user_roles",
     Base.metadata,
     Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4),
-    Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id")),
-    Column("role_id", UUID(as_uuid=True), ForeignKey("auth_roles.id")),
+    Column("user_id", UUID(as_uuid=True), ForeignKey("users.id")),
+    Column("role_id", UUID(as_uuid=True), ForeignKey("roles.id")),
 )
diff --git a/brewman/brewman/models/voucher.py b/brewman/brewman/models/voucher.py
index e4f86479..685db9bd 100644
--- a/brewman/brewman/models/voucher.py
+++ b/brewman/brewman/models/voucher.py
@@ -21,9 +21,9 @@ class Voucher(Base):
     creation_date = Column("creation_date", DateTime(), nullable=False)
     last_edit_date = Column("last_edit_date", DateTime(), nullable=False)
     _type = Column("voucher_type", Integer, nullable=False)
-    user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id"), nullable=False)
+    user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
     posted = Column("is_posted", Boolean, nullable=False)
-    poster_id = Column("poster_id", UUID(as_uuid=True), ForeignKey("auth_users.id"))
+    poster_id = Column("poster_id", UUID(as_uuid=True), ForeignKey("users.id"))
 
     user = relationship("User", primaryjoin="User.id==Voucher.user_id", cascade=None)
     poster = relationship("User", primaryjoin="User.id==Voucher.poster_id", cascade=None)