# S02 Research — Creator Freshness + Homepage Card Dates

## Summary

Straightforward slice. Two independent changes using established patterns — no new endpoints, no migrations, no new dependencies.

**Requirements targeted:** R033 (Creator Last Updated Date)

## Recommendation

Wire `last_technique_at` through existing creator list endpoint (backend + frontend), and render `created_at` on homepage recently-added cards (frontend only). Two tasks, fully independent.

## Implementation Landscape

### 1. Creator "Last Updated" on Creators Browse Page

**Backend change — `backend/routers/creators.py`:**
- The `list_creators` endpoint already uses correlated subqueries for `technique_count` and `video_count`. Add a third:
  ```python
  last_technique_sq = (
      select(func.max(TechniquePage.created_at))
      .where(TechniquePage.creator_id == Creator.id)
      .correlate(Creator)
      .scalar_subquery()
  )
  ```
- Add it to the `select()` call and read it from the result row.
- The field should be `datetime | None` (null if creator has 0 technique pages).

**Backend schema — `backend/schemas.py`:**
- Add `last_technique_at: datetime | None = None` to `CreatorBrowseItem` (line ~358).

**Frontend type — `frontend/src/api/public-client.ts`:**
- Add `last_technique_at: string | null` to the `CreatorBrowseItem` interface (line ~156).

**Frontend display — `frontend/src/pages/CreatorsBrowse.tsx`:**
- In the `creator-row__stats` span (around line 152), add a "Last updated: Mon D" display after the existing stats when `last_technique_at` is non-null.
- Format with `new Date(creator.last_technique_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })`.
- Use muted styling consistent with other secondary text.

### 2. Date on Homepage Recently-Added Cards

**No backend change needed.** `TechniqueListItem` already includes `created_at` (confirmed in schema and TS interface).

**Frontend display — `frontend/src/pages/Home.tsx`:**
- Inside the `.recent-card` Link (around line 237), render `t.created_at` as a small date badge.
- Position: after the creator name in `.recent-card__header`, or as a subtle tag in `.recent-card__meta`.
- Same date formatting as creators page.

**Frontend styling — `frontend/src/App.css`:**
- Add minimal CSS for the date elements (muted color, small font-size, consistent with existing secondary text patterns).

### File Inventory

| File | Change |
|------|--------|
| `backend/routers/creators.py` | Add `last_technique_sq` subquery, include in select + row reading |
| `backend/schemas.py` | Add `last_technique_at` field to `CreatorBrowseItem` |
| `frontend/src/api/public-client.ts` | Add `last_technique_at` to TS interface |
| `frontend/src/pages/CreatorsBrowse.tsx` | Render last updated date in creator row |
| `frontend/src/pages/Home.tsx` | Render created_at on recently-added cards |
| `frontend/src/App.css` | Minimal date styling |

### Natural Task Seams

**Task 1: Backend — Add `last_technique_at` to creators endpoint**
- Files: `backend/routers/creators.py`, `backend/schemas.py`
- Verify: `curl http://ub01:8096/api/v1/creators | python3 -m json.tool | grep last_technique_at`

**Task 2: Frontend — Creator dates + homepage card dates**
- Files: `frontend/src/api/public-client.ts`, `frontend/src/pages/CreatorsBrowse.tsx`, `frontend/src/pages/Home.tsx`, `frontend/src/App.css`
- Verify: Visual check at http://ub01:8096/creators and http://ub01:8096
- Depends on Task 1 (needs the API field to exist)

### Constraints

- Date formatting should use short month format ("Apr 3") not full dates — keeps the UI compact.
- `last_technique_at` will be null for creators with 0 techniques — frontend must handle this gracefully (hide or show "No articles yet").
- The correlated subquery adds negligible cost — creator count is <100 and `technique_pages.creator_id` is already indexed via FK.
