feat(req-013): add portfolio-list-user-required requirement and batch
- Add REQ-013: Portfolio list filtered by user requirement with acceptance criteria - Add DCY-003 discovery document for portfolio list user filtering - Create BAT-003 batch with planning, design, implementation, and verification - Enhance app/cli/commands/portfolio.py with user-based list filtering - Add comprehensive tests for portfolio list CLI command with user filtering - Update docs indices (discovery, srs, batches) - Improve README with latest capability status
This commit is contained in:
@@ -51,6 +51,18 @@ def _with_service(ctx: typer.Context, callback):
|
||||
repository.close()
|
||||
|
||||
|
||||
def _with_service_and_repo(ctx: typer.Context, callback):
|
||||
app_context = ctx.obj
|
||||
repository = app_context.repository_factory(app_context.settings)
|
||||
service = PortfolioService(repository)
|
||||
try:
|
||||
result = execute_command(app_context.console, callback=lambda: callback(service, repository, app_context))
|
||||
return result
|
||||
finally:
|
||||
if callable(getattr(type(repository), "close", None)):
|
||||
repository.close()
|
||||
|
||||
|
||||
def _confirm(force: bool, message: str) -> None:
|
||||
if force:
|
||||
return
|
||||
@@ -62,22 +74,31 @@ def _confirm(force: bool, message: str) -> None:
|
||||
@portfolio_app.command("list")
|
||||
def list_portfolios(
|
||||
ctx: typer.Context,
|
||||
user: str | None = typer.Option(None, "--user", help="Filter by username (required)."),
|
||||
broker: str | None = typer.Option(None, help="Filter by broker."),
|
||||
status: str | None = typer.Option(None, help="Filter by status."),
|
||||
include_tags: list[str] | None = typer.Option(None, "--include-tag", help="Include tag filter. Repeatable."),
|
||||
exclude_tags: list[str] | None = typer.Option(None, "--exclude-tag", help="Exclude tag filter. Repeatable."),
|
||||
match_mode: str | None = typer.Option(None, "--match-mode", help="AND or OR for include tags."),
|
||||
) -> None:
|
||||
detail = _with_service(
|
||||
ctx,
|
||||
lambda service, app_context: service.list_portfolios(
|
||||
if user is None:
|
||||
ctx.obj.console.print("Error: --user 옵션은 필수입니다.")
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
def _callback(service, repository, app_context):
|
||||
owner = repository.get_user_by_username(user)
|
||||
if owner is None:
|
||||
raise ValueError(f"사용자를 찾을 수 없습니다: {user}")
|
||||
return service.list_portfolios(
|
||||
owner_user_id=owner.id,
|
||||
broker=broker,
|
||||
status=status,
|
||||
include_tags=include_tags,
|
||||
exclude_tags=exclude_tags,
|
||||
match_mode=match_mode,
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
detail = _with_service_and_repo(ctx, _callback)
|
||||
render_output(ctx.obj.console, ctx.obj.output_format, detail, empty_message="No portfolios found.")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user