chore: initial project scaffold and gitignore

This commit is contained in:
2026-04-03 07:33:32 +00:00
commit 3e3acbd13d
41 changed files with 3658 additions and 0 deletions
+114
View File
@@ -0,0 +1,114 @@
"""Portfolio API routes."""
from fastapi import APIRouter, Depends, Response, status
from app.core.auth import require_admin, require_read, require_trade_write
from app.schemas.portfolio import (
BuyRequest,
CreatePortfolioRequest,
InvestRequest,
PortfolioDetailResponse,
PortfolioListItem,
ResetPortfolioRequest,
SellRequest,
TransferRequest,
UpdatePortfolioRequest,
)
from app.services.portfolio_service import PortfolioService, get_portfolio_service
router = APIRouter(prefix="/portfolios", tags=["portfolios"])
@router.get("", response_model=list[PortfolioListItem], dependencies=[Depends(require_read)])
def list_portfolios(
broker: str | None = None,
status_filter: str | None = None,
service: PortfolioService = Depends(get_portfolio_service),
) -> list[PortfolioListItem]:
return service.list_portfolios(broker=broker, status=status_filter)
@router.get("/{portfolio_id}", response_model=PortfolioDetailResponse, dependencies=[Depends(require_read)])
def get_portfolio(
portfolio_id: str,
recent_trades: int = 5,
service: PortfolioService = Depends(get_portfolio_service),
) -> PortfolioDetailResponse:
return service.get_portfolio_status(portfolio_id=portfolio_id, recent_trades=recent_trades)
@router.post(
"",
response_model=PortfolioDetailResponse,
status_code=status.HTTP_201_CREATED,
dependencies=[Depends(require_trade_write)],
)
def create_portfolio(
payload: CreatePortfolioRequest,
service: PortfolioService = Depends(get_portfolio_service),
) -> PortfolioDetailResponse:
return service.create_portfolio(payload)
@router.patch("/{portfolio_id}", response_model=PortfolioDetailResponse, dependencies=[Depends(require_trade_write)])
def update_portfolio(
portfolio_id: str,
payload: UpdatePortfolioRequest,
service: PortfolioService = Depends(get_portfolio_service),
) -> PortfolioDetailResponse:
return service.update_portfolio(portfolio_id, payload)
@router.post("/{portfolio_id}/buy", response_model=PortfolioDetailResponse, dependencies=[Depends(require_trade_write)])
def buy_portfolio_asset(
portfolio_id: str,
payload: BuyRequest,
service: PortfolioService = Depends(get_portfolio_service),
) -> PortfolioDetailResponse:
return service.buy(portfolio_id, payload)
@router.post("/{portfolio_id}/sell", response_model=PortfolioDetailResponse, dependencies=[Depends(require_trade_write)])
def sell_portfolio_asset(
portfolio_id: str,
payload: SellRequest,
service: PortfolioService = Depends(get_portfolio_service),
) -> PortfolioDetailResponse:
return service.sell(portfolio_id, payload)
@router.post("/{portfolio_id}/invest", response_model=PortfolioDetailResponse, dependencies=[Depends(require_trade_write)])
def invest_buffer(
portfolio_id: str,
payload: InvestRequest,
service: PortfolioService = Depends(get_portfolio_service),
) -> PortfolioDetailResponse:
return service.invest(portfolio_id, payload)
@router.post("/{portfolio_id}/transfer", response_model=PortfolioDetailResponse, dependencies=[Depends(require_trade_write)])
def transfer_buffer(
portfolio_id: str,
payload: TransferRequest,
service: PortfolioService = Depends(get_portfolio_service),
) -> PortfolioDetailResponse:
return service.transfer(portfolio_id, payload)
@router.post("/{portfolio_id}/reset", response_model=PortfolioDetailResponse, dependencies=[Depends(require_trade_write)])
def reset_portfolio(
portfolio_id: str,
payload: ResetPortfolioRequest,
service: PortfolioService = Depends(get_portfolio_service),
) -> PortfolioDetailResponse:
return service.reset(portfolio_id, payload)
@router.delete("/{portfolio_id}", status_code=status.HTTP_204_NO_CONTENT, dependencies=[Depends(require_admin)])
def delete_portfolio(
portfolio_id: str,
keep_ledger: bool = False,
service: PortfolioService = Depends(get_portfolio_service),
) -> Response:
service.delete(portfolio_id, keep_ledger=keep_ledger)
return Response(status_code=status.HTTP_204_NO_CONTENT)