Jira Image Requests
AWS Lambda proxy that serves Hummingbird Image Request issues from Jira (with DynamoDB caching) and creates Stories/Epics from the catalog request form.
Features
- Public list: GET
/image-requestsreturns Ready Image Request issues - Form submit: POST
/image-requestscreates a version Story under a per-image Epic - Customer scoring: Writes the Customer criterion on the Epic from paid email domains (placeholder until subscriber login)
- Total scoring: Maintained by Jira Automation from manual triage fields
Prerequisites
- AWS CLI with permissions for Lambda, API Gateway, DynamoDB, SSM, CloudFormation
- Podman or Docker for SAM build
- Jira bot token in SSM (SecureString)
- HUM project custom fields for scoring (see below)
Deployment
make jira-image-requests/build
make jira-image-requests/deploy
Configuration
| Parameter / env | Description |
|---|---|
ResourcePrefix |
Prefix for AWS resource names |
JiraTokenParameter |
SSM parameter name for the Jira API token |
CacheTtlSeconds |
Cache TTL for the public list (default 300) |
CorsAllowOrigin |
Allowed CORS origin |
ScoringCustomerField |
Jira custom field id for Customer (customfield_…); empty skips write |
PaidCustomerDomains |
Comma-separated email domains scored as paid (e.g. acme.com,contoso.com) |
SentryDsn |
Optional Sentry DSN |
AlertTopicArn |
Optional SNS topic for Lambda error alarms |
Image request scoring
Triage scores live on the Image Request Epic, not on customer-facing Stories.
Custom fields (HUM Epics)
Create (or map) these fields, then record each customfield_XXXXX id:
| Field | Type / values | Who sets it |
|---|---|---|
| IR Legal | Select: Y / N | Manual |
| IR Competitive | Number (typically 0–1) | Manual |
| IR Marketable | Number | Manual |
| IR Supportability | Number | Manual |
| IR Upstream Health | Number | Manual |
| IR Level of Effort | Number: 3 easy, 2 medium, 1 hard | Manual |
| IR Technical Feasibility | Number: 0 blocking, 1 feasible | Manual |
| IR Portfolio Conflicts | Number: 0 conflict, 1 good | Manual |
| IR Customer | Number: 0 or 1 | Lambda (ScoringCustomerField) |
| IR Total | Number | Jira Automation only |
Gate: Legal must be Y to continue scoring. Competitive, Marketable, and Supportability / Maturity are also expected to be 1 before a meaningful Total (team convention from the triage spreadsheet).
Lambda: Customer criterion
On each successful POST (Story create), the Lambda:
- Loads Stories under the Epic
- Sets Customer to 1 if any submitter email domain is in
PaidCustomerDomains, otherwise 0 - Writes the value to
ScoringCustomerFieldwhen configured
When subscriber login lands, replace the domain list with real subscription status.
Jira Automation: Total and Legal flag
Configure two rules in Jira (Project settings → Automation). Use the real field names/ids from your instance.
Rule 1 — Sum Total when Legal is Y
- Trigger: Field value changed for any of: Competitive, Marketable, Supportability, Upstream Health, Level of Effort, Technical Feasibility, Portfolio Conflicts, Customer (and optionally Legal)
- Condition: Issue type = Epic AND component = Image Request AND IR Legal = Y
- Action: Edit issue → set IR Total to the sum of the numeric criteria (exclude Legal). Example smart value shape:
{{#=}}
{{issue.IR Competitive}} + {{issue.IR Marketable}} + {{issue.IR Supportability}} +
{{issue.IR Upstream Health}} + {{issue.IR Level of Effort}} +
{{issue.IR Technical Feasibility}} + {{issue.IR Portfolio Conflicts}} +
{{issue.IR Customer}}
{{/}}
Use your instance’s smart-value field keys (often customfield_XXXXX).
- Optional action: Remove label
ir-legal-blockedwhen Legal is Y
Rule 2 — Flag when Legal is not Y
- Trigger: IR Legal changed
- Condition: Issue type = Epic AND component = Image Request AND IR Legal is empty OR IR Legal = N
- Actions:
- Clear IR Total (or set to empty)
- Add label
ir-legal-blocked
Jira Automation recalculates Total whenever triage fields change — no webhook or Lambda rescoring path is required.
Development
make jira-image-requests/setup
make test
License
GPL-3.0-or-later