Initial commit: WealthWise financial analytics platform

This commit is contained in:
2026-02-14 21:16:57 +05:30
commit b8588df583
171 changed files with 29048 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
"""WealthWise database models.
This package contains all SQLModel database models for the application.
"""
from app.models.base import BaseModel, TimestampMixin
from app.models.portfolio import Portfolio, PortfolioBase
from app.models.transaction import Transaction, TransactionBase, TransactionType
from app.models.user import User, UserBase
__all__ = [
# Base models
"BaseModel",
"TimestampMixin",
# User models
"User",
"UserBase",
# Portfolio models
"Portfolio",
"PortfolioBase",
# Transaction models
"Transaction",
"TransactionBase",
"TransactionType",
]

View File

@@ -0,0 +1,88 @@
"""Base SQLModel configuration for WealthWise database models.
This module provides the base model class with common fields and utilities
for all database entities.
"""
from datetime import datetime
from typing import Optional
from uuid import UUID, uuid4
from sqlalchemy import func
from sqlmodel import Field, SQLModel
class BaseModel(SQLModel):
"""Base model with common fields for all database tables.
All models should inherit from this class to get:
- UUID primary key
- Created and updated timestamps
- Soft delete support
Attributes:
id: Unique identifier (UUID)
created_at: Timestamp when record was created
updated_at: Timestamp when record was last updated
deleted_at: Timestamp for soft deletes (None if active)
"""
id: Optional[UUID] = Field(
default_factory=uuid4,
primary_key=True,
index=True,
description="Unique identifier",
)
created_at: Optional[datetime] = Field(
default=None,
sa_column_kwargs={
"server_default": func.now(),
"nullable": False,
},
description="Timestamp when record was created",
)
updated_at: Optional[datetime] = Field(
default=None,
sa_column_kwargs={
"server_default": func.now(),
"onupdate": func.now(),
"nullable": False,
},
description="Timestamp when record was last updated",
)
deleted_at: Optional[datetime] = Field(
default=None,
description="Timestamp for soft delete (None if record is active)",
)
class Config:
"""Pydantic configuration."""
# Allow arbitrary types for UUID handling
arbitrary_types_allowed = True
class TimestampMixin(SQLModel):
"""Mixin for models that only need timestamp fields (no ID).
Use this for association tables or when ID is handled differently.
"""
created_at: Optional[datetime] = Field(
default=None,
sa_column_kwargs={
"server_default": func.now(),
"nullable": False,
},
)
updated_at: Optional[datetime] = Field(
default=None,
sa_column_kwargs={
"server_default": func.now(),
"onupdate": func.now(),
"nullable": False,
},
)

View File

@@ -0,0 +1,76 @@
"""Portfolio model for WealthWise.
This module defines the Portfolio database model. Portfolios belong to users
and contain multiple transactions. Users can have multiple portfolios for
different investment strategies or purposes.
"""
from typing import TYPE_CHECKING, List, Optional
from uuid import UUID
from sqlalchemy import Column, ForeignKey, String, Text
from sqlmodel import Field, Relationship, SQLModel
from app.models.base import BaseModel
if TYPE_CHECKING:
from app.models.transaction import Transaction
from app.models.user import User
class PortfolioBase(SQLModel):
"""Base Portfolio model with common attributes.
Attributes:
name: Portfolio name
description: Optional portfolio description
"""
name: str = Field(
sa_column=Column(String(255), nullable=False),
description="Portfolio name",
)
description: Optional[str] = Field(
default=None,
sa_column=Column(Text, nullable=True),
description="Optional portfolio description",
)
class Portfolio(BaseModel, PortfolioBase, table=True):
"""Portfolio database model.
Portfolios represent collections of financial transactions owned by a user.
Each portfolio tracks investments, expenses, or savings for a specific purpose.
Attributes:
id: UUID primary key (inherited from BaseModel)
user_id: Foreign key to users table
name: Portfolio name
description: Optional description
user: Relationship to owner
transactions: Relationship to portfolio transactions
created_at: Timestamp (inherited from BaseModel)
updated_at: Timestamp (inherited from BaseModel)
"""
__tablename__ = "portfolios"
user_id: UUID = Field(
sa_column=Column(
ForeignKey("users.id", ondelete="CASCADE"),
nullable=False,
),
description="Owner user ID",
)
# Relationships
user: "User" = Relationship(back_populates="portfolios")
transactions: List["Transaction"] = Relationship(
back_populates="portfolio",
sa_relationship_kwargs={"cascade": "all, delete-orphan"},
)
class Config:
"""Pydantic configuration."""
arbitrary_types_allowed = True

View File

@@ -0,0 +1,104 @@
"""Transaction model for WealthWise.
This module defines the Transaction database model. Transactions represent
individual financial entries (income, expenses, transfers) within a portfolio.
"""
import datetime as dt
from decimal import Decimal
from enum import Enum
from typing import TYPE_CHECKING, Optional
from uuid import UUID
from sqlalchemy import Column, Date, DateTime, ForeignKey, Numeric, String, Text
from sqlmodel import Field, Relationship, SQLModel
from app.models.base import BaseModel
if TYPE_CHECKING:
from app.models.portfolio import Portfolio
class TransactionType(str, Enum):
"""Transaction type enumeration.
Defines the possible types of financial transactions:
- INCOME: Money coming in (salary, dividends, etc.)
- EXPENSE: Money going out (purchases, bills, etc.)
- TRANSFER: Movement between accounts/portfolios
"""
INCOME = "income"
EXPENSE = "expense"
TRANSFER = "transfer"
class TransactionBase(SQLModel):
"""Base Transaction model with common attributes.
Attributes:
amount: Transaction amount (Decimal for financial precision)
transaction_type: Transaction type (income, expense, transfer)
date: Transaction date
description: Optional transaction description
category: Optional transaction category/tag
"""
amount: Decimal = Field(
sa_column=Column(Numeric(15, 2), nullable=False),
description="Transaction amount",
)
transaction_type: TransactionType = Field(
sa_column=Column(String(20), nullable=False),
description="Transaction type: income, expense, or transfer",
)
transaction_date: dt.date = Field(
sa_column=Column(Date, nullable=False),
description="Transaction date",
)
description: Optional[str] = Field(
default=None,
sa_column=Column(Text, nullable=True),
description="Optional transaction description",
)
category: Optional[str] = Field(
default=None,
sa_column=Column(String(100), nullable=True),
description="Optional transaction category or tag",
)
class Transaction(BaseModel, TransactionBase, table=True):
"""Transaction database model.
Transactions represent individual financial entries within a portfolio.
They track amounts, dates, types, and categorization for financial analysis.
Attributes:
id: UUID primary key (inherited from BaseModel)
portfolio_id: Foreign key to portfolios table
amount: Transaction amount with 2 decimal precision
transaction_type: Transaction type enum
date: Transaction date
description: Optional description
category: Optional category/tag
portfolio: Relationship to parent portfolio
created_at: Timestamp (inherited from BaseModel)
updated_at: Not used (transactions are immutable after creation)
"""
__tablename__ = "transactions"
portfolio_id: UUID = Field(
sa_column=Column(
ForeignKey("portfolios.id", ondelete="CASCADE"),
nullable=False,
),
description="Parent portfolio ID",
)
# Relationships
portfolio: "Portfolio" = Relationship(back_populates="transactions")
class Config:
"""Pydantic configuration."""
arbitrary_types_allowed = True

View File

@@ -0,0 +1,76 @@
"""User model for WealthWise.
This module defines the User database model for self-hosted authentication.
Users can have multiple portfolios and are authenticated via JWT tokens.
"""
from typing import TYPE_CHECKING, List, Optional
from uuid import UUID
from sqlalchemy import Boolean, Column, String
from sqlmodel import Field, Relationship, SQLModel
from app.models.base import BaseModel
if TYPE_CHECKING:
from app.models.portfolio import Portfolio
class UserBase(SQLModel):
"""Base User model with common attributes.
Attributes:
email: User's unique email address (indexed)
is_active: Whether the user account is active
is_superuser: Whether user has admin privileges
"""
email: str = Field(
sa_column=Column(String, unique=True, index=True, nullable=False),
description="User's unique email address",
)
is_active: bool = Field(
default=True,
sa_column=Column(Boolean, default=True, nullable=False),
description="Whether the user account is active",
)
is_superuser: bool = Field(
default=False,
sa_column=Column(Boolean, default=False, nullable=False),
description="Whether user has admin privileges",
)
class User(BaseModel, UserBase, table=True):
"""User database model.
This model stores user information including authentication credentials
and account status. Passwords are stored as bcrypt hashes.
Attributes:
id: UUID primary key (inherited from BaseModel)
email: Unique email address
hashed_password: Bcrypt hashed password
is_active: Account status
is_superuser: Admin flag
portfolios: Relationship to user's portfolios
created_at: Timestamp (inherited from BaseModel)
updated_at: Timestamp (inherited from BaseModel)
"""
__tablename__ = "users"
hashed_password: str = Field(
sa_column=Column(String, nullable=False),
description="Bcrypt hashed password",
)
# Relationships
portfolios: List["Portfolio"] = Relationship(
back_populates="user",
sa_relationship_kwargs={"cascade": "all, delete-orphan"},
)
class Config:
"""Pydantic configuration."""
arbitrary_types_allowed = True