feat(01-02): shared types module for leveling lib
Task 1 of Plan 01-02. Types-only file (no runtime behavior, no test). - Proficiency union (mirrors Prisma enum) - PROFICIENCY_BASE_BONUS lookup (untrained 0, trained 2, ..., legendary 8) - EvalResult discriminated union for prereq evaluation - StepKind union for wizard step ordering (D-10) - CharacterContext interface for prereq + recompute inputs - DerivedStats interface — does NOT include hpCurrent (Pitfall #9) - ClassProgressionRow interface (read-only) - WizardChoices interface
This commit is contained in:
88
server/src/modules/leveling/lib/types.ts
Normal file
88
server/src/modules/leveling/lib/types.ts
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
* Shared types for the Level-Up pure-function library.
|
||||||
|
* No runtime dependencies — types only.
|
||||||
|
*/
|
||||||
|
import type { AbilityAbbreviation } from './apply-attribute-boost';
|
||||||
|
|
||||||
|
export type { AbilityAbbreviation };
|
||||||
|
|
||||||
|
/** PF2e proficiency ranks (mirrors Prisma `Proficiency` enum). */
|
||||||
|
export type Proficiency = 'UNTRAINED' | 'TRAINED' | 'EXPERT' | 'MASTER' | 'LEGENDARY';
|
||||||
|
|
||||||
|
/** Numeric proficiency bonus per rank, for use in proficiencyBonus(rank, level) calculation. */
|
||||||
|
export const PROFICIENCY_BASE_BONUS: Record<Proficiency, number> = {
|
||||||
|
UNTRAINED: 0,
|
||||||
|
TRAINED: 2,
|
||||||
|
EXPERT: 4,
|
||||||
|
MASTER: 6,
|
||||||
|
LEGENDARY: 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Discriminated union for prereq evaluation result. */
|
||||||
|
export type EvalResult =
|
||||||
|
| { ok: true }
|
||||||
|
| { ok: false; reason: string }
|
||||||
|
| { unknown: true; raw: string };
|
||||||
|
|
||||||
|
/** Ordered union of wizard step kinds (UI-SPEC + RESEARCH §Pattern 1). */
|
||||||
|
export type StepKind =
|
||||||
|
| 'class-features'
|
||||||
|
| 'class-feature-choice'
|
||||||
|
| 'boost'
|
||||||
|
| 'skill-increase'
|
||||||
|
| 'feat-class'
|
||||||
|
| 'feat-skill'
|
||||||
|
| 'feat-general'
|
||||||
|
| 'feat-ancestry'
|
||||||
|
| 'feat-archetype'
|
||||||
|
| 'spellcaster'
|
||||||
|
| 'review';
|
||||||
|
|
||||||
|
/** Snapshot a character's mechanical state for prereq evaluation and recompute. */
|
||||||
|
export interface CharacterContext {
|
||||||
|
level: number;
|
||||||
|
className: string;
|
||||||
|
ancestryName: string;
|
||||||
|
heritageName?: string;
|
||||||
|
abilities: Record<AbilityAbbreviation, number>;
|
||||||
|
skills: Record<string, Proficiency>;
|
||||||
|
feats: Set<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Output of recomputeDerivedStats — never includes hpCurrent (Pitfall #9). */
|
||||||
|
export interface DerivedStats {
|
||||||
|
level: number;
|
||||||
|
hpMax: number;
|
||||||
|
ac: number;
|
||||||
|
classDc: number;
|
||||||
|
perception: number;
|
||||||
|
fortitude: number;
|
||||||
|
reflex: number;
|
||||||
|
will: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ClassProgression row shape — read-only input to recompute pipeline. */
|
||||||
|
export interface ClassProgressionRow {
|
||||||
|
className: string;
|
||||||
|
level: number;
|
||||||
|
grants: string[];
|
||||||
|
proficiencyChanges: Partial<Record<'fortitude' | 'reflex' | 'will' | 'perception' | 'classDc' | 'ac', Proficiency>>;
|
||||||
|
spellSlotIncrement?: { tradition: string; spellLevel: number; count: number } | null;
|
||||||
|
cantripIncrement?: number | null;
|
||||||
|
repertoireIncrement?: number | null;
|
||||||
|
choiceType?: string | null;
|
||||||
|
choiceOptionsRef?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Wizard choices subset — what the user picked across the wizard. */
|
||||||
|
export interface WizardChoices {
|
||||||
|
boostTargets?: AbilityAbbreviation[];
|
||||||
|
skillIncrease?: { skillName: string; toRank: Proficiency };
|
||||||
|
featClassId?: string;
|
||||||
|
featSkillId?: string;
|
||||||
|
featGeneralId?: string;
|
||||||
|
featAncestryId?: string;
|
||||||
|
featArchetypeId?: string;
|
||||||
|
classFeatureChoices?: Record<string, string>;
|
||||||
|
spellcasterRepertoirePicks?: string[];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user