Skip to content

feat: first-class callsign, display name, and export name composition #54

Description

@pskillen

Problem

Channels today store a single name (OpenGD77 Channel Name) and a derived callsign (first whitespace-separated token of name). That works for import but does not model the operator's intent:

  • Callsign — e.g. GB7GL (repeater/site id, used for map labels and external lookups)
  • Display name — e.g. Glasgow (human-readable qualifier)

On export to CPS CSV, operators often want a composed wire name such as GB7GL Glasgow, with control over whether/how the callsign is included. This was scoped in #11 and deferred from PR #42; see docs/features/crud/crud-outstanding.md.

Intended outcome

Data model

  • Treat callsign and name (display name) as first-class, independently editable channel fields.
  • Add a per-channel export name mode (working title — refine in UI copy), e.g.:
    • verbatim — export display name only (Glasgow)
    • callsignGB7GL Glasgow (full callsign + space + display name)
    • callsign_suffix — last two letters + display name (GL Glasgow) — common convention
    • omit_callsign — same as verbatim; alias if clearer in UI
  • Compose the OpenGD77 Channel Name on export from callsign + display name according to the selected mode.
  • Respect CPS field length limits when composing (truncate or validate with a clear error — decide during implementation).
  • Bump schema version and document migration (existing codeplugs: keep name as display name, infer callsign best-effort from current name / callsign).
  • While we're here, add a description field (single line) and note (multi line). These will generally be internal to our models but some CPS may support

Import (best effort)

  • On OpenGD77 CSV import, parse Channel Name with a standard callsign regex (UK repeater / amateur allocation patterns).
  • When a callsign prefix is recognised, split into callsign + display name (name).
  • Default export name mode to callsign + display name when a split was inferred; otherwise verbatim.
  • Round-trip: import GB7GL Glasgow → edit display name → export → CPS still gets a valid composed name.

Current helper: extractCallsign() in src/lib/csv.ts (first token only) — replace/extend for regex-based split.

Export

  • OpenGD77 Channels.csv Channel Name column is composed from internal fields + export mode (not a blind copy of name).
  • Zone Channel1Channel80 wire names must use the same composition rules so FK integrity holds.

UI

  • Channel create/edit: separate inputs for callsign and display name. add notes and description fields
  • Export name mode control must make the feature obvious but optional — users who want CPS names verbatim set mode accordingly.
  • Show a live preview of the exported wire name as fields/mode change.
  • Channel detail/list: show both fields; band pills etc. unchanged. add col for description, hideable, default on.

Map

  • CodeplugMap and related helpers currently infer callsign from name (markerLabel, fullChannelName toggle in src/lib/channels.ts).
  • After this change, use channel.callsign directly (no inference from display name).
  • Document map label behaviour in docs/features/map/.

Documentation (deliver with implementation)

Area Path
Display / naming conventions docs/reference/display-conventions.md
Data model docs/features/data-model/README.md + src/models/codeplug.ts
Import split logic docs/features/import/opengd77.md (and/or docs/features/import/)
Export composition docs/features/export/README.md + OpenGD77 export module docs
CRUD / progress docs/features/crud/crud-outstanding.md, crud-progress.md

Acceptance criteria

  • callsign and name (display name) are editable independently in channel CRUD
  • Per-channel export name mode with at least: verbatim, full callsign prefix, last-two-letters prefix
  • Export composes Channel Name and zone member names consistently; respects length limits
  • Import best-effort splits recognised callsign prefixes; sets sensible default export mode
  • Map markers and external links use channel.callsign, not derived-from-name
  • Schema migration for existing localStorage projects
  • Tests for split/compose round-trip and edge cases (no callsign, display name only, long names)
  • Docs updated as listed above

Related

  • Parent context: #11 (CRUD channels — export prefix bullet)
  • Shipped without this: PR #42
  • Data model today: docs/features/data-model/README.md (callsign noted as derived)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions