volleyballsimtypes 0.0.491 → 0.0.493

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 (135) hide show
  1. package/dist/cjs/src/api/index.d.ts +2 -1
  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/index.d.ts +1 -0
  31. package/dist/cjs/src/index.js +6 -0
  32. package/dist/cjs/src/service/competition/event-draft.d.ts +40 -0
  33. package/dist/cjs/src/service/competition/event-draft.js +68 -0
  34. package/dist/cjs/src/service/competition/event-draft.test.d.ts +1 -0
  35. package/dist/cjs/src/service/competition/event-draft.test.js +118 -0
  36. package/dist/cjs/src/service/competition/event-rewards.d.ts +26 -0
  37. package/dist/cjs/src/service/competition/event-rewards.js +49 -0
  38. package/dist/cjs/src/service/competition/event-rewards.test.d.ts +1 -0
  39. package/dist/cjs/src/service/competition/event-rewards.test.js +58 -0
  40. package/dist/cjs/src/service/competition/event-schedule.d.ts +126 -0
  41. package/dist/cjs/src/service/competition/event-schedule.js +141 -0
  42. package/dist/cjs/src/service/competition/event-schedule.test.d.ts +1 -0
  43. package/dist/cjs/src/service/competition/event-schedule.test.js +138 -0
  44. package/dist/cjs/src/service/competition/index.d.ts +3 -0
  45. package/dist/cjs/src/service/competition/index.js +3 -0
  46. package/dist/cjs/src/service/match/index.d.ts +1 -0
  47. package/dist/cjs/src/service/match/index.js +1 -0
  48. package/dist/cjs/src/service/match/match-generator.js +25 -48
  49. package/dist/cjs/src/service/match/match-generator.test.d.ts +1 -0
  50. package/dist/cjs/src/service/match/match-generator.test.js +48 -0
  51. package/dist/cjs/src/service/match/round-robin.d.ts +11 -0
  52. package/dist/cjs/src/service/match/round-robin.js +44 -0
  53. package/dist/cjs/src/service/match/round-robin.test.d.ts +1 -0
  54. package/dist/cjs/src/service/match/round-robin.test.js +71 -0
  55. package/dist/cjs/src/service/notification/catalog/en.json +21 -0
  56. package/dist/cjs/src/service/notification/catalog/es.json +21 -0
  57. package/dist/cjs/src/service/notification/catalog/fr.json +21 -0
  58. package/dist/cjs/src/service/notification/catalog/it.json +21 -0
  59. package/dist/cjs/src/service/notification/catalog/pl.json +21 -0
  60. package/dist/cjs/src/service/notification/catalog/pt-BR.json +21 -0
  61. package/dist/cjs/src/service/notification/catalog/tr.json +21 -0
  62. package/dist/cjs/src/service/notification/notification-type.d.ts +1 -1
  63. package/dist/cjs/src/service/notification/notification-type.js +6 -1
  64. package/dist/cjs/src/service/notification/notification.test.js +3 -1
  65. package/dist/cjs/src/service/notification/registry.js +52 -0
  66. package/dist/cjs/src/service/player/player-generator.d.ts +2 -1
  67. package/dist/cjs/src/service/player/player-generator.js +37 -5
  68. package/dist/esm/src/api/index.d.ts +2 -1
  69. package/dist/esm/src/api/index.js +1 -0
  70. package/dist/esm/src/api/tactics-player-refs.d.ts +13 -0
  71. package/dist/esm/src/api/tactics-player-refs.js +40 -0
  72. package/dist/esm/src/data/event-purge.d.ts +14 -0
  73. package/dist/esm/src/data/event-purge.js +110 -0
  74. package/dist/esm/src/data/index.d.ts +1 -0
  75. package/dist/esm/src/data/index.js +1 -0
  76. package/dist/esm/src/data/init-models.js +42 -1
  77. package/dist/esm/src/data/models/competition.d.ts +1 -1
  78. package/dist/esm/src/data/models/competition.js +1 -1
  79. package/dist/esm/src/data/models/event-bot-team.d.ts +21 -0
  80. package/dist/esm/src/data/models/event-bot-team.js +40 -0
  81. package/dist/esm/src/data/models/event-competition.d.ts +29 -0
  82. package/dist/esm/src/data/models/event-competition.js +48 -0
  83. package/dist/esm/src/data/models/event-pack-player.d.ts +22 -0
  84. package/dist/esm/src/data/models/event-pack-player.js +27 -0
  85. package/dist/esm/src/data/models/event-pack.d.ts +37 -0
  86. package/dist/esm/src/data/models/event-pack.js +51 -0
  87. package/dist/esm/src/data/models/event-result.d.ts +34 -0
  88. package/dist/esm/src/data/models/event-result.js +44 -0
  89. package/dist/esm/src/data/models/event-squad.d.ts +30 -0
  90. package/dist/esm/src/data/models/event-squad.js +42 -0
  91. package/dist/esm/src/data/models/event.d.ts +51 -0
  92. package/dist/esm/src/data/models/event.js +78 -0
  93. package/dist/esm/src/data/models/index.d.ts +7 -0
  94. package/dist/esm/src/data/models/index.js +7 -0
  95. package/dist/esm/src/data/models/lineup-preset.d.ts +3 -1
  96. package/dist/esm/src/data/models/lineup-preset.js +20 -0
  97. package/dist/esm/src/index.d.ts +1 -0
  98. package/dist/esm/src/index.js +4 -0
  99. package/dist/esm/src/service/competition/event-draft.d.ts +40 -0
  100. package/dist/esm/src/service/competition/event-draft.js +62 -0
  101. package/dist/esm/src/service/competition/event-draft.test.d.ts +1 -0
  102. package/dist/esm/src/service/competition/event-draft.test.js +116 -0
  103. package/dist/esm/src/service/competition/event-rewards.d.ts +26 -0
  104. package/dist/esm/src/service/competition/event-rewards.js +44 -0
  105. package/dist/esm/src/service/competition/event-rewards.test.d.ts +1 -0
  106. package/dist/esm/src/service/competition/event-rewards.test.js +56 -0
  107. package/dist/esm/src/service/competition/event-schedule.d.ts +126 -0
  108. package/dist/esm/src/service/competition/event-schedule.js +129 -0
  109. package/dist/esm/src/service/competition/event-schedule.test.d.ts +1 -0
  110. package/dist/esm/src/service/competition/event-schedule.test.js +136 -0
  111. package/dist/esm/src/service/competition/index.d.ts +3 -0
  112. package/dist/esm/src/service/competition/index.js +3 -0
  113. package/dist/esm/src/service/match/index.d.ts +1 -0
  114. package/dist/esm/src/service/match/index.js +1 -0
  115. package/dist/esm/src/service/match/match-generator.js +25 -48
  116. package/dist/esm/src/service/match/match-generator.test.d.ts +1 -0
  117. package/dist/esm/src/service/match/match-generator.test.js +43 -0
  118. package/dist/esm/src/service/match/round-robin.d.ts +11 -0
  119. package/dist/esm/src/service/match/round-robin.js +41 -0
  120. package/dist/esm/src/service/match/round-robin.test.d.ts +1 -0
  121. package/dist/esm/src/service/match/round-robin.test.js +69 -0
  122. package/dist/esm/src/service/notification/catalog/en.json +21 -0
  123. package/dist/esm/src/service/notification/catalog/es.json +21 -0
  124. package/dist/esm/src/service/notification/catalog/fr.json +21 -0
  125. package/dist/esm/src/service/notification/catalog/it.json +21 -0
  126. package/dist/esm/src/service/notification/catalog/pl.json +21 -0
  127. package/dist/esm/src/service/notification/catalog/pt-BR.json +21 -0
  128. package/dist/esm/src/service/notification/catalog/tr.json +21 -0
  129. package/dist/esm/src/service/notification/notification-type.d.ts +1 -1
  130. package/dist/esm/src/service/notification/notification-type.js +6 -1
  131. package/dist/esm/src/service/notification/notification.test.js +3 -1
  132. package/dist/esm/src/service/notification/registry.js +52 -0
  133. package/dist/esm/src/service/player/player-generator.d.ts +2 -1
  134. package/dist/esm/src/service/player/player-generator.js +36 -4
  135. 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,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,40 @@
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 hard each rarity's recruits are skewed toward the top of their range when drafted in an event.
19
+ *
20
+ * Owner decision (2026-07-23): commons and rares are generated NEAR THEIR BEST, so a lower-rarity event still
21
+ * fields strong squads, while legendaries (and up) stay uniform, so a legendary event fields average
22
+ * legendaries rather than peak ones. The number is a generator skew strength (see randomIntSkewed): 0 is the
23
+ * plain uniform draw, and 2 was measured to land the typical common/rare recruit around the 80th percentile of
24
+ * its normal role-score distribution (the top fifth) while keeping real spread and never forcing a maxed
25
+ * player. This replaces the old reject-and-reroll fairness band: the skew lives in the generator, so the
26
+ * material is comparable in one draw.
27
+ */
28
+ export declare const EVENT_DRAFT_TOP_SKEW: Record<Rarity, number>;
29
+ /**
30
+ * The players a pack offers: `PACK_SIZE` of the pack's role at the event's rarity. The lower rarities are
31
+ * generated with a top-end skew (EVENT_DRAFT_TOP_SKEW) so their recruits cluster near the best; legendaries
32
+ * are left uniform.
33
+ *
34
+ * `pickRole` decides what an ANY pack rolls; it is passed in rather than chosen here so the caller controls the
35
+ * randomness (and a test can make it deterministic).
36
+ */
37
+ export declare function generatePack(country: Country, rarity: Rarity, packRole: DraftRole, pickRole: (roles: readonly Role[]) => Role): Player[];
38
+ /** The role of the pack at `index`, or undefined once the draft is complete. */
39
+ export declare function draftPackRole(index: number): DraftRole | undefined;
40
+ export declare function isDraftComplete(picks: number): boolean;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EVENT_DRAFT_TOP_SKEW = exports.DRAFT_SQUAD_SIZE = exports.DRAFT_PLAN = exports.PACK_SIZE = void 0;
4
+ exports.generatePack = generatePack;
5
+ exports.draftPackRole = draftPackRole;
6
+ exports.isDraftComplete = isDraftComplete;
7
+ const player_1 = require("../player");
8
+ /** How many players an opened pack offers. */
9
+ exports.PACK_SIZE = 4;
10
+ /**
11
+ * The pack sequence, in the order they are opened. One pick each, so this is also the squad: 2 setters,
12
+ * 4 outsides, 3 middles, 2 opposites, 2 liberos, plus one free pick, for a squad of 14 like every other team.
13
+ *
14
+ * Role-targeted rather than free choice on purpose: it makes a positionally valid squad impossible to get
15
+ * wrong, so nobody drafts six liberos and then cannot field a legal lineup.
16
+ */
17
+ exports.DRAFT_PLAN = [
18
+ player_1.RoleEnum.SETTER, player_1.RoleEnum.SETTER,
19
+ player_1.RoleEnum.OUTSIDE_HITTER, player_1.RoleEnum.OUTSIDE_HITTER, player_1.RoleEnum.OUTSIDE_HITTER, player_1.RoleEnum.OUTSIDE_HITTER,
20
+ player_1.RoleEnum.MIDDLE_BLOCKER, player_1.RoleEnum.MIDDLE_BLOCKER, player_1.RoleEnum.MIDDLE_BLOCKER,
21
+ player_1.RoleEnum.OPPOSITE_HITTER, player_1.RoleEnum.OPPOSITE_HITTER,
22
+ player_1.RoleEnum.LIBERO, player_1.RoleEnum.LIBERO,
23
+ 'ANY'
24
+ ];
25
+ /** The size of a drafted squad: one pick per pack. */
26
+ exports.DRAFT_SQUAD_SIZE = exports.DRAFT_PLAN.length;
27
+ /** The role a free pack rolls its choices at, so an ANY pack still offers a coherent set. */
28
+ const ANY_PACK_ROLES = [
29
+ player_1.RoleEnum.SETTER, player_1.RoleEnum.OUTSIDE_HITTER, player_1.RoleEnum.MIDDLE_BLOCKER, player_1.RoleEnum.OPPOSITE_HITTER, player_1.RoleEnum.LIBERO
30
+ ];
31
+ /**
32
+ * How hard each rarity's recruits are skewed toward the top of their range when drafted in an event.
33
+ *
34
+ * Owner decision (2026-07-23): commons and rares are generated NEAR THEIR BEST, so a lower-rarity event still
35
+ * fields strong squads, while legendaries (and up) stay uniform, so a legendary event fields average
36
+ * legendaries rather than peak ones. The number is a generator skew strength (see randomIntSkewed): 0 is the
37
+ * plain uniform draw, and 2 was measured to land the typical common/rare recruit around the 80th percentile of
38
+ * its normal role-score distribution (the top fifth) while keeping real spread and never forcing a maxed
39
+ * player. This replaces the old reject-and-reroll fairness band: the skew lives in the generator, so the
40
+ * material is comparable in one draw.
41
+ */
42
+ exports.EVENT_DRAFT_TOP_SKEW = {
43
+ [player_1.RarityEnum.COMMON]: 2,
44
+ [player_1.RarityEnum.RARE]: 2,
45
+ [player_1.RarityEnum.LEGENDARY]: 0,
46
+ [player_1.RarityEnum.MYTHIC]: 0,
47
+ [player_1.RarityEnum.SPECIAL]: 0
48
+ };
49
+ /**
50
+ * The players a pack offers: `PACK_SIZE` of the pack's role at the event's rarity. The lower rarities are
51
+ * generated with a top-end skew (EVENT_DRAFT_TOP_SKEW) so their recruits cluster near the best; legendaries
52
+ * are left uniform.
53
+ *
54
+ * `pickRole` decides what an ANY pack rolls; it is passed in rather than chosen here so the caller controls the
55
+ * randomness (and a test can make it deterministic).
56
+ */
57
+ function generatePack(country, rarity, packRole, pickRole) {
58
+ const role = packRole === 'ANY' ? pickRole(ANY_PACK_ROLES) : packRole;
59
+ const skew = exports.EVENT_DRAFT_TOP_SKEW[rarity] ?? 0;
60
+ return Array.from({ length: exports.PACK_SIZE }, () => player_1.PlayerGenerator.generatePlayer(country, rarity, role, false, 1, skew));
61
+ }
62
+ /** The role of the pack at `index`, or undefined once the draft is complete. */
63
+ function draftPackRole(index) {
64
+ return exports.DRAFT_PLAN[index];
65
+ }
66
+ function isDraftComplete(picks) {
67
+ return picks >= exports.DRAFT_SQUAD_SIZE;
68
+ }