@sideline/domain 0.1.2 → 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/dist/cjs/api/AgeThresholdApi.js +86 -0
- package/dist/cjs/api/AgeThresholdApi.js.map +1 -0
- package/dist/cjs/api/Auth.js +33 -2
- package/dist/cjs/api/Auth.js.map +1 -1
- package/dist/cjs/api/Invite.js +1 -2
- package/dist/cjs/api/Invite.js.map +1 -1
- package/dist/cjs/api/NotificationApi.js +42 -0
- package/dist/cjs/api/NotificationApi.js.map +1 -0
- package/dist/cjs/api/RoleApi.js +123 -0
- package/dist/cjs/api/RoleApi.js.map +1 -0
- package/dist/cjs/api/Roster.js +159 -0
- package/dist/cjs/api/Roster.js.map +1 -0
- package/dist/cjs/api/SubgroupApi.js +122 -0
- package/dist/cjs/api/SubgroupApi.js.map +1 -0
- package/dist/cjs/index.js +25 -1
- package/dist/cjs/models/AgeThresholdRule.js +21 -0
- package/dist/cjs/models/AgeThresholdRule.js.map +1 -0
- package/dist/cjs/models/MemberRole.js +15 -0
- package/dist/cjs/models/MemberRole.js.map +1 -0
- package/dist/cjs/models/Notification.js +24 -0
- package/dist/cjs/models/Notification.js.map +1 -0
- package/dist/cjs/models/Role.js +32 -0
- package/dist/cjs/models/Role.js.map +1 -0
- package/dist/cjs/models/RosterMemberModel.js +19 -0
- package/dist/cjs/models/RosterMemberModel.js.map +1 -0
- package/dist/cjs/models/RosterModel.js +19 -0
- package/dist/cjs/models/RosterModel.js.map +1 -0
- package/dist/cjs/models/SubgroupModel.js +18 -0
- package/dist/cjs/models/SubgroupModel.js.map +1 -0
- package/dist/cjs/models/TeamMember.js +2 -3
- package/dist/cjs/models/TeamMember.js.map +1 -1
- package/dist/dts/api/AgeThresholdApi.d.ts +119 -0
- package/dist/dts/api/AgeThresholdApi.d.ts.map +1 -0
- package/dist/dts/api/Auth.d.ts +60 -1
- package/dist/dts/api/Auth.d.ts.map +1 -1
- package/dist/dts/api/Invite.d.ts +7 -7
- package/dist/dts/api/Invite.d.ts.map +1 -1
- package/dist/dts/api/NotificationApi.d.ts +53 -0
- package/dist/dts/api/NotificationApi.d.ts.map +1 -0
- package/dist/dts/api/RoleApi.d.ts +138 -0
- package/dist/dts/api/RoleApi.d.ts.map +1 -0
- package/dist/dts/api/Roster.d.ts +225 -0
- package/dist/dts/api/Roster.d.ts.map +1 -0
- package/dist/dts/api/SubgroupApi.d.ts +140 -0
- package/dist/dts/api/SubgroupApi.d.ts.map +1 -0
- package/dist/dts/index.d.ts +12 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/models/AgeThresholdRule.d.ts +97 -0
- package/dist/dts/models/AgeThresholdRule.d.ts.map +1 -0
- package/dist/dts/models/MemberRole.d.ts +16 -0
- package/dist/dts/models/MemberRole.d.ts.map +1 -0
- package/dist/dts/models/Notification.d.ts +125 -0
- package/dist/dts/models/Notification.d.ts.map +1 -0
- package/dist/dts/models/Role.d.ts +102 -0
- package/dist/dts/models/Role.d.ts.map +1 -0
- package/dist/dts/models/RosterMemberModel.d.ts +71 -0
- package/dist/dts/models/RosterMemberModel.d.ts.map +1 -0
- package/dist/dts/models/RosterModel.d.ts +84 -0
- package/dist/dts/models/RosterModel.d.ts.map +1 -0
- package/dist/dts/models/SubgroupModel.d.ts +71 -0
- package/dist/dts/models/SubgroupModel.d.ts.map +1 -0
- package/dist/dts/models/TeamInvite.d.ts +4 -4
- package/dist/dts/models/TeamMember.d.ts +11 -13
- package/dist/dts/models/TeamMember.d.ts.map +1 -1
- package/dist/esm/api/AgeThresholdApi.js +72 -0
- package/dist/esm/api/AgeThresholdApi.js.map +1 -0
- package/dist/esm/api/Auth.js +28 -1
- package/dist/esm/api/Auth.js.map +1 -1
- package/dist/esm/api/Invite.js +1 -2
- package/dist/esm/api/Invite.js.map +1 -1
- package/dist/esm/api/NotificationApi.js +32 -0
- package/dist/esm/api/NotificationApi.js.map +1 -0
- package/dist/esm/api/RoleApi.js +106 -0
- package/dist/esm/api/RoleApi.js.map +1 -0
- package/dist/esm/api/Roster.js +142 -0
- package/dist/esm/api/Roster.js.map +1 -0
- package/dist/esm/api/SubgroupApi.js +106 -0
- package/dist/esm/api/SubgroupApi.js.map +1 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/models/AgeThresholdRule.js +14 -0
- package/dist/esm/models/AgeThresholdRule.js.map +1 -0
- package/dist/esm/models/MemberRole.js +8 -0
- package/dist/esm/models/MemberRole.js.map +1 -0
- package/dist/esm/models/Notification.js +17 -0
- package/dist/esm/models/Notification.js.map +1 -0
- package/dist/esm/models/Role.js +24 -0
- package/dist/esm/models/Role.js.map +1 -0
- package/dist/esm/models/RosterMemberModel.js +12 -0
- package/dist/esm/models/RosterMemberModel.js.map +1 -0
- package/dist/esm/models/RosterModel.js +12 -0
- package/dist/esm/models/RosterModel.js.map +1 -0
- package/dist/esm/models/SubgroupModel.js +11 -0
- package/dist/esm/models/SubgroupModel.js.map +1 -0
- package/dist/esm/models/TeamMember.js +1 -2
- package/dist/esm/models/TeamMember.js.map +1 -1
- package/package.json +1 -1
- package/src/api/AgeThresholdApi.ts +99 -0
- package/src/api/Auth.ts +52 -0
- package/src/api/Invite.ts +1 -2
- package/src/api/NotificationApi.ts +49 -0
- package/src/api/RoleApi.ts +130 -0
- package/src/api/Roster.ts +176 -0
- package/src/api/SubgroupApi.ts +146 -0
- package/src/index.ts +24 -0
- package/src/models/AgeThresholdRule.ts +16 -0
- package/src/models/MemberRole.ts +8 -0
- package/src/models/Notification.ts +26 -0
- package/src/models/Role.ts +53 -0
- package/src/models/RosterMemberModel.ts +14 -0
- package/src/models/RosterModel.ts +14 -0
- package/src/models/SubgroupModel.ts +13 -0
- package/src/models/TeamMember.ts +1 -4
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from '@effect/platform';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { AuthMiddleware } from '~/api/Auth.js';
|
|
4
|
+
import { Permission, RoleId } from '~/models/Role.js';
|
|
5
|
+
import { TeamId } from '~/models/Team.js';
|
|
6
|
+
import { TeamMemberId } from '~/models/TeamMember.js';
|
|
7
|
+
|
|
8
|
+
export class RoleInfo extends Schema.Class<RoleInfo>('RoleInfo')({
|
|
9
|
+
roleId: RoleId,
|
|
10
|
+
teamId: TeamId,
|
|
11
|
+
name: Schema.String,
|
|
12
|
+
isBuiltIn: Schema.Boolean,
|
|
13
|
+
permissionCount: Schema.Number,
|
|
14
|
+
}) {}
|
|
15
|
+
|
|
16
|
+
export class RoleDetail extends Schema.Class<RoleDetail>('RoleDetail')({
|
|
17
|
+
roleId: RoleId,
|
|
18
|
+
teamId: TeamId,
|
|
19
|
+
name: Schema.String,
|
|
20
|
+
isBuiltIn: Schema.Boolean,
|
|
21
|
+
permissions: Schema.Array(Permission),
|
|
22
|
+
}) {}
|
|
23
|
+
|
|
24
|
+
export class CreateRoleRequest extends Schema.Class<CreateRoleRequest>('CreateRoleRequest')({
|
|
25
|
+
name: Schema.NonEmptyString,
|
|
26
|
+
permissions: Schema.Array(Permission),
|
|
27
|
+
}) {}
|
|
28
|
+
|
|
29
|
+
export class UpdateRoleRequest extends Schema.Class<UpdateRoleRequest>('UpdateRoleRequest')({
|
|
30
|
+
name: Schema.NullOr(Schema.NonEmptyString),
|
|
31
|
+
permissions: Schema.NullOr(Schema.Array(Permission)),
|
|
32
|
+
}) {}
|
|
33
|
+
|
|
34
|
+
export class RoleNotFound extends Schema.TaggedError<RoleNotFound>()(
|
|
35
|
+
'RoleNotFound',
|
|
36
|
+
{},
|
|
37
|
+
HttpApiSchema.annotations({ status: 404 }),
|
|
38
|
+
) {}
|
|
39
|
+
|
|
40
|
+
export class Forbidden extends Schema.TaggedError<Forbidden>()(
|
|
41
|
+
'RoleForbidden',
|
|
42
|
+
{},
|
|
43
|
+
HttpApiSchema.annotations({ status: 403 }),
|
|
44
|
+
) {}
|
|
45
|
+
|
|
46
|
+
export class CannotModifyBuiltIn extends Schema.TaggedError<CannotModifyBuiltIn>()(
|
|
47
|
+
'CannotModifyBuiltIn',
|
|
48
|
+
{},
|
|
49
|
+
HttpApiSchema.annotations({ status: 400 }),
|
|
50
|
+
) {}
|
|
51
|
+
|
|
52
|
+
export class AssignRoleRequest extends Schema.Class<AssignRoleRequest>('AssignRoleRequest')({
|
|
53
|
+
roleId: RoleId,
|
|
54
|
+
}) {}
|
|
55
|
+
|
|
56
|
+
export class MemberNotFound extends Schema.TaggedError<MemberNotFound>()(
|
|
57
|
+
'MemberNotFound',
|
|
58
|
+
{},
|
|
59
|
+
HttpApiSchema.annotations({ status: 404 }),
|
|
60
|
+
) {}
|
|
61
|
+
|
|
62
|
+
export class RoleInUse extends Schema.TaggedError<RoleInUse>()(
|
|
63
|
+
'RoleInUse',
|
|
64
|
+
{},
|
|
65
|
+
HttpApiSchema.annotations({ status: 409 }),
|
|
66
|
+
) {}
|
|
67
|
+
|
|
68
|
+
export class RoleApiGroup extends HttpApiGroup.make('role')
|
|
69
|
+
.add(
|
|
70
|
+
HttpApiEndpoint.get('listRoles', '/teams/:teamId/roles')
|
|
71
|
+
.addSuccess(Schema.Array(RoleInfo))
|
|
72
|
+
.addError(Forbidden, { status: 403 })
|
|
73
|
+
.setPath(Schema.Struct({ teamId: TeamId }))
|
|
74
|
+
.middleware(AuthMiddleware),
|
|
75
|
+
)
|
|
76
|
+
.add(
|
|
77
|
+
HttpApiEndpoint.post('createRole', '/teams/:teamId/roles')
|
|
78
|
+
.addSuccess(RoleDetail, { status: 201 })
|
|
79
|
+
.addError(Forbidden, { status: 403 })
|
|
80
|
+
.setPath(Schema.Struct({ teamId: TeamId }))
|
|
81
|
+
.setPayload(CreateRoleRequest)
|
|
82
|
+
.middleware(AuthMiddleware),
|
|
83
|
+
)
|
|
84
|
+
.add(
|
|
85
|
+
HttpApiEndpoint.get('getRole', '/teams/:teamId/roles/:roleId')
|
|
86
|
+
.addSuccess(RoleDetail)
|
|
87
|
+
.addError(Forbidden, { status: 403 })
|
|
88
|
+
.addError(RoleNotFound, { status: 404 })
|
|
89
|
+
.setPath(Schema.Struct({ teamId: TeamId, roleId: RoleId }))
|
|
90
|
+
.middleware(AuthMiddleware),
|
|
91
|
+
)
|
|
92
|
+
.add(
|
|
93
|
+
HttpApiEndpoint.patch('updateRole', '/teams/:teamId/roles/:roleId')
|
|
94
|
+
.addSuccess(RoleDetail)
|
|
95
|
+
.addError(Forbidden, { status: 403 })
|
|
96
|
+
.addError(RoleNotFound, { status: 404 })
|
|
97
|
+
.addError(CannotModifyBuiltIn, { status: 400 })
|
|
98
|
+
.setPath(Schema.Struct({ teamId: TeamId, roleId: RoleId }))
|
|
99
|
+
.setPayload(UpdateRoleRequest)
|
|
100
|
+
.middleware(AuthMiddleware),
|
|
101
|
+
)
|
|
102
|
+
.add(
|
|
103
|
+
HttpApiEndpoint.del('deleteRole', '/teams/:teamId/roles/:roleId')
|
|
104
|
+
.addSuccess(Schema.Void)
|
|
105
|
+
.addError(Forbidden, { status: 403 })
|
|
106
|
+
.addError(RoleNotFound, { status: 404 })
|
|
107
|
+
.addError(CannotModifyBuiltIn, { status: 400 })
|
|
108
|
+
.addError(RoleInUse, { status: 409 })
|
|
109
|
+
.setPath(Schema.Struct({ teamId: TeamId, roleId: RoleId }))
|
|
110
|
+
.middleware(AuthMiddleware),
|
|
111
|
+
)
|
|
112
|
+
.add(
|
|
113
|
+
HttpApiEndpoint.post('assignRole', '/teams/:teamId/members/:memberId/roles')
|
|
114
|
+
.addSuccess(Schema.Void, { status: 204 })
|
|
115
|
+
.addError(Forbidden, { status: 403 })
|
|
116
|
+
.addError(MemberNotFound, { status: 404 })
|
|
117
|
+
.addError(RoleNotFound, { status: 404 })
|
|
118
|
+
.setPath(Schema.Struct({ teamId: TeamId, memberId: TeamMemberId }))
|
|
119
|
+
.setPayload(AssignRoleRequest)
|
|
120
|
+
.middleware(AuthMiddleware),
|
|
121
|
+
)
|
|
122
|
+
.add(
|
|
123
|
+
HttpApiEndpoint.del('unassignRole', '/teams/:teamId/members/:memberId/roles/:roleId')
|
|
124
|
+
.addSuccess(Schema.Void)
|
|
125
|
+
.addError(Forbidden, { status: 403 })
|
|
126
|
+
.addError(MemberNotFound, { status: 404 })
|
|
127
|
+
.addError(RoleNotFound, { status: 404 })
|
|
128
|
+
.setPath(Schema.Struct({ teamId: TeamId, memberId: TeamMemberId, roleId: RoleId }))
|
|
129
|
+
.middleware(AuthMiddleware),
|
|
130
|
+
) {}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from '@effect/platform';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { AuthMiddleware } from '~/api/Auth.js';
|
|
4
|
+
import { Permission } from '~/models/Role.js';
|
|
5
|
+
import { RosterId } from '~/models/RosterModel.js';
|
|
6
|
+
import { TeamId } from '~/models/Team.js';
|
|
7
|
+
import { TeamMemberId } from '~/models/TeamMember.js';
|
|
8
|
+
import { Gender, Position, Proficiency, UserId } from '~/models/User.js';
|
|
9
|
+
|
|
10
|
+
export class RosterPlayer extends Schema.Class<RosterPlayer>('RosterPlayer')({
|
|
11
|
+
memberId: TeamMemberId,
|
|
12
|
+
userId: UserId,
|
|
13
|
+
roleNames: Schema.Array(Schema.String),
|
|
14
|
+
permissions: Schema.Array(Permission),
|
|
15
|
+
name: Schema.NullOr(Schema.String),
|
|
16
|
+
birthYear: Schema.NullOr(Schema.Number),
|
|
17
|
+
gender: Schema.NullOr(Gender),
|
|
18
|
+
jerseyNumber: Schema.NullOr(Schema.Number),
|
|
19
|
+
position: Schema.NullOr(Position),
|
|
20
|
+
proficiency: Schema.NullOr(Proficiency),
|
|
21
|
+
discordUsername: Schema.String,
|
|
22
|
+
discordAvatar: Schema.NullOr(Schema.String),
|
|
23
|
+
}) {}
|
|
24
|
+
|
|
25
|
+
export class UpdatePlayerRequest extends Schema.Class<UpdatePlayerRequest>('UpdatePlayerRequest')({
|
|
26
|
+
name: Schema.NullOr(Schema.String),
|
|
27
|
+
birthYear: Schema.NullOr(Schema.Number),
|
|
28
|
+
gender: Schema.NullOr(Gender),
|
|
29
|
+
jerseyNumber: Schema.NullOr(Schema.Number),
|
|
30
|
+
position: Schema.NullOr(Position),
|
|
31
|
+
proficiency: Schema.NullOr(Proficiency),
|
|
32
|
+
}) {}
|
|
33
|
+
|
|
34
|
+
export class PlayerNotFound extends Schema.TaggedError<PlayerNotFound>()(
|
|
35
|
+
'PlayerNotFound',
|
|
36
|
+
{},
|
|
37
|
+
HttpApiSchema.annotations({ status: 404 }),
|
|
38
|
+
) {}
|
|
39
|
+
|
|
40
|
+
export class Forbidden extends Schema.TaggedError<Forbidden>()(
|
|
41
|
+
'Forbidden',
|
|
42
|
+
{},
|
|
43
|
+
HttpApiSchema.annotations({ status: 403 }),
|
|
44
|
+
) {}
|
|
45
|
+
|
|
46
|
+
export class RosterNotFound extends Schema.TaggedError<RosterNotFound>()(
|
|
47
|
+
'RosterNotFound',
|
|
48
|
+
{},
|
|
49
|
+
HttpApiSchema.annotations({ status: 404 }),
|
|
50
|
+
) {}
|
|
51
|
+
|
|
52
|
+
export class RosterInfo extends Schema.Class<RosterInfo>('RosterInfo')({
|
|
53
|
+
rosterId: RosterId,
|
|
54
|
+
teamId: TeamId,
|
|
55
|
+
name: Schema.String,
|
|
56
|
+
active: Schema.Boolean,
|
|
57
|
+
memberCount: Schema.Number,
|
|
58
|
+
createdAt: Schema.String,
|
|
59
|
+
}) {}
|
|
60
|
+
|
|
61
|
+
export class RosterDetail extends Schema.Class<RosterDetail>('RosterDetail')({
|
|
62
|
+
rosterId: RosterId,
|
|
63
|
+
teamId: TeamId,
|
|
64
|
+
name: Schema.String,
|
|
65
|
+
active: Schema.Boolean,
|
|
66
|
+
createdAt: Schema.String,
|
|
67
|
+
members: Schema.Array(RosterPlayer),
|
|
68
|
+
}) {}
|
|
69
|
+
|
|
70
|
+
export class CreateRosterRequest extends Schema.Class<CreateRosterRequest>('CreateRosterRequest')({
|
|
71
|
+
name: Schema.String,
|
|
72
|
+
}) {}
|
|
73
|
+
|
|
74
|
+
export class UpdateRosterRequest extends Schema.Class<UpdateRosterRequest>('UpdateRosterRequest')({
|
|
75
|
+
name: Schema.NullOr(Schema.String),
|
|
76
|
+
active: Schema.NullOr(Schema.Boolean),
|
|
77
|
+
}) {}
|
|
78
|
+
|
|
79
|
+
export class AddRosterMemberRequest extends Schema.Class<AddRosterMemberRequest>(
|
|
80
|
+
'AddRosterMemberRequest',
|
|
81
|
+
)({
|
|
82
|
+
memberId: TeamMemberId,
|
|
83
|
+
}) {}
|
|
84
|
+
|
|
85
|
+
export class RosterApiGroup extends HttpApiGroup.make('roster')
|
|
86
|
+
.add(
|
|
87
|
+
HttpApiEndpoint.get('listMembers', '/teams/:teamId/members')
|
|
88
|
+
.addSuccess(Schema.Array(RosterPlayer))
|
|
89
|
+
.addError(Forbidden, { status: 403 })
|
|
90
|
+
.setPath(Schema.Struct({ teamId: TeamId }))
|
|
91
|
+
.middleware(AuthMiddleware),
|
|
92
|
+
)
|
|
93
|
+
.add(
|
|
94
|
+
HttpApiEndpoint.get('getMember', '/teams/:teamId/members/:memberId')
|
|
95
|
+
.addSuccess(RosterPlayer)
|
|
96
|
+
.addError(Forbidden, { status: 403 })
|
|
97
|
+
.addError(PlayerNotFound, { status: 404 })
|
|
98
|
+
.setPath(Schema.Struct({ teamId: TeamId, memberId: TeamMemberId }))
|
|
99
|
+
.middleware(AuthMiddleware),
|
|
100
|
+
)
|
|
101
|
+
.add(
|
|
102
|
+
HttpApiEndpoint.patch('updateMember', '/teams/:teamId/members/:memberId')
|
|
103
|
+
.addSuccess(RosterPlayer)
|
|
104
|
+
.addError(Forbidden, { status: 403 })
|
|
105
|
+
.addError(PlayerNotFound, { status: 404 })
|
|
106
|
+
.setPath(Schema.Struct({ teamId: TeamId, memberId: TeamMemberId }))
|
|
107
|
+
.setPayload(UpdatePlayerRequest)
|
|
108
|
+
.middleware(AuthMiddleware),
|
|
109
|
+
)
|
|
110
|
+
.add(
|
|
111
|
+
HttpApiEndpoint.del('deactivateMember', '/teams/:teamId/members/:memberId')
|
|
112
|
+
.addSuccess(Schema.Void)
|
|
113
|
+
.addError(Forbidden, { status: 403 })
|
|
114
|
+
.addError(PlayerNotFound, { status: 404 })
|
|
115
|
+
.setPath(Schema.Struct({ teamId: TeamId, memberId: TeamMemberId }))
|
|
116
|
+
.middleware(AuthMiddleware),
|
|
117
|
+
)
|
|
118
|
+
.add(
|
|
119
|
+
HttpApiEndpoint.get('listRosters', '/teams/:teamId/rosters')
|
|
120
|
+
.addSuccess(Schema.Array(RosterInfo))
|
|
121
|
+
.addError(Forbidden, { status: 403 })
|
|
122
|
+
.setPath(Schema.Struct({ teamId: TeamId }))
|
|
123
|
+
.middleware(AuthMiddleware),
|
|
124
|
+
)
|
|
125
|
+
.add(
|
|
126
|
+
HttpApiEndpoint.post('createRoster', '/teams/:teamId/rosters')
|
|
127
|
+
.addSuccess(RosterInfo, { status: 201 })
|
|
128
|
+
.addError(Forbidden, { status: 403 })
|
|
129
|
+
.setPath(Schema.Struct({ teamId: TeamId }))
|
|
130
|
+
.setPayload(CreateRosterRequest)
|
|
131
|
+
.middleware(AuthMiddleware),
|
|
132
|
+
)
|
|
133
|
+
.add(
|
|
134
|
+
HttpApiEndpoint.get('getRoster', '/teams/:teamId/rosters/:rosterId')
|
|
135
|
+
.addSuccess(RosterDetail)
|
|
136
|
+
.addError(Forbidden, { status: 403 })
|
|
137
|
+
.addError(RosterNotFound, { status: 404 })
|
|
138
|
+
.setPath(Schema.Struct({ teamId: TeamId, rosterId: RosterId }))
|
|
139
|
+
.middleware(AuthMiddleware),
|
|
140
|
+
)
|
|
141
|
+
.add(
|
|
142
|
+
HttpApiEndpoint.patch('updateRoster', '/teams/:teamId/rosters/:rosterId')
|
|
143
|
+
.addSuccess(RosterInfo)
|
|
144
|
+
.addError(Forbidden, { status: 403 })
|
|
145
|
+
.addError(RosterNotFound, { status: 404 })
|
|
146
|
+
.setPath(Schema.Struct({ teamId: TeamId, rosterId: RosterId }))
|
|
147
|
+
.setPayload(UpdateRosterRequest)
|
|
148
|
+
.middleware(AuthMiddleware),
|
|
149
|
+
)
|
|
150
|
+
.add(
|
|
151
|
+
HttpApiEndpoint.del('deleteRoster', '/teams/:teamId/rosters/:rosterId')
|
|
152
|
+
.addSuccess(Schema.Void)
|
|
153
|
+
.addError(Forbidden, { status: 403 })
|
|
154
|
+
.addError(RosterNotFound, { status: 404 })
|
|
155
|
+
.setPath(Schema.Struct({ teamId: TeamId, rosterId: RosterId }))
|
|
156
|
+
.middleware(AuthMiddleware),
|
|
157
|
+
)
|
|
158
|
+
.add(
|
|
159
|
+
HttpApiEndpoint.post('addRosterMember', '/teams/:teamId/rosters/:rosterId/members')
|
|
160
|
+
.addSuccess(Schema.Void)
|
|
161
|
+
.addError(Forbidden, { status: 403 })
|
|
162
|
+
.addError(RosterNotFound, { status: 404 })
|
|
163
|
+
.addError(PlayerNotFound, { status: 404 })
|
|
164
|
+
.setPath(Schema.Struct({ teamId: TeamId, rosterId: RosterId }))
|
|
165
|
+
.setPayload(AddRosterMemberRequest)
|
|
166
|
+
.middleware(AuthMiddleware),
|
|
167
|
+
)
|
|
168
|
+
.add(
|
|
169
|
+
HttpApiEndpoint.del('removeRosterMember', '/teams/:teamId/rosters/:rosterId/members/:memberId')
|
|
170
|
+
.addSuccess(Schema.Void)
|
|
171
|
+
.addError(Forbidden, { status: 403 })
|
|
172
|
+
.addError(RosterNotFound, { status: 404 })
|
|
173
|
+
.addError(PlayerNotFound, { status: 404 })
|
|
174
|
+
.setPath(Schema.Struct({ teamId: TeamId, rosterId: RosterId, memberId: TeamMemberId }))
|
|
175
|
+
.middleware(AuthMiddleware),
|
|
176
|
+
) {}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from '@effect/platform';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { AuthMiddleware } from '~/api/Auth.js';
|
|
4
|
+
import { Permission } from '~/models/Role.js';
|
|
5
|
+
import { SubgroupId } from '~/models/SubgroupModel.js';
|
|
6
|
+
import { TeamId } from '~/models/Team.js';
|
|
7
|
+
import { TeamMemberId } from '~/models/TeamMember.js';
|
|
8
|
+
|
|
9
|
+
export class SubgroupInfo extends Schema.Class<SubgroupInfo>('SubgroupInfo')({
|
|
10
|
+
subgroupId: SubgroupId,
|
|
11
|
+
teamId: TeamId,
|
|
12
|
+
name: Schema.String,
|
|
13
|
+
memberCount: Schema.Number,
|
|
14
|
+
}) {}
|
|
15
|
+
|
|
16
|
+
export class SubgroupDetail extends Schema.Class<SubgroupDetail>('SubgroupDetail')({
|
|
17
|
+
subgroupId: SubgroupId,
|
|
18
|
+
teamId: TeamId,
|
|
19
|
+
name: Schema.String,
|
|
20
|
+
permissions: Schema.Array(Permission),
|
|
21
|
+
members: Schema.Array(
|
|
22
|
+
Schema.Struct({
|
|
23
|
+
memberId: TeamMemberId,
|
|
24
|
+
name: Schema.NullOr(Schema.String),
|
|
25
|
+
discordUsername: Schema.String,
|
|
26
|
+
}),
|
|
27
|
+
),
|
|
28
|
+
}) {}
|
|
29
|
+
|
|
30
|
+
export class CreateSubgroupRequest extends Schema.Class<CreateSubgroupRequest>(
|
|
31
|
+
'CreateSubgroupRequest',
|
|
32
|
+
)({
|
|
33
|
+
name: Schema.NonEmptyString,
|
|
34
|
+
}) {}
|
|
35
|
+
|
|
36
|
+
export class UpdateSubgroupRequest extends Schema.Class<UpdateSubgroupRequest>(
|
|
37
|
+
'UpdateSubgroupRequest',
|
|
38
|
+
)({
|
|
39
|
+
name: Schema.NonEmptyString,
|
|
40
|
+
}) {}
|
|
41
|
+
|
|
42
|
+
export class AddSubgroupMemberRequest extends Schema.Class<AddSubgroupMemberRequest>(
|
|
43
|
+
'AddSubgroupMemberRequest',
|
|
44
|
+
)({
|
|
45
|
+
memberId: TeamMemberId,
|
|
46
|
+
}) {}
|
|
47
|
+
|
|
48
|
+
export class SetSubgroupPermissionsRequest extends Schema.Class<SetSubgroupPermissionsRequest>(
|
|
49
|
+
'SetSubgroupPermissionsRequest',
|
|
50
|
+
)({
|
|
51
|
+
permissions: Schema.Array(Permission),
|
|
52
|
+
}) {}
|
|
53
|
+
|
|
54
|
+
export class SubgroupNotFound extends Schema.TaggedError<SubgroupNotFound>()(
|
|
55
|
+
'SubgroupNotFound',
|
|
56
|
+
{},
|
|
57
|
+
HttpApiSchema.annotations({ status: 404 }),
|
|
58
|
+
) {}
|
|
59
|
+
|
|
60
|
+
export class Forbidden extends Schema.TaggedError<Forbidden>()(
|
|
61
|
+
'SubgroupForbidden',
|
|
62
|
+
{},
|
|
63
|
+
HttpApiSchema.annotations({ status: 403 }),
|
|
64
|
+
) {}
|
|
65
|
+
|
|
66
|
+
export class MemberNotFound extends Schema.TaggedError<MemberNotFound>()(
|
|
67
|
+
'SubgroupMemberNotFound',
|
|
68
|
+
{},
|
|
69
|
+
HttpApiSchema.annotations({ status: 404 }),
|
|
70
|
+
) {}
|
|
71
|
+
|
|
72
|
+
export class SubgroupApiGroup extends HttpApiGroup.make('subgroup')
|
|
73
|
+
.add(
|
|
74
|
+
HttpApiEndpoint.get('listSubgroups', '/teams/:teamId/subgroups')
|
|
75
|
+
.addSuccess(Schema.Array(SubgroupInfo))
|
|
76
|
+
.addError(Forbidden, { status: 403 })
|
|
77
|
+
.setPath(Schema.Struct({ teamId: TeamId }))
|
|
78
|
+
.middleware(AuthMiddleware),
|
|
79
|
+
)
|
|
80
|
+
.add(
|
|
81
|
+
HttpApiEndpoint.post('createSubgroup', '/teams/:teamId/subgroups')
|
|
82
|
+
.addSuccess(SubgroupInfo, { status: 201 })
|
|
83
|
+
.addError(Forbidden, { status: 403 })
|
|
84
|
+
.setPath(Schema.Struct({ teamId: TeamId }))
|
|
85
|
+
.setPayload(CreateSubgroupRequest)
|
|
86
|
+
.middleware(AuthMiddleware),
|
|
87
|
+
)
|
|
88
|
+
.add(
|
|
89
|
+
HttpApiEndpoint.get('getSubgroup', '/teams/:teamId/subgroups/:subgroupId')
|
|
90
|
+
.addSuccess(SubgroupDetail)
|
|
91
|
+
.addError(Forbidden, { status: 403 })
|
|
92
|
+
.addError(SubgroupNotFound, { status: 404 })
|
|
93
|
+
.setPath(Schema.Struct({ teamId: TeamId, subgroupId: SubgroupId }))
|
|
94
|
+
.middleware(AuthMiddleware),
|
|
95
|
+
)
|
|
96
|
+
.add(
|
|
97
|
+
HttpApiEndpoint.patch('updateSubgroup', '/teams/:teamId/subgroups/:subgroupId')
|
|
98
|
+
.addSuccess(SubgroupInfo)
|
|
99
|
+
.addError(Forbidden, { status: 403 })
|
|
100
|
+
.addError(SubgroupNotFound, { status: 404 })
|
|
101
|
+
.setPath(Schema.Struct({ teamId: TeamId, subgroupId: SubgroupId }))
|
|
102
|
+
.setPayload(UpdateSubgroupRequest)
|
|
103
|
+
.middleware(AuthMiddleware),
|
|
104
|
+
)
|
|
105
|
+
.add(
|
|
106
|
+
HttpApiEndpoint.del('deleteSubgroup', '/teams/:teamId/subgroups/:subgroupId')
|
|
107
|
+
.addSuccess(Schema.Void)
|
|
108
|
+
.addError(Forbidden, { status: 403 })
|
|
109
|
+
.addError(SubgroupNotFound, { status: 404 })
|
|
110
|
+
.setPath(Schema.Struct({ teamId: TeamId, subgroupId: SubgroupId }))
|
|
111
|
+
.middleware(AuthMiddleware),
|
|
112
|
+
)
|
|
113
|
+
.add(
|
|
114
|
+
HttpApiEndpoint.post('addSubgroupMember', '/teams/:teamId/subgroups/:subgroupId/members')
|
|
115
|
+
.addSuccess(Schema.Void, { status: 204 })
|
|
116
|
+
.addError(Forbidden, { status: 403 })
|
|
117
|
+
.addError(SubgroupNotFound, { status: 404 })
|
|
118
|
+
.addError(MemberNotFound, { status: 404 })
|
|
119
|
+
.setPath(Schema.Struct({ teamId: TeamId, subgroupId: SubgroupId }))
|
|
120
|
+
.setPayload(AddSubgroupMemberRequest)
|
|
121
|
+
.middleware(AuthMiddleware),
|
|
122
|
+
)
|
|
123
|
+
.add(
|
|
124
|
+
HttpApiEndpoint.del(
|
|
125
|
+
'removeSubgroupMember',
|
|
126
|
+
'/teams/:teamId/subgroups/:subgroupId/members/:memberId',
|
|
127
|
+
)
|
|
128
|
+
.addSuccess(Schema.Void)
|
|
129
|
+
.addError(Forbidden, { status: 403 })
|
|
130
|
+
.addError(SubgroupNotFound, { status: 404 })
|
|
131
|
+
.addError(MemberNotFound, { status: 404 })
|
|
132
|
+
.setPath(Schema.Struct({ teamId: TeamId, subgroupId: SubgroupId, memberId: TeamMemberId }))
|
|
133
|
+
.middleware(AuthMiddleware),
|
|
134
|
+
)
|
|
135
|
+
.add(
|
|
136
|
+
HttpApiEndpoint.patch(
|
|
137
|
+
'setSubgroupPermissions',
|
|
138
|
+
'/teams/:teamId/subgroups/:subgroupId/permissions',
|
|
139
|
+
)
|
|
140
|
+
.addSuccess(SubgroupDetail)
|
|
141
|
+
.addError(Forbidden, { status: 403 })
|
|
142
|
+
.addError(SubgroupNotFound, { status: 404 })
|
|
143
|
+
.setPath(Schema.Struct({ teamId: TeamId, subgroupId: SubgroupId }))
|
|
144
|
+
.setPayload(SetSubgroupPermissionsRequest)
|
|
145
|
+
.middleware(AuthMiddleware),
|
|
146
|
+
) {}
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
export * as ApiGroup from './ApiGroup.js';
|
|
2
2
|
|
|
3
|
+
export * as AgeThresholdApi from './api/AgeThresholdApi.js';
|
|
4
|
+
|
|
3
5
|
export * as Auth from './api/Auth.js';
|
|
4
6
|
|
|
5
7
|
export * as Invite from './api/Invite.js';
|
|
6
8
|
|
|
9
|
+
export * as NotificationApi from './api/NotificationApi.js';
|
|
10
|
+
|
|
11
|
+
export * as RoleApi from './api/RoleApi.js';
|
|
12
|
+
|
|
13
|
+
export * as Roster from './api/Roster.js';
|
|
14
|
+
|
|
15
|
+
export * as SubgroupApi from './api/SubgroupApi.js';
|
|
16
|
+
|
|
17
|
+
export * as AgeThresholdRule from './models/AgeThresholdRule.js';
|
|
18
|
+
|
|
19
|
+
export * as MemberRole from './models/MemberRole.js';
|
|
20
|
+
|
|
21
|
+
export * as Notification from './models/Notification.js';
|
|
22
|
+
|
|
23
|
+
export * as Role from './models/Role.js';
|
|
24
|
+
|
|
25
|
+
export * as RosterMemberModel from './models/RosterMemberModel.js';
|
|
26
|
+
|
|
27
|
+
export * as RosterModel from './models/RosterModel.js';
|
|
28
|
+
|
|
7
29
|
export * as Session from './models/Session.js';
|
|
8
30
|
|
|
31
|
+
export * as SubgroupModel from './models/SubgroupModel.js';
|
|
32
|
+
|
|
9
33
|
export * as Team from './models/Team.js';
|
|
10
34
|
|
|
11
35
|
export * as TeamInvite from './models/TeamInvite.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Model } from '@effect/sql';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { RoleId } from '~/models/Role.js';
|
|
4
|
+
import { TeamId } from '~/models/Team.js';
|
|
5
|
+
|
|
6
|
+
export const AgeThresholdRuleId = Schema.String.pipe(Schema.brand('AgeThresholdRuleId'));
|
|
7
|
+
export type AgeThresholdRuleId = typeof AgeThresholdRuleId.Type;
|
|
8
|
+
|
|
9
|
+
export class AgeThresholdRule extends Model.Class<AgeThresholdRule>('AgeThresholdRule')({
|
|
10
|
+
id: Model.Generated(AgeThresholdRuleId),
|
|
11
|
+
team_id: TeamId,
|
|
12
|
+
role_id: RoleId,
|
|
13
|
+
min_age: Schema.NullOr(Schema.Number),
|
|
14
|
+
max_age: Schema.NullOr(Schema.Number),
|
|
15
|
+
created_at: Model.DateTimeInsertFromDate,
|
|
16
|
+
}) {}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
import { RoleId } from '~/models/Role.js';
|
|
3
|
+
import { TeamMemberId } from '~/models/TeamMember.js';
|
|
4
|
+
|
|
5
|
+
export class MemberRole extends Schema.Class<MemberRole>('MemberRole')({
|
|
6
|
+
team_member_id: TeamMemberId,
|
|
7
|
+
role_id: RoleId,
|
|
8
|
+
}) {}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Model } from '@effect/sql';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { TeamId } from '~/models/Team.js';
|
|
4
|
+
import { UserId } from '~/models/User.js';
|
|
5
|
+
|
|
6
|
+
export const NotificationId = Schema.String.pipe(Schema.brand('NotificationId'));
|
|
7
|
+
export type NotificationId = typeof NotificationId.Type;
|
|
8
|
+
|
|
9
|
+
export const NotificationType = Schema.Literal(
|
|
10
|
+
'age_role_assigned',
|
|
11
|
+
'age_role_removed',
|
|
12
|
+
'role_assigned',
|
|
13
|
+
'role_removed',
|
|
14
|
+
);
|
|
15
|
+
export type NotificationType = typeof NotificationType.Type;
|
|
16
|
+
|
|
17
|
+
export class Notification extends Model.Class<Notification>('Notification')({
|
|
18
|
+
id: Model.Generated(NotificationId),
|
|
19
|
+
team_id: TeamId,
|
|
20
|
+
user_id: UserId,
|
|
21
|
+
type: NotificationType,
|
|
22
|
+
title: Schema.String,
|
|
23
|
+
body: Schema.String,
|
|
24
|
+
is_read: Schema.Boolean,
|
|
25
|
+
created_at: Model.DateTimeInsertFromDate,
|
|
26
|
+
}) {}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Model } from '@effect/sql';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { TeamId } from '~/models/Team.js';
|
|
4
|
+
|
|
5
|
+
export const RoleId = Schema.String.pipe(Schema.brand('RoleId'));
|
|
6
|
+
export type RoleId = typeof RoleId.Type;
|
|
7
|
+
|
|
8
|
+
export const Permission = Schema.Literal(
|
|
9
|
+
'team:manage',
|
|
10
|
+
'team:invite',
|
|
11
|
+
'roster:view',
|
|
12
|
+
'roster:manage',
|
|
13
|
+
'member:view',
|
|
14
|
+
'member:edit',
|
|
15
|
+
'member:remove',
|
|
16
|
+
'role:view',
|
|
17
|
+
'role:manage',
|
|
18
|
+
);
|
|
19
|
+
export type Permission = typeof Permission.Type;
|
|
20
|
+
|
|
21
|
+
export const allPermissions: ReadonlyArray<Permission> =
|
|
22
|
+
Permission.literals as ReadonlyArray<Permission>;
|
|
23
|
+
|
|
24
|
+
export const defaultPermissions: Record<string, ReadonlyArray<Permission>> = {
|
|
25
|
+
Admin: [
|
|
26
|
+
'team:manage',
|
|
27
|
+
'team:invite',
|
|
28
|
+
'roster:view',
|
|
29
|
+
'roster:manage',
|
|
30
|
+
'member:view',
|
|
31
|
+
'member:edit',
|
|
32
|
+
'member:remove',
|
|
33
|
+
'role:view',
|
|
34
|
+
'role:manage',
|
|
35
|
+
],
|
|
36
|
+
Captain: ['roster:view', 'roster:manage', 'member:view', 'member:edit', 'role:view'],
|
|
37
|
+
Player: ['roster:view', 'member:view'],
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const builtInRoleNames = ['Admin', 'Captain', 'Player'] as const;
|
|
41
|
+
|
|
42
|
+
export class Role extends Model.Class<Role>('Role')({
|
|
43
|
+
id: Model.Generated(RoleId),
|
|
44
|
+
team_id: TeamId,
|
|
45
|
+
name: Schema.String,
|
|
46
|
+
is_built_in: Schema.Boolean,
|
|
47
|
+
created_at: Model.DateTimeInsertFromDate,
|
|
48
|
+
}) {}
|
|
49
|
+
|
|
50
|
+
export class RolePermission extends Schema.Class<RolePermission>('RolePermission')({
|
|
51
|
+
role_id: RoleId,
|
|
52
|
+
permission: Permission,
|
|
53
|
+
}) {}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Model } from '@effect/sql';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { RosterId } from '~/models/RosterModel.js';
|
|
4
|
+
import { TeamMemberId } from '~/models/TeamMember.js';
|
|
5
|
+
|
|
6
|
+
export const RosterMemberId = Schema.String.pipe(Schema.brand('RosterMemberId'));
|
|
7
|
+
export type RosterMemberId = typeof RosterMemberId.Type;
|
|
8
|
+
|
|
9
|
+
export class RosterMember extends Model.Class<RosterMember>('RosterMember')({
|
|
10
|
+
id: Model.Generated(RosterMemberId),
|
|
11
|
+
roster_id: RosterId,
|
|
12
|
+
team_member_id: TeamMemberId,
|
|
13
|
+
created_at: Model.DateTimeInsertFromDate,
|
|
14
|
+
}) {}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Model } from '@effect/sql';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { TeamId } from '~/models/Team.js';
|
|
4
|
+
|
|
5
|
+
export const RosterId = Schema.String.pipe(Schema.brand('RosterId'));
|
|
6
|
+
export type RosterId = typeof RosterId.Type;
|
|
7
|
+
|
|
8
|
+
export class Roster extends Model.Class<Roster>('Roster')({
|
|
9
|
+
id: Model.Generated(RosterId),
|
|
10
|
+
team_id: TeamId,
|
|
11
|
+
name: Schema.String,
|
|
12
|
+
active: Schema.Boolean,
|
|
13
|
+
created_at: Model.DateTimeInsertFromDate,
|
|
14
|
+
}) {}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Model } from '@effect/sql';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { TeamId } from '~/models/Team.js';
|
|
4
|
+
|
|
5
|
+
export const SubgroupId = Schema.String.pipe(Schema.brand('SubgroupId'));
|
|
6
|
+
export type SubgroupId = typeof SubgroupId.Type;
|
|
7
|
+
|
|
8
|
+
export class Subgroup extends Model.Class<Subgroup>('Subgroup')({
|
|
9
|
+
id: Model.Generated(SubgroupId),
|
|
10
|
+
team_id: TeamId,
|
|
11
|
+
name: Schema.String,
|
|
12
|
+
created_at: Model.DateTimeInsertFromDate,
|
|
13
|
+
}) {}
|
package/src/models/TeamMember.ts
CHANGED
|
@@ -6,13 +6,10 @@ import { UserId } from '~/models/User.js';
|
|
|
6
6
|
export const TeamMemberId = Schema.String.pipe(Schema.brand('TeamMemberId'));
|
|
7
7
|
export type TeamMemberId = typeof TeamMemberId.Type;
|
|
8
8
|
|
|
9
|
-
export const TeamRole = Schema.Literal('admin', 'member');
|
|
10
|
-
export type TeamRole = typeof TeamRole.Type;
|
|
11
|
-
|
|
12
9
|
export class TeamMember extends Model.Class<TeamMember>('TeamMember')({
|
|
13
10
|
id: Model.Generated(TeamMemberId),
|
|
14
11
|
team_id: TeamId,
|
|
15
12
|
user_id: UserId,
|
|
16
|
-
|
|
13
|
+
active: Schema.Boolean,
|
|
17
14
|
joined_at: Model.DateTimeInsertFromDate,
|
|
18
15
|
}) {}
|