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-requests returns Ready Image Request issues
  • Form submit: POST /image-requests creates 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:

  1. Loads Stories under the Epic
  2. Sets Customer to 1 if any submitter email domain is in PaidCustomerDomains, otherwise 0
  3. Writes the value to ScoringCustomerField when configured

When subscriber login lands, replace the domain list with real subscription status.

Configure two rules in Jira (Project settings → Automation). Use the real field names/ids from your instance.

  • 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-blocked when Legal is Y
  • Trigger: IR Legal changed
  • Condition: Issue type = Epic AND component = Image Request AND IR Legal is empty OR IR Legal = N
  • Actions:
    1. Clear IR Total (or set to empty)
    2. 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