All files / web/src/db/schema player-abacus-identity.ts

100% Statements 43/43
100% Branches 1/1
100% Functions 1/1
100% Lines 43/43

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 442x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x  
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'
import { ABACUS_COLOR_PALETTES, ABACUS_COLOR_SCHEMES } from '@/lib/abacus/identity'
import { players } from './players'
 
/**
 * Player abacus identity table - the player-bound "my abacus" style and form
 *
 * One row per player, absent row = default identity. Stores exactly the
 * identity triple the Abacus Studio projects into print params
 * (paramsFromDisplayConfig): color scheme + palette (style) and column count
 * (form). Display-behavior preferences (animation, sound, bead shape, ...)
 * stay per-USER in abacus_settings — they are how an account likes abaci
 * rendered, not who a student's abacus is.
 *
 * Shared vocabulary (enums, AbacusIdentity type, defaults, parse guard)
 * lives drizzle-free in @/lib/abacus/identity for client-side reuse.
 *
 * Cascade-deletes when the player is deleted; rides along on guest→user
 * merges because players themselves are reparented.
 */
export const playerAbacusIdentity = sqliteTable('player_abacus_identity', {
  /** Player ID (primary key, FK → players) */
  playerId: text('player_id')
    .primaryKey()
    .references(() => players.id, { onDelete: 'cascade' }),
 
  /** Color scheme for beads */
  colorScheme: text('color_scheme', { enum: ABACUS_COLOR_SCHEMES })
    .notNull()
    .default('place-value'),
 
  /** Color palette */
  colorPalette: text('color_palette', { enum: ABACUS_COLOR_PALETTES }).notNull().default('default'),
 
  /** Physical column count (1-21; the studio clamps its own floor to 3) */
  columns: integer('columns').notNull().default(4),
 
  /** Timestamp of last update (unix ms) */
  updatedAt: integer('updated_at').notNull(),
})
 
export type PlayerAbacusIdentity = typeof playerAbacusIdentity.$inferSelect
export type NewPlayerAbacusIdentity = typeof playerAbacusIdentity.$inferInsert