# Article List Metadata Display Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Show type, tags, categories, and date for each article row in the articles list (both IT and EN tabs).

**Architecture:** Extend `ArticleItem` to render a two-line item: line 1 = slug + translation badge (existing), line 2 = metadata fields extracted from `article.frontmatter`. Use `\n` in item text and `setSizeHint` for row height. No new files needed.

**Tech Stack:** PyQt6 QListWidgetItem, existing Article.frontmatter dict.

---

### Task 1: Add metadata helpers to Article model

**Files:**
- Modify: `core/models.py`
- Test: `tests/test_models.py`

- [ ] **Step 1: Write failing tests**

Add to `tests/test_models.py`:

```python
def test_article_draft_property():
    fm = {"draft": True, "type": "Tech", "tags": ["linux"], "categories": ["DIY"], "date": "2024-01-15T10:00:00+00:00"}
    a = Article(slug="test", lang="it", path=Path("/tmp/test"), frontmatter=fm, has_translation=False, translation_path=None)
    assert a.draft is True

def test_article_meta_type():
    fm = {"type": "Tech"}
    a = Article(slug="test", lang="it", path=Path("/tmp/test"), frontmatter=fm, has_translation=False, translation_path=None)
    assert a.meta_type == "Tech"

def test_article_meta_type_missing():
    a = Article(slug="test", lang="it", path=Path("/tmp/test"), frontmatter={}, has_translation=False, translation_path=None)
    assert a.meta_type == ""

def test_article_meta_tags():
    fm = {"tags": ["linux", "python"]}
    a = Article(slug="test", lang="it", path=Path("/tmp/test"), frontmatter=fm, has_translation=False, translation_path=None)
    assert a.meta_tags == "linux, python"

def test_article_meta_tags_empty():
    a = Article(slug="test", lang="it", path=Path("/tmp/test"), frontmatter={}, has_translation=False, translation_path=None)
    assert a.meta_tags == ""

def test_article_meta_categories():
    fm = {"categories": ["DIY", "Tech"]}
    a = Article(slug="test", lang="it", path=Path("/tmp/test"), frontmatter=fm, has_translation=False, translation_path=None)
    assert a.meta_categories == "DIY, Tech"

def test_article_meta_date():
    fm = {"date": "2024-01-15T10:00:00+00:00"}
    a = Article(slug="test", lang="it", path=Path("/tmp/test"), frontmatter=fm, has_translation=False, translation_path=None)
    assert a.meta_date == "2024-01-15"

def test_article_meta_date_missing():
    a = Article(slug="test", lang="it", path=Path("/tmp/test"), frontmatter={}, has_translation=False, translation_path=None)
    assert a.meta_date == ""
```

- [ ] **Step 2: Run tests to confirm they fail**

```bash
pytest tests/test_models.py -v
```

Expected: FAIL — `Article` has no `meta_type`, `meta_tags`, `meta_categories`, `meta_date` attributes.

- [ ] **Step 3: Implement properties in Article**

In `core/models.py`, add four properties after the existing `draft` property:

```python
@property
def meta_type(self) -> str:
    return str(self.frontmatter.get("type", ""))

@property
def meta_tags(self) -> str:
    tags = self.frontmatter.get("tags", [])
    if isinstance(tags, list):
        return ", ".join(str(t) for t in tags)
    return str(tags) if tags else ""

@property
def meta_categories(self) -> str:
    cats = self.frontmatter.get("categories", [])
    if isinstance(cats, list):
        return ", ".join(str(c) for c in cats)
    return str(cats) if cats else ""

@property
def meta_date(self) -> str:
    raw = self.frontmatter.get("date", "")
    if not raw:
        return ""
    return str(raw)[:10]  # ISO date → "YYYY-MM-DD"
```

- [ ] **Step 4: Run tests to confirm they pass**

```bash
pytest tests/test_models.py -v
```

Expected: all pass.

- [ ] **Step 5: Commit**

```bash
git add core/models.py tests/test_models.py
git commit -m "feat: add meta_type, meta_tags, meta_categories, meta_date properties to Article"
```

---

### Task 2: Render metadata in ArticleItem

**Files:**
- Modify: `ui/articles_view.py`

No automated tests for UI — verify manually.

- [ ] **Step 1: Update ArticleItem to render two-line text**

In `ui/articles_view.py`, replace the `ArticleItem.__init__` method. The first line keeps slug + translation badge (and `[DRAFT]` prefix). The second line shows metadata fields, omitting empty ones.

Replace the existing `ArticleItem` class (lines 10-26) with:

```python
class ArticleItem(QListWidgetItem):
    def __init__(self, article: Article):
        super().__init__()
        self.article = article
        if article.has_translation:
            badge = f"🇬🇧 ✓" if article.lang == "it" else "🇮🇹 ✓"
        else:
            badge = f"🇬🇧 ✗" if article.lang == "it" else "🇮🇹 ✗"
        line1 = f"{article.slug}  [{badge}]"
        if article.draft:
            line1 = f"[DRAFT]  {line1}"

        parts = []
        if article.meta_type:
            parts.append(article.meta_type)
        if article.meta_date:
            parts.append(article.meta_date)
        if article.meta_tags:
            parts.append(f"#{article.meta_tags.replace(', ', '  #')}")
        if article.meta_categories:
            parts.append(f"[{article.meta_categories}]")
        line2 = "  ".join(parts) if parts else ""

        text = f"{line1}\n{line2}" if line2 else line1
        self.setText(text)
        self.setSizeHint(QSize(0, 42) if line2 else QSize(0, 26))

        if article.draft:
            self.setForeground(QColor("#f59e0b"))
        elif not article.has_translation:
            self.setForeground(QColor("#ff6b6b"))
```

Also add `QSize` to the imports at the top of the file:

```python
from PyQt6.QtCore import Qt, pyqtSignal, QSize
```

- [ ] **Step 2: Run the app and verify visually**

```bash
python main.py
```

Check:
- Each article row shows two lines: slug + badge on line 1, metadata on line 2
- Articles with no metadata (missing type/date/tags/categories) show single line
- Draft articles: amber color on both lines
- Missing-translation articles: red color
- Tags rendered as `#tag1  #tag2`
- Categories rendered as `[Cat1, Cat2]`
- Date rendered as `YYYY-MM-DD`
- Row height accommodates two lines without clipping

- [ ] **Step 3: Run full test suite**

```bash
pytest tests/ -v
```

Expected: all 22+ tests pass (UI change has no tests, but existing tests must not break).

- [ ] **Step 4: Commit**

```bash
git add ui/articles_view.py
git commit -m "feat: show type, date, tags, categories in article list rows"
```
