volleyballsimtypes 0.0.463 → 0.0.465

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/cjs/src/api/index.d.ts +13 -1
  2. package/dist/cjs/src/data/init-models.js +8 -0
  3. package/dist/cjs/src/data/models/currency-transaction.d.ts +4 -2
  4. package/dist/cjs/src/data/models/currency-transaction.js +2 -0
  5. package/dist/cjs/src/data/models/index.d.ts +2 -0
  6. package/dist/cjs/src/data/models/index.js +2 -0
  7. package/dist/cjs/src/data/models/match-set.d.ts +2 -0
  8. package/dist/cjs/src/data/models/match-set.js +5 -0
  9. package/dist/cjs/src/data/models/match.d.ts +3 -1
  10. package/dist/cjs/src/data/models/match.js +4 -0
  11. package/dist/cjs/src/data/models/physician.d.ts +25 -0
  12. package/dist/cjs/src/data/models/physician.js +57 -0
  13. package/dist/cjs/src/data/models/physiotherapist.d.ts +25 -0
  14. package/dist/cjs/src/data/models/physiotherapist.js +57 -0
  15. package/dist/cjs/src/data/models/player.d.ts +8 -0
  16. package/dist/cjs/src/data/models/player.js +17 -0
  17. package/dist/cjs/src/data/models/tactics.d.ts +10 -1
  18. package/dist/cjs/src/data/models/tactics.js +9 -0
  19. package/dist/cjs/src/data/transformers/lineup-preset.js +7 -1
  20. package/dist/cjs/src/data/transformers/lineup-preset.test.js +15 -2
  21. package/dist/cjs/src/data/transformers/match-set.js +2 -0
  22. package/dist/cjs/src/data/transformers/match.js +6 -2
  23. package/dist/cjs/src/data/transformers/player.js +15 -1
  24. package/dist/cjs/src/data/transformers/rally-event-injury.test.d.ts +1 -0
  25. package/dist/cjs/src/data/transformers/rally-event-injury.test.js +33 -0
  26. package/dist/cjs/src/data/transformers/rally-event.d.ts +1 -0
  27. package/dist/cjs/src/data/transformers/rally-event.js +4 -1
  28. package/dist/cjs/src/data/transformers/tactics.js +83 -4
  29. package/dist/cjs/src/service/event/schemas/substitution.z.d.ts +1 -0
  30. package/dist/cjs/src/service/event/schemas/substitution.z.js +2 -1
  31. package/dist/cjs/src/service/event/substitution.d.ts +1 -0
  32. package/dist/cjs/src/service/event/substitution.js +4 -2
  33. package/dist/cjs/src/service/match/match-set-forfeit.test.d.ts +1 -0
  34. package/dist/cjs/src/service/match/match-set-forfeit.test.js +76 -0
  35. package/dist/cjs/src/service/match/match-set.d.ts +8 -0
  36. package/dist/cjs/src/service/match/match-set.js +23 -1
  37. package/dist/cjs/src/service/match/match.d.ts +2 -0
  38. package/dist/cjs/src/service/match/match.js +2 -1
  39. package/dist/cjs/src/service/match/schemas/match-set.z.d.ts +1 -0
  40. package/dist/cjs/src/service/match/schemas/match-set.z.js +30 -2
  41. package/dist/cjs/src/service/match/schemas/match.z.d.ts +4 -0
  42. package/dist/cjs/src/service/match/schemas/match.z.js +4 -1
  43. package/dist/cjs/src/service/player/index.d.ts +1 -0
  44. package/dist/cjs/src/service/player/index.js +1 -0
  45. package/dist/cjs/src/service/player/injury.d.ts +14 -0
  46. package/dist/cjs/src/service/player/injury.js +39 -0
  47. package/dist/cjs/src/service/player/injury.test.d.ts +1 -0
  48. package/dist/cjs/src/service/player/injury.test.js +78 -0
  49. package/dist/cjs/src/service/player/player-generator.js +3 -1
  50. package/dist/cjs/src/service/player/player.d.ts +3 -0
  51. package/dist/cjs/src/service/player/player.js +3 -1
  52. package/dist/cjs/src/service/player/schemas/player.z.d.ts +6 -0
  53. package/dist/cjs/src/service/player/schemas/player.z.js +7 -0
  54. package/dist/cjs/src/service/team/index.d.ts +1 -0
  55. package/dist/cjs/src/service/team/index.js +1 -0
  56. package/dist/cjs/src/service/team/injury-replacement.d.ts +6 -0
  57. package/dist/cjs/src/service/team/injury-replacement.js +2 -0
  58. package/dist/cjs/src/service/team/schemas/injury-replacement.z.test.d.ts +1 -0
  59. package/dist/cjs/src/service/team/schemas/injury-replacement.z.test.js +142 -0
  60. package/dist/cjs/src/service/team/schemas/tactics.z.d.ts +6 -0
  61. package/dist/cjs/src/service/team/schemas/tactics.z.js +47 -1
  62. package/dist/cjs/src/service/team/schemas/team.z.d.ts +6 -0
  63. package/dist/cjs/src/service/team/tactics.d.ts +5 -0
  64. package/dist/cjs/src/service/team/tactics.js +3 -1
  65. package/dist/esm/src/api/index.d.ts +13 -1
  66. package/dist/esm/src/data/init-models.js +9 -1
  67. package/dist/esm/src/data/models/currency-transaction.d.ts +4 -2
  68. package/dist/esm/src/data/models/currency-transaction.js +2 -0
  69. package/dist/esm/src/data/models/index.d.ts +2 -0
  70. package/dist/esm/src/data/models/index.js +2 -0
  71. package/dist/esm/src/data/models/match-set.d.ts +2 -0
  72. package/dist/esm/src/data/models/match-set.js +5 -0
  73. package/dist/esm/src/data/models/match.d.ts +3 -1
  74. package/dist/esm/src/data/models/match.js +4 -0
  75. package/dist/esm/src/data/models/physician.d.ts +25 -0
  76. package/dist/esm/src/data/models/physician.js +53 -0
  77. package/dist/esm/src/data/models/physiotherapist.d.ts +25 -0
  78. package/dist/esm/src/data/models/physiotherapist.js +53 -0
  79. package/dist/esm/src/data/models/player.d.ts +8 -0
  80. package/dist/esm/src/data/models/player.js +17 -0
  81. package/dist/esm/src/data/models/tactics.d.ts +10 -1
  82. package/dist/esm/src/data/models/tactics.js +9 -0
  83. package/dist/esm/src/data/transformers/lineup-preset.js +7 -1
  84. package/dist/esm/src/data/transformers/lineup-preset.test.js +15 -2
  85. package/dist/esm/src/data/transformers/match-set.js +2 -0
  86. package/dist/esm/src/data/transformers/match.js +6 -2
  87. package/dist/esm/src/data/transformers/player.js +15 -1
  88. package/dist/esm/src/data/transformers/rally-event-injury.test.d.ts +1 -0
  89. package/dist/esm/src/data/transformers/rally-event-injury.test.js +31 -0
  90. package/dist/esm/src/data/transformers/rally-event.d.ts +1 -0
  91. package/dist/esm/src/data/transformers/rally-event.js +4 -1
  92. package/dist/esm/src/data/transformers/tactics.js +83 -4
  93. package/dist/esm/src/service/event/schemas/substitution.z.d.ts +1 -0
  94. package/dist/esm/src/service/event/schemas/substitution.z.js +2 -1
  95. package/dist/esm/src/service/event/substitution.d.ts +1 -0
  96. package/dist/esm/src/service/event/substitution.js +4 -2
  97. package/dist/esm/src/service/match/match-set-forfeit.test.d.ts +1 -0
  98. package/dist/esm/src/service/match/match-set-forfeit.test.js +74 -0
  99. package/dist/esm/src/service/match/match-set.d.ts +8 -0
  100. package/dist/esm/src/service/match/match-set.js +23 -1
  101. package/dist/esm/src/service/match/match.d.ts +2 -0
  102. package/dist/esm/src/service/match/match.js +2 -1
  103. package/dist/esm/src/service/match/schemas/match-set.z.d.ts +1 -0
  104. package/dist/esm/src/service/match/schemas/match-set.z.js +30 -2
  105. package/dist/esm/src/service/match/schemas/match.z.d.ts +4 -0
  106. package/dist/esm/src/service/match/schemas/match.z.js +4 -1
  107. package/dist/esm/src/service/player/index.d.ts +1 -0
  108. package/dist/esm/src/service/player/index.js +1 -0
  109. package/dist/esm/src/service/player/injury.d.ts +14 -0
  110. package/dist/esm/src/service/player/injury.js +33 -0
  111. package/dist/esm/src/service/player/injury.test.d.ts +1 -0
  112. package/dist/esm/src/service/player/injury.test.js +76 -0
  113. package/dist/esm/src/service/player/player-generator.js +3 -1
  114. package/dist/esm/src/service/player/player.d.ts +3 -0
  115. package/dist/esm/src/service/player/player.js +3 -1
  116. package/dist/esm/src/service/player/schemas/player.z.d.ts +6 -0
  117. package/dist/esm/src/service/player/schemas/player.z.js +7 -0
  118. package/dist/esm/src/service/team/index.d.ts +1 -0
  119. package/dist/esm/src/service/team/index.js +1 -0
  120. package/dist/esm/src/service/team/injury-replacement.d.ts +6 -0
  121. package/dist/esm/src/service/team/injury-replacement.js +1 -0
  122. package/dist/esm/src/service/team/schemas/injury-replacement.z.test.d.ts +1 -0
  123. package/dist/esm/src/service/team/schemas/injury-replacement.z.test.js +140 -0
  124. package/dist/esm/src/service/team/schemas/tactics.z.d.ts +6 -0
  125. package/dist/esm/src/service/team/schemas/tactics.z.js +47 -1
  126. package/dist/esm/src/service/team/schemas/team.z.d.ts +6 -0
  127. package/dist/esm/src/service/team/tactics.d.ts +5 -0
  128. package/dist/esm/src/service/team/tactics.js +3 -1
  129. package/package.json +1 -1
@@ -54,7 +54,11 @@ export type Match = Omit<DataProps<_Match>, 'sets' | 'homeTeam' | 'awayTeam' | '
54
54
  export type RallyEvent = DataProps<_RallyEvent> & {
55
55
  teamId?: string;
56
56
  };
57
- export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthIteration' | 'declineProfile' | 'nickname'> & {
57
+ export interface ApiPlayerInjuryStatus {
58
+ severity: number;
59
+ injuredUntil: string;
60
+ }
61
+ export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthIteration' | 'declineProfile' | 'nickname' | 'injuryProneProfile' | 'injury'> & {
58
62
  -readonly [K in 'birthAge' | 'birthIteration']?: DataProps<_Player>[K];
59
63
  } & {
60
64
  stats?: PerformanceStats;
@@ -62,6 +66,7 @@ export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthItera
62
66
  jerseyNumber: number;
63
67
  locked?: boolean;
64
68
  declineStatus?: DeclineStatus;
69
+ injuryStatus?: ApiPlayerInjuryStatus;
65
70
  nickname?: string;
66
71
  };
67
72
  export interface StartingLineup {
@@ -100,6 +105,11 @@ export interface ApiSystemSet {
100
105
  rotationSystem: RotationSystemEnum;
101
106
  designatedSetters: string[];
102
107
  }
108
+ export interface ApiInjuryReplacement {
109
+ starterId: string;
110
+ replacementId: string;
111
+ benchBackfillId?: string;
112
+ }
103
113
  export interface ApiLiberoSetSubConfig {
104
114
  mode: LiberoSubMode;
105
115
  fatigueBand?: EnergyBand;
@@ -121,6 +131,8 @@ export interface Tactics {
121
131
  offensivePreferences: ApiOffensivePreference[];
122
132
  systemSets?: ApiSystemSet[];
123
133
  offensivePreferenceSets?: ApiOffensivePreference[][];
134
+ replaceInjuredImmediately: boolean;
135
+ injuryReplacements?: ApiInjuryReplacement[];
124
136
  }
125
137
  export interface ApiLineupPreset {
126
138
  presetId: string;
@@ -5,6 +5,8 @@ const models_1 = require("./models");
5
5
  function initModels(sequelize) {
6
6
  const Coach = models_1.CoachModel.initModel(sequelize);
7
7
  const Scout = models_1.ScoutModel.initModel(sequelize);
8
+ const Physician = models_1.PhysicianModel.initModel(sequelize);
9
+ const Physiotherapist = models_1.PhysiotherapistModel.initModel(sequelize);
8
10
  const CurrencyTransaction = models_1.CurrencyTransactionModel.initModel(sequelize);
9
11
  const Tactics = models_1.TacticsModel.initModel(sequelize);
10
12
  const LineupPreset = models_1.LineupPresetModel.initModel(sequelize);
@@ -211,6 +213,10 @@ function initModels(sequelize) {
211
213
  Coach.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
212
214
  Team.hasOne(Scout, { as: 'Scout', foreignKey: 'team_id' });
213
215
  Scout.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
216
+ Team.hasOne(Physician, { as: 'Physician', foreignKey: 'team_id' });
217
+ Physician.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
218
+ Team.hasOne(Physiotherapist, { as: 'Physiotherapist', foreignKey: 'team_id' });
219
+ Physiotherapist.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
214
220
  Team.hasOne(Tactics, { as: 'tactics', foreignKey: 'team_id' });
215
221
  // Lineup presets are loaded only by the management API; deliberately NOT in Team.defaultScope so the
216
222
  // simulator's team loads are unchanged (it reads the active config from the mirrored Tactics row).
@@ -310,6 +316,8 @@ function initModels(sequelize) {
310
316
  Notification,
311
317
  Coach,
312
318
  Scout,
319
+ Physician,
320
+ Physiotherapist,
313
321
  CurrencyTransaction,
314
322
  VPER,
315
323
  LegacyTeamFlag,
@@ -15,9 +15,11 @@ export declare enum CurrencyTransactionSourceEnum {
15
15
  PLAYER_RETIRE = "PLAYER_RETIRE",
16
16
  ADMIN_GRANT = "ADMIN_GRANT",
17
17
  SEASON_REWARD = "SEASON_REWARD",
18
- COMPETITION_REWARD = "COMPETITION_REWARD"
18
+ COMPETITION_REWARD = "COMPETITION_REWARD",
19
+ PHYSICIAN_UPGRADE = "PHYSICIAN_UPGRADE",
20
+ PHYSIOTHERAPIST_UPGRADE = "PHYSIOTHERAPIST_UPGRADE"
19
21
  }
20
- export type CurrencyTransactionSource = CurrencyTransactionSourceEnum.MATCH_REWARD | CurrencyTransactionSourceEnum.GACHA_PULL | CurrencyTransactionSourceEnum.COACH_UPGRADE | CurrencyTransactionSourceEnum.SCOUT_UPGRADE | CurrencyTransactionSourceEnum.PLAYER_DISMISS | CurrencyTransactionSourceEnum.PLAYER_RETIRE | CurrencyTransactionSourceEnum.ADMIN_GRANT | CurrencyTransactionSourceEnum.SEASON_REWARD | CurrencyTransactionSourceEnum.COMPETITION_REWARD;
22
+ export type CurrencyTransactionSource = CurrencyTransactionSourceEnum.MATCH_REWARD | CurrencyTransactionSourceEnum.GACHA_PULL | CurrencyTransactionSourceEnum.COACH_UPGRADE | CurrencyTransactionSourceEnum.SCOUT_UPGRADE | CurrencyTransactionSourceEnum.PLAYER_DISMISS | CurrencyTransactionSourceEnum.PLAYER_RETIRE | CurrencyTransactionSourceEnum.ADMIN_GRANT | CurrencyTransactionSourceEnum.SEASON_REWARD | CurrencyTransactionSourceEnum.COMPETITION_REWARD | CurrencyTransactionSourceEnum.PHYSICIAN_UPGRADE | CurrencyTransactionSourceEnum.PHYSIOTHERAPIST_UPGRADE;
21
23
  export interface CurrencyTransactionAttributes {
22
24
  transaction_id: string;
23
25
  user_id: string;
@@ -18,6 +18,8 @@ var CurrencyTransactionSourceEnum;
18
18
  CurrencyTransactionSourceEnum["ADMIN_GRANT"] = "ADMIN_GRANT";
19
19
  CurrencyTransactionSourceEnum["SEASON_REWARD"] = "SEASON_REWARD";
20
20
  CurrencyTransactionSourceEnum["COMPETITION_REWARD"] = "COMPETITION_REWARD";
21
+ CurrencyTransactionSourceEnum["PHYSICIAN_UPGRADE"] = "PHYSICIAN_UPGRADE";
22
+ CurrencyTransactionSourceEnum["PHYSIOTHERAPIST_UPGRADE"] = "PHYSIOTHERAPIST_UPGRADE";
21
23
  })(CurrencyTransactionSourceEnum || (exports.CurrencyTransactionSourceEnum = CurrencyTransactionSourceEnum = {}));
22
24
  class CurrencyTransactionModel extends sequelize_1.Model {
23
25
  static initModel(sequelize) {
@@ -32,6 +32,8 @@ export * from './region-qualifier';
32
32
  export * from './national-country';
33
33
  export * from './coach';
34
34
  export * from './scout';
35
+ export * from './physician';
36
+ export * from './physiotherapist';
35
37
  export * from './team';
36
38
  export * from './team-replacement';
37
39
  export * from './tactics';
@@ -48,6 +48,8 @@ __exportStar(require("./region-qualifier"), exports);
48
48
  __exportStar(require("./national-country"), exports);
49
49
  __exportStar(require("./coach"), exports);
50
50
  __exportStar(require("./scout"), exports);
51
+ __exportStar(require("./physician"), exports);
52
+ __exportStar(require("./physiotherapist"), exports);
51
53
  __exportStar(require("./team"), exports);
52
54
  __exportStar(require("./team-replacement"), exports);
53
55
  __exportStar(require("./tactics"), exports);
@@ -9,6 +9,7 @@ export interface MatchSetAttributes {
9
9
  order: number;
10
10
  home_score: number;
11
11
  away_score: number;
12
+ forfeited?: boolean;
12
13
  player_positions: PlayerPositionAttributes[];
13
14
  Rallies?: RallyAttributes[];
14
15
  BoxScores?: BoxScoreAttributes[];
@@ -23,6 +24,7 @@ export declare class MatchSetModel extends Model<MatchSetAttributes, MatchSetCre
23
24
  order: number;
24
25
  home_score: number;
25
26
  away_score: number;
27
+ forfeited: boolean;
26
28
  player_positions: PlayerPositionAttributes[];
27
29
  match: MatchModel;
28
30
  getMatch: Sequelize.BelongsToGetAssociationMixin<MatchModel>;
@@ -35,6 +35,11 @@ class MatchSetModel extends sequelize_1.Model {
35
35
  type: sequelize_1.DataTypes.INTEGER,
36
36
  allowNull: false
37
37
  },
38
+ forfeited: {
39
+ type: sequelize_1.DataTypes.BOOLEAN,
40
+ allowNull: false,
41
+ defaultValue: false
42
+ },
38
43
  player_positions: {
39
44
  type: sequelize_1.DataTypes.JSONB,
40
45
  allowNull: false,
@@ -2,7 +2,7 @@ import * as Sequelize from 'sequelize';
2
2
  import { Model } from 'sequelize';
3
3
  import { Status } from '../common';
4
4
  import { CompetitionMatchId, CompetitionMatchModel, MatchRatingId, MatchRatingModel, MatchResultId, MatchResultModel, MatchPresetModel, MatchSetAttributes, MatchSetId, MatchSetModel, VPERAttributes, VPERId, VPERModel, TeamId, TeamModel } from '.';
5
- import { MatchRallyAggregates } from '../../service';
5
+ import { MatchForfeitType, MatchRallyAggregates } from '../../service';
6
6
  export interface MatchAttributes {
7
7
  match_id: string;
8
8
  home_team: string;
@@ -13,6 +13,7 @@ export interface MatchAttributes {
13
13
  in_progress_at?: Date;
14
14
  complete_at?: Date;
15
15
  rally_aggregates?: MatchRallyAggregates | null;
16
+ forfeit_type?: MatchForfeitType | null;
16
17
  MatchSets?: MatchSetAttributes[];
17
18
  VPERs?: VPERAttributes[];
18
19
  }
@@ -29,6 +30,7 @@ export declare class MatchModel extends Model<MatchAttributes, MatchCreationAttr
29
30
  in_progress_at?: Date;
30
31
  complete_at?: Date;
31
32
  rally_aggregates?: MatchRallyAggregates | null;
33
+ forfeit_type?: MatchForfeitType | null;
32
34
  CompetitionMatch: CompetitionMatchModel;
33
35
  getCompetitionMatch: Sequelize.HasOneGetAssociationMixin<CompetitionMatchModel>;
34
36
  setCompetitionMatch: Sequelize.HasOneSetAssociationMixin<CompetitionMatchModel, CompetitionMatchId>;
@@ -51,6 +51,10 @@ class MatchModel extends sequelize_1.Model {
51
51
  rally_aggregates: {
52
52
  type: sequelize_1.DataTypes.JSONB,
53
53
  allowNull: true
54
+ },
55
+ forfeit_type: {
56
+ type: sequelize_1.DataTypes.TEXT,
57
+ allowNull: true
54
58
  }
55
59
  }, {
56
60
  sequelize,
@@ -0,0 +1,25 @@
1
+ import * as Sequelize from 'sequelize';
2
+ import { Model } from 'sequelize';
3
+ import { TeamId, TeamModel } from '.';
4
+ export interface PhysicianAttributes {
5
+ physician_id: string;
6
+ team_id: string;
7
+ name: string;
8
+ rarity: string;
9
+ currency_invested: number;
10
+ }
11
+ export type PhysicianPk = 'physician_id';
12
+ export type PhysicianId = PhysicianModel[PhysicianPk];
13
+ export type PhysicianCreationAttributes = PhysicianAttributes;
14
+ export declare class PhysicianModel extends Model<PhysicianAttributes, PhysicianCreationAttributes> implements PhysicianAttributes {
15
+ physician_id: string;
16
+ team_id: string;
17
+ name: string;
18
+ rarity: string;
19
+ currency_invested: number;
20
+ team: TeamModel;
21
+ getTeam: Sequelize.BelongsToGetAssociationMixin<TeamModel>;
22
+ setTeam: Sequelize.BelongsToSetAssociationMixin<TeamModel, TeamId>;
23
+ createTeam: Sequelize.BelongsToCreateAssociationMixin<TeamModel>;
24
+ static initModel(sequelize: Sequelize.Sequelize): typeof PhysicianModel;
25
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PhysicianModel = void 0;
4
+ const sequelize_1 = require("sequelize");
5
+ class PhysicianModel extends sequelize_1.Model {
6
+ static initModel(sequelize) {
7
+ return PhysicianModel.init({
8
+ physician_id: {
9
+ type: sequelize_1.DataTypes.UUID,
10
+ allowNull: false,
11
+ primaryKey: true
12
+ },
13
+ team_id: {
14
+ type: sequelize_1.DataTypes.UUID,
15
+ allowNull: false,
16
+ unique: true,
17
+ references: {
18
+ model: 'Team',
19
+ key: 'team_id'
20
+ }
21
+ },
22
+ name: {
23
+ type: sequelize_1.DataTypes.STRING,
24
+ allowNull: false,
25
+ defaultValue: ''
26
+ },
27
+ rarity: {
28
+ type: sequelize_1.DataTypes.STRING,
29
+ allowNull: false,
30
+ defaultValue: 'COMMON'
31
+ },
32
+ currency_invested: {
33
+ type: sequelize_1.DataTypes.INTEGER,
34
+ allowNull: false,
35
+ defaultValue: 0
36
+ }
37
+ }, {
38
+ sequelize,
39
+ tableName: 'Physician',
40
+ schema: 'public',
41
+ timestamps: false,
42
+ indexes: [
43
+ {
44
+ name: 'Physician_pk',
45
+ unique: true,
46
+ fields: [{ name: 'physician_id' }]
47
+ },
48
+ {
49
+ name: 'Physician_team_id_unique',
50
+ unique: true,
51
+ fields: [{ name: 'team_id' }]
52
+ }
53
+ ]
54
+ });
55
+ }
56
+ }
57
+ exports.PhysicianModel = PhysicianModel;
@@ -0,0 +1,25 @@
1
+ import * as Sequelize from 'sequelize';
2
+ import { Model } from 'sequelize';
3
+ import { TeamId, TeamModel } from '.';
4
+ export interface PhysiotherapistAttributes {
5
+ physiotherapist_id: string;
6
+ team_id: string;
7
+ name: string;
8
+ rarity: string;
9
+ currency_invested: number;
10
+ }
11
+ export type PhysiotherapistPk = 'physiotherapist_id';
12
+ export type PhysiotherapistId = PhysiotherapistModel[PhysiotherapistPk];
13
+ export type PhysiotherapistCreationAttributes = PhysiotherapistAttributes;
14
+ export declare class PhysiotherapistModel extends Model<PhysiotherapistAttributes, PhysiotherapistCreationAttributes> implements PhysiotherapistAttributes {
15
+ physiotherapist_id: string;
16
+ team_id: string;
17
+ name: string;
18
+ rarity: string;
19
+ currency_invested: number;
20
+ team: TeamModel;
21
+ getTeam: Sequelize.BelongsToGetAssociationMixin<TeamModel>;
22
+ setTeam: Sequelize.BelongsToSetAssociationMixin<TeamModel, TeamId>;
23
+ createTeam: Sequelize.BelongsToCreateAssociationMixin<TeamModel>;
24
+ static initModel(sequelize: Sequelize.Sequelize): typeof PhysiotherapistModel;
25
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PhysiotherapistModel = void 0;
4
+ const sequelize_1 = require("sequelize");
5
+ class PhysiotherapistModel extends sequelize_1.Model {
6
+ static initModel(sequelize) {
7
+ return PhysiotherapistModel.init({
8
+ physiotherapist_id: {
9
+ type: sequelize_1.DataTypes.UUID,
10
+ allowNull: false,
11
+ primaryKey: true
12
+ },
13
+ team_id: {
14
+ type: sequelize_1.DataTypes.UUID,
15
+ allowNull: false,
16
+ unique: true,
17
+ references: {
18
+ model: 'Team',
19
+ key: 'team_id'
20
+ }
21
+ },
22
+ name: {
23
+ type: sequelize_1.DataTypes.STRING,
24
+ allowNull: false,
25
+ defaultValue: ''
26
+ },
27
+ rarity: {
28
+ type: sequelize_1.DataTypes.STRING,
29
+ allowNull: false,
30
+ defaultValue: 'COMMON'
31
+ },
32
+ currency_invested: {
33
+ type: sequelize_1.DataTypes.INTEGER,
34
+ allowNull: false,
35
+ defaultValue: 0
36
+ }
37
+ }, {
38
+ sequelize,
39
+ tableName: 'Physiotherapist',
40
+ schema: 'public',
41
+ timestamps: false,
42
+ indexes: [
43
+ {
44
+ name: 'Physiotherapist_pk',
45
+ unique: true,
46
+ fields: [{ name: 'physiotherapist_id' }]
47
+ },
48
+ {
49
+ name: 'Physiotherapist_team_id_unique',
50
+ unique: true,
51
+ fields: [{ name: 'team_id' }]
52
+ }
53
+ ]
54
+ });
55
+ }
56
+ }
57
+ exports.PhysiotherapistModel = PhysiotherapistModel;
@@ -15,6 +15,10 @@ export interface PlayerAttributes {
15
15
  birth_iteration: number;
16
16
  last_declined_iteration: number | null;
17
17
  decline_profile: DeclineProfile;
18
+ injury_prone_profile?: number | string;
19
+ injury_severity?: number | null;
20
+ injured_until?: Date | string | null;
21
+ injury_debuff?: number | string | null;
18
22
  PerformanceStat?: PerformanceStatsAttributes;
19
23
  BoxScores?: BoxScoreAttributes[];
20
24
  }
@@ -34,6 +38,10 @@ export declare class PlayerModel extends Model<PlayerAttributes, PlayerCreationA
34
38
  birth_iteration: number;
35
39
  last_declined_iteration: number | null;
36
40
  decline_profile: DeclineProfile;
41
+ injury_prone_profile: number | string;
42
+ injury_severity: number | null;
43
+ injured_until: Date | string | null;
44
+ injury_debuff: number | string | null;
37
45
  country: CountryModel;
38
46
  getCountry: Sequelize.BelongsToGetAssociationMixin<CountryModel>;
39
47
  setCountry: Sequelize.BelongsToSetAssociationMixin<CountryModel, CountryId>;
@@ -62,6 +62,23 @@ class PlayerModel extends sequelize_1.Model {
62
62
  type: sequelize_1.DataTypes.ENUM(...Object.values(service_1.DeclineProfileEnum)),
63
63
  allowNull: false,
64
64
  defaultValue: service_1.DeclineProfileEnum.STANDARD
65
+ },
66
+ injury_prone_profile: {
67
+ type: sequelize_1.DataTypes.DECIMAL(3, 2),
68
+ allowNull: false,
69
+ defaultValue: 0.5
70
+ },
71
+ injury_severity: {
72
+ type: sequelize_1.DataTypes.INTEGER,
73
+ allowNull: true
74
+ },
75
+ injured_until: {
76
+ type: sequelize_1.DataTypes.DATE,
77
+ allowNull: true
78
+ },
79
+ injury_debuff: {
80
+ type: sequelize_1.DataTypes.DECIMAL(3, 2),
81
+ allowNull: true
65
82
  }
66
83
  }, {
67
84
  sequelize,
@@ -39,6 +39,11 @@ export interface SystemSetAttributes {
39
39
  rotationSystem: RotationSystemEnum;
40
40
  designatedSetters: PlayerId[];
41
41
  }
42
+ export interface InjuryReplacementAttributes {
43
+ starterId: PlayerId;
44
+ replacementId: PlayerId;
45
+ benchBackfillId?: PlayerId;
46
+ }
42
47
  export interface LiberoSetSubConfigAttributes {
43
48
  mode: LiberoSubMode;
44
49
  fatigueBand?: EnergyBand;
@@ -61,10 +66,12 @@ export interface TacticsAttributes {
61
66
  offensive_preferences: OffensivePreferenceAttributes[];
62
67
  system_sets?: SystemSetAttributes[];
63
68
  offensive_preference_sets?: OffensivePreferenceAttributes[][];
69
+ replace_injured_immediately?: boolean;
70
+ injury_replacements?: InjuryReplacementAttributes[];
64
71
  }
65
72
  export type TacticsPk = 'team_id';
66
73
  export type TacticsId = TacticsModel[TacticsPk];
67
- export type TacticsOptionalAttributes = 'lineup' | 'libero_replacements' | 'receive_rotation_offset' | 'designated_subs' | 'substitution_band' | 'second_libero' | 'libero_sub' | 'libero_replacement_sets' | 'rotation_system' | 'designated_setters' | 'offensive_preferences' | 'system_sets' | 'offensive_preference_sets';
74
+ export type TacticsOptionalAttributes = 'lineup' | 'libero_replacements' | 'receive_rotation_offset' | 'designated_subs' | 'substitution_band' | 'second_libero' | 'libero_sub' | 'libero_replacement_sets' | 'rotation_system' | 'designated_setters' | 'offensive_preferences' | 'system_sets' | 'offensive_preference_sets' | 'replace_injured_immediately' | 'injury_replacements';
68
75
  export type TacticsCreationAttributes = Optional<TacticsAttributes, TacticsOptionalAttributes>;
69
76
  export declare class TacticsModel extends Model<TacticsAttributes, TacticsCreationAttributes> implements TacticsAttributes {
70
77
  team_id: string;
@@ -81,6 +88,8 @@ export declare class TacticsModel extends Model<TacticsAttributes, TacticsCreati
81
88
  offensive_preferences: OffensivePreferenceAttributes[];
82
89
  system_sets?: SystemSetAttributes[];
83
90
  offensive_preference_sets?: OffensivePreferenceAttributes[][];
91
+ replace_injured_immediately?: boolean;
92
+ injury_replacements?: InjuryReplacementAttributes[];
84
93
  team: TeamModel;
85
94
  getTeam: Sequelize.BelongsToGetAssociationMixin<TeamModel>;
86
95
  setTeam: Sequelize.BelongsToSetAssociationMixin<TeamModel, TeamId>;
@@ -74,6 +74,15 @@ class TacticsModel extends sequelize_1.Model {
74
74
  offensive_preference_sets: {
75
75
  type: sequelize_1.DataTypes.JSONB,
76
76
  allowNull: true
77
+ },
78
+ replace_injured_immediately: {
79
+ type: sequelize_1.DataTypes.BOOLEAN,
80
+ allowNull: false,
81
+ defaultValue: true
82
+ },
83
+ injury_replacements: {
84
+ type: sequelize_1.DataTypes.JSONB,
85
+ allowNull: true
77
86
  }
78
87
  }, {
79
88
  sequelize,
@@ -2,12 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.transformToLineupPreset = transformToObject;
4
4
  // `config` is already stored as the API Tactics DTO, so a preset row maps to its API shape with no hydration.
5
+ // Presets saved before the injuries fields exist lack replaceInjuredImmediately: heal it to the effective
6
+ // default (true, matching transformToTactics' hydration) so the DTO's required field is honest and a UI
7
+ // toggle seeded from an old preset cannot silently flip the user's effective setting on re-save.
5
8
  function transformToObject(model) {
6
9
  return {
7
10
  presetId: model.preset_id,
8
11
  name: model.name,
9
12
  isActive: model.is_active,
10
13
  orderIndex: model.order_index,
11
- config: model.config
14
+ config: {
15
+ ...model.config,
16
+ replaceInjuredImmediately: model.config.replaceInjuredImmediately ?? true
17
+ }
12
18
  };
13
19
  }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const globals_1 = require("@jest/globals");
4
4
  const lineup_preset_1 = require("./lineup-preset");
5
5
  (0, globals_1.describe)('transformToLineupPreset()', () => {
6
- (0, globals_1.it)('maps preset columns to the API shape and passes config through by reference', () => {
6
+ (0, globals_1.it)('maps preset columns to the API shape and heals a pre-injuries config to the effective default', () => {
7
7
  const config = { lineup: { bench: [] }, substitutionBand: 'TIRED' };
8
8
  const preset = (0, lineup_preset_1.transformToLineupPreset)({
9
9
  preset_id: 'p1',
@@ -18,8 +18,21 @@ const lineup_preset_1 = require("./lineup-preset");
18
18
  name: 'Starters',
19
19
  isActive: true,
20
20
  orderIndex: 2,
21
+ // A config stored before the injuries fields lacks replaceInjuredImmediately; the transform heals it
22
+ // to true (the effective hydration default) so the DTO's required field is honest.
23
+ config: { ...config, replaceInjuredImmediately: true }
24
+ });
25
+ });
26
+ (0, globals_1.it)('keeps an explicit replaceInjuredImmediately: false', () => {
27
+ const config = { lineup: { bench: [] }, substitutionBand: 'TIRED', replaceInjuredImmediately: false };
28
+ const preset = (0, lineup_preset_1.transformToLineupPreset)({
29
+ preset_id: 'p2',
30
+ team_id: 't1',
31
+ name: 'Risky',
32
+ is_active: false,
33
+ order_index: 3,
21
34
  config
22
35
  });
23
- (0, globals_1.expect)(preset.config).toBe(config);
36
+ (0, globals_1.expect)(preset.config.replaceInjuredImmediately).toBe(false);
24
37
  });
25
38
  });
@@ -27,6 +27,7 @@ function transformToAttributes(set, matchId) {
27
27
  is_tie_break: set.isTieBreak,
28
28
  home_score: set.homeScore,
29
29
  away_score: set.awayScore,
30
+ forfeited: set.forfeited,
30
31
  player_positions: [...homeSetPositions, ...awaySetPositions],
31
32
  BoxScores: (set.boxScores ?? []).map(_1.transformFromBoxScore),
32
33
  Rallies: (set.rallies ?? []).map((rally) => (0, _1.transformFromRally)(rally, set.id))
@@ -43,6 +44,7 @@ function transformToObject(model) {
43
44
  homeScore: model.home_score,
44
45
  awayScore: model.away_score,
45
46
  isTieBreak: model.is_tie_break,
47
+ forfeited: model.forfeited ?? false,
46
48
  boxScores: (model.BoxScores ?? []).map(_1.transformToBoxScore),
47
49
  homePlayerPosition,
48
50
  awayPlayerPosition,
@@ -12,7 +12,10 @@ function transformToAttributes(match) {
12
12
  away_team: match.awayTeam.id,
13
13
  home_team: match.homeTeam.id,
14
14
  scheduled_date: match.scheduledDate,
15
- status: match.status
15
+ status: match.status,
16
+ // Both directions on purpose (the read is in transformToObject below). NOTE for the Sim: updateMatch's
17
+ // completion write uses an explicit column list and must include forfeit_type or the marker is lost.
18
+ forfeit_type: match.forfeitType ?? null
16
19
  };
17
20
  }
18
21
  function transformToObject(model, currentIteration, onPresetFallback) {
@@ -67,6 +70,7 @@ function transformToObject(model, currentIteration, onPresetFallback) {
67
70
  VPERs,
68
71
  homeScore,
69
72
  awayScore,
70
- winner: model.MatchResult?.Winner != null ? (0, team_1.transformToTeam)(model.MatchResult.Winner, currentIteration) : undefined
73
+ winner: model.MatchResult?.Winner != null ? (0, team_1.transformToTeam)(model.MatchResult.Winner, currentIteration) : undefined,
74
+ forfeitType: model.forfeit_type ?? undefined
71
75
  });
72
76
  }
@@ -25,7 +25,11 @@ function transformToAttributes(player) {
25
25
  birth_age: player.birthAge,
26
26
  birth_iteration: player.birthIteration,
27
27
  last_declined_iteration: null,
28
- decline_profile: player.declineProfile
28
+ decline_profile: player.declineProfile,
29
+ injury_prone_profile: player.injuryProneProfile,
30
+ injury_severity: player.injury?.severity ?? null,
31
+ injured_until: player.injury?.injuredUntil ?? null,
32
+ injury_debuff: player.injury?.debuff ?? null
29
33
  };
30
34
  }
31
35
  function transformToBoxScoreTotals(model) {
@@ -91,6 +95,16 @@ function transformToObject(model, currentIteration) {
91
95
  birthAge: model.birth_age,
92
96
  birthIteration: model.birth_iteration,
93
97
  declineProfile: model.decline_profile,
98
+ // DECIMAL comes back as a string from pg; schema-defaulted when the column is absent (pre-migration rows).
99
+ injuryProneProfile: model.injury_prone_profile != null ? Number(model.injury_prone_profile) : undefined,
100
+ // Severity defends against a partial write: an injured_until without severity reads as MINOR.
101
+ injury: model.injured_until != null
102
+ ? {
103
+ severity: model.injury_severity != null ? Number(model.injury_severity) : 1,
104
+ injuredUntil: model.injured_until,
105
+ debuff: model.injury_debuff != null ? Number(model.injury_debuff) : undefined
106
+ }
107
+ : undefined,
94
108
  boxScores: (model.BoxScores ?? []).map(_1.transformToBoxScore),
95
109
  boxScoreTotals
96
110
  });
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const globals_1 = require("@jest/globals");
4
+ const uuid_1 = require("uuid");
5
+ const service_1 = require("../../service");
6
+ const rally_event_1 = require("./rally-event");
7
+ (0, globals_1.describe)('rally-event compact round trip — injury substitution marker', () => {
8
+ const playerIn = (0, uuid_1.v4)();
9
+ const playerOut = (0, uuid_1.v4)();
10
+ const roster = [playerIn, playerOut];
11
+ const playerIndex = new Map(roster.map((id, i) => [id, i]));
12
+ (0, globals_1.it)('packs the injury flag as j=1 and round-trips it', () => {
13
+ const sub = service_1.Substitution.create({ playerId: playerIn, playerOut, injury: true });
14
+ const compact = (0, rally_event_1.transformToCompact)(sub, playerIndex);
15
+ (0, globals_1.expect)(compact.j).toBe(1);
16
+ const decoded = (0, rally_event_1.transformToSubstitution)(compact, roster);
17
+ (0, globals_1.expect)(decoded.injury).toBe(true);
18
+ (0, globals_1.expect)(decoded.playerId).toBe(playerIn);
19
+ (0, globals_1.expect)(decoded.playerOut).toBe(playerOut);
20
+ });
21
+ (0, globals_1.it)('omits j entirely for a normal substitution', () => {
22
+ const sub = service_1.Substitution.create({ playerId: playerIn, playerOut });
23
+ const compact = (0, rally_event_1.transformToCompact)(sub, playerIndex);
24
+ (0, globals_1.expect)('j' in compact).toBe(false);
25
+ const decoded = (0, rally_event_1.transformToSubstitution)(compact, roster);
26
+ (0, globals_1.expect)(decoded.injury).toBeUndefined();
27
+ });
28
+ (0, globals_1.it)('decodes a legacy compact event (no j key) as a non-injury substitution', () => {
29
+ const legacy = { p: 0, e: service_1.EventTypeEnum.SUBSTITUTION, o: 1 };
30
+ const decoded = (0, rally_event_1.transformToSubstitution)(legacy, roster);
31
+ (0, globals_1.expect)(decoded.injury).toBeUndefined();
32
+ });
33
+ });
@@ -9,6 +9,7 @@ export interface CompactEvent {
9
9
  b?: number[];
10
10
  l?: number;
11
11
  o?: number;
12
+ j?: number;
12
13
  }
13
14
  export declare function transformToCompact(evt: RallyEvent, playerIndex: Map<string, number>): CompactEvent;
14
15
  export declare function transformToBlock(event: CompactEvent, roster: string[]): Block;
@@ -29,6 +29,8 @@ function transformToCompact(evt, playerIndex) {
29
29
  }
30
30
  else if (evt instanceof service_1.Substitution) {
31
31
  out.o = playerIndex.get(evt.playerOut);
32
+ if (evt.injury === true)
33
+ out.j = 1;
32
34
  }
33
35
  return out;
34
36
  }
@@ -88,6 +90,7 @@ function transformToSpike(event, roster) {
88
90
  function transformToSubstitution(event, roster) {
89
91
  return service_1.Substitution.create({
90
92
  playerId: roster[event.p],
91
- playerOut: roster[event.o]
93
+ playerOut: roster[event.o],
94
+ injury: event.j === 1 ? true : undefined
92
95
  });
93
96
  }