# Etapa 92 — Resumo da entrega

## Objetivo

Criar a **base de favoritos gerenciais, casos observados e fila pessoal de acompanhamento** (watchlist), para que a gestão destaque ciclos importantes além da priorização global. Sem quebrar a camada Quest nem as camadas web já existentes. A nova etapa **adiciona** watchlist/favoritos; não substitui priorização nem filtros.

---

## Ficheiros criados

### Web (Assets/Web/)

| Caminho | Descrição |
|---------|-----------|
| **Domain/EventCycleWatchItem.cs** | WatchItemId, CycleId, OpportunityId, Title, IsFavorite, IsPinned, WatchReason, AddedAt, LastTouchedAt, Notes. |
| **Domain/EventCycleWatchlistState.cs** | Items, FavoriteItems, PinnedItems, TotalWatched, WatchlistSummary, TopPinnedItem, LastUpdatedAt. |
| **Application/WatchlistStore.cs** | Add(cycleId, opportunityId, title, watchReason), Remove(cycleId), Get(cycleId), GetAll(), IsWatched(cycleId), SetFavorite(cycleId, value), SetPinned(cycleId, value), UpdateNotes(cycleId, notes), UpdateWatchReason(cycleId, reason), UpdateTitle(cycleId, title). Em memória. |
| **Application/EventCycleWatchlistController.cs** | AddToWatchlist, RemoveFromWatchlist, SetFavorite, SetPinned, UpdateNotes, UpdateWatchReason, GetWatchlistState(priorityState), IsWatched. GetWatchlistState actualiza títulos a partir da priorização e constrói FavoriteItems, PinnedItems, TopPinnedItem. |
| **Presentation/EventCycleWatchlistPanel.cs** | Resumo; lista de observados (título, ★/📌, motivo, notas, Favorito/Desfavoritar, Fixar/Desfixar, Remover); secção "Adicionar à watchlist" com itens da carteira não observados e botão Adicionar. |
| **Presentation/EventCycleWatchlistStripView.cs** | Total observados, favoritos, fixado principal, timestamp. |

### Documentação

| Caminho | Descrição |
|---------|-----------|
| **Docs/Web/WEB_EVENT_CYCLE_WATCHLIST.md** | Favoritos/watchlist, acompanhamento manual, diferença prioridade vs observação, limitações. |
| **Docs/Web/ETAPA_92_RESUMO.md** | Este resumo. |

---

## Ficheiros alterados

| Caminho | Alteração |
|---------|-----------|
| **Presentation/EventCycleDashboardPanel.cs** | watchState = GetWatchlistState(portfolioState); quando TotalWatched > 0, linha "Watchlist: N observado(s) | M favorito(s) | Fixado: [título] | timestamp". |
| **Presentation/HotelCRMDashboardController.cs** | Secções EventCycleWatchlistStripView ("Watchlist (resumo)") e EventCycleWatchlistPanel ("Favoritos e casos observados (watchlist)"). |

---

## Como a watchlist foi implementada

1. **Store**  
   WatchlistStore mantém um dicionário por CycleId com EventCycleWatchItem. Add cria ou actualiza (título, reason, LastTouchedAt). SetFavorite, SetPinned, UpdateNotes, UpdateWatchReason actualizam campos e LastTouchedAt.

2. **Controller**  
   GetWatchlistState(priorityState) obtém todos os itens do store; se priorityState for fornecido, actualiza Title dos itens a partir dos portfolio items; deriva FavoriteItems e PinnedItems; ordena PinnedItems por LastTouchedAt e toma o primeiro como TopPinnedItem; gera WatchlistSummary.

3. **Panel**  
   Obtém priorityState e watchState; mostra resumo e lista de observados com botões Favorito, Fixar, Remover; mostra secção "Adicionar à watchlist" com itens da carteira onde !IsWatched(p.CycleId) e botão Adicionar que chama AddToWatchlist(p.CycleId, p.OpportunityId, p.Title, null).

4. **Strip e dashboard**  
   Strip mostra total, favoritos e fixado principal. Dashboard mostra uma linha condicional quando há itens observados.

---

## Garantia de que Quest e camadas web existentes não foram quebradas

- **Quest** — Nenhuma alteração em QuestPresentation, QuestPresentationSession, controllers Quest, runtime XR ou apresentação.
- **Web Hotel** — CRM mantido; apenas duas novas secções (Strip e Panel da watchlist) e uma linha no dashboard. Filtros, priorização e restantes secções inalterados.
- **Web Produtor** — Painel do produtor e módulos operacionais não foram alterados.
- **Camada agregadora** — A watchlist **só consome** a priorização (para listar e actualizar títulos); não altera priorização, filtros nem overview; não introduz dependência circular.
