Module: CollavreLinear::FieldMapper
- Defined in:
- app/services/collavre_linear/field_mapper.rb
Overview
Pure field translation between Collavre Creative attributes and Linear issue attributes. NO I/O — this class never reads from the DB or makes HTTP calls.
priority <-> sequence mapping (locked product decision)
Linear priority is a 5-value enum:
0 = No priority, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low
Collavre sequence is a dense, ZERO-BASED total order of siblings (closure_tree):
core resequencing (CreateService#resequence, Reorderer#resequence!) assigns
each_with_index, so the first sibling is sequence 0. The mapping must honor
that base — otherwise the first (top-ranked) sibling would export as "None".
Inbound (Linear → Collavre): sequence = (priority == 0 ? 4 : priority - 1) Urgent(1) → 0 (first), Low(4) → 3, None(0) → 4 (after all ranked buckets).
Outbound (Collavre → Linear): sequence 0-3 maps to priority 1-4 (0→Urgent); sequence 4 (the "None" sentinel) and nil/unranked → priority 0 (None).
Lossy edge: Linear priority is a 5-bucket enum; Collavre sequence is a dense integer total order. Within-bucket ordering is NOT representable in Linear priority — only the bucket (1-4) is preserved. The Task 10 applier must write the computed sequence via closure_tree's reorder path, not a raw column update, because closure_tree maintains sibling order invariants.
Class Method Summary collapse
-
.creative_to_issue_attrs(creative) ⇒ Hash
Outbound: Creative → Linear issue attributes.
-
.issue_to_creative_attrs(issue_payload) ⇒ Hash
Inbound: Linear issue payload → Collavre creative attributes.
Class Method Details
.creative_to_issue_attrs(creative) ⇒ Hash
Outbound: Creative → Linear issue attributes.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'app/services/collavre_linear/field_mapper.rb', line 37 def creative_to_issue_attrs(creative) attrs = { title: creative.title, description: creative.description, priority: sequence_to_priority(creative.sequence) } linear_data = (creative.data || {})["linear"] || {} if (state = linear_data["state"]) attrs[:state_id] = state["id"] end if (labels = linear_data["labels"]) && labels.any? attrs[:label_ids] = labels.map { |l| l["id"] } end attrs end |
.issue_to_creative_attrs(issue_payload) ⇒ Hash
Inbound: Linear issue payload → Collavre creative attributes.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'app/services/collavre_linear/field_mapper.rb', line 65 def issue_to_creative_attrs(issue_payload) priority = issue_payload["priority"].to_i { title: issue_payload["title"], description: issue_payload["description"], sequence: priority_to_sequence(priority), data_linear: { state: issue_payload["state"], labels: normalize_labels(issue_payload["labels"]), assignee: issue_payload["assignee"] } } end |