@sideline/domain 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.
Files changed (133) 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 +2 -3
  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/Session.js +1 -1
  29. package/dist/cjs/models/SubgroupModel.js +18 -0
  30. package/dist/cjs/models/SubgroupModel.js.map +1 -0
  31. package/dist/cjs/models/Team.js +1 -1
  32. package/dist/cjs/models/TeamInvite.js +2 -2
  33. package/dist/cjs/models/TeamMember.js +4 -5
  34. package/dist/cjs/models/TeamMember.js.map +1 -1
  35. package/dist/dts/api/AgeThresholdApi.d.ts +119 -0
  36. package/dist/dts/api/AgeThresholdApi.d.ts.map +1 -0
  37. package/dist/dts/api/Auth.d.ts +60 -1
  38. package/dist/dts/api/Auth.d.ts.map +1 -1
  39. package/dist/dts/api/Invite.d.ts +11 -11
  40. package/dist/dts/api/Invite.d.ts.map +1 -1
  41. package/dist/dts/api/NotificationApi.d.ts +53 -0
  42. package/dist/dts/api/NotificationApi.d.ts.map +1 -0
  43. package/dist/dts/api/RoleApi.d.ts +138 -0
  44. package/dist/dts/api/RoleApi.d.ts.map +1 -0
  45. package/dist/dts/api/Roster.d.ts +225 -0
  46. package/dist/dts/api/Roster.d.ts.map +1 -0
  47. package/dist/dts/api/SubgroupApi.d.ts +140 -0
  48. package/dist/dts/api/SubgroupApi.d.ts.map +1 -0
  49. package/dist/dts/index.d.ts +12 -0
  50. package/dist/dts/index.d.ts.map +1 -1
  51. package/dist/dts/models/AgeThresholdRule.d.ts +97 -0
  52. package/dist/dts/models/AgeThresholdRule.d.ts.map +1 -0
  53. package/dist/dts/models/MemberRole.d.ts +16 -0
  54. package/dist/dts/models/MemberRole.d.ts.map +1 -0
  55. package/dist/dts/models/Notification.d.ts +125 -0
  56. package/dist/dts/models/Notification.d.ts.map +1 -0
  57. package/dist/dts/models/Role.d.ts +102 -0
  58. package/dist/dts/models/Role.d.ts.map +1 -0
  59. package/dist/dts/models/RosterMemberModel.d.ts +71 -0
  60. package/dist/dts/models/RosterMemberModel.d.ts.map +1 -0
  61. package/dist/dts/models/RosterModel.d.ts +84 -0
  62. package/dist/dts/models/RosterModel.d.ts.map +1 -0
  63. package/dist/dts/models/SubgroupModel.d.ts +71 -0
  64. package/dist/dts/models/SubgroupModel.d.ts.map +1 -0
  65. package/dist/dts/models/TeamInvite.d.ts +4 -4
  66. package/dist/dts/models/TeamMember.d.ts +11 -13
  67. package/dist/dts/models/TeamMember.d.ts.map +1 -1
  68. package/dist/esm/api/AgeThresholdApi.js +72 -0
  69. package/dist/esm/api/AgeThresholdApi.js.map +1 -0
  70. package/dist/esm/api/Auth.js +28 -1
  71. package/dist/esm/api/Auth.js.map +1 -1
  72. package/dist/esm/api/Invite.js +2 -3
  73. package/dist/esm/api/Invite.js.map +1 -1
  74. package/dist/esm/api/NotificationApi.js +32 -0
  75. package/dist/esm/api/NotificationApi.js.map +1 -0
  76. package/dist/esm/api/RoleApi.js +106 -0
  77. package/dist/esm/api/RoleApi.js.map +1 -0
  78. package/dist/esm/api/Roster.js +142 -0
  79. package/dist/esm/api/Roster.js.map +1 -0
  80. package/dist/esm/api/SubgroupApi.js +106 -0
  81. package/dist/esm/api/SubgroupApi.js.map +1 -0
  82. package/dist/esm/index.js +12 -0
  83. package/dist/esm/index.js.map +1 -1
  84. package/dist/esm/models/AgeThresholdRule.js +14 -0
  85. package/dist/esm/models/AgeThresholdRule.js.map +1 -0
  86. package/dist/esm/models/MemberRole.js +8 -0
  87. package/dist/esm/models/MemberRole.js.map +1 -0
  88. package/dist/esm/models/Notification.js +17 -0
  89. package/dist/esm/models/Notification.js.map +1 -0
  90. package/dist/esm/models/Role.js +24 -0
  91. package/dist/esm/models/Role.js.map +1 -0
  92. package/dist/esm/models/RosterMemberModel.js +12 -0
  93. package/dist/esm/models/RosterMemberModel.js.map +1 -0
  94. package/dist/esm/models/RosterModel.js +12 -0
  95. package/dist/esm/models/RosterModel.js.map +1 -0
  96. package/dist/esm/models/Session.js +1 -1
  97. package/dist/esm/models/Session.js.map +1 -1
  98. package/dist/esm/models/SubgroupModel.js +11 -0
  99. package/dist/esm/models/SubgroupModel.js.map +1 -0
  100. package/dist/esm/models/Team.js +1 -1
  101. package/dist/esm/models/Team.js.map +1 -1
  102. package/dist/esm/models/TeamInvite.js +2 -2
  103. package/dist/esm/models/TeamInvite.js.map +1 -1
  104. package/dist/esm/models/TeamMember.js +3 -4
  105. package/dist/esm/models/TeamMember.js.map +1 -1
  106. package/package.json +1 -69
  107. package/src/api/AgeThresholdApi.ts +99 -0
  108. package/src/api/Auth.ts +54 -2
  109. package/src/api/Invite.ts +3 -4
  110. package/src/api/NotificationApi.ts +49 -0
  111. package/src/api/RoleApi.ts +130 -0
  112. package/src/api/Roster.ts +176 -0
  113. package/src/api/SubgroupApi.ts +146 -0
  114. package/src/index.ts +24 -0
  115. package/src/models/AgeThresholdRule.ts +16 -0
  116. package/src/models/MemberRole.ts +8 -0
  117. package/src/models/Notification.ts +26 -0
  118. package/src/models/Role.ts +53 -0
  119. package/src/models/RosterMemberModel.ts +14 -0
  120. package/src/models/RosterModel.ts +14 -0
  121. package/src/models/Session.ts +1 -1
  122. package/src/models/SubgroupModel.ts +13 -0
  123. package/src/models/Team.ts +1 -1
  124. package/src/models/TeamInvite.ts +2 -2
  125. package/src/models/TeamMember.ts +3 -6
  126. package/ApiGroup/package.json +0 -6
  127. package/api/Auth/package.json +0 -6
  128. package/api/Invite/package.json +0 -6
  129. package/models/Session/package.json +0 -6
  130. package/models/Team/package.json +0 -6
  131. package/models/TeamInvite/package.json +0 -6
  132. package/models/TeamMember/package.json +0 -6
  133. package/models/User/package.json +0 -6
@@ -1 +1 @@
1
- {"version":3,"file":"TeamInvite.js","names":["Model","DateTime","Schema","TeamId","UserId","TeamInviteId","String","pipe","brand","NullableDateTimeFromDate","NullOr","transform","DateFromSelf","DateTimeUtcFromSelf","decode","date","unsafeFromDate","encode","dt","Date","toEpochMillis","TeamInvite","Class","id","Generated","team_id","code","active","Boolean","created_by","created_at","DateTimeInsertFromDate","expires_at"],"sources":["../../../src/models/TeamInvite.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,KAAK,QAAQ,aAAa;AACnC,SAASC,QAAQ,EAAEC,MAAM,QAAQ,QAAQ;AACzC,SAASC,MAAM,QAAQ,WAAW;AAClC,SAASC,MAAM,QAAQ,WAAW;AAElC,OAAO,MAAMC,YAAY,gBAAGH,MAAM,CAACI,MAAM,CAACC,IAAI,cAACL,MAAM,CAACM,KAAK,CAAC,cAAc,CAAC,CAAC;AAG5E,MAAMC,wBAAwB,gBAAGP,MAAM,CAACQ,MAAM,cAC5CR,MAAM,CAACS,SAAS,CAACT,MAAM,CAACU,YAAY,EAAEV,MAAM,CAACW,mBAAmB,EAAE;EAChEC,MAAM,EAAGC,IAAI,IAAKd,QAAQ,CAACe,cAAc,CAACD,IAAI,CAAC;EAC/CE,MAAM,EAAGC,EAAE,IAAK,IAAIC,IAAI,CAAClB,QAAQ,CAACmB,aAAa,CAACF,EAAE,CAAC;CACpD,CAAC,CACH;AAED,OAAM,MAAOG,UAAW,sBAAQrB,KAAK,CAACsB,KAAK,CAAa,YAAY,CAAC,CAAC;EACpEC,EAAE,eAAEvB,KAAK,CAACwB,SAAS,CAACnB,YAAY,CAAC;EACjCoB,OAAO,EAAEtB,MAAM;EACfuB,IAAI,EAAExB,MAAM,CAACI,MAAM;EACnBqB,MAAM,EAAEzB,MAAM,CAAC0B,OAAO;EACtBC,UAAU,EAAEzB,MAAM;EAClB0B,UAAU,EAAE9B,KAAK,CAAC+B,sBAAsB;EACxCC,UAAU,EAAEvB;CACb,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"TeamInvite.js","names":["Model","DateTime","Schema","TeamId","UserId","TeamInviteId","String","pipe","brand","NullableDateTimeFromDate","NullOr","transform","DateFromSelf","DateTimeUtcFromSelf","decode","date","unsafeFromDate","encode","dt","Date","toEpochMillis","TeamInvite","Class","id","Generated","team_id","code","active","Boolean","created_by","created_at","DateTimeInsertFromDate","expires_at"],"sources":["../../../src/models/TeamInvite.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,KAAK,QAAQ,aAAa;AACnC,SAASC,QAAQ,EAAEC,MAAM,QAAQ,QAAQ;AACzC,SAASC,MAAM,QAAQ,mBAAmB;AAC1C,SAASC,MAAM,QAAQ,mBAAmB;AAE1C,OAAO,MAAMC,YAAY,gBAAGH,MAAM,CAACI,MAAM,CAACC,IAAI,cAACL,MAAM,CAACM,KAAK,CAAC,cAAc,CAAC,CAAC;AAG5E,MAAMC,wBAAwB,gBAAGP,MAAM,CAACQ,MAAM,cAC5CR,MAAM,CAACS,SAAS,CAACT,MAAM,CAACU,YAAY,EAAEV,MAAM,CAACW,mBAAmB,EAAE;EAChEC,MAAM,EAAGC,IAAI,IAAKd,QAAQ,CAACe,cAAc,CAACD,IAAI,CAAC;EAC/CE,MAAM,EAAGC,EAAE,IAAK,IAAIC,IAAI,CAAClB,QAAQ,CAACmB,aAAa,CAACF,EAAE,CAAC;CACpD,CAAC,CACH;AAED,OAAM,MAAOG,UAAW,sBAAQrB,KAAK,CAACsB,KAAK,CAAa,YAAY,CAAC,CAAC;EACpEC,EAAE,eAAEvB,KAAK,CAACwB,SAAS,CAACnB,YAAY,CAAC;EACjCoB,OAAO,EAAEtB,MAAM;EACfuB,IAAI,EAAExB,MAAM,CAACI,MAAM;EACnBqB,MAAM,EAAEzB,MAAM,CAAC0B,OAAO;EACtBC,UAAU,EAAEzB,MAAM;EAClB0B,UAAU,EAAE9B,KAAK,CAAC+B,sBAAsB;EACxCC,UAAU,EAAEvB;CACb,CAAC","ignoreList":[]}
@@ -1,14 +1,13 @@
1
1
  import { Model } from '@effect/sql';
2
2
  import { Schema } from 'effect';
3
- import { TeamId } from './Team.js';
4
- import { UserId } from './User.js';
3
+ import { TeamId } from '../models/Team.js';
4
+ import { UserId } from '../models/User.js';
5
5
  export const TeamMemberId = /*#__PURE__*/Schema.String.pipe(/*#__PURE__*/Schema.brand('TeamMemberId'));
6
- export const TeamRole = /*#__PURE__*/Schema.Literal('admin', 'member');
7
6
  export class TeamMember extends /*#__PURE__*/Model.Class('TeamMember')({
8
7
  id: /*#__PURE__*/Model.Generated(TeamMemberId),
9
8
  team_id: TeamId,
10
9
  user_id: UserId,
11
- role: TeamRole,
10
+ active: Schema.Boolean,
12
11
  joined_at: Model.DateTimeInsertFromDate
13
12
  }) {}
14
13
  //# sourceMappingURL=TeamMember.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TeamMember.js","names":["Model","Schema","TeamId","UserId","TeamMemberId","String","pipe","brand","TeamRole","Literal","TeamMember","Class","id","Generated","team_id","user_id","role","joined_at","DateTimeInsertFromDate"],"sources":["../../../src/models/TeamMember.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,QAAQ,QAAQ;AAC/B,SAASC,MAAM,QAAQ,WAAW;AAClC,SAASC,MAAM,QAAQ,WAAW;AAElC,OAAO,MAAMC,YAAY,gBAAGH,MAAM,CAACI,MAAM,CAACC,IAAI,cAACL,MAAM,CAACM,KAAK,CAAC,cAAc,CAAC,CAAC;AAG5E,OAAO,MAAMC,QAAQ,gBAAGP,MAAM,CAACQ,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC;AAGzD,OAAM,MAAOC,UAAW,sBAAQV,KAAK,CAACW,KAAK,CAAa,YAAY,CAAC,CAAC;EACpEC,EAAE,eAAEZ,KAAK,CAACa,SAAS,CAACT,YAAY,CAAC;EACjCU,OAAO,EAAEZ,MAAM;EACfa,OAAO,EAAEZ,MAAM;EACfa,IAAI,EAAER,QAAQ;EACdS,SAAS,EAAEjB,KAAK,CAACkB;CAClB,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"TeamMember.js","names":["Model","Schema","TeamId","UserId","TeamMemberId","String","pipe","brand","TeamMember","Class","id","Generated","team_id","user_id","active","Boolean","joined_at","DateTimeInsertFromDate"],"sources":["../../../src/models/TeamMember.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,QAAQ,QAAQ;AAC/B,SAASC,MAAM,QAAQ,mBAAmB;AAC1C,SAASC,MAAM,QAAQ,mBAAmB;AAE1C,OAAO,MAAMC,YAAY,gBAAGH,MAAM,CAACI,MAAM,CAACC,IAAI,cAACL,MAAM,CAACM,KAAK,CAAC,cAAc,CAAC,CAAC;AAG5E,OAAM,MAAOC,UAAW,sBAAQR,KAAK,CAACS,KAAK,CAAa,YAAY,CAAC,CAAC;EACpEC,EAAE,eAAEV,KAAK,CAACW,SAAS,CAACP,YAAY,CAAC;EACjCQ,OAAO,EAAEV,MAAM;EACfW,OAAO,EAAEV,MAAM;EACfW,MAAM,EAAEb,MAAM,CAACc,OAAO;EACtBC,SAAS,EAAEhB,KAAK,CAACiB;CAClB,CAAC","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sideline/domain",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "The domain template",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -24,74 +24,6 @@
24
24
  "types": "./dist/dts/index.d.ts",
25
25
  "import": "./dist/esm/index.js",
26
26
  "default": "./dist/cjs/index.js"
27
- },
28
- "./ApiGroup": {
29
- "types": "./dist/dts/ApiGroup.d.ts",
30
- "import": "./dist/esm/ApiGroup.js",
31
- "default": "./dist/cjs/ApiGroup.js"
32
- },
33
- "./api/Auth": {
34
- "types": "./dist/dts/api/Auth.d.ts",
35
- "import": "./dist/esm/api/Auth.js",
36
- "default": "./dist/cjs/api/Auth.js"
37
- },
38
- "./api/Invite": {
39
- "types": "./dist/dts/api/Invite.d.ts",
40
- "import": "./dist/esm/api/Invite.js",
41
- "default": "./dist/cjs/api/Invite.js"
42
- },
43
- "./models/Session": {
44
- "types": "./dist/dts/models/Session.d.ts",
45
- "import": "./dist/esm/models/Session.js",
46
- "default": "./dist/cjs/models/Session.js"
47
- },
48
- "./models/Team": {
49
- "types": "./dist/dts/models/Team.d.ts",
50
- "import": "./dist/esm/models/Team.js",
51
- "default": "./dist/cjs/models/Team.js"
52
- },
53
- "./models/TeamInvite": {
54
- "types": "./dist/dts/models/TeamInvite.d.ts",
55
- "import": "./dist/esm/models/TeamInvite.js",
56
- "default": "./dist/cjs/models/TeamInvite.js"
57
- },
58
- "./models/TeamMember": {
59
- "types": "./dist/dts/models/TeamMember.d.ts",
60
- "import": "./dist/esm/models/TeamMember.js",
61
- "default": "./dist/cjs/models/TeamMember.js"
62
- },
63
- "./models/User": {
64
- "types": "./dist/dts/models/User.d.ts",
65
- "import": "./dist/esm/models/User.js",
66
- "default": "./dist/cjs/models/User.js"
67
- }
68
- },
69
- "typesVersions": {
70
- "*": {
71
- "ApiGroup": [
72
- "./dist/dts/ApiGroup.d.ts"
73
- ],
74
- "api/Auth": [
75
- "./dist/dts/api/Auth.d.ts"
76
- ],
77
- "api/Invite": [
78
- "./dist/dts/api/Invite.d.ts"
79
- ],
80
- "models/Session": [
81
- "./dist/dts/models/Session.d.ts"
82
- ],
83
- "models/Team": [
84
- "./dist/dts/models/Team.d.ts"
85
- ],
86
- "models/TeamInvite": [
87
- "./dist/dts/models/TeamInvite.d.ts"
88
- ],
89
- "models/TeamMember": [
90
- "./dist/dts/models/TeamMember.d.ts"
91
- ],
92
- "models/User": [
93
- "./dist/dts/models/User.d.ts"
94
- ]
95
27
  }
96
28
  }
97
29
  }
@@ -0,0 +1,99 @@
1
+ import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from '@effect/platform';
2
+ import { Schema } from 'effect';
3
+ import { AuthMiddleware } from '~/api/Auth.js';
4
+ import { AgeThresholdRuleId } from '~/models/AgeThresholdRule.js';
5
+ import { RoleId } from '~/models/Role.js';
6
+ import { TeamId } from '~/models/Team.js';
7
+ import { TeamMemberId } from '~/models/TeamMember.js';
8
+
9
+ export class AgeThresholdInfo extends Schema.Class<AgeThresholdInfo>('AgeThresholdInfo')({
10
+ ruleId: AgeThresholdRuleId,
11
+ teamId: TeamId,
12
+ roleId: RoleId,
13
+ roleName: Schema.String,
14
+ minAge: Schema.NullOr(Schema.Number),
15
+ maxAge: Schema.NullOr(Schema.Number),
16
+ }) {}
17
+
18
+ export class AgeRoleChange extends Schema.Class<AgeRoleChange>('AgeRoleChange')({
19
+ memberId: TeamMemberId,
20
+ memberName: Schema.String,
21
+ roleId: RoleId,
22
+ roleName: Schema.String,
23
+ action: Schema.Literal('assigned', 'removed'),
24
+ }) {}
25
+
26
+ export class CreateAgeThresholdRequest extends Schema.Class<CreateAgeThresholdRequest>(
27
+ 'CreateAgeThresholdRequest',
28
+ )({
29
+ roleId: RoleId,
30
+ minAge: Schema.NullOr(Schema.Number),
31
+ maxAge: Schema.NullOr(Schema.Number),
32
+ }) {}
33
+
34
+ export class UpdateAgeThresholdRequest extends Schema.Class<UpdateAgeThresholdRequest>(
35
+ 'UpdateAgeThresholdRequest',
36
+ )({
37
+ minAge: Schema.NullOr(Schema.Number),
38
+ maxAge: Schema.NullOr(Schema.Number),
39
+ }) {}
40
+
41
+ export class Forbidden extends Schema.TaggedError<Forbidden>()(
42
+ 'AgeThresholdForbidden',
43
+ {},
44
+ HttpApiSchema.annotations({ status: 403 }),
45
+ ) {}
46
+
47
+ export class RuleNotFound extends Schema.TaggedError<RuleNotFound>()(
48
+ 'AgeThresholdRuleNotFound',
49
+ {},
50
+ HttpApiSchema.annotations({ status: 404 }),
51
+ ) {}
52
+
53
+ export class RoleNotFound extends Schema.TaggedError<RoleNotFound>()(
54
+ 'AgeThresholdRoleNotFound',
55
+ {},
56
+ HttpApiSchema.annotations({ status: 404 }),
57
+ ) {}
58
+
59
+ export class AgeThresholdApiGroup extends HttpApiGroup.make('ageThreshold')
60
+ .add(
61
+ HttpApiEndpoint.get('listAgeThresholds', '/teams/:teamId/age-thresholds')
62
+ .addSuccess(Schema.Array(AgeThresholdInfo))
63
+ .addError(Forbidden, { status: 403 })
64
+ .setPath(Schema.Struct({ teamId: TeamId }))
65
+ .middleware(AuthMiddleware),
66
+ )
67
+ .add(
68
+ HttpApiEndpoint.post('createAgeThreshold', '/teams/:teamId/age-thresholds')
69
+ .addSuccess(AgeThresholdInfo, { status: 201 })
70
+ .addError(Forbidden, { status: 403 })
71
+ .addError(RoleNotFound, { status: 404 })
72
+ .setPath(Schema.Struct({ teamId: TeamId }))
73
+ .setPayload(CreateAgeThresholdRequest)
74
+ .middleware(AuthMiddleware),
75
+ )
76
+ .add(
77
+ HttpApiEndpoint.patch('updateAgeThreshold', '/teams/:teamId/age-thresholds/:ruleId')
78
+ .addSuccess(AgeThresholdInfo)
79
+ .addError(Forbidden, { status: 403 })
80
+ .addError(RuleNotFound, { status: 404 })
81
+ .setPath(Schema.Struct({ teamId: TeamId, ruleId: AgeThresholdRuleId }))
82
+ .setPayload(UpdateAgeThresholdRequest)
83
+ .middleware(AuthMiddleware),
84
+ )
85
+ .add(
86
+ HttpApiEndpoint.del('deleteAgeThreshold', '/teams/:teamId/age-thresholds/:ruleId')
87
+ .addSuccess(Schema.Void)
88
+ .addError(Forbidden, { status: 403 })
89
+ .addError(RuleNotFound, { status: 404 })
90
+ .setPath(Schema.Struct({ teamId: TeamId, ruleId: AgeThresholdRuleId }))
91
+ .middleware(AuthMiddleware),
92
+ )
93
+ .add(
94
+ HttpApiEndpoint.post('evaluateAgeThresholds', '/teams/:teamId/age-thresholds/evaluate')
95
+ .addSuccess(Schema.Array(AgeRoleChange))
96
+ .addError(Forbidden, { status: 403 })
97
+ .setPath(Schema.Struct({ teamId: TeamId }))
98
+ .middleware(AuthMiddleware),
99
+ ) {}
package/src/api/Auth.ts CHANGED
@@ -6,12 +6,21 @@ import {
6
6
  HttpApiSecurity,
7
7
  } from '@effect/platform';
8
8
  import { Context, Schema } from 'effect';
9
- import { Gender, Locale, Position, Proficiency, UserId } from '../models/User.js';
9
+ import { Permission } from '~/models/Role.js';
10
+ import { TeamId } from '~/models/Team.js';
11
+ import { Gender, Locale, Position, Proficiency, UserId } from '~/models/User.js';
10
12
 
11
- export { UserId } from '../models/User.js';
13
+ export { UserId } from '~/models/User.js';
12
14
 
13
15
  export const MIN_AGE = 6;
14
16
 
17
+ export class UserTeam extends Schema.Class<UserTeam>('UserTeam')({
18
+ teamId: TeamId,
19
+ teamName: Schema.String,
20
+ roleNames: Schema.Array(Schema.String),
21
+ permissions: Schema.Array(Permission),
22
+ }) {}
23
+
15
24
  export class CurrentUser extends Schema.Class<CurrentUser>('CurrentUser')({
16
25
  id: UserId,
17
26
  discordId: Schema.String,
@@ -31,6 +40,10 @@ export class UpdateLocaleRequest extends Schema.Class<UpdateLocaleRequest>('Upda
31
40
  locale: Locale,
32
41
  }) {}
33
42
 
43
+ export class CreateTeamRequest extends Schema.Class<CreateTeamRequest>('CreateTeamRequest')({
44
+ name: Schema.String.pipe(Schema.minLength(1), Schema.maxLength(100)),
45
+ }) {}
46
+
34
47
  export class CompleteProfileRequest extends Schema.Class<CompleteProfileRequest>(
35
48
  'CompleteProfileRequest',
36
49
  )({
@@ -50,6 +63,25 @@ export class CompleteProfileRequest extends Schema.Class<CompleteProfileRequest>
50
63
  proficiency: Proficiency,
51
64
  }) {}
52
65
 
66
+ export class UpdateProfileRequest extends Schema.Class<UpdateProfileRequest>(
67
+ 'UpdateProfileRequest',
68
+ )({
69
+ name: Schema.NullOr(Schema.String),
70
+ birthYear: Schema.NullOr(
71
+ Schema.Number.pipe(
72
+ Schema.int(),
73
+ Schema.greaterThanOrEqualTo(1900),
74
+ Schema.filter((year) => year <= new Date().getFullYear() - MIN_AGE, {
75
+ message: () => `Birth year must be at most ${new Date().getFullYear() - MIN_AGE}`,
76
+ }),
77
+ ),
78
+ ),
79
+ gender: Schema.NullOr(Gender),
80
+ jerseyNumber: Schema.NullOr(Schema.Number.pipe(Schema.int(), Schema.between(0, 99))),
81
+ position: Schema.NullOr(Position),
82
+ proficiency: Schema.NullOr(Proficiency),
83
+ }) {}
84
+
53
85
  export class Unauthorized extends Schema.TaggedError<Unauthorized>()(
54
86
  'Unauthorized',
55
87
  {},
@@ -101,4 +133,24 @@ export class AuthApiGroup extends HttpApiGroup.make('auth')
101
133
  .setPayload(UpdateLocaleRequest)
102
134
  .middleware(AuthMiddleware),
103
135
  )
136
+ .add(
137
+ HttpApiEndpoint.patch('updateProfile', '/me')
138
+ .addSuccess(CurrentUser)
139
+ .addError(Unauthorized, { status: 401 })
140
+ .setPayload(UpdateProfileRequest)
141
+ .middleware(AuthMiddleware),
142
+ )
143
+ .add(
144
+ HttpApiEndpoint.get('myTeams', '/me/teams')
145
+ .addSuccess(Schema.Array(UserTeam))
146
+ .addError(Unauthorized, { status: 401 })
147
+ .middleware(AuthMiddleware),
148
+ )
149
+ .add(
150
+ HttpApiEndpoint.post('createTeam', '/me/teams')
151
+ .addSuccess(UserTeam)
152
+ .addError(Unauthorized, { status: 401 })
153
+ .setPayload(CreateTeamRequest)
154
+ .middleware(AuthMiddleware),
155
+ )
104
156
  .prefix('/auth') {}
package/src/api/Invite.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from '@effect/platform';
2
2
  import { Schema } from 'effect';
3
- import { TeamId } from '../models/Team.js';
4
- import { TeamRole } from '../models/TeamMember.js';
5
- import { AuthMiddleware } from './Auth.js';
3
+ import { AuthMiddleware } from '~/api/Auth.js';
4
+ import { TeamId } from '~/models/Team.js';
6
5
 
7
6
  export class InviteInfo extends Schema.Class<InviteInfo>('InviteInfo')({
8
7
  teamName: Schema.String,
@@ -12,7 +11,7 @@ export class InviteInfo extends Schema.Class<InviteInfo>('InviteInfo')({
12
11
 
13
12
  export class JoinResult extends Schema.Class<JoinResult>('JoinResult')({
14
13
  teamId: TeamId,
15
- role: TeamRole,
14
+ roleNames: Schema.Array(Schema.String),
16
15
  isProfileComplete: Schema.Boolean,
17
16
  }) {}
18
17
 
@@ -0,0 +1,49 @@
1
+ import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from '@effect/platform';
2
+ import { Schema } from 'effect';
3
+ import { AuthMiddleware } from '~/api/Auth.js';
4
+ import { NotificationId, NotificationType } from '~/models/Notification.js';
5
+ import { TeamId } from '~/models/Team.js';
6
+
7
+ export class NotificationInfo extends Schema.Class<NotificationInfo>('NotificationInfo')({
8
+ notificationId: NotificationId,
9
+ teamId: TeamId,
10
+ type: NotificationType,
11
+ title: Schema.String,
12
+ body: Schema.String,
13
+ isRead: Schema.Boolean,
14
+ createdAt: Schema.String,
15
+ }) {}
16
+
17
+ export class Forbidden extends Schema.TaggedError<Forbidden>()(
18
+ 'NotificationForbidden',
19
+ {},
20
+ HttpApiSchema.annotations({ status: 403 }),
21
+ ) {}
22
+
23
+ export class NotificationNotFound extends Schema.TaggedError<NotificationNotFound>()(
24
+ 'NotificationNotFound',
25
+ {},
26
+ HttpApiSchema.annotations({ status: 404 }),
27
+ ) {}
28
+
29
+ export class NotificationApiGroup extends HttpApiGroup.make('notification')
30
+ .add(
31
+ HttpApiEndpoint.get('listNotifications', '/notifications')
32
+ .addSuccess(Schema.Array(NotificationInfo))
33
+ .addError(Forbidden, { status: 403 })
34
+ .middleware(AuthMiddleware),
35
+ )
36
+ .add(
37
+ HttpApiEndpoint.patch('markAsRead', '/notifications/:notificationId/read')
38
+ .addSuccess(Schema.Void)
39
+ .addError(Forbidden, { status: 403 })
40
+ .addError(NotificationNotFound, { status: 404 })
41
+ .setPath(Schema.Struct({ notificationId: NotificationId }))
42
+ .middleware(AuthMiddleware),
43
+ )
44
+ .add(
45
+ HttpApiEndpoint.post('markAllAsRead', '/notifications/read-all')
46
+ .addSuccess(Schema.Void)
47
+ .addError(Forbidden, { status: 403 })
48
+ .middleware(AuthMiddleware),
49
+ ) {}
@@ -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
+ ) {}