Issue 1: repo scaffold and project structure
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
"""SQLModel table definitions for Ten31Portal."""
|
||||
|
||||
import enum
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
from typing import Optional
|
||||
|
||||
from sqlmodel import Field, SQLModel, Column, String, JSON, UniqueConstraint
|
||||
|
||||
|
||||
# --- Enums ---
|
||||
|
||||
class UserRole(str, enum.Enum):
|
||||
approver = "approver"
|
||||
cfo = "cfo"
|
||||
fund_admin = "fund_admin"
|
||||
viewer = "viewer"
|
||||
|
||||
|
||||
class EntityType(str, enum.Enum):
|
||||
fund = "fund"
|
||||
spv = "spv"
|
||||
gp = "gp"
|
||||
mgmt_co = "mgmt_co"
|
||||
|
||||
|
||||
class EntityStatus(str, enum.Enum):
|
||||
active = "active"
|
||||
closed = "closed"
|
||||
|
||||
|
||||
class RoundStatus(str, enum.Enum):
|
||||
draft = "draft"
|
||||
submitted = "submitted"
|
||||
approved = "approved"
|
||||
returned = "returned"
|
||||
|
||||
|
||||
# --- Tables ---
|
||||
|
||||
class User(SQLModel, table=True):
|
||||
__tablename__ = "users"
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True)
|
||||
name: str
|
||||
email: str = Field(sa_column=Column(String, unique=True, nullable=False))
|
||||
password_hash: str
|
||||
role: UserRole
|
||||
is_active: bool = Field(default=True)
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
|
||||
class Entity(SQLModel, table=True):
|
||||
__tablename__ = "entities"
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True)
|
||||
name: str
|
||||
type: EntityType
|
||||
vintage_year: int | None = None
|
||||
fund_size_cents: int | None = None
|
||||
status: EntityStatus = Field(default=EntityStatus.active)
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
|
||||
class Holding(SQLModel, table=True):
|
||||
__tablename__ = "holdings"
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True)
|
||||
entity_id: int = Field(foreign_key="entities.id")
|
||||
company_name: str
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
|
||||
class Position(SQLModel, table=True):
|
||||
__tablename__ = "positions"
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True)
|
||||
holding_id: int = Field(foreign_key="holdings.id")
|
||||
security_name: str
|
||||
investment_date: date
|
||||
shares: str | None = None # Decimal stored as string
|
||||
cost_cents: int
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
|
||||
class ValuationRound(SQLModel, table=True):
|
||||
__tablename__ = "valuation_rounds"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("entity_id", "quarter_end", name="uq_round_entity_quarter"),
|
||||
)
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True)
|
||||
entity_id: int = Field(foreign_key="entities.id")
|
||||
quarter_end: date
|
||||
status: RoundStatus = Field(default=RoundStatus.draft)
|
||||
submitted_by: int | None = Field(default=None, foreign_key="users.id")
|
||||
submitted_at: datetime | None = None
|
||||
approved_by: int | None = Field(default=None, foreign_key="users.id")
|
||||
approved_at: datetime | None = None
|
||||
return_note: str | None = None
|
||||
is_seed: bool = Field(default=False)
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
|
||||
class Valuation(SQLModel, table=True):
|
||||
__tablename__ = "valuations"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("round_id", "position_id", name="uq_valuation_round_position"),
|
||||
)
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True)
|
||||
round_id: int = Field(foreign_key="valuation_rounds.id")
|
||||
position_id: int = Field(foreign_key="positions.id")
|
||||
value_cents: int
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
|
||||
class AuditLog(SQLModel, table=True):
|
||||
__tablename__ = "audit_log"
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True)
|
||||
actor_user_id: int | None = Field(default=None, foreign_key="users.id")
|
||||
action: str
|
||||
object_type: str
|
||||
object_id: int | None = None
|
||||
detail: str | None = Field(default=None, sa_column=Column(JSON, nullable=True))
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
Reference in New Issue
Block a user