# Achievements

**Module:** `wow_achievement`

Two things, both exposed as operators would expect:

1. The **catalog** — every WoW achievement (~9,000 entries), organized into categories, with points, icons, descriptions, and completion criteria.
2. **Per-character progress** — which achievements each imported character has completed, and when.

## What's stored

- **Achievements** (content entity): name, description, points, icon, category reference, account-wide flag, display order, structured criteria data.
- **Achievement categories** (taxonomy): character and guild category trees, preserving Blizzard's hierarchy. Two separate vocabularies — `wow_char_achi_category` and `wow_guild_achi_category`.
- **Achievement progress** (junction entity): per-character row with `completed_timestamp`, criteria progress amount, structured criteria data, and a `last_fetched` stamp.

## Setting up

```
drush en wow_achievement -y
drush wow:sync-achi-categories --force
drush wow:sync-achievements --force
```

Achievement sync is queue-backed. `wow:sync-achievements` enqueues one `wow_achievement_sync` job per achievement via Advanced Queue; drush cron (or a dedicated runner) processes them. On the dashboard, **Sync now** runs the full enqueue + drain as a Drupal batch with a progress bar.

Typical full-catalog sync: ~15–20 minutes at the default rate.

## Per-character progress

Achievement progress is pulled automatically on every character sync when `wow_achievement` is enabled — the module registers a [`CharacterDataProvider`](../development/character-data-providers.md) plugin that hits `/profile/wow/character/{realm}/{name}/achievements` after the character itself is saved.

No separate drush command, no separate dashboard button.

Progress rows survive character deletes only as their cascade wiring ([lifecycle](../architecture/lifecycle.md)) dictates: they go away with the character entity they reference.

## Dashboard actions

- **Sync now** — enqueue + process the entire catalog.
- **Force resync** — wipe + re-sync. Categories (taxonomy) are preserved to avoid breaking references.
- **Wipe** — delete all achievement entities without re-syncing.

## Requirements

- [Advanced Queue](https://www.drupal.org/project/advancedqueue) (installed as a dependency)
- A cron or queue-worker schedule for the Advanced Queue processor
