baticket
Example output

Example: from rough notes to a Jira-ready ticket

Below is the kind of input a Business Analyst typically has after a short call, and the ticket and specification baticket produces from it. Nothing was tidied up beforehand.

1. The input: raw meeting notes

Shorthand, a missing decision, and a security requirement buried in the middle.

notes.txt
call w/ Marta (product) + Piotr (support), 14.09

- ppl keep forgetting pw, support gets ~40 tickets/week just for resets
- want "forgot password" on login page
- email w/ link, link valid short time (1h? Marta said "an hour is fine")
- don't reveal if email exists!! (security asked for this last audit)
- new pw min 10 chars, same rules as registration
- after reset -> log them in? Piotr: no, send them to login w/ success msg
- rate limit? not discussed

2. The ticket: TICKET_CONTENT.md

Five fixed sections — context, goal, user stories and Given/When/Then acceptance criteria, each scenario in its own block so it pastes cleanly into Jira, Linear or Azure DevOps.

TICKET_CONTENT.md
# [BE/FE] Self-service password reset by email

## 1. 🔵 Business context & user stories
Support handles around 40 password-reset requests a week. Letting users reset
their own password removes that load and unblocks users immediately.

## 2. 🎯 High-level goal
Users who forget their password can set a new one on their own from the login
page, without contacting support. The flow must not reveal whether an email
address has an account. Success means password-reset tickets to support drop
to near zero.

## 3. 👤 User stories
- As a registered user, I want to request a password reset link from the login
  page, so that I can regain access without contacting support.
- As a registered user, I want to set a new password from that link, so that I
  can log in again.
- As a support agent, I want users to reset passwords themselves, so that I can
  focus on real issues.

## 4. 🟩 Acceptance criteria
```
Scenario 1: Request a reset link for an existing account
Given: a registered user on the login page
When: they click "Forgot password?" and submit their email address
Then: the API responds 200
And: an email with a single-use reset link valid for 1 hour is sent
And: the page shows "If an account exists for this email, we've sent a link."
```

```
Scenario 2: Request a reset link for an unknown email
Given: an email address with no account
When: it is submitted on the "Forgot password" form
Then: the API responds 200 with the same body as Scenario 1
And: no email is sent
```

```
Scenario 3: Set a new password
Given: a valid, unused reset link
When: the user submits a new password of at least 10 characters
Then: the password is updated and the link is invalidated
And: the user is redirected to the login page with "Your password has been changed."
```

```
Scenario 4: Expired or used link
Given: a reset link older than 1 hour, or one already used
When: the user opens it
Then: the page shows "This link has expired" with an option to request a new one
```

```
Scenario 5: Unit tests — token handling
Given: the token service
When: a token is created, verified, expired and reused
Then: only an unexpired, unused token verifies successfully
```

## 5. 📄 Full specification
See the accompanying SPECIFICATION.md for full detail.

3. The specification: SPECIFICATION.md (excerpt)

The full detail lives here, including the API contract with validation rules — and the questions the notes left open, instead of guesses.

SPECIFICATION.md
# [BE/FE] Self-service password reset by email

## Scope
- "Forgot password?" link on the login page.
- Request form that emails a single-use reset link valid for 1 hour.
- Reset form that sets a new password using the registration password rules.
- Neutral responses that never reveal whether an account exists.

## API
**Endpoint:** `POST /api/v1/auth/forgot-password`

**Request body (JSON):**
```json
{ "email": "string" }
```

**Validation**

| Field | Rules | Error message |
|---|---|---|
| email | required, email | "Enter a valid email address." |

**Endpoint:** `POST /api/v1/auth/reset-password`

**Request body (JSON):**
```json
{ "token": "string", "password": "string" }
```

| Field | Rules | Error message |
|---|---|---|
| password | required, minLength 10 | "Your password must be at least 10 characters long." |

## Missing / to confirm
- Rate limiting for reset requests was not discussed — confirm limits with security.
- Should existing sessions be signed out after a password change?