docs: add stock name display implementation plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c836c133dd
commit
b92f8f298b
722
docs/plans/2026-02-16-stock-name-display-plan.md
Normal file
722
docs/plans/2026-02-16-stock-name-display-plan.md
Normal file
@ -0,0 +1,722 @@
|
||||
# Stock Name Display Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Replace stock code displays with stock name as primary text across all portfolio-related views, with stock codes available via tooltip.
|
||||
|
||||
**Architecture:** Backend schemas and API endpoints that currently lack stock names (`SnapshotHoldingResponse`, `TransactionResponse`, backtest `TransactionItem`) get `name` fields added, with name resolution via the existing `RebalanceService.get_stock_names()`. Frontend swaps display pattern from `ticker` (primary) + `name` (subtitle) to `name` (primary) with `title={ticker}` tooltip.
|
||||
|
||||
**Tech Stack:** FastAPI + SQLAlchemy (backend), Next.js 15 + React 19 + TypeScript (frontend)
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Add `name` field to `SnapshotHoldingResponse` schema
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/schemas/portfolio.py:114-122`
|
||||
|
||||
**Step 1: Add name field to schema**
|
||||
|
||||
In `backend/app/schemas/portfolio.py`, add `name` field to `SnapshotHoldingResponse`:
|
||||
|
||||
```python
|
||||
class SnapshotHoldingResponse(BaseModel):
|
||||
ticker: str
|
||||
name: str | None = None
|
||||
quantity: int
|
||||
price: FloatDecimal
|
||||
value: FloatDecimal
|
||||
current_ratio: FloatDecimal
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
```
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/schemas/portfolio.py
|
||||
git commit -m "feat: add name field to SnapshotHoldingResponse schema"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Add `name` field to `TransactionResponse` schema
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/schemas/portfolio.py:72-76`
|
||||
|
||||
**Step 1: Add name field to schema**
|
||||
|
||||
In `backend/app/schemas/portfolio.py`, add `name` field to `TransactionResponse`:
|
||||
|
||||
```python
|
||||
class TransactionResponse(TransactionBase):
|
||||
id: int
|
||||
name: str | None = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
```
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/schemas/portfolio.py
|
||||
git commit -m "feat: add name field to TransactionResponse schema"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Add `name` field to backtest `TransactionItem` schema
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/schemas/backtest.py:119-131`
|
||||
|
||||
**Step 1: Add name field to schema**
|
||||
|
||||
In `backend/app/schemas/backtest.py`, add `name` field to `TransactionItem`:
|
||||
|
||||
```python
|
||||
class TransactionItem(BaseModel):
|
||||
"""Single transaction."""
|
||||
id: int
|
||||
date: date
|
||||
ticker: str
|
||||
name: str | None = None
|
||||
action: str
|
||||
shares: int
|
||||
price: FloatDecimal
|
||||
commission: FloatDecimal
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
```
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/schemas/backtest.py
|
||||
git commit -m "feat: add name field to backtest TransactionItem schema"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Populate snapshot holdings with stock names in snapshot API
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/api/snapshot.py:53-128` (create_snapshot endpoint)
|
||||
- Modify: `backend/app/api/snapshot.py:131-168` (get_snapshot endpoint)
|
||||
|
||||
**Step 1: Update imports**
|
||||
|
||||
Add `RebalanceService` import at top of `backend/app/api/snapshot.py`:
|
||||
|
||||
```python
|
||||
from app.services.rebalance import RebalanceService
|
||||
```
|
||||
|
||||
**Step 2: Update `create_snapshot` endpoint to include names**
|
||||
|
||||
In the `create_snapshot` function, after getting prices and before creating snapshot, resolve names and include them in the response. Replace the return statement (lines 113-128):
|
||||
|
||||
```python
|
||||
# Get stock names
|
||||
name_service = RebalanceService(db)
|
||||
names = name_service.get_stock_names(tickers)
|
||||
|
||||
return SnapshotResponse(
|
||||
id=snapshot.id,
|
||||
portfolio_id=snapshot.portfolio_id,
|
||||
total_value=snapshot.total_value,
|
||||
snapshot_date=snapshot.snapshot_date,
|
||||
holdings=[
|
||||
SnapshotHoldingResponse(
|
||||
ticker=h.ticker,
|
||||
name=names.get(h.ticker),
|
||||
quantity=h.quantity,
|
||||
price=h.price,
|
||||
value=h.value,
|
||||
current_ratio=h.current_ratio,
|
||||
)
|
||||
for h in snapshot.holdings
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
**Step 3: Update `get_snapshot` endpoint to include names**
|
||||
|
||||
In the `get_snapshot` function, resolve names before returning. Replace lines 153-168:
|
||||
|
||||
```python
|
||||
# Get stock names
|
||||
tickers = [h.ticker for h in snapshot.holdings]
|
||||
name_service = RebalanceService(db)
|
||||
names = name_service.get_stock_names(tickers)
|
||||
|
||||
return SnapshotResponse(
|
||||
id=snapshot.id,
|
||||
portfolio_id=snapshot.portfolio_id,
|
||||
total_value=snapshot.total_value,
|
||||
snapshot_date=snapshot.snapshot_date,
|
||||
holdings=[
|
||||
SnapshotHoldingResponse(
|
||||
ticker=h.ticker,
|
||||
name=names.get(h.ticker),
|
||||
quantity=h.quantity,
|
||||
price=h.price,
|
||||
value=h.value,
|
||||
current_ratio=h.current_ratio,
|
||||
)
|
||||
for h in snapshot.holdings
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/api/snapshot.py
|
||||
git commit -m "feat: include stock names in snapshot API responses"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: Populate transactions with stock names in portfolio API
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/api/portfolio.py:218-234`
|
||||
|
||||
**Step 1: Update imports**
|
||||
|
||||
At top of `backend/app/api/portfolio.py`, `RebalanceService` is already imported (line 21). No change needed.
|
||||
|
||||
**Step 2: Update `get_transactions` endpoint**
|
||||
|
||||
Replace the `get_transactions` function body to resolve names:
|
||||
|
||||
```python
|
||||
@router.get("/{portfolio_id}/transactions", response_model=List[TransactionResponse])
|
||||
async def get_transactions(
|
||||
portfolio_id: int,
|
||||
current_user: CurrentUser,
|
||||
db: Session = Depends(get_db),
|
||||
limit: int = 50,
|
||||
):
|
||||
"""Get transaction history for a portfolio."""
|
||||
_get_portfolio(db, portfolio_id, current_user.id)
|
||||
transactions = (
|
||||
db.query(Transaction)
|
||||
.filter(Transaction.portfolio_id == portfolio_id)
|
||||
.order_by(Transaction.executed_at.desc())
|
||||
.limit(limit)
|
||||
.all()
|
||||
)
|
||||
|
||||
# Resolve stock names
|
||||
tickers = list({tx.ticker for tx in transactions})
|
||||
service = RebalanceService(db)
|
||||
names = service.get_stock_names(tickers)
|
||||
|
||||
return [
|
||||
TransactionResponse(
|
||||
id=tx.id,
|
||||
ticker=tx.ticker,
|
||||
name=names.get(tx.ticker),
|
||||
tx_type=tx.tx_type.value,
|
||||
quantity=tx.quantity,
|
||||
price=tx.price,
|
||||
executed_at=tx.executed_at,
|
||||
memo=tx.memo,
|
||||
)
|
||||
for tx in transactions
|
||||
]
|
||||
```
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/api/portfolio.py
|
||||
git commit -m "feat: include stock names in transaction API responses"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: Populate backtest transactions with stock names
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/api/backtest.py:209-242`
|
||||
|
||||
**Step 1: Add import**
|
||||
|
||||
Add `RebalanceService` import at top of `backend/app/api/backtest.py`:
|
||||
|
||||
```python
|
||||
from app.services.rebalance import RebalanceService
|
||||
```
|
||||
|
||||
**Step 2: Update `get_transactions` endpoint**
|
||||
|
||||
Replace the return logic in the backtest `get_transactions` endpoint:
|
||||
|
||||
```python
|
||||
transactions = (
|
||||
db.query(BacktestTransaction)
|
||||
.filter(BacktestTransaction.backtest_id == backtest_id)
|
||||
.order_by(BacktestTransaction.date, BacktestTransaction.id)
|
||||
.all()
|
||||
)
|
||||
|
||||
# Resolve stock names
|
||||
tickers = list({t.ticker for t in transactions})
|
||||
name_service = RebalanceService(db)
|
||||
names = name_service.get_stock_names(tickers)
|
||||
|
||||
return [
|
||||
TransactionItem(
|
||||
id=t.id,
|
||||
date=t.date,
|
||||
ticker=t.ticker,
|
||||
name=names.get(t.ticker),
|
||||
action=t.action,
|
||||
shares=t.shares,
|
||||
price=t.price,
|
||||
commission=t.commission,
|
||||
)
|
||||
for t in transactions
|
||||
]
|
||||
```
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/api/backtest.py
|
||||
git commit -m "feat: include stock names in backtest transaction responses"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 7: Update portfolio-card.tsx - show name instead of ticker
|
||||
|
||||
**Files:**
|
||||
- Modify: `frontend/src/components/portfolio/portfolio-card.tsx`
|
||||
|
||||
**Step 1: Add `name` to Holding interface**
|
||||
|
||||
```typescript
|
||||
interface Holding {
|
||||
ticker: string;
|
||||
name: string | null;
|
||||
current_ratio: number | null;
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Update pieData mapping to use name**
|
||||
|
||||
Change line 64 from `name: h.ticker` to:
|
||||
|
||||
```typescript
|
||||
name: h.name || h.ticker,
|
||||
```
|
||||
|
||||
**Step 3: Add title attribute to holdings preview badges**
|
||||
|
||||
Change the badge span (line 144-149) to include a `title`:
|
||||
|
||||
```tsx
|
||||
<span
|
||||
key={index}
|
||||
className="text-xs px-2 py-0.5 rounded bg-muted text-muted-foreground"
|
||||
title={pieData[index]?.name !== holdings[index]?.name ? holdings.find(h => (h.name || h.ticker) === item.name)?.ticker : undefined}
|
||||
>
|
||||
{item.name}
|
||||
</span>
|
||||
```
|
||||
|
||||
Actually, simpler approach - since `pieData` is derived from `holdings`, we can track the original ticker. Let's use a simpler approach: map pieData to include the original ticker, then use `title={item.ticker}`:
|
||||
|
||||
Change the pieData mapping (lines 60-67):
|
||||
|
||||
```typescript
|
||||
const pieData = holdings
|
||||
.filter((h) => h.current_ratio !== null && h.current_ratio > 0)
|
||||
.slice(0, 6)
|
||||
.map((h, index) => ({
|
||||
name: h.name || h.ticker,
|
||||
ticker: h.ticker,
|
||||
value: h.current_ratio ?? 0,
|
||||
color: CHART_COLORS[index % CHART_COLORS.length],
|
||||
}));
|
||||
```
|
||||
|
||||
Then update the badge (lines 143-149):
|
||||
|
||||
```tsx
|
||||
{pieData.slice(0, 4).map((item, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="text-xs px-2 py-0.5 rounded bg-muted text-muted-foreground"
|
||||
title={item.ticker}
|
||||
>
|
||||
{item.name}
|
||||
</span>
|
||||
))}
|
||||
```
|
||||
|
||||
**Step 4: Also update HoldingWithValue in portfolio list page**
|
||||
|
||||
In `frontend/src/app/portfolio/page.tsx`, add `name` to the `HoldingWithValue` interface (line 12-15):
|
||||
|
||||
```typescript
|
||||
interface HoldingWithValue {
|
||||
ticker: string;
|
||||
name: string | null;
|
||||
current_ratio: number | null;
|
||||
}
|
||||
```
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add frontend/src/components/portfolio/portfolio-card.tsx frontend/src/app/portfolio/page.tsx
|
||||
git commit -m "feat: show stock names in portfolio cards"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 8: Update portfolio detail page - fix holdings ticker subtitle removal + transactions name
|
||||
|
||||
**Files:**
|
||||
- Modify: `frontend/src/app/portfolio/[id]/page.tsx`
|
||||
|
||||
**Step 1: Add `name` to Transaction interface**
|
||||
|
||||
```typescript
|
||||
interface Transaction {
|
||||
id: number;
|
||||
ticker: string;
|
||||
name: string | null;
|
||||
tx_type: string;
|
||||
quantity: number;
|
||||
price: number;
|
||||
executed_at: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Update holdings table - remove ticker subtitle, add title tooltip**
|
||||
|
||||
Change lines 343-348 from:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-3">
|
||||
<div className="font-medium text-sm">{holding.name || holding.ticker}</div>
|
||||
{holding.name && (
|
||||
<div className="text-xs text-muted-foreground">{holding.ticker}</div>
|
||||
)}
|
||||
</td>
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-3">
|
||||
<span className="font-medium text-sm" title={holding.ticker}>{holding.name || holding.ticker}</span>
|
||||
</td>
|
||||
```
|
||||
|
||||
**Step 3: Update transactions table - show name instead of ticker**
|
||||
|
||||
Change line 457 from:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-3 text-sm font-medium">{tx.ticker}</td>
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-3 text-sm font-medium" title={tx.ticker}>{tx.name || tx.ticker}</td>
|
||||
```
|
||||
|
||||
**Step 4: Update Target vs Actual section - add title tooltip**
|
||||
|
||||
Change line 522 from:
|
||||
|
||||
```tsx
|
||||
<span className="font-medium">{holding?.name || target.ticker}</span>
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```tsx
|
||||
<span className="font-medium" title={target.ticker}>{holding?.name || target.ticker}</span>
|
||||
```
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add frontend/src/app/portfolio/[id]/page.tsx
|
||||
git commit -m "feat: show stock names as primary display in portfolio detail"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 9: Update rebalance page - name as primary display
|
||||
|
||||
**Files:**
|
||||
- Modify: `frontend/src/app/portfolio/[id]/rebalance/page.tsx`
|
||||
|
||||
**Step 1: Fetch stock names for price input labels**
|
||||
|
||||
The rebalance page needs names for the price input section. The targets and holdings don't have names, but the rebalance result does. We need to store a name map. Add state and fetch names when targets/holdings load.
|
||||
|
||||
Add `nameMap` state after existing state declarations (after line 61):
|
||||
|
||||
```typescript
|
||||
const [nameMap, setNameMap] = useState<Record<string, string>>({});
|
||||
```
|
||||
|
||||
In the `init` function, after setting targets and holdings, fetch portfolio detail to get names:
|
||||
|
||||
```typescript
|
||||
// Fetch stock names from portfolio detail
|
||||
try {
|
||||
const detail = await api.get<{ holdings: { ticker: string; name: string | null }[] }>(`/api/portfolios/${portfolioId}/detail`);
|
||||
const names: Record<string, string> = {};
|
||||
for (const h of detail.holdings) {
|
||||
if (h.name) names[h.ticker] = h.name;
|
||||
}
|
||||
setNameMap(names);
|
||||
} catch {
|
||||
// Names are optional, continue without
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Update price input labels to use name**
|
||||
|
||||
Change line 183 from:
|
||||
|
||||
```tsx
|
||||
{ticker} {target ? `(목표 ${target.target_ratio}%)` : ''} - 보유 {getHoldingQty(ticker)}주
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```tsx
|
||||
{nameMap[ticker] || ticker} {target ? `(목표 ${target.target_ratio}%)` : ''} - 보유 {getHoldingQty(ticker)}주
|
||||
```
|
||||
|
||||
**Step 3: Update results table - name as primary**
|
||||
|
||||
Change lines 299-304 from:
|
||||
|
||||
```tsx
|
||||
<td className="px-3 py-3">
|
||||
<div className="font-medium">{item.ticker}</div>
|
||||
{item.name && (
|
||||
<div className="text-xs text-muted-foreground">{item.name}</div>
|
||||
)}
|
||||
</td>
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```tsx
|
||||
<td className="px-3 py-3">
|
||||
<span className="font-medium" title={item.ticker}>{item.name || item.ticker}</span>
|
||||
</td>
|
||||
```
|
||||
|
||||
**Step 4: Also update nameMap from rebalance results**
|
||||
|
||||
After the calculate function sets the result, update nameMap with any names from the result:
|
||||
|
||||
In the `calculate` function, after `setResult(data)` (line 117), add:
|
||||
|
||||
```typescript
|
||||
// Update name map from results
|
||||
const newNames = { ...nameMap };
|
||||
for (const item of data.items) {
|
||||
if (item.name) newNames[item.ticker] = item.name;
|
||||
}
|
||||
setNameMap(newNames);
|
||||
```
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add frontend/src/app/portfolio/[id]/rebalance/page.tsx
|
||||
git commit -m "feat: show stock names as primary display in rebalance page"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 10: Update portfolio history page - show names in snapshot
|
||||
|
||||
**Files:**
|
||||
- Modify: `frontend/src/app/portfolio/[id]/history/page.tsx`
|
||||
|
||||
**Step 1: Add `name` to SnapshotDetail holdings interface**
|
||||
|
||||
Change the `holdings` type in `SnapshotDetail` interface (lines 23-29):
|
||||
|
||||
```typescript
|
||||
holdings: {
|
||||
ticker: string;
|
||||
name: string | null;
|
||||
quantity: number;
|
||||
price: string;
|
||||
value: string;
|
||||
current_ratio: string;
|
||||
}[];
|
||||
```
|
||||
|
||||
**Step 2: Update snapshot detail modal table**
|
||||
|
||||
Change line 428 from:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-2 text-sm text-foreground">
|
||||
{holding.ticker}
|
||||
</td>
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-2 text-sm text-foreground" title={holding.ticker}>
|
||||
{holding.name || holding.ticker}
|
||||
</td>
|
||||
```
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add frontend/src/app/portfolio/[id]/history/page.tsx
|
||||
git commit -m "feat: show stock names in portfolio history snapshots"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 11: Update strategy pages - name as primary (3 files)
|
||||
|
||||
**Files:**
|
||||
- Modify: `frontend/src/app/strategy/multi-factor/page.tsx:209-211`
|
||||
- Modify: `frontend/src/app/strategy/quality/page.tsx:174-176`
|
||||
- Modify: `frontend/src/app/strategy/value-momentum/page.tsx:190-192`
|
||||
|
||||
**Step 1: Update multi-factor page**
|
||||
|
||||
Change lines 209-211 from:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-3">
|
||||
<div className="font-medium">{stock.ticker}</div>
|
||||
<div className="text-xs text-muted-foreground">{stock.name}</div>
|
||||
</td>
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-3">
|
||||
<span className="font-medium" title={stock.ticker}>{stock.name || stock.ticker}</span>
|
||||
</td>
|
||||
```
|
||||
|
||||
**Step 2: Update quality page**
|
||||
|
||||
Same change at lines 174-176.
|
||||
|
||||
**Step 3: Update value-momentum page**
|
||||
|
||||
Same change at lines 190-192.
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add frontend/src/app/strategy/multi-factor/page.tsx frontend/src/app/strategy/quality/page.tsx frontend/src/app/strategy/value-momentum/page.tsx
|
||||
git commit -m "feat: show stock names as primary display in strategy pages"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 12: Update backtest detail page - name as primary
|
||||
|
||||
**Files:**
|
||||
- Modify: `frontend/src/app/backtest/[id]/page.tsx`
|
||||
|
||||
**Step 1: Add `name` to TransactionItem interface**
|
||||
|
||||
```typescript
|
||||
interface TransactionItem {
|
||||
id: number;
|
||||
date: string;
|
||||
ticker: string;
|
||||
name: string | null;
|
||||
action: string;
|
||||
shares: number;
|
||||
price: number;
|
||||
commission: number;
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Update holdings tab display**
|
||||
|
||||
Change lines 392-394 from:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-3">
|
||||
<div className="font-medium">{h.ticker}</div>
|
||||
<div className="text-xs text-muted-foreground">{h.name}</div>
|
||||
</td>
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-3">
|
||||
<span className="font-medium" title={h.ticker}>{h.name || h.ticker}</span>
|
||||
</td>
|
||||
```
|
||||
|
||||
**Step 3: Update transactions tab display**
|
||||
|
||||
Change line 425 from:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-3 text-sm font-medium">{t.ticker}</td>
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```tsx
|
||||
<td className="px-4 py-3 text-sm font-medium" title={t.ticker}>{t.name || t.ticker}</td>
|
||||
```
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add frontend/src/app/backtest/[id]/page.tsx
|
||||
git commit -m "feat: show stock names as primary display in backtest detail"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 13: Verify frontend build
|
||||
|
||||
**Step 1: Run frontend build to check for TypeScript errors**
|
||||
|
||||
```bash
|
||||
cd frontend && npm run build
|
||||
```
|
||||
|
||||
Expected: Build succeeds with no type errors.
|
||||
|
||||
**Step 2: If build fails, fix any TypeScript errors and re-run**
|
||||
|
||||
**Step 3: Commit any fixes**
|
||||
|
||||
```bash
|
||||
git add -A && git commit -m "fix: resolve build errors from stock name display changes"
|
||||
```
|
||||
Loading…
x
Reference in New Issue
Block a user