army_units

Unit rows belonging to a specific army list
SQL Army System Transactional
army_units

Purpose

Stores the actual units inside an army list. These are user- or import-created unit rows and may either link to a canonical master unit in units or exist as legacy/free-text rows without a valid master unit link.

Role in the system

units (canonical)
   ↑
army_units
   ↑
army_lists

This table is where army construction becomes gameplay-ready. It holds points, flags, notes, quantity, and ordering for units that will later be used in games, previews, imports, and scoring flows.

Columns

Column Type Null Notes
idbigint unsignedNoPrimary key
army_list_idbigint unsignedNoParent army
master_unit_idintYesOriginal master unit reference, may be non-positive or null in legacy flows
namevarchar(200)NoUnit display name stored on the army row
unit_typevarchar(100)YesHero/Core/etc on the army row
pointsintNoPoints value stored on this army unit
quantityintNoQuantity count, default 1
notesvarchar(500)YesImported options / notes text
is_generaltinyint(1)NoGeneral flag
is_bsbtinyint(1)NoBattle standard bearer flag
has_standardtinyint(1)NoUnit has standard/banner flag
sort_orderintNoExplicit UI/display ordering
created_atdatetime(3)NoCreation timestamp
updated_atdatetime(3)NoLast update timestamp
master_unit_id_fkint unsigned (generated)YesComputed foreign-key-safe version of master_unit_id

Generated column behaviour

master_unit_id_fk is generated as:

CASE WHEN master_unit_id > 0 THEN master_unit_id ELSE NULL END

This allows the schema to support legacy/non-canonical rows while still enforcing a foreign key for valid linked rows.

Keys and indexes

  • PRIMARY KEY (id)
  • ix_units_list (army_list_id)
  • ix_units_list_sort (army_list_id, sort_order, id)
  • idx_army_units_master_unit_id (master_unit_id)
  • idx_army_units_master_unit_id_fk (master_unit_id_fk)

Foreign keys

  • fk_units_list: army_units.army_list_id → army_lists.id ON DELETE CASCADE
  • fk_army_units_master_unit: army_units.master_unit_id_fk → units.id

Relationships

Relationship Type Notes
army_units.army_list_id → army_lists.id Many-to-one Each unit row belongs to one army
army_units.master_unit_id_fk → units.id Optional many-to-one Only applies when a valid positive master unit id exists
game_units derived from army_units Copied/expanded downstream Gameplay state later depends on these rows

Gameplay-relevant flags

  • is_general affects scoring bonuses
  • is_bsb affects scoring bonuses
  • has_standard affects banner scoring logic

Used by

  • Army units create/get/list/update/delete endpoints
  • Army import commit endpoints
  • TO entrant army unit preview
  • Game setup and game-unit generation flows
  • Scoring logic after game units are instantiated

Design notes

  • This table intentionally stores a snapshot-like unit row, not just a pure reference
  • Points are stored here per army unit, not on canonical units
  • The schema supports both strongly linked and weakly linked unit rows
  • sort_order is central to predictable UI rendering

Risks

  • Mixed canonical and legacy behaviour increases complexity
  • Free-text rows can reduce downstream consistency
  • Changing unit flags incorrectly can distort gameplay scoring
  • Large notes payloads from imports may affect readability and maintenance

Recommended future improvements

  • Decide whether legacy/unlinked units should remain supported long-term
  • Consider stricter validation around valid unit_type values
  • Document or enforce single-general / single-BSB rules if needed
  • Consider wider use of generated/FK-safe patterns if legacy support continues