feat: archive zoo_backup for home sync
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
# Skill: sprint-report
|
||||
|
||||
Generate sprint status report from Jira data.
|
||||
|
||||
## Invoked by
|
||||
|
||||
🎫 JiraOps mode (or 🪃 Orchestrator delegating to JiraOps)
|
||||
|
||||
## Required Inputs
|
||||
|
||||
| Input | Source | Example |
|
||||
|-------|--------|---------|
|
||||
| `PROJECT_KEY` | Jira project key | `ESIDEPAISY` |
|
||||
| `SPRINT_ID` | Sprint ID (optional — auto-detected if omitted) | `1234` |
|
||||
| `OUTPUT_FORMAT` | Report format (optional) | `markdown`, `confluence`, `teams` |
|
||||
|
||||
## Output
|
||||
|
||||
- Markdown report: `docs/sprint-reports/sprint-<sprint_name>-<date>.md`
|
||||
- Optionally: Confluence page or Teams message
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Get active sprint
|
||||
|
||||
If `SPRINT_ID` is not provided, auto-detect:
|
||||
|
||||
```python
|
||||
# Get the board
|
||||
boards = get_agile_boards(project_key="ESIDEPAISY")
|
||||
board_id = boards[0]["id"]
|
||||
|
||||
# Get active sprint
|
||||
sprints = get_sprints_from_board(board_id=board_id, states="active")
|
||||
sprint = sprints[0]
|
||||
sprint_id = sprint["id"]
|
||||
sprint_name = sprint["name"]
|
||||
```
|
||||
|
||||
### 2. Get sprint tickets
|
||||
|
||||
```python
|
||||
tickets = get_tickets_from_sprint(
|
||||
sprint_id=sprint_id,
|
||||
fields="project,summary,status,issuetype,assignee,customfield_10001,customfield_10106"
|
||||
)
|
||||
```
|
||||
|
||||
Key fields:
|
||||
- `status` — current ticket status
|
||||
- `assignee` — who's working on it
|
||||
- `issuetype` — Story, Bug, Task
|
||||
- `customfield_10106` — Story Points (if configured)
|
||||
- `customfield_10001` — Feature Link (Epic)
|
||||
|
||||
### 3. Categorize tickets by status
|
||||
|
||||
Group tickets into workflow buckets:
|
||||
|
||||
| Category | Statuses |
|
||||
|----------|----------|
|
||||
| To Do | `Open`, `Backlog`, `To Do` |
|
||||
| In Progress | `In Progress`, `In Development` |
|
||||
| In Review | `In Review`, `Code Review` |
|
||||
| Done | `Done`, `Accepted`, `Closed` |
|
||||
| Blocked | Any ticket with `Blocked` flag or label |
|
||||
|
||||
### 4. Calculate metrics
|
||||
|
||||
```python
|
||||
total = len(tickets)
|
||||
done = len([t for t in tickets if t["status"] in DONE_STATUSES])
|
||||
in_progress = len([t for t in tickets if t["status"] in PROGRESS_STATUSES])
|
||||
todo = len([t for t in tickets if t["status"] in TODO_STATUSES])
|
||||
completion_pct = round(done / total * 100) if total > 0 else 0
|
||||
```
|
||||
|
||||
### 5. Group by assignee
|
||||
|
||||
```python
|
||||
by_assignee = {}
|
||||
for ticket in tickets:
|
||||
assignee = ticket.get("assignee", "Unassigned")
|
||||
by_assignee.setdefault(assignee, []).append(ticket)
|
||||
```
|
||||
|
||||
### 6. Group by Epic/Feature
|
||||
|
||||
```python
|
||||
by_epic = {}
|
||||
for ticket in tickets:
|
||||
epic = ticket.get("customfield_10001", "Kein Epic")
|
||||
by_epic.setdefault(epic, []).append(ticket)
|
||||
```
|
||||
|
||||
### 7. Generate report
|
||||
|
||||
Write `docs/sprint-reports/sprint-<sprint_name>-<date>.md`:
|
||||
|
||||
```markdown
|
||||
# Sprint Report: <sprint_name>
|
||||
|
||||
**Datum:** <today>
|
||||
**Sprint:** <sprint_name>
|
||||
**Zeitraum:** <start_date> — <end_date>
|
||||
**Projekt:** ESIDEPAISY
|
||||
|
||||
---
|
||||
|
||||
## Übersicht
|
||||
|
||||
| Metrik | Wert |
|
||||
|--------|------|
|
||||
| Tickets gesamt | <total> |
|
||||
| Erledigt | <done> (<completion_pct>%) |
|
||||
| In Bearbeitung | <in_progress> |
|
||||
| Offen | <todo> |
|
||||
| In Review | <in_review> |
|
||||
|
||||
## Fortschritt
|
||||
|
||||
```
|
||||
[████████████░░░░░░░░] 60% (<done>/<total>)
|
||||
```
|
||||
|
||||
## Nach Status
|
||||
|
||||
### ✅ Erledigt (<done>)
|
||||
|
||||
| Ticket | Typ | Zusammenfassung | Bearbeiter |
|
||||
|--------|-----|----------------|------------|
|
||||
| <key> | Story | <summary> | <assignee> |
|
||||
|
||||
### 🔄 In Bearbeitung (<in_progress>)
|
||||
|
||||
| Ticket | Typ | Zusammenfassung | Bearbeiter |
|
||||
|--------|-----|----------------|------------|
|
||||
| <key> | Bug | <summary> | <assignee> |
|
||||
|
||||
### ⏳ Offen (<todo>)
|
||||
|
||||
| Ticket | Typ | Zusammenfassung | Bearbeiter |
|
||||
|--------|-----|----------------|------------|
|
||||
| <key> | Task | <summary> | <assignee> |
|
||||
|
||||
## Nach Bearbeiter
|
||||
|
||||
| Bearbeiter | Gesamt | Erledigt | In Bearbeitung | Offen |
|
||||
|-----------|--------|----------|---------------|-------|
|
||||
| <name> | <n> | <done> | <wip> | <todo> |
|
||||
|
||||
## Nach Feature/Epic
|
||||
|
||||
| Epic | Tickets | Erledigt | Fortschritt |
|
||||
|------|---------|----------|-------------|
|
||||
| <epic_name> | <n> | <done> | <pct>% |
|
||||
|
||||
## Blocker / Risiken
|
||||
|
||||
| Ticket | Beschreibung | Seit | Auswirkung |
|
||||
|--------|-------------|------|-----------|
|
||||
| <key> | <blocker description> | <date> | <impact> |
|
||||
|
||||
<If no blockers: "Keine Blocker im aktuellen Sprint.">
|
||||
```
|
||||
|
||||
### 8. Publish to Confluence (optional)
|
||||
|
||||
If `OUTPUT_FORMAT` includes `confluence`:
|
||||
|
||||
```python
|
||||
create_page(
|
||||
space_key="ESIDEPAISY",
|
||||
title=f"Sprint Report: {sprint_name} — {date}",
|
||||
content=<html_converted_content>,
|
||||
parent_id="<sprint-reports-parent-page-id>"
|
||||
)
|
||||
```
|
||||
|
||||
### 9. Send Teams summary (optional)
|
||||
|
||||
If `OUTPUT_FORMAT` includes `teams`:
|
||||
|
||||
```python
|
||||
teams_send_channel_message(
|
||||
team_id="<team_id>",
|
||||
channel_id="<channel_id>",
|
||||
content=f"📊 *Sprint Report: {sprint_name}*\n\n"
|
||||
f"Fortschritt: {done}/{total} ({completion_pct}%)\n"
|
||||
f"In Bearbeitung: {in_progress}\n"
|
||||
f"Offen: {todo}\n"
|
||||
f"Blocker: {blocked}\n\n"
|
||||
f"Vollständiger Bericht: <confluence_link or file path>"
|
||||
)
|
||||
```
|
||||
|
||||
### 10. Store in BigMind
|
||||
|
||||
```python
|
||||
memory_store_fact(
|
||||
category="codebase",
|
||||
fact=f"Sprint report for {sprint_name}: {done}/{total} done ({completion_pct}%), {in_progress} in progress, {blocked} blocked."
|
||||
)
|
||||
```
|
||||
|
||||
## Expected Output
|
||||
|
||||
- Markdown sprint report with ticket breakdown
|
||||
- Metrics: completion %, by-status, by-assignee, by-epic
|
||||
- Blocker/risk section
|
||||
- Optionally published to Confluence and/or Teams
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Error | Resolution |
|
||||
|-------|------------|
|
||||
| No active sprint found | Check `states="active"` — may need `states="active,future"` |
|
||||
| No tickets in sprint | Sprint may be empty or newly created — report "0 tickets" |
|
||||
| Board not found | Verify project key, try `get_agile_boards` with different key |
|
||||
| Story points not configured | Skip story point metrics, use ticket count only |
|
||||
| Confluence publish fails | Save markdown locally, report Confluence error |
|
||||
|
||||
## Report Variants
|
||||
|
||||
| Variant | When | Content |
|
||||
|---------|------|---------|
|
||||
| Daily standup | Mid-sprint | Focus on in-progress + blockers only |
|
||||
| Sprint review | End of sprint | Full report with all sections |
|
||||
| Management summary | On request | Metrics + epic progress only, no ticket details |
|
||||
|
||||
Adjust the template based on the variant requested.
|
||||
|
||||
## Language
|
||||
|
||||
- Report content: **German**
|
||||
- Ticket keys, branch names: English as-is
|
||||
- Teams messages: **German**
|
||||
- Confluence page: **German**
|
||||
Reference in New Issue
Block a user