ballrush-core 0.1.1 → 0.2.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/README.md +60 -11
- package/dist/domain/event-template.d.ts +84 -0
- package/dist/domain/event-template.js +86 -0
- package/dist/domain/event.d.ts +59 -0
- package/dist/domain/event.js +79 -0
- package/dist/domain/group.d.ts +31 -0
- package/dist/domain/group.js +81 -0
- package/dist/domain/index.d.ts +4 -0
- package/dist/domain/index.js +20 -0
- package/dist/domain/user.d.ts +20 -0
- package/dist/domain/user.js +38 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/mongo/schemas/event.schema.d.ts +1 -1
- package/dist/ports/event-templates.repository.d.ts +11 -0
- package/dist/ports/event-templates.repository.js +2 -0
- package/dist/ports/events.repository.d.ts +29 -0
- package/dist/ports/events.repository.js +2 -0
- package/dist/ports/groups.repository.d.ts +23 -0
- package/dist/ports/groups.repository.js +2 -0
- package/dist/ports/index.d.ts +4 -0
- package/dist/ports/index.js +20 -0
- package/dist/ports/users.repository.d.ts +7 -0
- package/dist/ports/users.repository.js +2 -0
- package/dist/repositories/index.d.ts +4 -0
- package/dist/repositories/index.js +20 -0
- package/dist/repositories/mongo/event-template.mapper.d.ts +6 -0
- package/dist/repositories/mongo/event-template.mapper.js +36 -0
- package/dist/repositories/mongo/event-template.repository.d.ts +16 -0
- package/dist/repositories/mongo/event-template.repository.js +39 -0
- package/dist/repositories/mongo/event.mapper.d.ts +7 -0
- package/dist/repositories/mongo/event.mapper.js +41 -0
- package/dist/repositories/mongo/event.repository.d.ts +18 -0
- package/dist/repositories/mongo/event.repository.js +53 -0
- package/dist/repositories/mongo/group.mapper.d.ts +7 -0
- package/dist/repositories/mongo/group.mapper.js +25 -0
- package/dist/repositories/mongo/group.repository.d.ts +13 -0
- package/dist/repositories/mongo/group.repository.js +30 -0
- package/dist/repositories/mongo/user.mapper.d.ts +9 -0
- package/dist/repositories/mongo/user.mapper.js +21 -0
- package/dist/repositories/mongo/user.repository.d.ts +12 -0
- package/dist/repositories/mongo/user.repository.js +24 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +17 -0
- package/dist/utils/rating.d.ts +4 -0
- package/dist/utils/rating.js +30 -0
- package/package.json +25 -5
package/README.md
CHANGED
|
@@ -1,21 +1,70 @@
|
|
|
1
1
|
# ballrush-core
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Contains TypeScript types and Mongoose schema factories (without models).
|
|
3
|
+
⚠️ **Note:** This library is for **personal use** in the Ballrush project.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
- 🗂 Shared **TypeScript types**
|
|
9
|
-
- 🏗 Mongoose **schema factories** (`createXSchema`) without `model()`
|
|
10
|
-
- 🎯 Designed for **DDD** (domain-driven design) architecture
|
|
11
|
-
- 🔌 Reusable in bot (`ballrush-bot`) and API (`ballrush-api`)
|
|
5
|
+
Shared core library for **Ballrush**.
|
|
6
|
+
Includes **TypeScript types**, **domain entities**, **repository ports & Mongo implementations**, **Mongoose schema factories** (no models), and **utils**.
|
|
12
7
|
|
|
13
|
-
##
|
|
8
|
+
## Features
|
|
9
|
+
- 🧠 **Domain**: `User`, `Group`, `Event`, `EventTemplate`
|
|
10
|
+
- 🔌 **Ports**: repository interfaces (DDD)
|
|
11
|
+
- 🗄️ **Mongo adapters**: ready-to-use repository implementations (accept Mongoose Models)
|
|
12
|
+
- 🏗 **Schema factories**: `createXSchema()` (without `model()`)
|
|
13
|
+
- 🧰 **Utils**: small reusable helpers (e.g., rating utils)
|
|
14
14
|
|
|
15
|
+
## Install
|
|
15
16
|
```bash
|
|
16
17
|
npm install ballrush-core
|
|
18
|
+
````
|
|
19
|
+
|
|
20
|
+
## Exports (subpaths)
|
|
21
|
+
|
|
22
|
+
* `ballrush-core/types`
|
|
23
|
+
* `ballrush-core/domain`
|
|
24
|
+
* `ballrush-core/ports`
|
|
25
|
+
* `ballrush-core/mongo`
|
|
26
|
+
* `ballrush-core/repositories`
|
|
27
|
+
* `ballrush-core/utils`
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
### 1) Create Mongoose models in your app
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { connection } from "mongoose";
|
|
35
|
+
import { createUserSchema, UserDoc } from "ballrush-core/mongo";
|
|
36
|
+
|
|
37
|
+
export const UserModel = connection.model<UserDoc>("User", createUserSchema());
|
|
17
38
|
```
|
|
18
39
|
|
|
19
|
-
|
|
40
|
+
### 2) Use Mongo repositories (bot or API)
|
|
20
41
|
|
|
21
|
-
|
|
42
|
+
```ts
|
|
43
|
+
import { MongoUsersRepository } from "ballrush-core/repositories";
|
|
44
|
+
import type { UsersRepository } from "ballrush-core/ports";
|
|
45
|
+
|
|
46
|
+
const usersRepo: UsersRepository = new MongoUsersRepository(UserModel);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 3) Work with domain entities
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { User } from "ballrush-core/domain";
|
|
53
|
+
|
|
54
|
+
const user = User.create({
|
|
55
|
+
userId: 1,
|
|
56
|
+
firstName: "Alex",
|
|
57
|
+
username: "alex"
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 4) Utils
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { addRating, getCurrentRating } from "ballrush-core/utils";
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
```
|
|
69
|
+
MIT © 2025 Serhii Zghama
|
|
70
|
+
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ParticipantEvent } from "../types";
|
|
2
|
+
export declare class EventTemplate {
|
|
3
|
+
private templateId;
|
|
4
|
+
private groupId;
|
|
5
|
+
private adminId;
|
|
6
|
+
private description;
|
|
7
|
+
private title;
|
|
8
|
+
private preViewImg;
|
|
9
|
+
private options;
|
|
10
|
+
private autoPost;
|
|
11
|
+
private defaultTime;
|
|
12
|
+
private defaultDayOfWeek;
|
|
13
|
+
private defaultLocation;
|
|
14
|
+
private defaultDuration;
|
|
15
|
+
private defaultParticipants;
|
|
16
|
+
private maxPlayers;
|
|
17
|
+
private createdAt;
|
|
18
|
+
constructor(templateId: number, groupId: number, adminId: number, description: string, title: string, preViewImg: string, options: string[], autoPost: boolean, defaultTime: string, defaultDayOfWeek: number, // 0..6
|
|
19
|
+
defaultLocation: string, defaultDuration: string, defaultParticipants: ParticipantEvent[], maxPlayers: number, createdAt: Date);
|
|
20
|
+
static create(p: {
|
|
21
|
+
templateId: number;
|
|
22
|
+
groupId: number;
|
|
23
|
+
adminId: number;
|
|
24
|
+
description: string;
|
|
25
|
+
title: string;
|
|
26
|
+
previewImg: string;
|
|
27
|
+
options: string[];
|
|
28
|
+
autoPost?: boolean;
|
|
29
|
+
defaultTime: string;
|
|
30
|
+
defaultDayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
31
|
+
defaultLocation: string;
|
|
32
|
+
defaultDuration: string;
|
|
33
|
+
defaultParticipants?: ParticipantEvent[];
|
|
34
|
+
maxPlayers: number;
|
|
35
|
+
createdAt?: Date;
|
|
36
|
+
}): EventTemplate;
|
|
37
|
+
getTemplateId(): number;
|
|
38
|
+
getGroupId(): number;
|
|
39
|
+
getAdminId(): number;
|
|
40
|
+
getDescription(): string;
|
|
41
|
+
getTitle(): string;
|
|
42
|
+
getPreViewImg(): string;
|
|
43
|
+
getOptions(): string[];
|
|
44
|
+
getAutoPost(): boolean;
|
|
45
|
+
getDefaultTime(): string;
|
|
46
|
+
getDefaultDayOfWeek(): number;
|
|
47
|
+
getDefaultLocation(): string;
|
|
48
|
+
getDefaultDuration(): string;
|
|
49
|
+
getDefaultParticipants(): ParticipantEvent[];
|
|
50
|
+
getMaxPlayers(): number;
|
|
51
|
+
getCreatedAt(): Date;
|
|
52
|
+
setGroupId(groupId: number): void;
|
|
53
|
+
setAdminId(adminId: number): void;
|
|
54
|
+
setDescription(description: string): void;
|
|
55
|
+
setTitle(title: string): void;
|
|
56
|
+
setPreViewImg(url: string): void;
|
|
57
|
+
setOptions(options: string[]): void;
|
|
58
|
+
setAutoPost(flag: boolean): void;
|
|
59
|
+
setDefaultTime(time: string): void;
|
|
60
|
+
setDefaultDayOfWeek(day: number): void;
|
|
61
|
+
setDefaultLocation(loc: string): void;
|
|
62
|
+
setDefaultDuration(duration: string): void;
|
|
63
|
+
setDefaultParticipants(participants: ParticipantEvent[]): void;
|
|
64
|
+
setMaxPlayers(n: number): void;
|
|
65
|
+
addDefaultParticipant(p: ParticipantEvent): void;
|
|
66
|
+
removeDefaultParticipant(userId: number): void;
|
|
67
|
+
toObject(): {
|
|
68
|
+
templateId: number;
|
|
69
|
+
groupId: number;
|
|
70
|
+
adminId: number;
|
|
71
|
+
description: string;
|
|
72
|
+
title: string;
|
|
73
|
+
preViewImg: string;
|
|
74
|
+
options: string[];
|
|
75
|
+
autoPost: boolean;
|
|
76
|
+
defaultTime: string;
|
|
77
|
+
defaultDayOfWeek: number;
|
|
78
|
+
defaultLocation: string;
|
|
79
|
+
defaultDuration: string;
|
|
80
|
+
defaultParticipants: ParticipantEvent[];
|
|
81
|
+
maxPlayers: number;
|
|
82
|
+
createdAt: Date;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EventTemplate = void 0;
|
|
4
|
+
class EventTemplate {
|
|
5
|
+
constructor(templateId, groupId, adminId, description, title, preViewImg, options, autoPost, defaultTime, defaultDayOfWeek, // 0..6
|
|
6
|
+
defaultLocation, defaultDuration, defaultParticipants, maxPlayers, createdAt) {
|
|
7
|
+
this.templateId = templateId;
|
|
8
|
+
this.groupId = groupId;
|
|
9
|
+
this.adminId = adminId;
|
|
10
|
+
this.description = description;
|
|
11
|
+
this.title = title;
|
|
12
|
+
this.preViewImg = preViewImg;
|
|
13
|
+
this.options = options;
|
|
14
|
+
this.autoPost = autoPost;
|
|
15
|
+
this.defaultTime = defaultTime;
|
|
16
|
+
this.defaultDayOfWeek = defaultDayOfWeek;
|
|
17
|
+
this.defaultLocation = defaultLocation;
|
|
18
|
+
this.defaultDuration = defaultDuration;
|
|
19
|
+
this.defaultParticipants = defaultParticipants;
|
|
20
|
+
this.maxPlayers = maxPlayers;
|
|
21
|
+
this.createdAt = createdAt;
|
|
22
|
+
}
|
|
23
|
+
static create(p) {
|
|
24
|
+
if (!p.title?.trim())
|
|
25
|
+
throw new Error("Title is required");
|
|
26
|
+
if (p.maxPlayers < 1)
|
|
27
|
+
throw new Error("maxPlayers must be >= 1");
|
|
28
|
+
return new EventTemplate(p.templateId, p.groupId, p.adminId, p.description.trim(), p.title.trim(), p.previewImg, [...p.options], p.autoPost ?? false, p.defaultTime, p.defaultDayOfWeek, p.defaultLocation, p.defaultDuration, [...(p.defaultParticipants ?? [])], p.maxPlayers, p.createdAt ?? new Date());
|
|
29
|
+
}
|
|
30
|
+
// ---- GETTERS
|
|
31
|
+
getTemplateId() { return this.templateId; }
|
|
32
|
+
getGroupId() { return this.groupId; }
|
|
33
|
+
getAdminId() { return this.adminId; }
|
|
34
|
+
getDescription() { return this.description; }
|
|
35
|
+
getTitle() { return this.title; }
|
|
36
|
+
getPreViewImg() { return this.preViewImg; }
|
|
37
|
+
getOptions() { return this.options; }
|
|
38
|
+
getAutoPost() { return this.autoPost; }
|
|
39
|
+
getDefaultTime() { return this.defaultTime; }
|
|
40
|
+
getDefaultDayOfWeek() { return this.defaultDayOfWeek; }
|
|
41
|
+
getDefaultLocation() { return this.defaultLocation; }
|
|
42
|
+
getDefaultDuration() { return this.defaultDuration; }
|
|
43
|
+
getDefaultParticipants() { return this.defaultParticipants; }
|
|
44
|
+
getMaxPlayers() { return this.maxPlayers; }
|
|
45
|
+
getCreatedAt() { return this.createdAt; }
|
|
46
|
+
// ---- SETTERS
|
|
47
|
+
setGroupId(groupId) { this.groupId = groupId; }
|
|
48
|
+
setAdminId(adminId) { this.adminId = adminId; }
|
|
49
|
+
setDescription(description) { this.description = description; }
|
|
50
|
+
setTitle(title) { this.title = title; }
|
|
51
|
+
setPreViewImg(url) { this.preViewImg = url; }
|
|
52
|
+
setOptions(options) { this.options = options; }
|
|
53
|
+
setAutoPost(flag) { this.autoPost = flag; }
|
|
54
|
+
setDefaultTime(time) { this.defaultTime = time; }
|
|
55
|
+
setDefaultDayOfWeek(day) { this.defaultDayOfWeek = day; }
|
|
56
|
+
setDefaultLocation(loc) { this.defaultLocation = loc; }
|
|
57
|
+
setDefaultDuration(duration) { this.defaultDuration = duration; }
|
|
58
|
+
setDefaultParticipants(participants) { this.defaultParticipants = participants; }
|
|
59
|
+
setMaxPlayers(n) { this.maxPlayers = n; }
|
|
60
|
+
addDefaultParticipant(p) {
|
|
61
|
+
this.defaultParticipants = [...this.defaultParticipants, p];
|
|
62
|
+
}
|
|
63
|
+
removeDefaultParticipant(userId) {
|
|
64
|
+
this.defaultParticipants = this.defaultParticipants.filter(p => p.userId !== userId);
|
|
65
|
+
}
|
|
66
|
+
toObject() {
|
|
67
|
+
return {
|
|
68
|
+
templateId: this.templateId,
|
|
69
|
+
groupId: this.groupId,
|
|
70
|
+
adminId: this.adminId,
|
|
71
|
+
description: this.description,
|
|
72
|
+
title: this.title,
|
|
73
|
+
preViewImg: this.preViewImg,
|
|
74
|
+
options: this.options,
|
|
75
|
+
autoPost: this.autoPost,
|
|
76
|
+
defaultTime: this.defaultTime,
|
|
77
|
+
defaultDayOfWeek: this.defaultDayOfWeek,
|
|
78
|
+
defaultLocation: this.defaultLocation,
|
|
79
|
+
defaultDuration: this.defaultDuration,
|
|
80
|
+
defaultParticipants: this.defaultParticipants,
|
|
81
|
+
maxPlayers: this.maxPlayers,
|
|
82
|
+
createdAt: this.createdAt,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.EventTemplate = EventTemplate;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { EventStatus, Match, ParticipantEvent, Team } from "../types";
|
|
2
|
+
export declare class Event {
|
|
3
|
+
private readonly eventId;
|
|
4
|
+
private readonly groupId;
|
|
5
|
+
private messageId;
|
|
6
|
+
private readonly templateId;
|
|
7
|
+
private date;
|
|
8
|
+
private participants;
|
|
9
|
+
private teams;
|
|
10
|
+
private matches;
|
|
11
|
+
private readonly createdBy;
|
|
12
|
+
private isRatingApplied;
|
|
13
|
+
private seasonName;
|
|
14
|
+
private reportMessageId?;
|
|
15
|
+
private status;
|
|
16
|
+
private constructor();
|
|
17
|
+
static create(params: {
|
|
18
|
+
eventId: number;
|
|
19
|
+
groupId: number;
|
|
20
|
+
templateId: number;
|
|
21
|
+
date: Date;
|
|
22
|
+
createdBy: number;
|
|
23
|
+
seasonName: string;
|
|
24
|
+
participants?: ParticipantEvent[];
|
|
25
|
+
teams?: Team[];
|
|
26
|
+
matches?: Match[];
|
|
27
|
+
messageId?: number;
|
|
28
|
+
reportMessageId?: number;
|
|
29
|
+
isRatingApplied?: boolean;
|
|
30
|
+
status?: EventStatus;
|
|
31
|
+
}): Event;
|
|
32
|
+
getEventId(): number;
|
|
33
|
+
getGroupId(): number;
|
|
34
|
+
getTemplateId(): number;
|
|
35
|
+
getMessageId(): number;
|
|
36
|
+
getReportMessageId(): number | undefined;
|
|
37
|
+
getDate(): Date;
|
|
38
|
+
getSeasonName(): string;
|
|
39
|
+
getParticipants(): ParticipantEvent[];
|
|
40
|
+
getTeams(): Team[];
|
|
41
|
+
getMatches(): Match[];
|
|
42
|
+
getCreatedBy(): number;
|
|
43
|
+
getStatus(): EventStatus;
|
|
44
|
+
getIsRatingApplied(): boolean;
|
|
45
|
+
renameSeason(newName: string): void;
|
|
46
|
+
reschedule(newDate: Date): void;
|
|
47
|
+
attachMessage(messageId: number): void;
|
|
48
|
+
attachReportMessage(reportMessageId: number): void;
|
|
49
|
+
replaceParticipants(list: ParticipantEvent[]): void;
|
|
50
|
+
replaceTeams(teams: Team[]): void;
|
|
51
|
+
replaceMatches(matches: Match[]): void;
|
|
52
|
+
markRatingApplied(): void;
|
|
53
|
+
start(): void;
|
|
54
|
+
complete(): void;
|
|
55
|
+
reset(): void;
|
|
56
|
+
isActive(): boolean;
|
|
57
|
+
isInProgress(): boolean;
|
|
58
|
+
isCompleted(): boolean;
|
|
59
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Event = void 0;
|
|
4
|
+
class Event {
|
|
5
|
+
constructor(eventId, groupId, messageId, templateId, date, participants, teams, matches, createdBy, isRatingApplied, seasonName, reportMessageId, status = "active") {
|
|
6
|
+
this.eventId = eventId;
|
|
7
|
+
this.groupId = groupId;
|
|
8
|
+
this.messageId = messageId;
|
|
9
|
+
this.templateId = templateId;
|
|
10
|
+
this.date = date;
|
|
11
|
+
this.participants = participants;
|
|
12
|
+
this.teams = teams;
|
|
13
|
+
this.matches = matches;
|
|
14
|
+
this.createdBy = createdBy;
|
|
15
|
+
this.isRatingApplied = isRatingApplied;
|
|
16
|
+
this.seasonName = seasonName;
|
|
17
|
+
this.reportMessageId = reportMessageId;
|
|
18
|
+
this.status = status;
|
|
19
|
+
}
|
|
20
|
+
static create(params) {
|
|
21
|
+
if (!params.seasonName) {
|
|
22
|
+
throw new Error("Event must have a season name");
|
|
23
|
+
}
|
|
24
|
+
return new Event(params.eventId, params.groupId, params.messageId ?? 0, params.templateId, params.date, params.participants ?? [], params.teams ?? [], params.matches ?? [], params.createdBy, params.isRatingApplied ?? false, params.seasonName, params.reportMessageId, params.status ?? "active");
|
|
25
|
+
}
|
|
26
|
+
getEventId() { return this.eventId; }
|
|
27
|
+
getGroupId() { return this.groupId; }
|
|
28
|
+
getTemplateId() { return this.templateId; }
|
|
29
|
+
getMessageId() { return this.messageId; }
|
|
30
|
+
getReportMessageId() { return this.reportMessageId; }
|
|
31
|
+
getDate() { return this.date; }
|
|
32
|
+
getSeasonName() { return this.seasonName; }
|
|
33
|
+
getParticipants() { return this.participants; }
|
|
34
|
+
getTeams() { return this.teams; }
|
|
35
|
+
getMatches() { return this.matches; }
|
|
36
|
+
getCreatedBy() { return this.createdBy; }
|
|
37
|
+
getStatus() { return this.status; }
|
|
38
|
+
getIsRatingApplied() { return this.isRatingApplied; }
|
|
39
|
+
renameSeason(newName) {
|
|
40
|
+
if (!newName)
|
|
41
|
+
throw new Error("Season name cannot be empty");
|
|
42
|
+
this.seasonName = newName;
|
|
43
|
+
}
|
|
44
|
+
reschedule(newDate) {
|
|
45
|
+
this.date = newDate;
|
|
46
|
+
}
|
|
47
|
+
attachMessage(messageId) {
|
|
48
|
+
this.messageId = messageId;
|
|
49
|
+
}
|
|
50
|
+
attachReportMessage(reportMessageId) {
|
|
51
|
+
this.reportMessageId = reportMessageId;
|
|
52
|
+
}
|
|
53
|
+
replaceParticipants(list) {
|
|
54
|
+
this.participants = list;
|
|
55
|
+
}
|
|
56
|
+
replaceTeams(teams) {
|
|
57
|
+
this.teams = teams;
|
|
58
|
+
}
|
|
59
|
+
replaceMatches(matches) {
|
|
60
|
+
this.matches = matches;
|
|
61
|
+
}
|
|
62
|
+
markRatingApplied() {
|
|
63
|
+
this.isRatingApplied = true;
|
|
64
|
+
}
|
|
65
|
+
start() {
|
|
66
|
+
this.status = "in_progress";
|
|
67
|
+
}
|
|
68
|
+
complete() {
|
|
69
|
+
this.status = "completed";
|
|
70
|
+
}
|
|
71
|
+
reset() {
|
|
72
|
+
this.status = "active";
|
|
73
|
+
this.isRatingApplied = false;
|
|
74
|
+
}
|
|
75
|
+
isActive() { return this.status === "active"; }
|
|
76
|
+
isInProgress() { return this.status === "in_progress"; }
|
|
77
|
+
isCompleted() { return this.status === "completed"; }
|
|
78
|
+
}
|
|
79
|
+
exports.Event = Event;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ParticipantGroup, PlayerPosition } from "../types";
|
|
2
|
+
export declare class Group {
|
|
3
|
+
private readonly groupId;
|
|
4
|
+
private readonly groupName;
|
|
5
|
+
private participants;
|
|
6
|
+
private timezone;
|
|
7
|
+
private isMessageLast;
|
|
8
|
+
private constructor();
|
|
9
|
+
static create(params: {
|
|
10
|
+
groupId: number;
|
|
11
|
+
groupName: string;
|
|
12
|
+
participants?: ParticipantGroup[];
|
|
13
|
+
timezone?: string;
|
|
14
|
+
isMessageLast?: boolean;
|
|
15
|
+
}): Group;
|
|
16
|
+
getGroupId(): number;
|
|
17
|
+
getGroupName(): string;
|
|
18
|
+
getTimezone(): string;
|
|
19
|
+
getIsMessageLast(): boolean;
|
|
20
|
+
getParticipants(): ParticipantGroup[];
|
|
21
|
+
getAdmins(): ParticipantGroup[];
|
|
22
|
+
getAdminIds(): number[];
|
|
23
|
+
setTimezone(tz: string): void;
|
|
24
|
+
setIsMessageLast(v: boolean): void;
|
|
25
|
+
addAdmin(userId: number): void;
|
|
26
|
+
removeAdmin(userId: number): void;
|
|
27
|
+
addParticipant(userId: number, isAdmin?: boolean, initialRating?: number): boolean;
|
|
28
|
+
removeParticipant(userId: number): void;
|
|
29
|
+
setPosition(userId: number, pos: PlayerPosition): void;
|
|
30
|
+
addRatingPoint(userId: number, value: number, at?: Date): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Group = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
class Group {
|
|
7
|
+
constructor(groupId, groupName, participants, timezone = "UTC+0", isMessageLast = false) {
|
|
8
|
+
this.groupId = groupId;
|
|
9
|
+
this.groupName = groupName;
|
|
10
|
+
this.participants = participants;
|
|
11
|
+
this.timezone = timezone;
|
|
12
|
+
this.isMessageLast = isMessageLast;
|
|
13
|
+
}
|
|
14
|
+
static create(params) {
|
|
15
|
+
if (!params.groupName)
|
|
16
|
+
throw new Error("Group name is required");
|
|
17
|
+
return new Group(params.groupId, params.groupName, (params.participants ?? []).map(p => ({ ...p, ratingHistory: [...p.ratingHistory] })), params.timezone ?? "UTC+0", params.isMessageLast ?? false);
|
|
18
|
+
}
|
|
19
|
+
getGroupId() { return this.groupId; }
|
|
20
|
+
getGroupName() { return this.groupName; }
|
|
21
|
+
getTimezone() { return this.timezone; }
|
|
22
|
+
getIsMessageLast() { return this.isMessageLast; }
|
|
23
|
+
getParticipants() { return this.participants; }
|
|
24
|
+
getAdmins() {
|
|
25
|
+
return this.participants.filter(p => p.isAdmin);
|
|
26
|
+
}
|
|
27
|
+
getAdminIds() {
|
|
28
|
+
return this.participants.filter(p => p.isAdmin).map(p => p.userId);
|
|
29
|
+
}
|
|
30
|
+
setTimezone(tz) {
|
|
31
|
+
this.timezone = tz;
|
|
32
|
+
}
|
|
33
|
+
setIsMessageLast(v) {
|
|
34
|
+
this.isMessageLast = v;
|
|
35
|
+
}
|
|
36
|
+
addAdmin(userId) {
|
|
37
|
+
const p = this.participants.find(x => x.userId === userId);
|
|
38
|
+
if (p) {
|
|
39
|
+
p.isAdmin = true;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
this.participants.push({
|
|
43
|
+
userId,
|
|
44
|
+
position: types_1.PlayerPosition.UN,
|
|
45
|
+
ratingHistory: (0, utils_1.addRating)([], 0),
|
|
46
|
+
isAdmin: true,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
removeAdmin(userId) {
|
|
51
|
+
const p = this.participants.find(x => x.userId === userId);
|
|
52
|
+
if (p)
|
|
53
|
+
p.isAdmin = false;
|
|
54
|
+
}
|
|
55
|
+
addParticipant(userId, isAdmin = false, initialRating = 0) {
|
|
56
|
+
if (this.participants.some(p => p.userId === userId))
|
|
57
|
+
return false;
|
|
58
|
+
this.participants.push({
|
|
59
|
+
userId,
|
|
60
|
+
position: types_1.PlayerPosition.UN,
|
|
61
|
+
ratingHistory: (0, utils_1.addRating)([], initialRating),
|
|
62
|
+
isAdmin,
|
|
63
|
+
});
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
removeParticipant(userId) {
|
|
67
|
+
this.participants = this.participants.filter(p => p.userId !== userId);
|
|
68
|
+
}
|
|
69
|
+
setPosition(userId, pos) {
|
|
70
|
+
const p = this.participants.find(x => x.userId === userId);
|
|
71
|
+
if (p)
|
|
72
|
+
p.position = pos;
|
|
73
|
+
}
|
|
74
|
+
addRatingPoint(userId, value, at = new Date()) {
|
|
75
|
+
const p = this.participants.find(x => x.userId === userId);
|
|
76
|
+
if (!p)
|
|
77
|
+
return;
|
|
78
|
+
p.ratingHistory = (0, utils_1.addRating)(p.ratingHistory, value, at);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.Group = Group;
|
|
@@ -0,0 +1,20 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./user"), exports);
|
|
18
|
+
__exportStar(require("./group"), exports);
|
|
19
|
+
__exportStar(require("./event"), exports);
|
|
20
|
+
__exportStar(require("./event-template"), exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LanguageType } from "../types";
|
|
2
|
+
export declare class User {
|
|
3
|
+
private readonly userId;
|
|
4
|
+
private readonly firstName;
|
|
5
|
+
private readonly username?;
|
|
6
|
+
private language;
|
|
7
|
+
private constructor();
|
|
8
|
+
static create(params: {
|
|
9
|
+
userId: number;
|
|
10
|
+
firstName: string;
|
|
11
|
+
username?: string;
|
|
12
|
+
language?: LanguageType;
|
|
13
|
+
}): User;
|
|
14
|
+
getUserId(): number;
|
|
15
|
+
getFirstName(): string;
|
|
16
|
+
getUsername(): string | undefined;
|
|
17
|
+
getLanguage(): LanguageType;
|
|
18
|
+
setLanguage(language: LanguageType): void;
|
|
19
|
+
getFullName(): string;
|
|
20
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.User = void 0;
|
|
4
|
+
class User {
|
|
5
|
+
constructor(userId, firstName, username, language = "ru") {
|
|
6
|
+
this.userId = userId;
|
|
7
|
+
this.firstName = firstName;
|
|
8
|
+
this.username = username;
|
|
9
|
+
this.language = language;
|
|
10
|
+
}
|
|
11
|
+
static create(params) {
|
|
12
|
+
if (!params.firstName || !params.userId) {
|
|
13
|
+
throw new Error("User must have a first name and userId");
|
|
14
|
+
}
|
|
15
|
+
return new User(params.userId, params.firstName, params.username, params.language ?? "ru");
|
|
16
|
+
}
|
|
17
|
+
getUserId() {
|
|
18
|
+
return this.userId;
|
|
19
|
+
}
|
|
20
|
+
getFirstName() {
|
|
21
|
+
return this.firstName;
|
|
22
|
+
}
|
|
23
|
+
getUsername() {
|
|
24
|
+
return this.username;
|
|
25
|
+
}
|
|
26
|
+
getLanguage() {
|
|
27
|
+
return this.language;
|
|
28
|
+
}
|
|
29
|
+
setLanguage(language) {
|
|
30
|
+
this.language = language;
|
|
31
|
+
}
|
|
32
|
+
getFullName() {
|
|
33
|
+
return this.username
|
|
34
|
+
? `${this.firstName} (${this.username})`
|
|
35
|
+
: this.firstName;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.User = User;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -15,4 +15,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./utils"), exports);
|
|
19
|
+
__exportStar(require("./domain"), exports);
|
|
20
|
+
__exportStar(require("./ports"), exports);
|
|
18
21
|
__exportStar(require("./mongo"), exports);
|
|
22
|
+
__exportStar(require("./repositories"), exports);
|
|
@@ -12,7 +12,7 @@ export interface EventDoc {
|
|
|
12
12
|
matches: Match[];
|
|
13
13
|
seasonName: string;
|
|
14
14
|
status: EventStatus;
|
|
15
|
-
isRatingApplied
|
|
15
|
+
isRatingApplied: boolean;
|
|
16
16
|
reportMessageId?: number;
|
|
17
17
|
}
|
|
18
18
|
export declare function createParticipantEventSchema(): Schema<ParticipantEvent, import("mongoose").Model<ParticipantEvent, any, any, any, import("mongoose").Document<unknown, any, ParticipantEvent> & ParticipantEvent & {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { EventTemplate } from "../domain/event-template";
|
|
2
|
+
import { ParticipantEvent } from "../types";
|
|
3
|
+
export interface IEventTemplatesRepository {
|
|
4
|
+
getById(templateId: number): Promise<EventTemplate | null>;
|
|
5
|
+
getByGroupId(groupId: number): Promise<EventTemplate[]>;
|
|
6
|
+
getAll(): Promise<EventTemplate[]>;
|
|
7
|
+
createFromDomain(entity: EventTemplate): Promise<EventTemplate | null>;
|
|
8
|
+
updateFromDomain(entity: EventTemplate): Promise<EventTemplate | null>;
|
|
9
|
+
deleteById(templateId: number): Promise<void>;
|
|
10
|
+
setDefaultParticipants(templateId: number, participants: ParticipantEvent[]): Promise<EventTemplate | null>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Event } from "../domain/event";
|
|
2
|
+
import { ParticipantEvent, Team, Match, EventStatus } from "../types";
|
|
3
|
+
export type EventWrite = {
|
|
4
|
+
eventId: number;
|
|
5
|
+
groupId: number;
|
|
6
|
+
messageId: number;
|
|
7
|
+
templateId: number;
|
|
8
|
+
date: Date;
|
|
9
|
+
createdBy: number;
|
|
10
|
+
participants: ParticipantEvent[];
|
|
11
|
+
teams: Team[];
|
|
12
|
+
matches: Match[];
|
|
13
|
+
status: EventStatus;
|
|
14
|
+
seasonName: string;
|
|
15
|
+
isRatingApplied?: boolean;
|
|
16
|
+
reportMessageId?: number;
|
|
17
|
+
};
|
|
18
|
+
export interface EventsRepository {
|
|
19
|
+
create(eventData: EventWrite): Promise<Event>;
|
|
20
|
+
findById(eventId: number): Promise<Event | null>;
|
|
21
|
+
findByGroupAndStatuses(groupId: number, statuses: string[]): Promise<Event | null>;
|
|
22
|
+
findByTemplateAndGroup(templateId: number, groupId: number): Promise<Event | null>;
|
|
23
|
+
update(eventId: number, updates: Partial<EventWrite>): Promise<Event | null>;
|
|
24
|
+
findLastByGroup(groupId: number): Promise<Event | null>;
|
|
25
|
+
findAllByGroup(groupId: number): Promise<Event[]>;
|
|
26
|
+
countEvents(): Promise<number>;
|
|
27
|
+
countMatches(): Promise<number>;
|
|
28
|
+
getAll(): Promise<Event[]>;
|
|
29
|
+
}
|