diff --git a/README.md b/README.md index dc0f590..bc63fc1 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,32 @@ # Ticketr 🎫 -A powerful command-line tool that bridges the gap between local Markdown files and Jira, enabling seamless story and task management with bidirectional synchronization. +Bridge Markdown and Jira. Create, update, and sync tickets from simple `.md` files β€” fast, reliable, and CI/CD‑friendly. + +For developers who prefer editors and pull requests over tab‑heavy UIs: keep your backlog close to your code, reviewable, and scriptable. Tickets as code β€” not clicks. ✨ [![CI](https://github.com/karolswdev/ticketr/actions/workflows/ci.yml/badge.svg)](https://github.com/karolswdev/ticketr/actions/workflows/ci.yml) -[![Go Version](https://img.shields.io/badge/Go-1.24%2B-00ADD8?style=flat&logo=go)](https://go.dev) +[![Go](https://img.shields.io/badge/Go-1.22%2B-00ADD8?logo=go)](https://go.dev) [![PkgGoDev](https://pkg.go.dev/badge/github.com/karolswdev/ticketr)](https://pkg.go.dev/github.com/karolswdev/ticketr) [![Go Report Card](https://goreportcard.com/badge/github.com/karolswdev/ticketr?refresh=1)](https://goreportcard.com/report/github.com/karolswdev/ticketr) -[![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) -[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?style=flat&logo=docker)](Dockerfile) +[![MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) -## ✨ Features +## Why Ticketr -- **πŸ“ Markdown-First Workflow**: Define stories and tasks in simple Markdown files -- **πŸ”„ Bidirectional Sync**: Create new items or update existing ones in Jira -- **🎯 Smart Updates**: Automatically detects and updates only changed items -- **πŸš€ CI/CD Ready**: Built for automation with non-interactive modes -- **🐳 Docker Support**: Lightweight container (~15MB) for consistent execution -- **πŸ”’ Secure**: Environment-based configuration keeps credentials safe -- **πŸ“Š Analytics**: Built-in reporting and progress tracking +- **πŸ“ Markdown‑first**: Keep tickets next to code, review with PRs. +- **πŸ”„ Bidirectional sync**: Push to Jira and pull back safely. +- **🧠 State‑aware**: Skips unchanged, detects conflicts, supports strategies. +- **βš™οΈ CI/CD friendly**: Dry‑run, partial‑upload, clear exit codes. +- **πŸ”” Portable**: Docker image + webhook server for real‑time sync. -## πŸš€ Quick Start +## Install -> **New to Ticketr?** Check out our comprehensive [Getting Started Guide](docs/GETTING_STARTED.md)! +- Using Go: `go install github.com/karolswdev/ticketr/cmd/ticketr@latest` +- From source: `go build -o ticketr cmd/ticketr/main.go` +- Dockerfile provided (see Getting Started for usage). -### Installation +## Configure -#### Using Go -```bash -go install github.com/karolswdev/ticketr/cmd/ticketr@latest -``` - -#### Building from Source -```bash -git clone https://github.com/karolswdev/ticketr.git -cd ticketr -go build -o ticketr cmd/ticketr/main.go -``` - -### Configuration - -Set up your Jira credentials as environment variables: +Set environment variables (or use `.env` β€” see `.env.example`): ```bash export JIRA_URL="https://yourcompany.atlassian.net" @@ -48,518 +35,87 @@ export JIRA_API_KEY="your-api-token" export JIRA_PROJECT_KEY="PROJ" ``` -πŸ’‘ **Tip**: Store these in a `.env` file for convenience (see `.env.example`) - -### Basic Usage - -1. **Create a story file** (`stories.md`): - -```markdown -# STORY: User Authentication System - -## Description -As a developer, I want to implement a secure authentication system -so that users can safely access the application. - -## Acceptance Criteria -- Users can register with email and password -- Passwords are securely hashed -- Session management is implemented - -## Tasks -- Set up authentication database schema -- Implement password hashing service -- Create login/logout endpoints -- Add session middleware -``` - -2. **Sync with Jira**: +Optional: +- `JIRA_STORY_TYPE` (default: `Task`) +- `JIRA_SUBTASK_TYPE` (default: `Sub-task`) -```bash -ticketr -f stories.md -``` +## 30‑Second Example πŸš€ -3. **Result**: Your file is updated with Jira IDs: +Create `tickets.md`: ```markdown -# STORY: [PROJ-123] User Authentication System +# TICKET: Implement User Login ## Description -As a developer, I want to implement a secure authentication system -so that users can safely access the application. +As a user, I want to log into the app so I can access my dashboard. ## Acceptance Criteria -- Users can register with email and password -- Passwords are securely hashed -- Session management is implemented +- Invalid credentials show an error +- Successful login redirects to dashboard ## Tasks -- [PROJ-124] Set up authentication database schema -- [PROJ-125] Implement password hashing service -- [PROJ-126] Create login/logout endpoints -- [PROJ-127] Add session middleware +- Design login form UI +- Implement authentication API ``` -## πŸ“– Advanced Usage - -### Updating Existing Items - -Simply edit your file and run the tool again - it intelligently handles updates: +Custom fields example (optional `## Fields` section): ```markdown -# STORY: [PROJ-123] User Authentication System (Updated) - -## Tasks -- [PROJ-124] Set up authentication database schema βœ… -- [PROJ-125] Implement password hashing service -- Add JWT token generation # New task will be created -``` - -### Command-Line Options - -```bash -# Push tickets to JIRA (with pre-flight validation) -ticketr push stories.md - -# Pull tickets from JIRA to Markdown -ticketr pull --project PROJ --jql "status=Done" -o done_tickets.md - -# Pull tickets from a specific epic -ticketr pull --epic PROJ-100 -o epic_tickets.md - -# Analyze tickets and display statistics -ticketr stats stories.md - -# Verbose output for debugging -ticketr push stories.md --verbose - -# Continue on errors (CI/CD mode) -ticketr push stories.md --force-partial-upload - -# Dry run - validate and preview changes without modifying JIRA -ticketr push stories.md --dry-run - -# Discover JIRA schema and generate configuration -ticketr schema > .ticketr.yaml - -# Legacy mode (backward compatibility) -ticketr -f stories.md -v --force-partial-upload -``` - -### Push Command - -The `ticketr push` command synchronizes your local Markdown tickets with JIRA: - -**Options:** -- `--dry-run` - Validate tickets and show what would be done without making any changes to JIRA -- `--force-partial-upload` - Continue processing even if some tickets fail (useful for CI/CD) -- `--verbose` or `-v` - Enable detailed logging output - -**Note**: Ticketr validates your file for correctness before sending any data to Jira, preventing partial failures. Validation includes: -- Hierarchical rules (e.g., Sub-tasks cannot be children of Epics) -- Required fields validation -- Format validation (only `# TICKET:` format is supported, legacy `# STORY:` format is rejected) - -### Pull Command - -The `ticketr pull` command fetches tickets from JIRA and intelligently merges them with your local file: - -```bash -# Pull all tickets from a project -ticketr pull --project PROJ - -# Pull tickets using JQL query -ticketr pull --jql "status IN ('In Progress', 'Done')" - -# Pull tickets from a specific epic -ticketr pull --epic PROJ-100 --output sprint_23.md - -# Combine filters -ticketr pull --project PROJ --jql "assignee=currentUser()" -o my_tickets.md -``` - -**Pull Command Options:** -- `--project` - JIRA project key to pull from (uses JIRA_PROJECT_KEY env var if not specified) -- `--epic` - Filter tickets by epic key -- `--jql` - Custom JQL query for filtering -- `-o, --output` - Output file path (default: pulled_tickets.md) - -**Conflict Detection:** - -The pull command now features intelligent conflict detection: -- **Safe Merge**: Automatically updates tickets that have only changed remotely -- **Conflict Detection**: Identifies when both local and remote versions have changed -- **Local Preservation**: Keeps local changes when only local has been modified -- **State Tracking**: Uses `.ticketr.state` to track both local and remote changes - -When conflicts are detected, you can resolve them using strategies: +## Fields +Story Points: 5 +Priority: High +Labels: auth, backend ``` -⚠️ Conflict detected! The following tickets have both local and remote changes: - - TICKET-123 - - TICKET-456 -To resolve conflicts, use --strategy flag with one of: - --strategy=local-wins Keep local changes - --strategy=remote-wins Use remote changes -``` +Push to Jira and update the file with IDs: -Example usage: ```bash -# Keep local changes when conflicts occur -ticketr pull --project PROJ --strategy=local-wins - -# Use remote changes when conflicts occur -ticketr pull --project PROJ --strategy=remote-wins +ticketr push tickets.md ``` -### Analytics and Reporting - -The `ticketr stats` command provides detailed analytics about your tickets: - -```bash -# Analyze tickets in a file -ticketr stats stories.md - -# Example output: -╔══════════════════════════════════════╗ -β•‘ TICKET ANALYTICS REPORT β•‘ -β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• - -πŸ“Š Overall Statistics -──────────────────── - Total Tickets: 10 - Total Tasks: 25 - Total Story Points: 42.5 - Acceptance Criteria: 35 - -πŸ”„ JIRA Synchronization -──────────────────── - Tickets Synced: 8/10 (80%) - Tasks Synced: 20/25 (80%) - -πŸ“‹ Tickets by Type -──────────────────── - Story: β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 5 - Bug: β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 2 - Feature: β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 2 - Epic: β–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 1 - -πŸ“ˆ Tickets by Status -──────────────────── - Done: β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 4 - In Progress: β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 3 - To Do: β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 3 - -🎯 Progress Summary -──────────────────── - Overall Completion: 48% - Items Completed: 12/35 -``` - -The stats command helps you: -- Track overall project progress -- Monitor JIRA synchronization status -- Visualize work distribution by type and status -- Identify bottlenecks and areas needing attention - -### Real-time Webhook Synchronization - -The `ticketr listen` command starts a webhook server for automatic, real-time synchronization: +Pull updates from Jira (safe merge, conflict strategies): ```bash -# Start webhook server with default settings -ticketr listen - -# Custom port and file -ticketr listen --port 3000 --path project-tickets.md - -# With webhook signature validation (recommended) -ticketr listen --secret "your-webhook-secret" +ticketr pull --project PROJ -o pulled.md +# or: ticketr pull --jql "assignee=currentUser()" --strategy=local-wins ``` -This enables instant updates to your local Markdown files whenever tickets change in JIRA. See the [Webhook Configuration Guide](docs/WEBHOOKS.md) for detailed setup instructions including: -- JIRA webhook configuration steps -- Security best practices -- Production deployment options -- Troubleshooting guide - -### Schema Discovery - -The `ticketr schema` command helps you discover available fields in your JIRA instance and generate a proper configuration file: +Quick stats πŸ“Š: ```bash -# Discover fields and generate configuration -ticketr schema > .ticketr.yaml - -# View available fields with verbose output -ticketr schema -v - -# The command will output field mappings like: -# field_mappings: -# "Story Points": -# id: "customfield_10010" -# type: "number" -# "Sprint": "customfield_10020" -# "Epic Link": "customfield_10014" +ticketr stats tickets.md ``` -This is especially useful when working with custom fields that vary between JIRA instances. - -### State Management - -Ticketr maintains a `.ticketr.state` file to track content hashes and support intelligent sync flows (e.g., conflict detection on pull): - -```bash -# The .ticketr.state file is created/updated as you sync -# It stores SHA256 hashes to detect local vs remote changes - -# Pull uses state to detect and resolve conflicts -ticketr pull --strategy=local-wins -``` - -Push is now state-aware by default. The CLI uses the `PushService` so unchanged tickets are skipped. In `--dry-run` mode, Ticketr shows all intended operations without writing to JIRA or the file/state. - -The `.ticketr.state` file is environment-specific and ignored by default via `.gitignore`. - -### Docker Usage - -Build and run using Docker: - -```bash -# Build the Docker image -docker build -t ticketr . - -# Run with Docker -docker run --rm \ - -e JIRA_URL="$JIRA_URL" \ - -e JIRA_EMAIL="$JIRA_EMAIL" \ - -e JIRA_API_KEY="$JIRA_API_KEY" \ - -e JIRA_PROJECT_KEY="$JIRA_PROJECT_KEY" \ - -v $(pwd)/stories.md:/data/stories.md \ - ticketr -f /data/stories.md - -# Or use Docker Compose (reads .env automatically) -docker-compose run --rm ticketr -``` - -## πŸ“‹ Story Templates - -### Epic Template -```markdown -# STORY: [Epic] Cloud Migration Initiative - -## Description -Migrate all services to cloud infrastructure for improved scalability and reliability. - -## Acceptance Criteria -- All services running in cloud -- Zero data loss during migration -- Downtime < 1 hour - -## Tasks -- Audit current infrastructure -- Design cloud architecture -- Set up cloud environments -- Migrate databases -- Migrate services -- Update DNS and routing -``` - -### Bug Report Template -```markdown -# STORY: [Bug] Login fails with special characters - -## Description -Users cannot login when password contains special characters like & or %. - -## Acceptance Criteria -- All special characters work in passwords -- Existing users can still login -- No security vulnerabilities introduced - -## Tasks -- Reproduce the issue -- Fix password encoding -- Add comprehensive tests -- Update documentation -``` - -### Feature Template -```markdown -# STORY: Dark Mode Support - -## Description -As a user, I want to switch between light and dark themes -so that I can use the app comfortably in different lighting conditions. - -## Acceptance Criteria -- Toggle switch in settings -- Theme preference persisted -- All UI elements properly themed - -## Tasks -- Design dark color palette -- Implement theme context -- Update all components -- Add theme toggle to settings -- Test across all pages -``` - -## πŸ”„ Workflow Examples - -### Sprint Planning Workflow - -1. **Create sprint backlog** in Markdown: -```bash -vim sprint-23.md # Define all stories for the sprint -``` - -2. **Review with team** (stories still in Markdown) - -3. **Push to Jira** when approved: -```bash -ticketr -f sprint-23.md -``` - -4. **Track progress** by updating the file: -```markdown -## Tasks -- [PROJ-124] Database setup βœ… DONE -- [PROJ-125] API implementation 🚧 IN PROGRESS -- [PROJ-126] Frontend integration -``` - -### CI/CD Integration - -#### Using the Official GitHub Action (Recommended) - -```yaml -# .github/workflows/jira-sync.yml -name: Sync Stories to Jira -on: - push: - paths: - - 'stories/*.md' - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-go@v4 - with: - go-version: '1.22' - - - name: Sync to JIRA - uses: ./.github/actions/ticketr-sync - with: - jira-url: ${{ secrets.JIRA_URL }} - jira-email: ${{ secrets.JIRA_EMAIL }} - jira-api-key: ${{ secrets.JIRA_API_KEY }} - jira-project-key: ${{ secrets.JIRA_PROJECT_KEY }} - command: 'push' - file-path: 'stories/backlog.md' - verbose: 'true' - - - name: Commit updates - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git add stories/backlog.md .ticketr.state || true - git diff --staged --quiet || git commit -m "Update JIRA IDs [skip ci]" - git push -``` - -#### Using Docker (Alternative) - -```yaml -jobs: - sync: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Sync to Jira - run: | - docker run --rm \ - -e JIRA_URL=${{ secrets.JIRA_URL }} \ - -e JIRA_EMAIL=${{ secrets.JIRA_EMAIL }} \ - -e JIRA_API_KEY=${{ secrets.JIRA_API_KEY }} \ - -e JIRA_PROJECT_KEY=${{ secrets.JIRA_PROJECT_KEY }} \ - -v ${{ github.workspace }}:/data \ - ticketr \ - push /data/stories/backlog.md \ - --force-partial-upload -``` - -## πŸ—οΈ Architecture - -Ticketr follows a clean architecture pattern: - -``` -ticketr/ -β”œβ”€β”€ cmd/ticketr/ # CLI entry point -β”œβ”€β”€ internal/ -β”‚ β”œβ”€β”€ core/ # Business logic -β”‚ β”‚ β”œβ”€β”€ domain/ # Domain models -β”‚ β”‚ β”œβ”€β”€ ports/ # Interface definitions -β”‚ β”‚ └── services/ # Core services -β”‚ └── adapters/ # External integrations -β”‚ β”œβ”€β”€ cli/ # Command-line interface -β”‚ β”œβ”€β”€ filesystem/ # File I/O operations -β”‚ └── jira/ # Jira API client -``` - -## 🀝 Contributing - -We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md). - -### Development Setup - -```bash -# Clone the repository -git clone https://github.com/karolswdev/ticketr.git -cd ticketr - -# Install dependencies -go mod download - -# Run tests -go test ./... - -# Build -go build -o ticketr cmd/ticketr/main.go -``` - -## πŸ“š Documentation - -- **[Getting Started Guide](docs/GETTING_STARTED.md)** - Step-by-step tutorial for new users -- **[Architecture Guide](docs/ARCHITECTURE.md)** - System design and component overview -- **[Development Guide](docs/DEVELOPMENT.md)** - Local setup, testing, and debugging -- **[Webhook Configuration](docs/WEBHOOKS.md)** - Real-time sync with JIRA webhooks -- **[Contributing Guide](CONTRIBUTING.md)** - How to contribute to the project -- **[API Documentation](https://pkg.go.dev/github.com/karolswdev/ticketr)** - Go package documentation - -## πŸ“„ License +## Usage πŸ“Œ -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. +- `push `: Validate, create/update in Jira, write IDs back. +- `pull [--project|--jql|--epic] [-o file] [--strategy=local-wins|remote-wins]`. +- `schema`: Discover fields; generate `.ticketr.yaml` template. +- `listen [--port 8080] [--path tickets.md] [--secret ...]`: Webhook server. +- `stats `: Simple analytics. -## πŸ†˜ Support +Format: Use `# TICKET:` headings in Markdown files. -- πŸ“– [Getting Started](docs/GETTING_STARTED.md) -- πŸ› [Issue Tracker](https://github.com/karolswdev/ticketr/issues) -- πŸ’¬ [Discussions](https://github.com/karolswdev/ticketr/discussions) -- πŸ” [Security](SECURITY.md) +## Documentation πŸ“š +- Getting Started: [docs/GETTING_STARTED.md](docs/GETTING_STARTED.md) +- Architecture: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) +- Webhooks: [docs/WEBHOOKS.md](docs/WEBHOOKS.md) +- Development: [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) +- CLI Reference: [docs/CLI.md](docs/CLI.md) +- Examples: [examples/](examples/) + - Rich custom fields example: [examples/tickets_with_custom_fields.md](examples/tickets_with_custom_fields.md) + - Sample state file: [examples/ticketr_state.example.json](examples/ticketr_state.example.json) +- Roadmap: [ROADMAP.md](ROADMAP.md) +- Contributing: [CONTRIBUTING.md](CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) +- Security: [SECURITY.md](SECURITY.md) +- Support: [SUPPORT.md](SUPPORT.md) -## πŸ™ Acknowledgments +## License -Built with ❀️ using: -- [Go](https://golang.org/) - The programming language -- [Jira REST API](https://developer.atlassian.com/cloud/jira/platform/rest/v2/) - Atlassian's API -- [Alpine Linux](https://alpinelinux.org/) - Container base image +MIT β€” see [LICENSE](LICENSE). ---- +## Community -**Happy Planning!** πŸš€ +- Issues: https://github.com/karolswdev/ticketr/issues +- Discussions: https://github.com/karolswdev/ticketr/discussions diff --git a/docs/CLI.md b/docs/CLI.md new file mode 100644 index 0000000..6362314 --- /dev/null +++ b/docs/CLI.md @@ -0,0 +1,119 @@ +# Ticketr CLI Reference + +Concise reference for commands, flags, and common examples. + +## Global + +- `-v, --verbose`: Enable detailed logs +- `--config `: Use an alternate `.ticketr.yaml` + +Environment (typical): `JIRA_URL`, `JIRA_EMAIL`, `JIRA_API_KEY`, `JIRA_PROJECT_KEY`, optional `JIRA_STORY_TYPE`, `JIRA_SUBTASK_TYPE`. + +## push + +Validate Markdown, create/update in Jira, and write IDs back to the file. + +Usage: +``` +ticketr push +``` + +Flags: +- `--dry-run`: Validate and print intended actions (no writes) +- `--force-partial-upload`: Continue after errors (good for CI) + +Example: +``` +ticketr push tickets.md -v --dry-run +``` + +## pull + +Fetch from Jira and merge into Markdown with conflict strategies. + +Usage: +``` +ticketr pull [flags] +``` + +Flags: +- `--project `: Project key (falls back to `JIRA_PROJECT_KEY`) +- `--jql `: Extra JQL to filter +- `--epic `: Filter by epic +- `-o, --output `: Output file (default `pulled_tickets.md`) +- `--strategy `: `local-wins` | `remote-wins` + +Examples: +``` +ticketr pull --project PROJ -o backlog.md +ticketr pull --jql "assignee=currentUser() AND sprint in openSprints()" --strategy=local-wins +``` + +## stats + +Analyze a Markdown file and print a simple report. + +Usage: +``` +ticketr stats +``` + +Example: +``` +ticketr stats tickets.md +``` + +## schema + +Discover available fields and output a `.ticketr.yaml` template. + +Usage: +``` +ticketr schema > .ticketr.yaml +``` + +Example: +``` +ticketr schema -v +``` + +## listen + +Start a lightweight webhook server for near‑real‑time sync. + +Usage: +``` +ticketr listen [flags] +``` + +Flags: +- `--port `: Port to listen on (default `8080`) +- `--path `: Markdown file to update +- `--secret `: Webhook signature secret (recommended) + +Examples: +``` +ticketr listen +ticketr listen --port 3000 --path project.md --secret "$WEBHOOK_SECRET" +``` + +## Markdown Format + +- Use `# TICKET: ` (IDs auto‑inserted as `# TICKET: [PROJ-123] <title>`) +- Optional sections: `## Description`, `## Fields`, `## Acceptance Criteria`, `## Tasks` +- Tasks use `- <title>` or `- [PROJ-456] <title>` with optional nested sections + +## State and Conflicts + +Ticketr maintains a JSON state file (default: `.ticketr.state`) mapping Jira IDs to local/remote hashes to detect changes and conflicts. + +Example: [examples/ticketr_state.example.json](../examples/ticketr_state.example.json) + +Conflict strategies when pulling: + +``` +ticketr pull --project PROJ --strategy=local-wins # keep local changes +ticketr pull --project PROJ --strategy=remote-wins # take remote changes +``` + +See a richer Markdown example with custom fields: [examples/tickets_with_custom_fields.md](../examples/tickets_with_custom_fields.md) diff --git a/examples/ticketr_state.example.json b/examples/ticketr_state.example.json new file mode 100644 index 0000000..cd52553 --- /dev/null +++ b/examples/ticketr_state.example.json @@ -0,0 +1,10 @@ +{ + "PROJ-123": { + "local_hash": "3f43f9d6f9b2a7a2e0a0f5f2b7c4e8d1e2f3a4b5c6d7e8f90123456789abcdef", + "remote_hash": "3f43f9d6f9b2a7a2e0a0f5f2b7c4e8d1e2f3a4b5c6d7e8f90123456789abcdef" + }, + "PROJ-124": { + "local_hash": "9f1c2b3a4d5e6f708192a3b4c5d6e7f80123456789abcdef0123456789abcdea", + "remote_hash": "8e1c2b3a4d5e6f708192a3b4c5d6e7f80123456789abcdef0123456789abcd11" + } +} diff --git a/examples/tickets_with_custom_fields.md b/examples/tickets_with_custom_fields.md new file mode 100644 index 0000000..4ed576f --- /dev/null +++ b/examples/tickets_with_custom_fields.md @@ -0,0 +1,40 @@ +# TICKET: Implement User Login + +## Description +As a user, I want to log into the app so I can access my dashboard. + +## Fields +Story Points: 5 +Priority: High +Labels: auth, backend +Components: Authentication, Web +Sprint: Sprint 24 + +## Acceptance Criteria +- Invalid credentials show an error +- Successful login redirects to dashboard +- Session persists for 24 hours + +## Tasks +- Design login form UI + ## Description + Create accessible form with client-side validation. + + ## Fields + Labels: frontend, ui + + ## Acceptance Criteria + - Meets WCAG AA + - Handles keyboard navigation + +- Implement authentication API + ## Description + API endpoint for login backed by secure password hashing. + + ## Fields + Labels: api, backend + Priority: Highest + + ## Acceptance Criteria + - Rate limited + - Returns meaningful error codes