ballrush-core 0.4.3 → 0.5.0
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.
- package/dist/mongo/index.d.ts +4 -0
- package/dist/mongo/index.js +4 -0
- package/dist/mongo/schemas/stat-group-activity-chart.schema.d.ts +27 -0
- package/dist/mongo/schemas/stat-group-activity-chart.schema.js +27 -0
- package/dist/mongo/schemas/stat-group-last-100-games.schema.d.ts +33 -0
- package/dist/mongo/schemas/stat-group-last-100-games.schema.js +31 -0
- package/dist/mongo/schemas/stat-group-profile.schema.d.ts +27 -0
- package/dist/mongo/schemas/stat-group-profile.schema.js +29 -0
- package/dist/mongo/schemas/stat-group-season.schema.d.ts +37 -0
- package/dist/mongo/schemas/stat-group-season.schema.js +39 -0
- package/dist/ports/index.d.ts +4 -0
- package/dist/ports/index.js +4 -0
- package/dist/ports/stat-group-activity-chart.repository.d.ts +14 -0
- package/dist/ports/stat-group-activity-chart.repository.js +2 -0
- package/dist/ports/stat-group-last-100-games.repository.d.ts +13 -0
- package/dist/ports/stat-group-last-100-games.repository.js +2 -0
- package/dist/ports/stat-group-profile.repository.d.ts +14 -0
- package/dist/ports/stat-group-profile.repository.js +2 -0
- package/dist/ports/stat-group-season.repository.d.ts +14 -0
- package/dist/ports/stat-group-season.repository.js +2 -0
- package/dist/repositories/index.d.ts +4 -0
- package/dist/repositories/index.js +4 -0
- package/dist/repositories/mongo/stat-group-activity-chart.repository.d.ts +13 -0
- package/dist/repositories/mongo/stat-group-activity-chart.repository.js +46 -0
- package/dist/repositories/mongo/stat-group-last-100-games.repository.d.ts +13 -0
- package/dist/repositories/mongo/stat-group-last-100-games.repository.js +49 -0
- package/dist/repositories/mongo/stat-group-profile.repository.d.ts +13 -0
- package/dist/repositories/mongo/stat-group-profile.repository.js +47 -0
- package/dist/repositories/mongo/stat-group-season.repository.d.ts +13 -0
- package/dist/repositories/mongo/stat-group-season.repository.js +54 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +4 -0
- package/dist/types/stat-group-activity-chart.types.d.ts +15 -0
- package/dist/types/stat-group-activity-chart.types.js +6 -0
- package/dist/types/stat-group-last-100-games.types.d.ts +21 -0
- package/dist/types/stat-group-last-100-games.types.js +6 -0
- package/dist/types/stat-group-profile.types.d.ts +19 -0
- package/dist/types/stat-group-profile.types.js +6 -0
- package/dist/types/stat-group-season.types.d.ts +25 -0
- package/dist/types/stat-group-season.types.js +6 -0
- package/package.json +1 -1
package/dist/mongo/index.d.ts
CHANGED
|
@@ -3,3 +3,7 @@ export * from "./schemas/event-template.schema";
|
|
|
3
3
|
export * from "./schemas/event.schema";
|
|
4
4
|
export * from "./schemas/group.schema";
|
|
5
5
|
export * from "./schemas/stat-group.schema";
|
|
6
|
+
export * from "./schemas/stat-group-profile.schema";
|
|
7
|
+
export * from "./schemas/stat-group-season.schema";
|
|
8
|
+
export * from "./schemas/stat-group-last-100-games.schema";
|
|
9
|
+
export * from "./schemas/stat-group-activity-chart.schema";
|
package/dist/mongo/index.js
CHANGED
|
@@ -19,3 +19,7 @@ __exportStar(require("./schemas/event-template.schema"), exports);
|
|
|
19
19
|
__exportStar(require("./schemas/event.schema"), exports);
|
|
20
20
|
__exportStar(require("./schemas/group.schema"), exports);
|
|
21
21
|
__exportStar(require("./schemas/stat-group.schema"), exports);
|
|
22
|
+
__exportStar(require("./schemas/stat-group-profile.schema"), exports);
|
|
23
|
+
__exportStar(require("./schemas/stat-group-season.schema"), exports);
|
|
24
|
+
__exportStar(require("./schemas/stat-group-last-100-games.schema"), exports);
|
|
25
|
+
__exportStar(require("./schemas/stat-group-activity-chart.schema"), exports);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Schema } from "mongoose";
|
|
2
|
+
/**
|
|
3
|
+
* Mongoose document interface for StatGroupActivityChart data point
|
|
4
|
+
*/
|
|
5
|
+
export interface StatGroupActivityDataPointDoc {
|
|
6
|
+
monthYear: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
matches: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Mongoose document interface for StatGroupActivityChart
|
|
12
|
+
*/
|
|
13
|
+
export interface StatGroupActivityChartDoc {
|
|
14
|
+
groupId: number;
|
|
15
|
+
timespan: 6 | 12;
|
|
16
|
+
data: StatGroupActivityDataPointDoc[];
|
|
17
|
+
updatedAt: Date;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Factory function to create StatGroupActivityChart schema
|
|
21
|
+
* Collection: stat_group_activity_charts
|
|
22
|
+
*/
|
|
23
|
+
export declare function createStatGroupActivityChartSchema(): Schema<StatGroupActivityChartDoc, import("mongoose").Model<StatGroupActivityChartDoc, any, any, any, import("mongoose").Document<unknown, any, StatGroupActivityChartDoc> & StatGroupActivityChartDoc & {
|
|
24
|
+
_id: import("mongoose").Types.ObjectId;
|
|
25
|
+
}, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, StatGroupActivityChartDoc, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<StatGroupActivityChartDoc>> & import("mongoose").FlatRecord<StatGroupActivityChartDoc> & {
|
|
26
|
+
_id: import("mongoose").Types.ObjectId;
|
|
27
|
+
}>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createStatGroupActivityChartSchema = createStatGroupActivityChartSchema;
|
|
4
|
+
const mongoose_1 = require("mongoose");
|
|
5
|
+
/**
|
|
6
|
+
* Factory function to create StatGroupActivityChart schema
|
|
7
|
+
* Collection: stat_group_activity_charts
|
|
8
|
+
*/
|
|
9
|
+
function createStatGroupActivityChartSchema() {
|
|
10
|
+
const DataPointSchema = new mongoose_1.Schema({
|
|
11
|
+
monthYear: { type: String, required: true }, // Format: "2024-10"
|
|
12
|
+
displayName: { type: String, required: true }, // Format: "Oct 2024"
|
|
13
|
+
matches: { type: Number, required: true, min: 0, default: 0 },
|
|
14
|
+
}, { _id: false });
|
|
15
|
+
const StatGroupActivityChartSchema = new mongoose_1.Schema({
|
|
16
|
+
groupId: { type: Number, required: true, index: true },
|
|
17
|
+
timespan: { type: Number, enum: [6, 12], required: true },
|
|
18
|
+
data: { type: [DataPointSchema], default: [] },
|
|
19
|
+
updatedAt: { type: Date, default: Date.now },
|
|
20
|
+
}, {
|
|
21
|
+
collection: 'stat_group_activity_charts',
|
|
22
|
+
versionKey: false,
|
|
23
|
+
});
|
|
24
|
+
// Composite unique index for groupId + timespan
|
|
25
|
+
StatGroupActivityChartSchema.index({ groupId: 1, timespan: 1 }, { unique: true });
|
|
26
|
+
return StatGroupActivityChartSchema;
|
|
27
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Schema } from "mongoose";
|
|
2
|
+
/**
|
|
3
|
+
* Mongoose document interface for StatGroupLast100Games player
|
|
4
|
+
*/
|
|
5
|
+
export interface StatGroupLast100GamesPlayerDoc {
|
|
6
|
+
userId: number;
|
|
7
|
+
playerName: string;
|
|
8
|
+
skillRating: number;
|
|
9
|
+
games: number;
|
|
10
|
+
wins: number;
|
|
11
|
+
draws: number;
|
|
12
|
+
losses: number;
|
|
13
|
+
winPercentage: number;
|
|
14
|
+
achievementsCount: number;
|
|
15
|
+
score: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Mongoose document interface for StatGroupLast100Games
|
|
19
|
+
*/
|
|
20
|
+
export interface StatGroupLast100GamesDoc {
|
|
21
|
+
groupId: number;
|
|
22
|
+
players: StatGroupLast100GamesPlayerDoc[];
|
|
23
|
+
updatedAt: Date;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Factory function to create StatGroupLast100Games schema
|
|
27
|
+
* Collection: stat_group_last_100_games
|
|
28
|
+
*/
|
|
29
|
+
export declare function createStatGroupLast100GamesSchema(): Schema<StatGroupLast100GamesDoc, import("mongoose").Model<StatGroupLast100GamesDoc, any, any, any, import("mongoose").Document<unknown, any, StatGroupLast100GamesDoc> & StatGroupLast100GamesDoc & {
|
|
30
|
+
_id: import("mongoose").Types.ObjectId;
|
|
31
|
+
}, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, StatGroupLast100GamesDoc, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<StatGroupLast100GamesDoc>> & import("mongoose").FlatRecord<StatGroupLast100GamesDoc> & {
|
|
32
|
+
_id: import("mongoose").Types.ObjectId;
|
|
33
|
+
}>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createStatGroupLast100GamesSchema = createStatGroupLast100GamesSchema;
|
|
4
|
+
const mongoose_1 = require("mongoose");
|
|
5
|
+
/**
|
|
6
|
+
* Factory function to create StatGroupLast100Games schema
|
|
7
|
+
* Collection: stat_group_last_100_games
|
|
8
|
+
*/
|
|
9
|
+
function createStatGroupLast100GamesSchema() {
|
|
10
|
+
const PlayerSchema = new mongoose_1.Schema({
|
|
11
|
+
userId: { type: Number, required: true },
|
|
12
|
+
playerName: { type: String, required: true },
|
|
13
|
+
skillRating: { type: Number, required: true, min: 0, default: 0 },
|
|
14
|
+
games: { type: Number, required: true, min: 0, max: 100, default: 0 },
|
|
15
|
+
wins: { type: Number, required: true, min: 0, default: 0 },
|
|
16
|
+
draws: { type: Number, required: true, min: 0, default: 0 },
|
|
17
|
+
losses: { type: Number, required: true, min: 0, default: 0 },
|
|
18
|
+
winPercentage: { type: Number, required: true, min: 0, max: 100, default: 0 },
|
|
19
|
+
achievementsCount: { type: Number, required: true, min: 0, default: 0 },
|
|
20
|
+
score: { type: Number, required: true, min: 0, default: 0 },
|
|
21
|
+
}, { _id: false });
|
|
22
|
+
const StatGroupLast100GamesSchema = new mongoose_1.Schema({
|
|
23
|
+
groupId: { type: Number, required: true, unique: true, index: true },
|
|
24
|
+
players: { type: [PlayerSchema], default: [] },
|
|
25
|
+
updatedAt: { type: Date, default: Date.now },
|
|
26
|
+
}, {
|
|
27
|
+
collection: 'stat_group_last_100_games',
|
|
28
|
+
versionKey: false,
|
|
29
|
+
});
|
|
30
|
+
return StatGroupLast100GamesSchema;
|
|
31
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Schema } from "mongoose";
|
|
2
|
+
/**
|
|
3
|
+
* Mongoose document interface for StatGroupProfile
|
|
4
|
+
*/
|
|
5
|
+
export interface StatGroupProfileDoc {
|
|
6
|
+
groupId: number;
|
|
7
|
+
groupName: string;
|
|
8
|
+
establishedDate: Date;
|
|
9
|
+
totalMembers: number;
|
|
10
|
+
activePlayers: number;
|
|
11
|
+
totalGames: number;
|
|
12
|
+
averageSkillRating: number;
|
|
13
|
+
currentSeason: {
|
|
14
|
+
seasonName: string;
|
|
15
|
+
status: 'in_progress' | 'completed';
|
|
16
|
+
} | null;
|
|
17
|
+
updatedAt: Date;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Factory function to create StatGroupProfile schema
|
|
21
|
+
* Collection: stat_group_profiles
|
|
22
|
+
*/
|
|
23
|
+
export declare function createStatGroupProfileSchema(): Schema<StatGroupProfileDoc, import("mongoose").Model<StatGroupProfileDoc, any, any, any, import("mongoose").Document<unknown, any, StatGroupProfileDoc> & StatGroupProfileDoc & {
|
|
24
|
+
_id: import("mongoose").Types.ObjectId;
|
|
25
|
+
}, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, StatGroupProfileDoc, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<StatGroupProfileDoc>> & import("mongoose").FlatRecord<StatGroupProfileDoc> & {
|
|
26
|
+
_id: import("mongoose").Types.ObjectId;
|
|
27
|
+
}>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createStatGroupProfileSchema = createStatGroupProfileSchema;
|
|
4
|
+
const mongoose_1 = require("mongoose");
|
|
5
|
+
/**
|
|
6
|
+
* Factory function to create StatGroupProfile schema
|
|
7
|
+
* Collection: stat_group_profiles
|
|
8
|
+
*/
|
|
9
|
+
function createStatGroupProfileSchema() {
|
|
10
|
+
const CurrentSeasonSchema = new mongoose_1.Schema({
|
|
11
|
+
seasonName: { type: String, required: true },
|
|
12
|
+
status: { type: String, enum: ['in_progress', 'completed'], required: true },
|
|
13
|
+
}, { _id: false });
|
|
14
|
+
const StatGroupProfileSchema = new mongoose_1.Schema({
|
|
15
|
+
groupId: { type: Number, required: true, unique: true, index: true },
|
|
16
|
+
groupName: { type: String, required: true },
|
|
17
|
+
establishedDate: { type: Date, required: true },
|
|
18
|
+
totalMembers: { type: Number, required: true, min: 0, default: 0 },
|
|
19
|
+
activePlayers: { type: Number, required: true, min: 0, default: 0 },
|
|
20
|
+
totalGames: { type: Number, required: true, min: 0, default: 0 },
|
|
21
|
+
averageSkillRating: { type: Number, required: true, min: 0, default: 0 },
|
|
22
|
+
currentSeason: { type: CurrentSeasonSchema, default: null },
|
|
23
|
+
updatedAt: { type: Date, default: Date.now },
|
|
24
|
+
}, {
|
|
25
|
+
collection: 'stat_group_profiles',
|
|
26
|
+
versionKey: false,
|
|
27
|
+
});
|
|
28
|
+
return StatGroupProfileSchema;
|
|
29
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Schema } from "mongoose";
|
|
2
|
+
/**
|
|
3
|
+
* Mongoose document interface for StatGroupSeason participant
|
|
4
|
+
*/
|
|
5
|
+
export interface StatGroupSeasonParticipantDoc {
|
|
6
|
+
userId: number;
|
|
7
|
+
playerName: string;
|
|
8
|
+
achievementsCount: number;
|
|
9
|
+
games: number;
|
|
10
|
+
wins: number;
|
|
11
|
+
losses: number;
|
|
12
|
+
draws: number;
|
|
13
|
+
winPercentage: number;
|
|
14
|
+
skillRating: number;
|
|
15
|
+
score: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Mongoose document interface for StatGroupSeason
|
|
19
|
+
*/
|
|
20
|
+
export interface StatGroupSeasonDoc {
|
|
21
|
+
groupId: number;
|
|
22
|
+
seasonName: string;
|
|
23
|
+
participants: StatGroupSeasonParticipantDoc[];
|
|
24
|
+
startDate: Date;
|
|
25
|
+
endDate: Date | null;
|
|
26
|
+
status: 'in_progress' | 'completed';
|
|
27
|
+
updatedAt: Date;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Factory function to create StatGroupSeason schema
|
|
31
|
+
* Collection: stat_group_seasons
|
|
32
|
+
*/
|
|
33
|
+
export declare function createStatGroupSeasonSchema(): Schema<StatGroupSeasonDoc, import("mongoose").Model<StatGroupSeasonDoc, any, any, any, import("mongoose").Document<unknown, any, StatGroupSeasonDoc> & StatGroupSeasonDoc & {
|
|
34
|
+
_id: import("mongoose").Types.ObjectId;
|
|
35
|
+
}, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, StatGroupSeasonDoc, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<StatGroupSeasonDoc>> & import("mongoose").FlatRecord<StatGroupSeasonDoc> & {
|
|
36
|
+
_id: import("mongoose").Types.ObjectId;
|
|
37
|
+
}>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createStatGroupSeasonSchema = createStatGroupSeasonSchema;
|
|
4
|
+
const mongoose_1 = require("mongoose");
|
|
5
|
+
/**
|
|
6
|
+
* Factory function to create StatGroupSeason schema
|
|
7
|
+
* Collection: stat_group_seasons
|
|
8
|
+
*/
|
|
9
|
+
function createStatGroupSeasonSchema() {
|
|
10
|
+
const ParticipantSchema = new mongoose_1.Schema({
|
|
11
|
+
userId: { type: Number, required: true },
|
|
12
|
+
playerName: { type: String, required: true },
|
|
13
|
+
achievementsCount: { type: Number, required: true, min: 0, default: 0 },
|
|
14
|
+
games: { type: Number, required: true, min: 0, default: 0 },
|
|
15
|
+
wins: { type: Number, required: true, min: 0, default: 0 },
|
|
16
|
+
losses: { type: Number, required: true, min: 0, default: 0 },
|
|
17
|
+
draws: { type: Number, required: true, min: 0, default: 0 },
|
|
18
|
+
winPercentage: { type: Number, required: true, min: 0, max: 100, default: 0 },
|
|
19
|
+
skillRating: { type: Number, required: true, min: 0, default: 0 },
|
|
20
|
+
score: { type: Number, required: true, min: 0, default: 0 },
|
|
21
|
+
}, { _id: false });
|
|
22
|
+
const StatGroupSeasonSchema = new mongoose_1.Schema({
|
|
23
|
+
groupId: { type: Number, required: true, index: true },
|
|
24
|
+
seasonName: { type: String, required: true },
|
|
25
|
+
participants: { type: [ParticipantSchema], default: [] },
|
|
26
|
+
startDate: { type: Date, required: true },
|
|
27
|
+
endDate: { type: Date, default: null },
|
|
28
|
+
status: { type: String, enum: ['in_progress', 'completed'], required: true },
|
|
29
|
+
updatedAt: { type: Date, default: Date.now },
|
|
30
|
+
}, {
|
|
31
|
+
collection: 'stat_group_seasons',
|
|
32
|
+
versionKey: false,
|
|
33
|
+
});
|
|
34
|
+
// Composite unique index for groupId + seasonName
|
|
35
|
+
StatGroupSeasonSchema.index({ groupId: 1, seasonName: 1 }, { unique: true });
|
|
36
|
+
// Index for listing seasons by group (newest first will be done in query)
|
|
37
|
+
StatGroupSeasonSchema.index({ groupId: 1, updatedAt: -1 });
|
|
38
|
+
return StatGroupSeasonSchema;
|
|
39
|
+
}
|
package/dist/ports/index.d.ts
CHANGED
|
@@ -3,3 +3,7 @@ export * from "./groups.repository";
|
|
|
3
3
|
export * from "./events.repository";
|
|
4
4
|
export * from "./event-templates.repository";
|
|
5
5
|
export * from "./stat-group.repository";
|
|
6
|
+
export * from "./stat-group-profile.repository";
|
|
7
|
+
export * from "./stat-group-season.repository";
|
|
8
|
+
export * from "./stat-group-last-100-games.repository";
|
|
9
|
+
export * from "./stat-group-activity-chart.repository";
|
package/dist/ports/index.js
CHANGED
|
@@ -19,3 +19,7 @@ __exportStar(require("./groups.repository"), exports);
|
|
|
19
19
|
__exportStar(require("./events.repository"), exports);
|
|
20
20
|
__exportStar(require("./event-templates.repository"), exports);
|
|
21
21
|
__exportStar(require("./stat-group.repository"), exports);
|
|
22
|
+
__exportStar(require("./stat-group-profile.repository"), exports);
|
|
23
|
+
__exportStar(require("./stat-group-season.repository"), exports);
|
|
24
|
+
__exportStar(require("./stat-group-last-100-games.repository"), exports);
|
|
25
|
+
__exportStar(require("./stat-group-activity-chart.repository"), exports);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StatGroupActivityChart } from "../types/stat-group-activity-chart.types";
|
|
2
|
+
/**
|
|
3
|
+
* Repository interface for StatGroupActivityChart
|
|
4
|
+
* Provides pre-aggregated time-series data for the group activity chart
|
|
5
|
+
*/
|
|
6
|
+
export interface StatGroupActivityChartRepository {
|
|
7
|
+
/**
|
|
8
|
+
* Finds activity chart data for a group within a timespan
|
|
9
|
+
* @param groupId - The group ID
|
|
10
|
+
* @param months - Number of months to look back (6 or 12)
|
|
11
|
+
* @returns Array of monthly activity data points
|
|
12
|
+
*/
|
|
13
|
+
findByGroupId(groupId: number, months: 6 | 12): Promise<StatGroupActivityChart | null>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StatGroupLast100Games } from "../types/stat-group-last-100-games.types";
|
|
2
|
+
/**
|
|
3
|
+
* Repository interface for StatGroupLast100Games
|
|
4
|
+
* Provides enriched statistics for players' last 100 games in a group
|
|
5
|
+
*/
|
|
6
|
+
export interface StatGroupLast100GamesRepository {
|
|
7
|
+
/**
|
|
8
|
+
* Finds enriched last 100 games statistics for all players in a group
|
|
9
|
+
* @param groupId - The group ID
|
|
10
|
+
* @returns Array of enriched statistics pre-sorted by score (descending)
|
|
11
|
+
*/
|
|
12
|
+
findByGroupId(groupId: number): Promise<StatGroupLast100Games | null>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StatGroupProfile } from "../types/stat-group-profile.types";
|
|
2
|
+
/**
|
|
3
|
+
* Repository interface for StatGroupProfile
|
|
4
|
+
* Provides pre-aggregated group profile data including header info,
|
|
5
|
+
* current season, and aggregate statistics
|
|
6
|
+
*/
|
|
7
|
+
export interface StatGroupProfileRepository {
|
|
8
|
+
/**
|
|
9
|
+
* Finds pre-aggregated group profile data by group ID
|
|
10
|
+
* @param groupId - The group ID
|
|
11
|
+
* @returns Group profile data or null if not found
|
|
12
|
+
*/
|
|
13
|
+
findByGroupId(groupId: number): Promise<StatGroupProfile | null>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StatGroupSeason } from "../types/stat-group-season.types";
|
|
2
|
+
/**
|
|
3
|
+
* Repository interface for StatGroupSeason
|
|
4
|
+
* Provides pre-aggregated season statistics including participant rankings
|
|
5
|
+
* and performance data
|
|
6
|
+
*/
|
|
7
|
+
export interface StatGroupSeasonRepository {
|
|
8
|
+
/**
|
|
9
|
+
* Finds all season statistics for a group
|
|
10
|
+
* @param groupId - The group ID
|
|
11
|
+
* @returns Array of season statistics ordered by season (newest first)
|
|
12
|
+
*/
|
|
13
|
+
findByGroupId(groupId: number): Promise<StatGroupSeason[]>;
|
|
14
|
+
}
|
|
@@ -3,3 +3,7 @@ export * from "./mongo/group.repository";
|
|
|
3
3
|
export * from "./mongo/event.repository";
|
|
4
4
|
export * from "./mongo/event-template.repository";
|
|
5
5
|
export * from "./mongo/stat-group.repository";
|
|
6
|
+
export * from "./mongo/stat-group-profile.repository";
|
|
7
|
+
export * from "./mongo/stat-group-season.repository";
|
|
8
|
+
export * from "./mongo/stat-group-last-100-games.repository";
|
|
9
|
+
export * from "./mongo/stat-group-activity-chart.repository";
|
|
@@ -19,3 +19,7 @@ __exportStar(require("./mongo/group.repository"), exports);
|
|
|
19
19
|
__exportStar(require("./mongo/event.repository"), exports);
|
|
20
20
|
__exportStar(require("./mongo/event-template.repository"), exports);
|
|
21
21
|
__exportStar(require("./mongo/stat-group.repository"), exports);
|
|
22
|
+
__exportStar(require("./mongo/stat-group-profile.repository"), exports);
|
|
23
|
+
__exportStar(require("./mongo/stat-group-season.repository"), exports);
|
|
24
|
+
__exportStar(require("./mongo/stat-group-last-100-games.repository"), exports);
|
|
25
|
+
__exportStar(require("./mongo/stat-group-activity-chart.repository"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Model } from "mongoose";
|
|
2
|
+
import type { StatGroupActivityChartRepository } from "../../ports/stat-group-activity-chart.repository";
|
|
3
|
+
import type { StatGroupActivityChartDoc } from "../../mongo/schemas/stat-group-activity-chart.schema";
|
|
4
|
+
import type { StatGroupActivityChart } from "../../types/stat-group-activity-chart.types";
|
|
5
|
+
/**
|
|
6
|
+
* MongoDB implementation of StatGroupActivityChartRepository
|
|
7
|
+
* Provides read-only access to pre-aggregated activity chart data
|
|
8
|
+
*/
|
|
9
|
+
export declare class MongoStatGroupActivityChartRepository implements StatGroupActivityChartRepository {
|
|
10
|
+
private readonly model;
|
|
11
|
+
constructor(model: Model<StatGroupActivityChartDoc>);
|
|
12
|
+
findByGroupId(groupId: number, months: 6 | 12): Promise<StatGroupActivityChart | null>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoStatGroupActivityChartRepository = void 0;
|
|
4
|
+
const errors_1 = require("../../errors");
|
|
5
|
+
/**
|
|
6
|
+
* MongoDB implementation of StatGroupActivityChartRepository
|
|
7
|
+
* Provides read-only access to pre-aggregated activity chart data
|
|
8
|
+
*/
|
|
9
|
+
class MongoStatGroupActivityChartRepository {
|
|
10
|
+
constructor(model) {
|
|
11
|
+
this.model = model;
|
|
12
|
+
}
|
|
13
|
+
async findByGroupId(groupId, months) {
|
|
14
|
+
try {
|
|
15
|
+
// Validate input
|
|
16
|
+
if (!groupId || groupId === 0) {
|
|
17
|
+
throw new errors_1.ValidationError('StatGroupActivityChart', 'groupId', groupId, 'must be a non-zero number');
|
|
18
|
+
}
|
|
19
|
+
if (months !== 6 && months !== 12) {
|
|
20
|
+
throw new errors_1.ValidationError('StatGroupActivityChart', 'months', months, 'must be 6 or 12');
|
|
21
|
+
}
|
|
22
|
+
const doc = await this.model.findOne({ groupId, timespan: months }).lean();
|
|
23
|
+
if (!doc) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
// Map document to domain type
|
|
27
|
+
return {
|
|
28
|
+
groupId: doc.groupId,
|
|
29
|
+
timespan: doc.timespan,
|
|
30
|
+
data: doc.data.map(d => ({
|
|
31
|
+
monthYear: d.monthYear,
|
|
32
|
+
displayName: d.displayName,
|
|
33
|
+
matches: d.matches,
|
|
34
|
+
})),
|
|
35
|
+
updatedAt: doc.updatedAt,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (error instanceof errors_1.ValidationError) {
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
throw new errors_1.QueryError('findByGroupId', 'StatGroupActivityChart', `${groupId}:${months}`, error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.MongoStatGroupActivityChartRepository = MongoStatGroupActivityChartRepository;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Model } from "mongoose";
|
|
2
|
+
import type { StatGroupLast100GamesRepository } from "../../ports/stat-group-last-100-games.repository";
|
|
3
|
+
import type { StatGroupLast100GamesDoc } from "../../mongo/schemas/stat-group-last-100-games.schema";
|
|
4
|
+
import type { StatGroupLast100Games } from "../../types/stat-group-last-100-games.types";
|
|
5
|
+
/**
|
|
6
|
+
* MongoDB implementation of StatGroupLast100GamesRepository
|
|
7
|
+
* Provides read-only access to enriched last 100 games statistics
|
|
8
|
+
*/
|
|
9
|
+
export declare class MongoStatGroupLast100GamesRepository implements StatGroupLast100GamesRepository {
|
|
10
|
+
private readonly model;
|
|
11
|
+
constructor(model: Model<StatGroupLast100GamesDoc>);
|
|
12
|
+
findByGroupId(groupId: number): Promise<StatGroupLast100Games | null>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoStatGroupLast100GamesRepository = void 0;
|
|
4
|
+
const errors_1 = require("../../errors");
|
|
5
|
+
/**
|
|
6
|
+
* MongoDB implementation of StatGroupLast100GamesRepository
|
|
7
|
+
* Provides read-only access to enriched last 100 games statistics
|
|
8
|
+
*/
|
|
9
|
+
class MongoStatGroupLast100GamesRepository {
|
|
10
|
+
constructor(model) {
|
|
11
|
+
this.model = model;
|
|
12
|
+
}
|
|
13
|
+
async findByGroupId(groupId) {
|
|
14
|
+
try {
|
|
15
|
+
// Validate input
|
|
16
|
+
if (!groupId || groupId === 0) {
|
|
17
|
+
throw new errors_1.ValidationError('StatGroupLast100Games', 'groupId', groupId, 'must be a non-zero number');
|
|
18
|
+
}
|
|
19
|
+
const doc = await this.model.findOne({ groupId }).lean();
|
|
20
|
+
if (!doc) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
// Map document to domain type
|
|
24
|
+
return {
|
|
25
|
+
groupId: doc.groupId,
|
|
26
|
+
players: doc.players.map(p => ({
|
|
27
|
+
userId: p.userId,
|
|
28
|
+
playerName: p.playerName,
|
|
29
|
+
skillRating: p.skillRating,
|
|
30
|
+
games: p.games,
|
|
31
|
+
wins: p.wins,
|
|
32
|
+
draws: p.draws,
|
|
33
|
+
losses: p.losses,
|
|
34
|
+
winPercentage: p.winPercentage,
|
|
35
|
+
achievementsCount: p.achievementsCount,
|
|
36
|
+
score: p.score,
|
|
37
|
+
})),
|
|
38
|
+
updatedAt: doc.updatedAt,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (error instanceof errors_1.ValidationError) {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
throw new errors_1.QueryError('findByGroupId', 'StatGroupLast100Games', groupId, error);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.MongoStatGroupLast100GamesRepository = MongoStatGroupLast100GamesRepository;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Model } from "mongoose";
|
|
2
|
+
import type { StatGroupProfileRepository } from "../../ports/stat-group-profile.repository";
|
|
3
|
+
import type { StatGroupProfileDoc } from "../../mongo/schemas/stat-group-profile.schema";
|
|
4
|
+
import type { StatGroupProfile } from "../../types/stat-group-profile.types";
|
|
5
|
+
/**
|
|
6
|
+
* MongoDB implementation of StatGroupProfileRepository
|
|
7
|
+
* Provides read-only access to pre-aggregated group profile data
|
|
8
|
+
*/
|
|
9
|
+
export declare class MongoStatGroupProfileRepository implements StatGroupProfileRepository {
|
|
10
|
+
private readonly model;
|
|
11
|
+
constructor(model: Model<StatGroupProfileDoc>);
|
|
12
|
+
findByGroupId(groupId: number): Promise<StatGroupProfile | null>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoStatGroupProfileRepository = void 0;
|
|
4
|
+
const errors_1 = require("../../errors");
|
|
5
|
+
/**
|
|
6
|
+
* MongoDB implementation of StatGroupProfileRepository
|
|
7
|
+
* Provides read-only access to pre-aggregated group profile data
|
|
8
|
+
*/
|
|
9
|
+
class MongoStatGroupProfileRepository {
|
|
10
|
+
constructor(model) {
|
|
11
|
+
this.model = model;
|
|
12
|
+
}
|
|
13
|
+
async findByGroupId(groupId) {
|
|
14
|
+
try {
|
|
15
|
+
// Validate input
|
|
16
|
+
if (!groupId || groupId === 0) {
|
|
17
|
+
throw new errors_1.ValidationError('StatGroupProfile', 'groupId', groupId, 'must be a non-zero number');
|
|
18
|
+
}
|
|
19
|
+
const doc = await this.model.findOne({ groupId }).lean();
|
|
20
|
+
if (!doc) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
// Map document to domain type
|
|
24
|
+
return {
|
|
25
|
+
groupId: doc.groupId,
|
|
26
|
+
groupName: doc.groupName,
|
|
27
|
+
establishedDate: doc.establishedDate,
|
|
28
|
+
totalMembers: doc.totalMembers,
|
|
29
|
+
activePlayers: doc.activePlayers,
|
|
30
|
+
totalGames: doc.totalGames,
|
|
31
|
+
averageSkillRating: doc.averageSkillRating,
|
|
32
|
+
currentSeason: doc.currentSeason ? {
|
|
33
|
+
seasonName: doc.currentSeason.seasonName,
|
|
34
|
+
status: doc.currentSeason.status,
|
|
35
|
+
} : null,
|
|
36
|
+
updatedAt: doc.updatedAt,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error instanceof errors_1.ValidationError) {
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
throw new errors_1.QueryError('findByGroupId', 'StatGroupProfile', groupId, error);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.MongoStatGroupProfileRepository = MongoStatGroupProfileRepository;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Model } from "mongoose";
|
|
2
|
+
import type { StatGroupSeasonRepository } from "../../ports/stat-group-season.repository";
|
|
3
|
+
import type { StatGroupSeasonDoc } from "../../mongo/schemas/stat-group-season.schema";
|
|
4
|
+
import type { StatGroupSeason } from "../../types/stat-group-season.types";
|
|
5
|
+
/**
|
|
6
|
+
* MongoDB implementation of StatGroupSeasonRepository
|
|
7
|
+
* Provides read-only access to pre-aggregated season statistics
|
|
8
|
+
*/
|
|
9
|
+
export declare class MongoStatGroupSeasonRepository implements StatGroupSeasonRepository {
|
|
10
|
+
private readonly model;
|
|
11
|
+
constructor(model: Model<StatGroupSeasonDoc>);
|
|
12
|
+
findByGroupId(groupId: number): Promise<StatGroupSeason[]>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoStatGroupSeasonRepository = void 0;
|
|
4
|
+
const errors_1 = require("../../errors");
|
|
5
|
+
/**
|
|
6
|
+
* MongoDB implementation of StatGroupSeasonRepository
|
|
7
|
+
* Provides read-only access to pre-aggregated season statistics
|
|
8
|
+
*/
|
|
9
|
+
class MongoStatGroupSeasonRepository {
|
|
10
|
+
constructor(model) {
|
|
11
|
+
this.model = model;
|
|
12
|
+
}
|
|
13
|
+
async findByGroupId(groupId) {
|
|
14
|
+
try {
|
|
15
|
+
// Validate input
|
|
16
|
+
if (!groupId || groupId === 0) {
|
|
17
|
+
throw new errors_1.ValidationError('StatGroupSeason', 'groupId', groupId, 'must be a non-zero number');
|
|
18
|
+
}
|
|
19
|
+
// Find all seasons for the group, sorted by start date (newest first)
|
|
20
|
+
const docs = await this.model
|
|
21
|
+
.find({ groupId })
|
|
22
|
+
.sort({ startDate: -1 })
|
|
23
|
+
.lean();
|
|
24
|
+
// Map documents to domain types
|
|
25
|
+
return docs.map(doc => ({
|
|
26
|
+
groupId: doc.groupId,
|
|
27
|
+
seasonName: doc.seasonName,
|
|
28
|
+
participants: doc.participants.map(p => ({
|
|
29
|
+
userId: p.userId,
|
|
30
|
+
playerName: p.playerName,
|
|
31
|
+
achievementsCount: p.achievementsCount,
|
|
32
|
+
games: p.games,
|
|
33
|
+
wins: p.wins,
|
|
34
|
+
losses: p.losses,
|
|
35
|
+
draws: p.draws,
|
|
36
|
+
winPercentage: p.winPercentage,
|
|
37
|
+
skillRating: p.skillRating,
|
|
38
|
+
score: p.score,
|
|
39
|
+
})),
|
|
40
|
+
startDate: doc.startDate,
|
|
41
|
+
endDate: doc.endDate,
|
|
42
|
+
status: doc.status,
|
|
43
|
+
updatedAt: doc.updatedAt,
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (error instanceof errors_1.ValidationError) {
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
throw new errors_1.QueryError('findByGroupId', 'StatGroupSeason', groupId, error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.MongoStatGroupSeasonRepository = MongoStatGroupSeasonRepository;
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/index.js
CHANGED
|
@@ -15,3 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./shared"), exports);
|
|
18
|
+
__exportStar(require("./stat-group-profile.types"), exports);
|
|
19
|
+
__exportStar(require("./stat-group-season.types"), exports);
|
|
20
|
+
__exportStar(require("./stat-group-last-100-games.types"), exports);
|
|
21
|
+
__exportStar(require("./stat-group-activity-chart.types"), exports);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statistics: Group Activity Chart Types
|
|
3
|
+
* Pre-aggregated time-series data for group activity visualization
|
|
4
|
+
*/
|
|
5
|
+
export interface StatGroupActivityDataPoint {
|
|
6
|
+
monthYear: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
matches: number;
|
|
9
|
+
}
|
|
10
|
+
export interface StatGroupActivityChart {
|
|
11
|
+
groupId: number;
|
|
12
|
+
timespan: 6 | 12;
|
|
13
|
+
data: StatGroupActivityDataPoint[];
|
|
14
|
+
updatedAt: Date;
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statistics: Group Last 100 Games Types
|
|
3
|
+
* Enriched statistics for players' last 100 games in a group
|
|
4
|
+
*/
|
|
5
|
+
export interface StatGroupLast100GamesPlayer {
|
|
6
|
+
userId: number;
|
|
7
|
+
playerName: string;
|
|
8
|
+
skillRating: number;
|
|
9
|
+
games: number;
|
|
10
|
+
wins: number;
|
|
11
|
+
draws: number;
|
|
12
|
+
losses: number;
|
|
13
|
+
winPercentage: number;
|
|
14
|
+
achievementsCount: number;
|
|
15
|
+
score: number;
|
|
16
|
+
}
|
|
17
|
+
export interface StatGroupLast100Games {
|
|
18
|
+
groupId: number;
|
|
19
|
+
players: StatGroupLast100GamesPlayer[];
|
|
20
|
+
updatedAt: Date;
|
|
21
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statistics: Group Profile Types
|
|
3
|
+
* Pre-aggregated group profile data for ballrush-api
|
|
4
|
+
*/
|
|
5
|
+
export interface StatGroupProfileCurrentSeason {
|
|
6
|
+
seasonName: string;
|
|
7
|
+
status: 'in_progress' | 'completed';
|
|
8
|
+
}
|
|
9
|
+
export interface StatGroupProfile {
|
|
10
|
+
groupId: number;
|
|
11
|
+
groupName: string;
|
|
12
|
+
establishedDate: Date;
|
|
13
|
+
totalMembers: number;
|
|
14
|
+
activePlayers: number;
|
|
15
|
+
totalGames: number;
|
|
16
|
+
averageSkillRating: number;
|
|
17
|
+
currentSeason: StatGroupProfileCurrentSeason | null;
|
|
18
|
+
updatedAt: Date;
|
|
19
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statistics: Group Season Types
|
|
3
|
+
* Pre-aggregated season statistics with participant rankings
|
|
4
|
+
*/
|
|
5
|
+
export interface StatGroupSeasonParticipant {
|
|
6
|
+
userId: number;
|
|
7
|
+
playerName: string;
|
|
8
|
+
achievementsCount: number;
|
|
9
|
+
games: number;
|
|
10
|
+
wins: number;
|
|
11
|
+
losses: number;
|
|
12
|
+
draws: number;
|
|
13
|
+
winPercentage: number;
|
|
14
|
+
skillRating: number;
|
|
15
|
+
score: number;
|
|
16
|
+
}
|
|
17
|
+
export interface StatGroupSeason {
|
|
18
|
+
groupId: number;
|
|
19
|
+
seasonName: string;
|
|
20
|
+
participants: StatGroupSeasonParticipant[];
|
|
21
|
+
startDate: Date;
|
|
22
|
+
endDate: Date | null;
|
|
23
|
+
status: 'in_progress' | 'completed';
|
|
24
|
+
updatedAt: Date;
|
|
25
|
+
}
|