@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.
Files changed (113) hide show
  1. package/dist/cjs/api/AgeThresholdApi.js +86 -0
  2. package/dist/cjs/api/AgeThresholdApi.js.map +1 -0
  3. package/dist/cjs/api/Auth.js +33 -2
  4. package/dist/cjs/api/Auth.js.map +1 -1
  5. package/dist/cjs/api/Invite.js +1 -2
  6. package/dist/cjs/api/Invite.js.map +1 -1
  7. package/dist/cjs/api/NotificationApi.js +42 -0
  8. package/dist/cjs/api/NotificationApi.js.map +1 -0
  9. package/dist/cjs/api/RoleApi.js +123 -0
  10. package/dist/cjs/api/RoleApi.js.map +1 -0
  11. package/dist/cjs/api/Roster.js +159 -0
  12. package/dist/cjs/api/Roster.js.map +1 -0
  13. package/dist/cjs/api/SubgroupApi.js +122 -0
  14. package/dist/cjs/api/SubgroupApi.js.map +1 -0
  15. package/dist/cjs/index.js +25 -1
  16. package/dist/cjs/models/AgeThresholdRule.js +21 -0
  17. package/dist/cjs/models/AgeThresholdRule.js.map +1 -0
  18. package/dist/cjs/models/MemberRole.js +15 -0
  19. package/dist/cjs/models/MemberRole.js.map +1 -0
  20. package/dist/cjs/models/Notification.js +24 -0
  21. package/dist/cjs/models/Notification.js.map +1 -0
  22. package/dist/cjs/models/Role.js +32 -0
  23. package/dist/cjs/models/Role.js.map +1 -0
  24. package/dist/cjs/models/RosterMemberModel.js +19 -0
  25. package/dist/cjs/models/RosterMemberModel.js.map +1 -0
  26. package/dist/cjs/models/RosterModel.js +19 -0
  27. package/dist/cjs/models/RosterModel.js.map +1 -0
  28. package/dist/cjs/models/SubgroupModel.js +18 -0
  29. package/dist/cjs/models/SubgroupModel.js.map +1 -0
  30. package/dist/cjs/models/TeamMember.js +2 -3
  31. package/dist/cjs/models/TeamMember.js.map +1 -1
  32. package/dist/dts/api/AgeThresholdApi.d.ts +119 -0
  33. package/dist/dts/api/AgeThresholdApi.d.ts.map +1 -0
  34. package/dist/dts/api/Auth.d.ts +60 -1
  35. package/dist/dts/api/Auth.d.ts.map +1 -1
  36. package/dist/dts/api/Invite.d.ts +7 -7
  37. package/dist/dts/api/Invite.d.ts.map +1 -1
  38. package/dist/dts/api/NotificationApi.d.ts +53 -0
  39. package/dist/dts/api/NotificationApi.d.ts.map +1 -0
  40. package/dist/dts/api/RoleApi.d.ts +138 -0
  41. package/dist/dts/api/RoleApi.d.ts.map +1 -0
  42. package/dist/dts/api/Roster.d.ts +225 -0
  43. package/dist/dts/api/Roster.d.ts.map +1 -0
  44. package/dist/dts/api/SubgroupApi.d.ts +140 -0
  45. package/dist/dts/api/SubgroupApi.d.ts.map +1 -0
  46. package/dist/dts/index.d.ts +12 -0
  47. package/dist/dts/index.d.ts.map +1 -1
  48. package/dist/dts/models/AgeThresholdRule.d.ts +97 -0
  49. package/dist/dts/models/AgeThresholdRule.d.ts.map +1 -0
  50. package/dist/dts/models/MemberRole.d.ts +16 -0
  51. package/dist/dts/models/MemberRole.d.ts.map +1 -0
  52. package/dist/dts/models/Notification.d.ts +125 -0
  53. package/dist/dts/models/Notification.d.ts.map +1 -0
  54. package/dist/dts/models/Role.d.ts +102 -0
  55. package/dist/dts/models/Role.d.ts.map +1 -0
  56. package/dist/dts/models/RosterMemberModel.d.ts +71 -0
  57. package/dist/dts/models/RosterMemberModel.d.ts.map +1 -0
  58. package/dist/dts/models/RosterModel.d.ts +84 -0
  59. package/dist/dts/models/RosterModel.d.ts.map +1 -0
  60. package/dist/dts/models/SubgroupModel.d.ts +71 -0
  61. package/dist/dts/models/SubgroupModel.d.ts.map +1 -0
  62. package/dist/dts/models/TeamInvite.d.ts +4 -4
  63. package/dist/dts/models/TeamMember.d.ts +11 -13
  64. package/dist/dts/models/TeamMember.d.ts.map +1 -1
  65. package/dist/esm/api/AgeThresholdApi.js +72 -0
  66. package/dist/esm/api/AgeThresholdApi.js.map +1 -0
  67. package/dist/esm/api/Auth.js +28 -1
  68. package/dist/esm/api/Auth.js.map +1 -1
  69. package/dist/esm/api/Invite.js +1 -2
  70. package/dist/esm/api/Invite.js.map +1 -1
  71. package/dist/esm/api/NotificationApi.js +32 -0
  72. package/dist/esm/api/NotificationApi.js.map +1 -0
  73. package/dist/esm/api/RoleApi.js +106 -0
  74. package/dist/esm/api/RoleApi.js.map +1 -0
  75. package/dist/esm/api/Roster.js +142 -0
  76. package/dist/esm/api/Roster.js.map +1 -0
  77. package/dist/esm/api/SubgroupApi.js +106 -0
  78. package/dist/esm/api/SubgroupApi.js.map +1 -0
  79. package/dist/esm/index.js +12 -0
  80. package/dist/esm/index.js.map +1 -1
  81. package/dist/esm/models/AgeThresholdRule.js +14 -0
  82. package/dist/esm/models/AgeThresholdRule.js.map +1 -0
  83. package/dist/esm/models/MemberRole.js +8 -0
  84. package/dist/esm/models/MemberRole.js.map +1 -0
  85. package/dist/esm/models/Notification.js +17 -0
  86. package/dist/esm/models/Notification.js.map +1 -0
  87. package/dist/esm/models/Role.js +24 -0
  88. package/dist/esm/models/Role.js.map +1 -0
  89. package/dist/esm/models/RosterMemberModel.js +12 -0
  90. package/dist/esm/models/RosterMemberModel.js.map +1 -0
  91. package/dist/esm/models/RosterModel.js +12 -0
  92. package/dist/esm/models/RosterModel.js.map +1 -0
  93. package/dist/esm/models/SubgroupModel.js +11 -0
  94. package/dist/esm/models/SubgroupModel.js.map +1 -0
  95. package/dist/esm/models/TeamMember.js +1 -2
  96. package/dist/esm/models/TeamMember.js.map +1 -1
  97. package/package.json +1 -1
  98. package/src/api/AgeThresholdApi.ts +99 -0
  99. package/src/api/Auth.ts +52 -0
  100. package/src/api/Invite.ts +1 -2
  101. package/src/api/NotificationApi.ts +49 -0
  102. package/src/api/RoleApi.ts +130 -0
  103. package/src/api/Roster.ts +176 -0
  104. package/src/api/SubgroupApi.ts +146 -0
  105. package/src/index.ts +24 -0
  106. package/src/models/AgeThresholdRule.ts +16 -0
  107. package/src/models/MemberRole.ts +8 -0
  108. package/src/models/Notification.ts +26 -0
  109. package/src/models/Role.ts +53 -0
  110. package/src/models/RosterMemberModel.ts +14 -0
  111. package/src/models/RosterModel.ts +14 -0
  112. package/src/models/SubgroupModel.ts +13 -0
  113. 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
+ }) {}
@@ -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
- role: TeamRole,
13
+ active: Schema.Boolean,
17
14
  joined_at: Model.DateTimeInsertFromDate,
18
15
  }) {}