All files / web/src/db/schema custom-skills.ts

100% Statements 55/55
100% Branches 4/4
100% Functions 2/2
100% Lines 55/55

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 44 45 46 47 48 49 50 51 52 53 54 55 562x 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 39x 39x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 39x 39x 2x  
import { sqliteTable, text, index, primaryKey } from 'drizzle-orm/sqlite-core'
import { users } from './users'
 
/**
 * Custom Skills Table
 *
 * Stores fully user-created custom skills for mastery mode progression.
 * These are new skills that users create from scratch, not modifications
 * of existing default skills.
 */
export const customSkills = sqliteTable(
  'custom_skills',
  {
    id: text('id').primaryKey().notNull(),
    userId: text('user_id')
      .notNull()
      .references(() => users.id, { onDelete: 'cascade' }),
    operator: text('operator').notNull(), // 'addition' | 'subtraction'
    name: text('name').notNull(),
    description: text('description'),
    digitRange: text('digit_range').notNull(), // JSON: {min, max}
    regroupingConfig: text('regrouping_config').notNull(), // JSON: {pAnyStart, pAllStart}
    displayRules: text('display_rules').notNull(), // JSON: DisplayRules
    createdAt: text('created_at').notNull(),
    updatedAt: text('updated_at').notNull(),
  },
  (table) => ({
    userOperatorIdx: index('idx_custom_skills_user_operator').on(table.userId, table.operator),
  })
)
 
/**
 * Skill Customizations Table
 *
 * Stores user customizations of default skills. These modifications
 * override the default skill configuration but maintain the skill's
 * identity and position in the progression.
 */
export const skillCustomizations = sqliteTable(
  'skill_customizations',
  {
    userId: text('user_id')
      .notNull()
      .references(() => users.id, { onDelete: 'cascade' }),
    skillId: text('skill_id').notNull(), // ID of the default skill being customized
    operator: text('operator').notNull(), // 'addition' | 'subtraction'
    digitRange: text('digit_range').notNull(), // JSON: {min, max}
    regroupingConfig: text('regrouping_config').notNull(), // JSON: {pAnyStart, pAllStart}
    displayRules: text('display_rules').notNull(), // JSON: DisplayRules
    updatedAt: text('updated_at').notNull(),
  },
  (table) => ({
    pk: primaryKey({ columns: [table.userId, table.skillId, table.operator] }),
  })
)