Skip to content

Goal

Add three new printing format options that were deferred during #650 — Update Names to Match Latest Platform Tab. These require new Kotlin enum values in CardSize and LabelSize, protobuf message mappings, and template configuration updates.

  • Template: 68791aae43e038a3d3ddf8af
  • Columns: 1
  • Description: 3x1 (Label Printer)
  • Requires: Adding X_SMALL to the LabelSize enum, protobuf mapping in ItemCsvUploadService, and database schema compatibility (enumerationByName columns).
  • Template: 68e84551bde271e6a116e94f
  • Columns: 1
  • Description: Quarter-Index
  • Requires: Adding X_SMALL to the CardSize enum, protobuf mapping in ItemCsvUploadService, and database schema compatibility.
  • Template: 690a35cc4d1069adadcc052c
  • Columns: 1
  • Description: 3 x 5 - Large QR Code
  • Requires: Deciding on the backend key name (e.g., LARGE_QR), adding it to the CardSize enum, and determining whether this is a size variant or a separate concept.

The goal of this project is to:

  1. Add additional printing format options to the back-end component (operations)
  2. Create a detailed specification and acceptance criteria for the front-end to enable the additional format options and create a Github ticket in the management repository with that information, assigned to the user danmerb (using the /gh-ticket skill). the arda-frontend-app repository can be consulted for this project but should not be modified as part of this project.

Each printing type (card, label, breadcrumb) has a corresponding Kotlin enum with four sizes and a parallel protobuf enum used for CSV upload ingestion.

Domain enums (Printing.kt): CardSize, LabelSize, and BreadcrumbSize — each with SMALL, MEDIUM, LARGE, X_LARGE.

Protobuf enums (item_row.proto): mirror the domain enums with a prefix and an UNSPECIFIED default (e.g., CARD_SIZE_SMALL = 1CARD_SIZE_EXTRA_LARGE = 4).

Protobuf → domain mapping (ItemCsvUploadService.kt): extension functions (CardSizeMessage.domain(), etc.) map each protobuf value to its domain counterpart; UNSPECIFIED defaults to MEDIUM.

Template configuration (pdf-templates.json): maps each {type}/{size} to a Documint template ID, column count, description, and default flag. Current entries:

TypeSizeDescriptionColumnsDefaultTemplate ID
labelSMALLQuarter-Index16841c1d253cae4c4b60dc90c
labelMEDIUMHalf-Index168ad11a2d1a29a9243cccb20
labelLARGE3x2 (Label Printer)1694c089357f8c05f7a9ceeec
labelX_LARGEBusiness Card Stock267ad0901dfb47a918976c164
breadcrumbSMALL3 x 1 (Label Printer)1695eb8be226280f110894177
breadcrumbMEDIUM3 x 2 (Label Printer)1695ebd2f226280f11089519f
breadcrumbLARGEBusiness Card Stock167af0a90a2ad294979b80133
breadcrumbX_LARGEHalf-Index167af0d4ca2ad294979b81954
cardSMALLHalf-Index1696087827ad281e7bbdc9348
cardMEDIUMBusiness Card Stock267ab48cbdfb47a918969cdc1
cardLARGE3 x 5168a8d1d5027704369e07e839
cardX_LARGE4 x 6168e8320abde271e6a116ce8d

Template resolution (PrintTemplates): looks up the requested size in the map; falls back to MEDIUM if the size key is missing.

The frontend defines TypeScript union types (CardSize, LabelSize, BreadcrumbSize) with the same four values and maps them to display labels in constants.ts. Notably, the three new options are already present but commented out:

// cardSizeOptions
/{ value: 'X-SMALL', label: 'Quarter-Index' }, // ← deferred
/{ value: 'LARGE+QR', label: '3 x 5 - Large QR Code' }, // ← deferred
// labelSizeOptions
/{ value: 'X-SMALL', label: '3x1 (Label Printer)' }, // ← deferred

The UI exposes size selection via dropdowns in ItemFormPanel.tsx and editable AG Grid columns in ItemTableAGGrid.tsx. Print actions proxy through Next.js API routes to backend endpoints (/v1/kanban/kanban-card/print-card, /v1/item/item/print-label, /v1/item/item/print-breadcrumb), which return a Documint PDF URL opened in a new browser tab.

Size mappers in ardaMappers.ts convert API response strings to the frontend union types.

  • REQ-EPO-001: CardSize, LabelSize, and BreadcrumbSize domain enums must each include X_SMALL, SMALL, MEDIUM, LARGE, X_LARGE, and SPECIAL_01 through SPECIAL_10 (15 values total).
  • REQ-EPO-002: Protobuf enums must mirror the domain enums with a type prefix and an UNSPECIFIED = 0 default value. New field numbers must be appended after existing values to maintain wire compatibility.
  • REQ-EPO-003: X_SMALL maps to the template configuration defined in the spreadsheet for each category.
  • REQ-EPO-004: LARGE+QR (from the original spreadsheet) maps to SPECIAL_01 for Card.
  • REQ-EPO-005: All other SPECIAL_NN values map to the default template configuration for their category.
  • REQ-EPO-006: pdf-templates.json must contain a template entry for every enum value in every category (45 entries total: 15 per category).
  • REQ-EPO-007: Each template entry must include template (Documint ID), columns, description, default (boolean), and active (boolean).
  • REQ-EPO-008: Template resolution must fall back to MEDIUM when the requested size is missing. The active flag must not affect backend template resolution.
  • REQ-EPO-009: Protobuf-to-domain mapping functions must handle all new protobuf values. UNSPECIFIED must continue to default to MEDIUM.
  • REQ-EPO-010: CSV upload must accept the Size of Template display names from the spreadsheet as aliases for enum values (e.g., “Quarter-Index” → X_SMALL for Card).
  • REQ-EPO-011: Existing database rows with SMALL, MEDIUM, LARGE, or X_LARGE must continue to deserialize correctly via enumerationByName without schema migration.
  • REQ-EPO-012: A new versioned sheet Documint Template Mapping (YYYYMMDD) must be created with all existing rows plus SPECIAL_01 through SPECIAL_10 for each category, an Active boolean column, and a Notes column.
  • REQ-EPO-013: The LARGE+QR row must not appear in the new sheet; its values are carried into SPECIAL_01 for Card.
  • REQ-EPO-014: cardSizeOptions, labelSizeOptions, and breadcrumbSizeOptions must include all enum values with display names from the spreadsheet. Non-compliant values (e.g., X-SMALL hyphenated) must be reconciled to underscore form (X_SMALL).
  • REQ-EPO-015: Each size option must include an enabled property sourced from the spreadsheet Active column. Only enabled options are selectable in the UI; disabled options are visible but not selectable.
  • REQ-EPO-016: Size selection must be encapsulated in a reusable React component following the UX Component Guidelines. The array of size options is determined at design time; specific mappings at mount time.

To support the requirements above, the system will implement:

Additional Printing Format Options (REQ-EPO-001, REQ-EPO-002)

Section titled “Additional Printing Format Options (REQ-EPO-001, REQ-EPO-002)”

Each of Card, Label and Breadcrumb will add:

  • X_SMALL
  • SPECIAL_01 through SPECIAL_10

Value Mapping (REQ-EPO-003, REQ-EPO-004, REQ-EPO-005)

Section titled “Value Mapping (REQ-EPO-003, REQ-EPO-004, REQ-EPO-005)”
  1. X_SMALL will follow the mapping in the spreadsheet.
  2. LARGE+QR will map to SPECIAL_01 for Card
  3. All other values for SPECIAL_** will be mapped to the Default value in the spreadsheet.

Changes to the Spreadsheet (REQ-EPO-012, REQ-EPO-013)

Section titled “Changes to the Spreadsheet (REQ-EPO-012, REQ-EPO-013)”

The spreadsheet will be updated to add a new Sheet called Documint Template Mapping (YYYYMMDD) with YYYYMMDD the date in which the spreadsheet is updated. The new sheet will be a copy of the Documint Template Mapping (20260129) sheet with the following changes:

  1. Add the new Values of SPECIAL_01 through SPECIAL_10 to each category (card, breadcrumb, label).
  2. The LARGE+QR row will be removed once its values are copied into the SPECIAL_01 row for the card.
  3. The other values for SPECIAL_NN will be copied from the corresponding Default row for each category.
  4. An additional column called Active with type Boolean will be added to the spreadsheet. Current Rows (X_SMALL through X_LARGE for all categories plus SPECIAL_01 for card) should be true the rest should be false.

Backend Changes (REQ-EPO-006 through REQ-EPO-011)

Section titled “Backend Changes (REQ-EPO-006 through REQ-EPO-011)”
  • Extend the Enum to all values.
  • Update the Protobuf mapping to all values.
  • Update the Template mapping to all values and populate them from the spreadsheet. Include the Active flag in the template configuration to keep backend data complete for future use.
  • The CSV upload should accept the new values and also provide aliases based on the Size of Template column in the spreadsheet.
  • Verify that existing items with SMALL/MEDIUM/LARGE/X_LARGE continue to deserialize correctly (enumerationByName stores string names, so no schema migration is expected — confirm at implementation time).

Frontend Changes (REQ-EPO-014, REQ-EPO-015, REQ-EPO-016)

Section titled “Frontend Changes (REQ-EPO-014, REQ-EPO-015, REQ-EPO-016)”
  • Extend the cardSizeOptions with all values from this specification. Reconcile non-compliant values (i.e. X-SMALL). Update it with information from the spreadsheet.
  • Add an enabled property to each of the options with the values from the spreadsheet.
  • Wherever possible, encapsulate all the behavior of the options in a single React Component following the UX Component Guidelines. The Array of size options should be determined at design time, the specific mappings of each option should be determined at mount time.
  1. New sheet Documint Template Mapping (YYYYMMDD) created with X_SMALL and SPECIAL_01 through SPECIAL_10 rows for each category.
  2. LARGE+QR values copied into SPECIAL_01 for card; original LARGE+QR row removed.
  3. Remaining SPECIAL_NN rows populated with default template values for their category.
  4. Active boolean column added; true for X_SMALL through X_LARGE (all categories) and SPECIAL_01 (card only); false for all other SPECIAL_NN rows.
  1. X_SMALL and SPECIAL_01 through SPECIAL_10 added to CardSize, LabelSize, and BreadcrumbSize domain enums in Printing.kt.
  2. Corresponding protobuf enum values added to item_row.proto with sequential field numbers.
  3. Protobuf → domain mapping functions in ItemCsvUploadService.kt updated for all new values.
  4. CSV upload accepts aliases based on the Size of Template column from the spreadsheet.
  5. pdf-templates.json updated with all new entries, template IDs, column counts, and active flag matching the spreadsheet.
  6. PrintTemplates fallback behavior unchanged — missing/unrecognized sizes still default to MEDIUM. The active flag is stored in configuration for future use but does not affect backend template resolution.
  7. Existing items with SMALL/MEDIUM/LARGE/X_LARGE continue to deserialize and print correctly.
  8. make clean build passes with no test failures.
  9. Code coverage meets or exceeds the targets configured in the Gradle build scripts.
  10. CHANGELOG updated.

Frontend (specification for arda-frontend-app — delivered as a GitHub ticket)

Section titled “Frontend (specification for arda-frontend-app — delivered as a GitHub ticket)”
  1. cardSizeOptions, labelSizeOptions, and breadcrumbSizeOptions extended with all new values; X-SMALL (hyphenated) reconciled to X_SMALL.
  2. Each size option includes an enabled property sourced from the spreadsheet Active column. The frontend uses this as the filter for selectable options (backend serves all templates regardless of active status).
  3. Size selection UI encapsulated in a reusable React component following the UX Component Guidelines.
  4. Only enabled options are selectable in dropdowns; disabled options are visible but not selectable.
  5. Code coverage meets or exceeds the targets configured in the npm build scripts.
  6. GitHub ticket created in Arda-cards/management, assigned to danmerb, with full specification and acceptance criteria.
  1. An item with cardSize = X_SMALL prints a PDF using the Quarter-Index template (68e84551bde271e6a116e94f).
  2. An item with labelSize = X_SMALL prints a PDF using the 3x1 Label Printer template (68791aae43e038a3d3ddf8af).
  3. An item with cardSize = SPECIAL_01 prints a PDF using the 3 x 5 - Large QR Code template (690a35cc4d1069adadcc052c).
  4. CSV upload with X_SMALL and SPECIAL_01 values (and their aliases) ingests correctly and maps to the expected domain values.