volleyballsimtypes 0.0.489 → 0.0.492

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 (151) hide show
  1. package/dist/cjs/src/api/index.d.ts +4 -3
  2. package/dist/cjs/src/api/index.js +15 -0
  3. package/dist/cjs/src/api/tactics-player-refs.d.ts +13 -0
  4. package/dist/cjs/src/api/tactics-player-refs.js +43 -0
  5. package/dist/cjs/src/data/event-purge.d.ts +14 -0
  6. package/dist/cjs/src/data/event-purge.js +116 -0
  7. package/dist/cjs/src/data/index.d.ts +1 -0
  8. package/dist/cjs/src/data/index.js +1 -0
  9. package/dist/cjs/src/data/init-models.js +41 -0
  10. package/dist/cjs/src/data/models/competition.d.ts +1 -1
  11. package/dist/cjs/src/data/models/competition.js +1 -1
  12. package/dist/cjs/src/data/models/event-bot-team.d.ts +21 -0
  13. package/dist/cjs/src/data/models/event-bot-team.js +44 -0
  14. package/dist/cjs/src/data/models/event-competition.d.ts +29 -0
  15. package/dist/cjs/src/data/models/event-competition.js +52 -0
  16. package/dist/cjs/src/data/models/event-pack-player.d.ts +22 -0
  17. package/dist/cjs/src/data/models/event-pack-player.js +31 -0
  18. package/dist/cjs/src/data/models/event-pack.d.ts +37 -0
  19. package/dist/cjs/src/data/models/event-pack.js +55 -0
  20. package/dist/cjs/src/data/models/event-result.d.ts +34 -0
  21. package/dist/cjs/src/data/models/event-result.js +48 -0
  22. package/dist/cjs/src/data/models/event-squad.d.ts +30 -0
  23. package/dist/cjs/src/data/models/event-squad.js +46 -0
  24. package/dist/cjs/src/data/models/event.d.ts +51 -0
  25. package/dist/cjs/src/data/models/event.js +82 -0
  26. package/dist/cjs/src/data/models/index.d.ts +7 -0
  27. package/dist/cjs/src/data/models/index.js +7 -0
  28. package/dist/cjs/src/data/models/lineup-preset.d.ts +3 -1
  29. package/dist/cjs/src/data/models/lineup-preset.js +53 -0
  30. package/dist/cjs/src/data/models/tactics.d.ts +2 -2
  31. package/dist/cjs/src/data/transformers/tactics.test.js +19 -0
  32. package/dist/cjs/src/index.d.ts +1 -0
  33. package/dist/cjs/src/index.js +6 -0
  34. package/dist/cjs/src/service/competition/event-draft.d.ts +46 -0
  35. package/dist/cjs/src/service/competition/event-draft.js +85 -0
  36. package/dist/cjs/src/service/competition/event-draft.test.d.ts +1 -0
  37. package/dist/cjs/src/service/competition/event-draft.test.js +91 -0
  38. package/dist/cjs/src/service/competition/event-rewards.d.ts +26 -0
  39. package/dist/cjs/src/service/competition/event-rewards.js +49 -0
  40. package/dist/cjs/src/service/competition/event-rewards.test.d.ts +1 -0
  41. package/dist/cjs/src/service/competition/event-rewards.test.js +58 -0
  42. package/dist/cjs/src/service/competition/event-schedule.d.ts +126 -0
  43. package/dist/cjs/src/service/competition/event-schedule.js +141 -0
  44. package/dist/cjs/src/service/competition/event-schedule.test.d.ts +1 -0
  45. package/dist/cjs/src/service/competition/event-schedule.test.js +138 -0
  46. package/dist/cjs/src/service/competition/index.d.ts +3 -0
  47. package/dist/cjs/src/service/competition/index.js +3 -0
  48. package/dist/cjs/src/service/match/index.d.ts +1 -0
  49. package/dist/cjs/src/service/match/index.js +1 -0
  50. package/dist/cjs/src/service/match/match-generator.js +25 -48
  51. package/dist/cjs/src/service/match/match-generator.test.d.ts +1 -0
  52. package/dist/cjs/src/service/match/match-generator.test.js +48 -0
  53. package/dist/cjs/src/service/match/round-robin.d.ts +11 -0
  54. package/dist/cjs/src/service/match/round-robin.js +44 -0
  55. package/dist/cjs/src/service/match/round-robin.test.d.ts +1 -0
  56. package/dist/cjs/src/service/match/round-robin.test.js +71 -0
  57. package/dist/cjs/src/service/notification/catalog/en.json +21 -0
  58. package/dist/cjs/src/service/notification/catalog/es.json +21 -0
  59. package/dist/cjs/src/service/notification/catalog/fr.json +21 -0
  60. package/dist/cjs/src/service/notification/catalog/it.json +21 -0
  61. package/dist/cjs/src/service/notification/catalog/pl.json +21 -0
  62. package/dist/cjs/src/service/notification/catalog/pt-BR.json +21 -0
  63. package/dist/cjs/src/service/notification/catalog/tr.json +21 -0
  64. package/dist/cjs/src/service/notification/notification-type.d.ts +1 -1
  65. package/dist/cjs/src/service/notification/notification-type.js +6 -1
  66. package/dist/cjs/src/service/notification/notification.test.js +3 -1
  67. package/dist/cjs/src/service/notification/registry.js +52 -0
  68. package/dist/cjs/src/service/player/player-generator.d.ts +1 -0
  69. package/dist/cjs/src/service/player/player-generator.js +16 -1
  70. package/dist/cjs/src/service/team/blocking-preference.d.ts +3 -1
  71. package/dist/cjs/src/service/team/blocking-preference.js +7 -0
  72. package/dist/cjs/src/service/team/schemas/tactics.z.d.ts +2 -2
  73. package/dist/cjs/src/service/team/schemas/tactics.z.js +7 -2
  74. package/dist/cjs/src/service/team/schemas/tactics.z.test.js +32 -0
  75. package/dist/cjs/src/service/team/schemas/team.z.d.ts +2 -2
  76. package/dist/esm/src/api/index.d.ts +4 -3
  77. package/dist/esm/src/api/index.js +1 -0
  78. package/dist/esm/src/api/tactics-player-refs.d.ts +13 -0
  79. package/dist/esm/src/api/tactics-player-refs.js +40 -0
  80. package/dist/esm/src/data/event-purge.d.ts +14 -0
  81. package/dist/esm/src/data/event-purge.js +110 -0
  82. package/dist/esm/src/data/index.d.ts +1 -0
  83. package/dist/esm/src/data/index.js +1 -0
  84. package/dist/esm/src/data/init-models.js +42 -1
  85. package/dist/esm/src/data/models/competition.d.ts +1 -1
  86. package/dist/esm/src/data/models/competition.js +1 -1
  87. package/dist/esm/src/data/models/event-bot-team.d.ts +21 -0
  88. package/dist/esm/src/data/models/event-bot-team.js +40 -0
  89. package/dist/esm/src/data/models/event-competition.d.ts +29 -0
  90. package/dist/esm/src/data/models/event-competition.js +48 -0
  91. package/dist/esm/src/data/models/event-pack-player.d.ts +22 -0
  92. package/dist/esm/src/data/models/event-pack-player.js +27 -0
  93. package/dist/esm/src/data/models/event-pack.d.ts +37 -0
  94. package/dist/esm/src/data/models/event-pack.js +51 -0
  95. package/dist/esm/src/data/models/event-result.d.ts +34 -0
  96. package/dist/esm/src/data/models/event-result.js +44 -0
  97. package/dist/esm/src/data/models/event-squad.d.ts +30 -0
  98. package/dist/esm/src/data/models/event-squad.js +42 -0
  99. package/dist/esm/src/data/models/event.d.ts +51 -0
  100. package/dist/esm/src/data/models/event.js +78 -0
  101. package/dist/esm/src/data/models/index.d.ts +7 -0
  102. package/dist/esm/src/data/models/index.js +7 -0
  103. package/dist/esm/src/data/models/lineup-preset.d.ts +3 -1
  104. package/dist/esm/src/data/models/lineup-preset.js +20 -0
  105. package/dist/esm/src/data/models/tactics.d.ts +2 -2
  106. package/dist/esm/src/data/transformers/tactics.test.js +20 -1
  107. package/dist/esm/src/index.d.ts +1 -0
  108. package/dist/esm/src/index.js +4 -0
  109. package/dist/esm/src/service/competition/event-draft.d.ts +46 -0
  110. package/dist/esm/src/service/competition/event-draft.js +78 -0
  111. package/dist/esm/src/service/competition/event-draft.test.d.ts +1 -0
  112. package/dist/esm/src/service/competition/event-draft.test.js +89 -0
  113. package/dist/esm/src/service/competition/event-rewards.d.ts +26 -0
  114. package/dist/esm/src/service/competition/event-rewards.js +44 -0
  115. package/dist/esm/src/service/competition/event-rewards.test.d.ts +1 -0
  116. package/dist/esm/src/service/competition/event-rewards.test.js +56 -0
  117. package/dist/esm/src/service/competition/event-schedule.d.ts +126 -0
  118. package/dist/esm/src/service/competition/event-schedule.js +129 -0
  119. package/dist/esm/src/service/competition/event-schedule.test.d.ts +1 -0
  120. package/dist/esm/src/service/competition/event-schedule.test.js +136 -0
  121. package/dist/esm/src/service/competition/index.d.ts +3 -0
  122. package/dist/esm/src/service/competition/index.js +3 -0
  123. package/dist/esm/src/service/match/index.d.ts +1 -0
  124. package/dist/esm/src/service/match/index.js +1 -0
  125. package/dist/esm/src/service/match/match-generator.js +25 -48
  126. package/dist/esm/src/service/match/match-generator.test.d.ts +1 -0
  127. package/dist/esm/src/service/match/match-generator.test.js +43 -0
  128. package/dist/esm/src/service/match/round-robin.d.ts +11 -0
  129. package/dist/esm/src/service/match/round-robin.js +41 -0
  130. package/dist/esm/src/service/match/round-robin.test.d.ts +1 -0
  131. package/dist/esm/src/service/match/round-robin.test.js +69 -0
  132. package/dist/esm/src/service/notification/catalog/en.json +21 -0
  133. package/dist/esm/src/service/notification/catalog/es.json +21 -0
  134. package/dist/esm/src/service/notification/catalog/fr.json +21 -0
  135. package/dist/esm/src/service/notification/catalog/it.json +21 -0
  136. package/dist/esm/src/service/notification/catalog/pl.json +21 -0
  137. package/dist/esm/src/service/notification/catalog/pt-BR.json +21 -0
  138. package/dist/esm/src/service/notification/catalog/tr.json +21 -0
  139. package/dist/esm/src/service/notification/notification-type.d.ts +1 -1
  140. package/dist/esm/src/service/notification/notification-type.js +6 -1
  141. package/dist/esm/src/service/notification/notification.test.js +3 -1
  142. package/dist/esm/src/service/notification/registry.js +52 -0
  143. package/dist/esm/src/service/player/player-generator.d.ts +1 -0
  144. package/dist/esm/src/service/player/player-generator.js +15 -0
  145. package/dist/esm/src/service/team/blocking-preference.d.ts +3 -1
  146. package/dist/esm/src/service/team/blocking-preference.js +6 -1
  147. package/dist/esm/src/service/team/schemas/tactics.z.d.ts +2 -2
  148. package/dist/esm/src/service/team/schemas/tactics.z.js +7 -2
  149. package/dist/esm/src/service/team/schemas/tactics.z.test.js +32 -0
  150. package/dist/esm/src/service/team/schemas/team.z.d.ts +2 -2
  151. package/package.json +6 -1
@@ -0,0 +1,34 @@
1
+ import * as Sequelize from 'sequelize';
2
+ import { Model } from 'sequelize';
3
+ import type { EventKey } from '../../service/competition/event-schedule';
4
+ import { EventId, EventModel, TeamAttributes, TeamId, TeamModel } from '.';
5
+ export interface EventResultAttributes {
6
+ event_id: string;
7
+ /** The user's permanent team, so their accolades page can find it. */
8
+ team_id: string;
9
+ /** Place in the FINAL table, or null for an entrant who never reached it (group stage). */
10
+ position: number | null;
11
+ entrants: number;
12
+ key: EventKey;
13
+ ended_at: Date;
14
+ Event?: EventModel;
15
+ team?: TeamAttributes;
16
+ }
17
+ export type EventResultPk = 'event_id' | 'team_id';
18
+ export type EventResultId = EventResultModel[EventResultPk];
19
+ export type EventResultCreationAttributes = EventResultAttributes;
20
+ export declare class EventResultModel extends Model<EventResultAttributes, EventResultCreationAttributes> implements EventResultAttributes {
21
+ event_id: string;
22
+ team_id: string;
23
+ position: number | null;
24
+ entrants: number;
25
+ key: EventKey;
26
+ ended_at: Date;
27
+ Event: EventModel;
28
+ getEvent: Sequelize.BelongsToGetAssociationMixin<EventModel>;
29
+ setEvent: Sequelize.BelongsToSetAssociationMixin<EventModel, EventId>;
30
+ team: TeamModel;
31
+ getTeam: Sequelize.BelongsToGetAssociationMixin<TeamModel>;
32
+ setTeam: Sequelize.BelongsToSetAssociationMixin<TeamModel, TeamId>;
33
+ static initModel(sequelize: Sequelize.Sequelize): typeof EventResultModel;
34
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventResultModel = void 0;
4
+ const sequelize_1 = require("sequelize");
5
+ class EventResultModel extends sequelize_1.Model {
6
+ static initModel(sequelize) {
7
+ return EventResultModel.init({
8
+ event_id: {
9
+ type: sequelize_1.DataTypes.UUID,
10
+ allowNull: false,
11
+ primaryKey: true,
12
+ references: { model: 'Event', key: 'event_id' }
13
+ },
14
+ team_id: {
15
+ type: sequelize_1.DataTypes.UUID,
16
+ allowNull: false,
17
+ primaryKey: true,
18
+ references: { model: 'Team', key: 'team_id' }
19
+ },
20
+ position: {
21
+ type: sequelize_1.DataTypes.INTEGER,
22
+ allowNull: true
23
+ },
24
+ entrants: {
25
+ type: sequelize_1.DataTypes.INTEGER,
26
+ allowNull: false
27
+ },
28
+ key: {
29
+ type: sequelize_1.DataTypes.TEXT,
30
+ allowNull: false
31
+ },
32
+ ended_at: {
33
+ type: sequelize_1.DataTypes.DATE,
34
+ allowNull: false
35
+ }
36
+ }, {
37
+ sequelize,
38
+ tableName: 'EventResult',
39
+ schema: 'public',
40
+ timestamps: false,
41
+ indexes: [
42
+ { name: 'EventResult_pk', unique: true, fields: [{ name: 'event_id' }, { name: 'team_id' }] },
43
+ { name: 'EventResult_team_id_idx', fields: [{ name: 'team_id' }] }
44
+ ]
45
+ });
46
+ }
47
+ }
48
+ exports.EventResultModel = EventResultModel;
@@ -0,0 +1,30 @@
1
+ import * as Sequelize from 'sequelize';
2
+ import { Model, Optional } from 'sequelize';
3
+ import { EventId, EventModel, TeamAttributes, TeamId, TeamModel } from '.';
4
+ export interface EventSquadAttributes {
5
+ event_id: string;
6
+ user_id: string;
7
+ /** The throwaway Team (active = false) holding the drafted players. Deleted at purge. */
8
+ team_id: string;
9
+ complete: boolean;
10
+ drafted_at: Date | null;
11
+ team?: TeamAttributes;
12
+ }
13
+ export type EventSquadPk = 'event_id' | 'user_id';
14
+ export type EventSquadId = EventSquadModel[EventSquadPk];
15
+ export type EventSquadOptionalAttributes = 'complete' | 'drafted_at';
16
+ export type EventSquadCreationAttributes = Optional<EventSquadAttributes, EventSquadOptionalAttributes>;
17
+ export declare class EventSquadModel extends Model<EventSquadAttributes, EventSquadCreationAttributes> implements EventSquadAttributes {
18
+ event_id: string;
19
+ user_id: string;
20
+ team_id: string;
21
+ complete: boolean;
22
+ drafted_at: Date | null;
23
+ Event: EventModel;
24
+ getEvent: Sequelize.BelongsToGetAssociationMixin<EventModel>;
25
+ setEvent: Sequelize.BelongsToSetAssociationMixin<EventModel, EventId>;
26
+ team: TeamModel;
27
+ getTeam: Sequelize.BelongsToGetAssociationMixin<TeamModel>;
28
+ setTeam: Sequelize.BelongsToSetAssociationMixin<TeamModel, TeamId>;
29
+ static initModel(sequelize: Sequelize.Sequelize): typeof EventSquadModel;
30
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventSquadModel = void 0;
4
+ const sequelize_1 = require("sequelize");
5
+ class EventSquadModel extends sequelize_1.Model {
6
+ static initModel(sequelize) {
7
+ return EventSquadModel.init({
8
+ event_id: {
9
+ type: sequelize_1.DataTypes.UUID,
10
+ allowNull: false,
11
+ primaryKey: true,
12
+ references: { model: 'Event', key: 'event_id' }
13
+ },
14
+ user_id: {
15
+ type: sequelize_1.DataTypes.UUID,
16
+ allowNull: false,
17
+ primaryKey: true,
18
+ references: { model: 'AuthUser', key: 'user_id' }
19
+ },
20
+ team_id: {
21
+ type: sequelize_1.DataTypes.UUID,
22
+ allowNull: false,
23
+ references: { model: 'Team', key: 'team_id' }
24
+ },
25
+ complete: {
26
+ type: sequelize_1.DataTypes.BOOLEAN,
27
+ allowNull: false,
28
+ defaultValue: false
29
+ },
30
+ drafted_at: {
31
+ type: sequelize_1.DataTypes.DATE,
32
+ allowNull: true
33
+ }
34
+ }, {
35
+ sequelize,
36
+ tableName: 'EventSquad',
37
+ schema: 'public',
38
+ timestamps: false,
39
+ indexes: [
40
+ { name: 'EventSquad_pk', unique: true, fields: [{ name: 'event_id' }, { name: 'user_id' }] },
41
+ { name: 'EventSquad_team_id_idx', fields: [{ name: 'team_id' }] }
42
+ ]
43
+ });
44
+ }
45
+ }
46
+ exports.EventSquadModel = EventSquadModel;
@@ -0,0 +1,51 @@
1
+ import * as Sequelize from 'sequelize';
2
+ import { Model, Optional } from 'sequelize';
3
+ import type { EventFormat, EventKey, EventStatus } from '../../service/competition/event-schedule';
4
+ import { EventCompetitionAttributes, EventCompetitionModel, EventSquadAttributes, EventSquadModel } from '.';
5
+ export interface EventAttributes {
6
+ event_id: string;
7
+ key: EventKey;
8
+ format: EventFormat;
9
+ /** The rarity every player in an entrant's lineup must be. */
10
+ restriction: string;
11
+ status: EventStatus;
12
+ registration_opens_at: Date;
13
+ registration_closes_at: Date;
14
+ starts_at: Date;
15
+ final_starts_at: Date;
16
+ ends_at: Date;
17
+ purge_at: Date;
18
+ /** Set when the event's data was deleted; null while it still has competitions and matches. */
19
+ purged_at: Date | null;
20
+ /**
21
+ * Which of this event's notifications have already gone out, keyed by notification type. The tick runs every
22
+ * ~60 seconds, so without a marker every phase transition would re-send on every pass.
23
+ */
24
+ notified: Record<string, boolean>;
25
+ EventCompetitions?: EventCompetitionAttributes[];
26
+ EventSquads?: EventSquadAttributes[];
27
+ }
28
+ export type EventPk = 'event_id';
29
+ export type EventId = EventModel[EventPk];
30
+ export type EventOptionalAttributes = 'event_id' | 'purged_at' | 'notified';
31
+ export type EventCreationAttributes = Optional<EventAttributes, EventOptionalAttributes>;
32
+ export declare class EventModel extends Model<EventAttributes, EventCreationAttributes> implements EventAttributes {
33
+ event_id: string;
34
+ key: EventKey;
35
+ format: EventFormat;
36
+ restriction: string;
37
+ status: EventStatus;
38
+ registration_opens_at: Date;
39
+ registration_closes_at: Date;
40
+ starts_at: Date;
41
+ final_starts_at: Date;
42
+ ends_at: Date;
43
+ purge_at: Date;
44
+ purged_at: Date | null;
45
+ notified: Record<string, boolean>;
46
+ EventCompetitions: EventCompetitionModel[];
47
+ getEventCompetitions: Sequelize.HasManyGetAssociationsMixin<EventCompetitionModel>;
48
+ EventSquads: EventSquadModel[];
49
+ getEventSquads: Sequelize.HasManyGetAssociationsMixin<EventSquadModel>;
50
+ static initModel(sequelize: Sequelize.Sequelize): typeof EventModel;
51
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventModel = void 0;
4
+ const sequelize_1 = require("sequelize");
5
+ class EventModel extends sequelize_1.Model {
6
+ static initModel(sequelize) {
7
+ return EventModel.init({
8
+ event_id: {
9
+ type: sequelize_1.DataTypes.UUID,
10
+ allowNull: false,
11
+ primaryKey: true,
12
+ defaultValue: sequelize_1.DataTypes.UUIDV4
13
+ },
14
+ key: {
15
+ type: sequelize_1.DataTypes.TEXT,
16
+ allowNull: false
17
+ },
18
+ format: {
19
+ type: sequelize_1.DataTypes.TEXT,
20
+ allowNull: false
21
+ },
22
+ restriction: {
23
+ type: sequelize_1.DataTypes.TEXT,
24
+ allowNull: false
25
+ },
26
+ status: {
27
+ type: sequelize_1.DataTypes.TEXT,
28
+ allowNull: false
29
+ },
30
+ registration_opens_at: {
31
+ type: sequelize_1.DataTypes.DATE,
32
+ allowNull: false
33
+ },
34
+ registration_closes_at: {
35
+ type: sequelize_1.DataTypes.DATE,
36
+ allowNull: false
37
+ },
38
+ starts_at: {
39
+ type: sequelize_1.DataTypes.DATE,
40
+ allowNull: false
41
+ },
42
+ final_starts_at: {
43
+ type: sequelize_1.DataTypes.DATE,
44
+ allowNull: false
45
+ },
46
+ ends_at: {
47
+ type: sequelize_1.DataTypes.DATE,
48
+ allowNull: false
49
+ },
50
+ purge_at: {
51
+ type: sequelize_1.DataTypes.DATE,
52
+ allowNull: false
53
+ },
54
+ purged_at: {
55
+ type: sequelize_1.DataTypes.DATE,
56
+ allowNull: true
57
+ },
58
+ notified: {
59
+ type: sequelize_1.DataTypes.JSONB,
60
+ allowNull: false,
61
+ defaultValue: {}
62
+ }
63
+ }, {
64
+ sequelize,
65
+ tableName: 'Event',
66
+ schema: 'public',
67
+ timestamps: false,
68
+ indexes: [
69
+ {
70
+ name: 'Event_pk',
71
+ unique: true,
72
+ fields: [{ name: 'event_id' }]
73
+ },
74
+ {
75
+ name: 'Event_starts_at_idx',
76
+ fields: [{ name: 'starts_at' }]
77
+ }
78
+ ]
79
+ });
80
+ }
81
+ }
82
+ exports.EventModel = EventModel;
@@ -38,6 +38,13 @@ export * from './team';
38
38
  export * from './team-replacement';
39
39
  export * from './tactics';
40
40
  export * from './lineup-preset';
41
+ export * from './event';
42
+ export * from './event-competition';
43
+ export * from './event-bot-team';
44
+ export * from './event-squad';
45
+ export * from './event-pack';
46
+ export * from './event-pack-player';
47
+ export * from './event-result';
41
48
  export * from './match-preset';
42
49
  export * from './user-currency';
43
50
  export * from './user-player-progress';
@@ -54,6 +54,13 @@ __exportStar(require("./team"), exports);
54
54
  __exportStar(require("./team-replacement"), exports);
55
55
  __exportStar(require("./tactics"), exports);
56
56
  __exportStar(require("./lineup-preset"), exports);
57
+ __exportStar(require("./event"), exports);
58
+ __exportStar(require("./event-competition"), exports);
59
+ __exportStar(require("./event-bot-team"), exports);
60
+ __exportStar(require("./event-squad"), exports);
61
+ __exportStar(require("./event-pack"), exports);
62
+ __exportStar(require("./event-pack-player"), exports);
63
+ __exportStar(require("./event-result"), exports);
57
64
  __exportStar(require("./match-preset"), exports);
58
65
  __exportStar(require("./user-currency"), exports);
59
66
  __exportStar(require("./user-player-progress"), exports);
@@ -9,10 +9,11 @@ export interface LineupPresetAttributes {
9
9
  is_active: boolean;
10
10
  order_index: number;
11
11
  config: ApiTactics;
12
+ event_id: string | null;
12
13
  }
13
14
  export type LineupPresetPk = 'preset_id';
14
15
  export type LineupPresetId = LineupPresetModel[LineupPresetPk];
15
- export type LineupPresetOptionalAttributes = 'preset_id' | 'is_active';
16
+ export type LineupPresetOptionalAttributes = 'preset_id' | 'is_active' | 'event_id';
16
17
  export type LineupPresetCreationAttributes = Optional<LineupPresetAttributes, LineupPresetOptionalAttributes>;
17
18
  export declare class LineupPresetModel extends Model<LineupPresetAttributes, LineupPresetCreationAttributes> implements LineupPresetAttributes {
18
19
  preset_id: string;
@@ -21,6 +22,7 @@ export declare class LineupPresetModel extends Model<LineupPresetAttributes, Lin
21
22
  is_active: boolean;
22
23
  order_index: number;
23
24
  config: ApiTactics;
25
+ event_id: string | null;
24
26
  team: TeamModel;
25
27
  getTeam: Sequelize.BelongsToGetAssociationMixin<TeamModel>;
26
28
  setTeam: Sequelize.BelongsToSetAssociationMixin<TeamModel, TeamId>;
@@ -1,6 +1,40 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.LineupPresetModel = void 0;
37
+ const Sequelize = __importStar(require("sequelize"));
4
38
  const sequelize_1 = require("sequelize");
5
39
  class LineupPresetModel extends sequelize_1.Model {
6
40
  static initModel(sequelize) {
@@ -35,6 +69,15 @@ class LineupPresetModel extends sequelize_1.Model {
35
69
  config: {
36
70
  type: sequelize_1.DataTypes.JSONB,
37
71
  allowNull: false
72
+ },
73
+ event_id: {
74
+ type: sequelize_1.DataTypes.UUID,
75
+ allowNull: true,
76
+ defaultValue: null,
77
+ references: {
78
+ model: 'Event',
79
+ key: 'event_id'
80
+ }
38
81
  }
39
82
  }, {
40
83
  sequelize,
@@ -63,6 +106,16 @@ class LineupPresetModel extends sequelize_1.Model {
63
106
  { name: 'team_id' }
64
107
  ],
65
108
  where: { is_active: true }
109
+ },
110
+ {
111
+ // At most one event lineup per team per event, so the save endpoint can upsert safely.
112
+ name: 'LineupPreset_one_per_team_event',
113
+ unique: true,
114
+ fields: [
115
+ { name: 'team_id' },
116
+ { name: 'event_id' }
117
+ ],
118
+ where: { event_id: { [Sequelize.Op.ne]: null } }
66
119
  }
67
120
  ]
68
121
  });
@@ -1,7 +1,7 @@
1
1
  import * as Sequelize from 'sequelize';
2
2
  import { Model, Optional } from 'sequelize';
3
3
  import { PlayerId, TeamId, TeamModel } from '.';
4
- import { ConditionLogic, CourtPosition, EnergyBand, PinchCondition, RoleEnum, RotationSystemEnum, SubBackMode, SubBand, SubMode } from '../../service';
4
+ import { BlockingAssignment, ConditionLogic, CourtPosition, EnergyBand, PinchCondition, RotationSystemEnum, SubBackMode, SubBand, SubMode } from '../../service';
5
5
  export interface TacticsLineupAttributes {
6
6
  [CourtPosition.LIBERO_ZONE]?: PlayerId;
7
7
  [CourtPosition.LEFT_BACK]: PlayerId;
@@ -36,7 +36,7 @@ export interface OffensivePreferenceAttributes {
36
36
  }
37
37
  export interface BlockingPreferenceAttributes {
38
38
  rotation: number;
39
- targets: Record<PlayerId, RoleEnum>;
39
+ targets: Record<PlayerId, BlockingAssignment>;
40
40
  }
41
41
  export interface SystemSetAttributes {
42
42
  rotationSystem: RotationSystemEnum;
@@ -216,6 +216,25 @@ function makeTactics(designatedSubs) {
216
216
  const back = (0, tactics_1.transformToTactics)(attrs, roster);
217
217
  (0, globals_1.expect)(back.blockingPreferences[0].targets).toEqual({ [p4.id]: service_1.RoleEnum.OUTSIDE_HITTER, [p3.id]: service_1.RoleEnum.MIDDLE_BLOCKER });
218
218
  });
219
+ // NO_BLOCK rides in the same targets map as a commit assignment, so the transformers copy it wholesale with no
220
+ // mapping code. This pins that: the sentinel must survive the row round-trip verbatim, mixed with a commit, and
221
+ // in the per-set overrides. If it ever gets translated or dropped, a player silently starts blocking again.
222
+ (0, globals_1.it)('round-trips a NO_BLOCK assignment, mixed with a commit and in per-set overrides', () => {
223
+ const withNoBlock = service_1.Tactics.create({
224
+ lineup: { 4: p4, 3: p3, 2: p2, 5: p5, 6: p6, 1: p1, bench: [] },
225
+ liberoReplacements: [],
226
+ blockingPreferences: [{ rotation: 1, targets: { [p4.id]: service_1.NO_BLOCK, [p3.id]: service_1.RoleEnum.MIDDLE_BLOCKER } }],
227
+ blockingPreferenceSets: [[{ rotation: 2, targets: { [p2.id]: service_1.NO_BLOCK } }]]
228
+ });
229
+ const attrs = (0, tactics_1.transformFromTactics)(withNoBlock, 'team-1');
230
+ (0, globals_1.expect)(attrs.blocking_preferences).toEqual([
231
+ { rotation: 1, targets: { [p4.id]: service_1.NO_BLOCK, [p3.id]: service_1.RoleEnum.MIDDLE_BLOCKER } }
232
+ ]);
233
+ (0, globals_1.expect)(attrs.blocking_preference_sets).toEqual([[{ rotation: 2, targets: { [p2.id]: service_1.NO_BLOCK } }]]);
234
+ const back = (0, tactics_1.transformToTactics)(attrs, roster);
235
+ (0, globals_1.expect)(back.blockingPreferences[0].targets).toEqual({ [p4.id]: service_1.NO_BLOCK, [p3.id]: service_1.RoleEnum.MIDDLE_BLOCKER });
236
+ (0, globals_1.expect)(back.blockingPreferenceSets?.[0][0].targets).toEqual({ [p2.id]: service_1.NO_BLOCK });
237
+ });
219
238
  });
220
239
  (0, globals_1.describe)('libero injuries — service <-> row round-trip + lenient heal', () => {
221
240
  const country = (0, test_helpers_1.makeCountry)();
@@ -1,3 +1,4 @@
1
1
  export * from './service';
2
2
  export * from './data';
3
3
  export * from './stat-config';
4
+ export { collectTacticsPlayerIds } from './api/tactics-player-refs';
@@ -14,6 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.collectTacticsPlayerIds = void 0;
17
18
  __exportStar(require("./service"), exports);
18
19
  __exportStar(require("./data"), exports);
19
20
  __exportStar(require("./stat-config"), exports);
21
+ // Named rather than `export * from './api'`: the api module re-declares Tactics/Player/Team/Match as DTO
22
+ // shapes, which would collide with the service classes of the same name at the root. Consumers that want the
23
+ // DTO types import them from the `volleyballsimtypes/api` subpath.
24
+ var tactics_player_refs_1 = require("./api/tactics-player-refs");
25
+ Object.defineProperty(exports, "collectTacticsPlayerIds", { enumerable: true, get: function () { return tactics_player_refs_1.collectTacticsPlayerIds; } });
@@ -0,0 +1,46 @@
1
+ import { Country } from '../country';
2
+ import { Player, Rarity, Role } from '../player';
3
+ /** A pack targets one role, or ANY for the single free pick at the end. */
4
+ export type DraftRole = Role | 'ANY';
5
+ /** How many players an opened pack offers. */
6
+ export declare const PACK_SIZE = 4;
7
+ /**
8
+ * The pack sequence, in the order they are opened. One pick each, so this is also the squad: 2 setters,
9
+ * 4 outsides, 3 middles, 2 opposites, 2 liberos, plus one free pick, for a squad of 14 like every other team.
10
+ *
11
+ * Role-targeted rather than free choice on purpose: it makes a positionally valid squad impossible to get
12
+ * wrong, so nobody drafts six liberos and then cannot field a legal lineup.
13
+ */
14
+ export declare const DRAFT_PLAN: readonly DraftRole[];
15
+ /** The size of a drafted squad: one pick per pack. */
16
+ export declare const DRAFT_SQUAD_SIZE: number;
17
+ /**
18
+ * How far a pack's players may sit from the median for their rarity, as a fraction of the role score.
19
+ *
20
+ * The whole point of a generated draft is that the material is comparable: without this, one entrant opens a
21
+ * pack of duds while another opens a pack of stars and the event is decided before a ball is served. A player
22
+ * whose role score falls outside the band is rerolled.
23
+ */
24
+ export declare const PACK_QUALITY_TOLERANCE = 0.08;
25
+ export interface PackQualityBand {
26
+ readonly role: Role;
27
+ readonly min: number;
28
+ readonly max: number;
29
+ }
30
+ /**
31
+ * The in-band range for a role at a rarity, measured from a sample of freshly generated players rather than
32
+ * from hardcoded numbers, so it tracks the generator instead of drifting away from it whenever stats are
33
+ * retuned. Deterministic enough in aggregate: the sample is large and the band is a fraction of its median.
34
+ */
35
+ export declare function packQualityBand(country: Country, rarity: Rarity, role: Role, sampleSize?: number): PackQualityBand;
36
+ /**
37
+ * The players a pack offers: `PACK_SIZE` of the pack's role at the event's rarity, every one of them inside
38
+ * the fairness band.
39
+ *
40
+ * `pickRole` decides what an ANY pack rolls; it is passed in rather than chosen here so the caller controls the
41
+ * randomness (and a test can make it deterministic).
42
+ */
43
+ export declare function generatePack(country: Country, rarity: Rarity, packRole: DraftRole, band: (role: Role) => PackQualityBand, pickRole: (roles: readonly Role[]) => Role): Player[];
44
+ /** The role of the pack at `index`, or undefined once the draft is complete. */
45
+ export declare function draftPackRole(index: number): DraftRole | undefined;
46
+ export declare function isDraftComplete(picks: number): boolean;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PACK_QUALITY_TOLERANCE = exports.DRAFT_SQUAD_SIZE = exports.DRAFT_PLAN = exports.PACK_SIZE = void 0;
4
+ exports.packQualityBand = packQualityBand;
5
+ exports.generatePack = generatePack;
6
+ exports.draftPackRole = draftPackRole;
7
+ exports.isDraftComplete = isDraftComplete;
8
+ const player_1 = require("../player");
9
+ /** How many players an opened pack offers. */
10
+ exports.PACK_SIZE = 4;
11
+ /**
12
+ * The pack sequence, in the order they are opened. One pick each, so this is also the squad: 2 setters,
13
+ * 4 outsides, 3 middles, 2 opposites, 2 liberos, plus one free pick, for a squad of 14 like every other team.
14
+ *
15
+ * Role-targeted rather than free choice on purpose: it makes a positionally valid squad impossible to get
16
+ * wrong, so nobody drafts six liberos and then cannot field a legal lineup.
17
+ */
18
+ exports.DRAFT_PLAN = [
19
+ player_1.RoleEnum.SETTER, player_1.RoleEnum.SETTER,
20
+ player_1.RoleEnum.OUTSIDE_HITTER, player_1.RoleEnum.OUTSIDE_HITTER, player_1.RoleEnum.OUTSIDE_HITTER, player_1.RoleEnum.OUTSIDE_HITTER,
21
+ player_1.RoleEnum.MIDDLE_BLOCKER, player_1.RoleEnum.MIDDLE_BLOCKER, player_1.RoleEnum.MIDDLE_BLOCKER,
22
+ player_1.RoleEnum.OPPOSITE_HITTER, player_1.RoleEnum.OPPOSITE_HITTER,
23
+ player_1.RoleEnum.LIBERO, player_1.RoleEnum.LIBERO,
24
+ 'ANY'
25
+ ];
26
+ /** The size of a drafted squad: one pick per pack. */
27
+ exports.DRAFT_SQUAD_SIZE = exports.DRAFT_PLAN.length;
28
+ /** The role a free pack rolls its choices at, so an ANY pack still offers a coherent set. */
29
+ const ANY_PACK_ROLES = [
30
+ player_1.RoleEnum.SETTER, player_1.RoleEnum.OUTSIDE_HITTER, player_1.RoleEnum.MIDDLE_BLOCKER, player_1.RoleEnum.OPPOSITE_HITTER, player_1.RoleEnum.LIBERO
31
+ ];
32
+ /**
33
+ * How far a pack's players may sit from the median for their rarity, as a fraction of the role score.
34
+ *
35
+ * The whole point of a generated draft is that the material is comparable: without this, one entrant opens a
36
+ * pack of duds while another opens a pack of stars and the event is decided before a ball is served. A player
37
+ * whose role score falls outside the band is rerolled.
38
+ */
39
+ exports.PACK_QUALITY_TOLERANCE = 0.08;
40
+ /** Give up rerolling after this many attempts and take what we have, so generation can never spin forever. */
41
+ const MAX_REROLLS = 40;
42
+ /**
43
+ * The in-band range for a role at a rarity, measured from a sample of freshly generated players rather than
44
+ * from hardcoded numbers, so it tracks the generator instead of drifting away from it whenever stats are
45
+ * retuned. Deterministic enough in aggregate: the sample is large and the band is a fraction of its median.
46
+ */
47
+ function packQualityBand(country, rarity, role, sampleSize = 60) {
48
+ const scores = Array.from({ length: sampleSize }, () => (0, player_1.calculateRoleScore)(player_1.PlayerGenerator.generatePlayer(country, rarity, role, false, 1).stats, role)).sort((a, b) => a - b);
49
+ const median = scores[Math.floor(scores.length / 2)];
50
+ return {
51
+ role,
52
+ min: median * (1 - exports.PACK_QUALITY_TOLERANCE),
53
+ max: median * (1 + exports.PACK_QUALITY_TOLERANCE)
54
+ };
55
+ }
56
+ /**
57
+ * The players a pack offers: `PACK_SIZE` of the pack's role at the event's rarity, every one of them inside
58
+ * the fairness band.
59
+ *
60
+ * `pickRole` decides what an ANY pack rolls; it is passed in rather than chosen here so the caller controls the
61
+ * randomness (and a test can make it deterministic).
62
+ */
63
+ function generatePack(country, rarity, packRole, band, pickRole) {
64
+ const role = packRole === 'ANY' ? pickRole(ANY_PACK_ROLES) : packRole;
65
+ const { min, max } = band(role);
66
+ const players = [];
67
+ for (let i = 0; i < exports.PACK_SIZE; i++) {
68
+ let player = player_1.PlayerGenerator.generatePlayer(country, rarity, role, false, 1);
69
+ for (let attempt = 0; attempt < MAX_REROLLS; attempt++) {
70
+ const score = (0, player_1.calculateRoleScore)(player.stats, role);
71
+ if (score >= min && score <= max)
72
+ break;
73
+ player = player_1.PlayerGenerator.generatePlayer(country, rarity, role, false, 1);
74
+ }
75
+ players.push(player);
76
+ }
77
+ return players;
78
+ }
79
+ /** The role of the pack at `index`, or undefined once the draft is complete. */
80
+ function draftPackRole(index) {
81
+ return exports.DRAFT_PLAN[index];
82
+ }
83
+ function isDraftComplete(picks) {
84
+ return picks >= exports.DRAFT_SQUAD_SIZE;
85
+ }