@ftisindia/create-app 0.1.3 → 0.1.4

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 (108) hide show
  1. package/package.json +1 -1
  2. package/template/README.md +1 -1
  3. package/template/_package.json +0 -2
  4. package/template/docs/API_REFERENCE.md +13 -0
  5. package/template/docs/OAUTH.md +7 -3
  6. package/template/scripts/gen-module.mjs +2 -0
  7. package/template/src/app.module.ts +16 -22
  8. package/template/src/common/dto/error-response.dto.ts +3 -3
  9. package/template/src/common/dto/membership-response.dto.ts +26 -14
  10. package/template/src/common/dto/mutation-response.dto.ts +1 -1
  11. package/template/src/common/dto/pagination-query.dto.ts +37 -0
  12. package/template/src/common/dto/role-summary.dto.ts +5 -5
  13. package/template/src/common/dto/user-summary.dto.ts +6 -6
  14. package/template/src/common/filters/http-exception.filter.ts +9 -19
  15. package/template/src/common/swagger/api-error-responses.ts +12 -12
  16. package/template/src/config/app.config.ts +3 -3
  17. package/template/src/config/auth.config.ts +3 -3
  18. package/template/src/config/database.config.ts +3 -3
  19. package/template/src/config/env.validation.ts +58 -40
  20. package/template/src/config/index.ts +5 -5
  21. package/template/src/config/rbac.config.ts +3 -3
  22. package/template/src/database/prisma/prisma-transaction.ts +1 -1
  23. package/template/src/database/prisma/prisma.module.ts +2 -2
  24. package/template/src/database/prisma/prisma.service.ts +3 -6
  25. package/template/src/main.ts +11 -11
  26. package/template/src/modules/access-control/access-control.module.ts +9 -9
  27. package/template/src/modules/access-control/application/role-permission-policy.ts +71 -0
  28. package/template/src/modules/access-control/application/route-registry.validator.ts +34 -63
  29. package/template/src/modules/access-control/application/services/ability.factory.ts +5 -9
  30. package/template/src/modules/access-control/application/services/access-control.service.ts +78 -85
  31. package/template/src/modules/access-control/application/services/permission.guard.ts +16 -21
  32. package/template/src/modules/access-control/application/services/rbac-cache.service.ts +7 -9
  33. package/template/src/modules/access-control/dto/access-control-response.dto.ts +32 -20
  34. package/template/src/modules/access-control/dto/create-role.dto.ts +6 -6
  35. package/template/src/modules/access-control/dto/update-role-permissions.dto.ts +3 -10
  36. package/template/src/modules/access-control/dto/update-role.dto.ts +6 -6
  37. package/template/src/modules/access-control/presentation/access-control.controller.ts +69 -74
  38. package/template/src/modules/access-control/presentation/permissions.decorator.ts +3 -3
  39. package/template/src/modules/access-control/presentation/public.decorator.ts +2 -2
  40. package/template/src/modules/access-control/types/permission-key.ts +19 -19
  41. package/template/src/modules/access-control/types/route-permission-registry.ts +76 -76
  42. package/template/src/modules/audit/application/services/audit.service.ts +7 -7
  43. package/template/src/modules/audit/audit.module.ts +4 -4
  44. package/template/src/modules/audit/dto/audit-response.dto.ts +18 -18
  45. package/template/src/modules/audit/dto/list-audit-logs-query.dto.ts +14 -14
  46. package/template/src/modules/audit/presentation/audit.controller.ts +17 -23
  47. package/template/src/modules/auth/application/services/auth.service.ts +147 -110
  48. package/template/src/modules/auth/application/services/password.service.ts +2 -2
  49. package/template/src/modules/auth/application/services/token.service.ts +20 -21
  50. package/template/src/modules/auth/auth.module.ts +20 -47
  51. package/template/src/modules/auth/dto/auth-response.dto.ts +9 -10
  52. package/template/src/modules/auth/dto/login.dto.ts +4 -4
  53. package/template/src/modules/auth/dto/logout.dto.ts +1 -1
  54. package/template/src/modules/auth/dto/oauth-exchange.dto.ts +4 -5
  55. package/template/src/modules/auth/dto/refresh-token.dto.ts +4 -5
  56. package/template/src/modules/auth/dto/signup.dto.ts +5 -11
  57. package/template/src/modules/auth/infrastructure/passport/google-auth.guard.ts +6 -14
  58. package/template/src/modules/auth/infrastructure/passport/google-oauth-state.store.ts +98 -0
  59. package/template/src/modules/auth/infrastructure/passport/google.strategy.ts +21 -30
  60. package/template/src/modules/auth/infrastructure/passport/jwt-auth.guard.ts +3 -3
  61. package/template/src/modules/auth/infrastructure/passport/jwt.strategy.ts +11 -11
  62. package/template/src/modules/auth/presentation/auth.controller.ts +45 -45
  63. package/template/src/modules/auth/presentation/current-user.decorator.ts +3 -5
  64. package/template/src/modules/auth/presentation/google-oauth-exception.filter.ts +5 -10
  65. package/template/src/modules/health/dto/health-response.dto.ts +5 -5
  66. package/template/src/modules/health/health.module.ts +2 -2
  67. package/template/src/modules/health/presentation/health.controller.ts +13 -13
  68. package/template/src/modules/invitations/application/services/invitations.service.ts +127 -176
  69. package/template/src/modules/invitations/dto/accept-invitation.dto.ts +6 -7
  70. package/template/src/modules/invitations/dto/create-invitation.dto.ts +14 -15
  71. package/template/src/modules/invitations/dto/invitation-response.dto.ts +37 -29
  72. package/template/src/modules/invitations/dto/invitation-token.dto.ts +4 -4
  73. package/template/src/modules/invitations/invitations.module.ts +5 -5
  74. package/template/src/modules/invitations/presentation/invitations.controller.ts +61 -63
  75. package/template/src/modules/memberships/application/services/memberships.service.ts +70 -84
  76. package/template/src/modules/memberships/dto/transfer-owner.dto.ts +4 -4
  77. package/template/src/modules/memberships/dto/update-billing-contact.dto.ts +2 -2
  78. package/template/src/modules/memberships/dto/update-membership-owner.dto.ts +2 -2
  79. package/template/src/modules/memberships/dto/update-membership-role.dto.ts +4 -4
  80. package/template/src/modules/memberships/dto/update-membership-status.dto.ts +3 -3
  81. package/template/src/modules/memberships/memberships.module.ts +4 -4
  82. package/template/src/modules/memberships/presentation/memberships.controller.ts +83 -99
  83. package/template/src/modules/organisations/application/services/organisations.service.ts +21 -23
  84. package/template/src/modules/organisations/dto/create-organisation.dto.ts +6 -13
  85. package/template/src/modules/organisations/dto/organisation-response.dto.ts +14 -14
  86. package/template/src/modules/organisations/infrastructure/repositories/organisations.repository.ts +4 -7
  87. package/template/src/modules/organisations/organisations.module.ts +5 -5
  88. package/template/src/modules/organisations/presentation/organisations.controller.ts +14 -23
  89. package/template/src/modules/organisations/types/default-organisation-data.ts +3 -9
  90. package/template/src/modules/request-context/application/services/request-context.service.ts +15 -7
  91. package/template/src/modules/request-context/presentation/org-scope.guard.ts +4 -9
  92. package/template/src/modules/request-context/presentation/request-context.interceptor.ts +4 -9
  93. package/template/src/modules/request-context/presentation/request-context.middleware.ts +7 -8
  94. package/template/src/modules/request-context/request-context.module.ts +7 -7
  95. package/template/src/modules/request-context/types/request-context.ts +2 -2
  96. package/template/src/modules/sample/application/services/sample.service.ts +10 -8
  97. package/template/src/modules/sample/dto/sample-echo.dto.ts +3 -3
  98. package/template/src/modules/sample/dto/sample-response.dto.ts +12 -12
  99. package/template/src/modules/sample/presentation/sample.controller.ts +25 -42
  100. package/template/src/modules/sample/sample.module.ts +4 -4
  101. package/template/src/modules/settings/application/services/settings.service.ts +15 -27
  102. package/template/src/modules/settings/dto/setting-response.dto.ts +9 -9
  103. package/template/src/modules/settings/dto/update-setting.dto.ts +5 -5
  104. package/template/src/modules/settings/presentation/settings.controller.ts +29 -35
  105. package/template/src/modules/settings/settings.module.ts +5 -5
  106. package/template/src/modules/settings/types/setting-definitions.ts +49 -33
  107. package/template/test/auth-refresh.spec.ts +90 -0
  108. package/template/test/role-permission-policy.spec.ts +94 -0
@@ -1,6 +1,6 @@
1
- import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
2
- import { InvitationTargetType } from "@prisma/client";
3
- import { Type } from "class-transformer";
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+ import { InvitationTargetType } from '@prisma/client';
3
+ import { Type } from 'class-transformer';
4
4
  import {
5
5
  isEmail,
6
6
  IsEnum,
@@ -16,7 +16,7 @@ import {
16
16
  ValidationArguments,
17
17
  ValidatorConstraint,
18
18
  ValidatorConstraintInterface,
19
- } from "class-validator";
19
+ } from 'class-validator';
20
20
 
21
21
  const mobileTargetPattern = /^\+?[1-9]\d{6,14}$/;
22
22
 
@@ -24,10 +24,10 @@ type InvitationTargetValueObject = {
24
24
  targetType?: InvitationTargetType;
25
25
  };
26
26
 
27
- @ValidatorConstraint({ name: "InvitationTargetValue", async: false })
27
+ @ValidatorConstraint({ name: 'InvitationTargetValue', async: false })
28
28
  class InvitationTargetValueConstraint implements ValidatorConstraintInterface {
29
29
  validate(value: unknown, args: ValidationArguments) {
30
- if (typeof value !== "string") {
30
+ if (typeof value !== 'string') {
31
31
  return false;
32
32
  }
33
33
 
@@ -46,14 +46,14 @@ class InvitationTargetValueConstraint implements ValidatorConstraintInterface {
46
46
  defaultMessage(args: ValidationArguments) {
47
47
  const targetType = (args.object as InvitationTargetValueObject).targetType;
48
48
  if (targetType === InvitationTargetType.EMAIL) {
49
- return "targetValue must be a valid email address when targetType is EMAIL";
49
+ return 'targetValue must be a valid email address when targetType is EMAIL';
50
50
  }
51
51
 
52
52
  if (targetType === InvitationTargetType.MOBILE) {
53
- return "targetValue must be an E.164-style mobile number when targetType is MOBILE";
53
+ return 'targetValue must be an E.164-style mobile number when targetType is MOBILE';
54
54
  }
55
55
 
56
- return "targetValue must match targetType";
56
+ return 'targetValue must match targetType';
57
57
  }
58
58
  }
59
59
 
@@ -66,9 +66,8 @@ export class CreateInvitationDto {
66
66
  targetType!: InvitationTargetType;
67
67
 
68
68
  @ApiProperty({
69
- description:
70
- "Email address or E.164-style mobile number matching targetType.",
71
- example: "new.member@example.com",
69
+ description: 'Email address or E.164-style mobile number matching targetType.',
70
+ example: 'new.member@example.com',
72
71
  minLength: 3,
73
72
  maxLength: 320,
74
73
  })
@@ -79,14 +78,14 @@ export class CreateInvitationDto {
79
78
  targetValue!: string;
80
79
 
81
80
  @ApiProperty({
82
- example: "f602c057-04f4-4ef8-8c84-1b7c62fbf8c5",
83
- format: "uuid",
81
+ example: 'f602c057-04f4-4ef8-8c84-1b7c62fbf8c5',
82
+ format: 'uuid',
84
83
  })
85
84
  @IsUUID()
86
85
  roleId!: string;
87
86
 
88
87
  @ApiPropertyOptional({
89
- description: "Invitation lifetime in days.",
88
+ description: 'Invitation lifetime in days.',
90
89
  example: 7,
91
90
  minimum: 1,
92
91
  maximum: 30,
@@ -1,22 +1,19 @@
1
- import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
2
- import { InvitationStatus, InvitationTargetType } from "@prisma/client";
3
- import { MembershipResponseDto } from "../../../common/dto/membership-response.dto";
4
- import { RoleSummaryDto } from "../../../common/dto/role-summary.dto";
5
- import {
6
- ActiveUserSummaryDto,
7
- UserSummaryDto,
8
- } from "../../../common/dto/user-summary.dto";
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+ import { InvitationStatus, InvitationTargetType } from '@prisma/client';
3
+ import { MembershipResponseDto } from '../../../common/dto/membership-response.dto';
4
+ import { RoleSummaryDto } from '../../../common/dto/role-summary.dto';
5
+ import { ActiveUserSummaryDto, UserSummaryDto } from '../../../common/dto/user-summary.dto';
9
6
 
10
7
  export class InvitationResponseDto {
11
8
  @ApiProperty({
12
- example: "17a21ad7-bd1b-42d8-b809-0a3892bb60c3",
13
- format: "uuid",
9
+ example: '17a21ad7-bd1b-42d8-b809-0a3892bb60c3',
10
+ format: 'uuid',
14
11
  })
15
12
  id!: string;
16
13
 
17
14
  @ApiProperty({
18
- example: "2c67399d-670c-4025-a5fd-1ea9a211891e",
19
- format: "uuid",
15
+ example: '2c67399d-670c-4025-a5fd-1ea9a211891e',
16
+ format: 'uuid',
20
17
  })
21
18
  orgId!: string;
22
19
 
@@ -26,33 +23,33 @@ export class InvitationResponseDto {
26
23
  })
27
24
  targetType!: InvitationTargetType;
28
25
 
29
- @ApiProperty({ example: "new.member@example.com" })
26
+ @ApiProperty({ example: 'new.member@example.com' })
30
27
  targetValue!: string;
31
28
 
32
- @ApiProperty({ example: "new.member@example.com" })
29
+ @ApiProperty({ example: 'new.member@example.com' })
33
30
  normalizedTargetValue!: string;
34
31
 
35
32
  @ApiProperty({
36
- example: "f602c057-04f4-4ef8-8c84-1b7c62fbf8c5",
37
- format: "uuid",
33
+ example: 'f602c057-04f4-4ef8-8c84-1b7c62fbf8c5',
34
+ format: 'uuid',
38
35
  })
39
36
  roleId!: string;
40
37
 
41
38
  @ApiProperty({ enum: InvitationStatus, example: InvitationStatus.PENDING })
42
39
  status!: InvitationStatus;
43
40
 
44
- @ApiProperty({ example: "2026-06-08T10:30:00.000Z", format: "date-time" })
41
+ @ApiProperty({ example: '2026-06-08T10:30:00.000Z', format: 'date-time' })
45
42
  expiresAt!: string;
46
43
 
47
44
  @ApiProperty({
48
- example: "4a4f0d8a-4bd2-469f-a6a9-3e1cb6a2b456",
49
- format: "uuid",
45
+ example: '4a4f0d8a-4bd2-469f-a6a9-3e1cb6a2b456',
46
+ format: 'uuid',
50
47
  })
51
48
  invitedByUserId!: string;
52
49
 
53
50
  @ApiPropertyOptional({
54
- example: "7efd9a26-fbec-4511-ae37-7fb1c35e5215",
55
- format: "uuid",
51
+ example: '7efd9a26-fbec-4511-ae37-7fb1c35e5215',
52
+ format: 'uuid',
56
53
  nullable: true,
57
54
  })
58
55
  acceptedByUserId?: string | null;
@@ -66,19 +63,19 @@ export class InvitationResponseDto {
66
63
  @ApiPropertyOptional({ type: UserSummaryDto, nullable: true })
67
64
  acceptedByUser?: UserSummaryDto | null;
68
65
 
69
- @ApiProperty({ example: "2026-06-01T10:30:00.000Z", format: "date-time" })
66
+ @ApiProperty({ example: '2026-06-01T10:30:00.000Z', format: 'date-time' })
70
67
  createdAt!: string;
71
68
 
72
69
  @ApiPropertyOptional({
73
- example: "2026-06-01T10:35:00.000Z",
74
- format: "date-time",
70
+ example: '2026-06-01T10:35:00.000Z',
71
+ format: 'date-time',
75
72
  nullable: true,
76
73
  })
77
74
  acceptedAt?: string | null;
78
75
 
79
76
  @ApiPropertyOptional({
80
- example: "2026-06-01T10:40:00.000Z",
81
- format: "date-time",
77
+ example: '2026-06-01T10:40:00.000Z',
78
+ format: 'date-time',
82
79
  nullable: true,
83
80
  })
84
81
  revokedAt?: string | null;
@@ -89,13 +86,24 @@ export class InvitationWithTokenResponseDto {
89
86
  invitation!: InvitationResponseDto;
90
87
 
91
88
  @ApiProperty({
92
- description:
93
- "One-time invitation token. This is returned only at create/resend time.",
94
- example: "k0Y7QJr7pC1r7GJrFXdN2vzmw1lYkT5YhJdORQb4Pp4",
89
+ description: 'One-time invitation token. This is returned only at create/resend time.',
90
+ example: 'k0Y7QJr7pC1r7GJrFXdN2vzmw1lYkT5YhJdORQb4Pp4',
95
91
  })
96
92
  inviteToken!: string;
97
93
  }
98
94
 
95
+ export class InvitationListResponseDto {
96
+ @ApiProperty({ type: [InvitationResponseDto] })
97
+ items!: InvitationResponseDto[];
98
+
99
+ @ApiPropertyOptional({
100
+ example: '17a21ad7-bd1b-42d8-b809-0a3892bb60c3',
101
+ format: 'uuid',
102
+ nullable: true,
103
+ })
104
+ nextCursor!: string | null;
105
+ }
106
+
99
107
  export class AcceptInvitationResponseDto {
100
108
  @ApiProperty({ type: InvitationResponseDto })
101
109
  invitation!: InvitationResponseDto;
@@ -1,10 +1,10 @@
1
- import { ApiProperty } from "@nestjs/swagger";
2
- import { IsString, MaxLength, MinLength } from "class-validator";
1
+ import { ApiProperty } from '@nestjs/swagger';
2
+ import { IsString, MaxLength, MinLength } from 'class-validator';
3
3
 
4
4
  export class InvitationTokenDto {
5
5
  @ApiProperty({
6
- description: "One-time invitation token from create/resend invitation.",
7
- example: "k0Y7QJr7pC1r7GJrFXdN2vzmw1lYkT5YhJdORQb4Pp4",
6
+ description: 'One-time invitation token from create/resend invitation.',
7
+ example: 'k0Y7QJr7pC1r7GJrFXdN2vzmw1lYkT5YhJdORQb4Pp4',
8
8
  minLength: 20,
9
9
  maxLength: 256,
10
10
  })
@@ -1,8 +1,8 @@
1
- import { Module } from "@nestjs/common";
2
- import { AuthModule } from "../auth/auth.module";
3
- import { MembershipsModule } from "../memberships/memberships.module";
4
- import { InvitationsService } from "./application/services/invitations.service";
5
- import { InvitationsController } from "./presentation/invitations.controller";
1
+ import { Module } from '@nestjs/common';
2
+ import { AuthModule } from '../auth/auth.module';
3
+ import { MembershipsModule } from '../memberships/memberships.module';
4
+ import { InvitationsService } from './application/services/invitations.service';
5
+ import { InvitationsController } from './presentation/invitations.controller';
6
6
 
7
7
  @Module({
8
8
  imports: [AuthModule, MembershipsModule],
@@ -1,12 +1,4 @@
1
- import {
2
- Body,
3
- Controller,
4
- Get,
5
- HttpCode,
6
- Param,
7
- Post,
8
- UseGuards,
9
- } from "@nestjs/common";
1
+ import { Body, Controller, Get, HttpCode, Param, Post, Query, UseGuards } from '@nestjs/common';
10
2
  import {
11
3
  ApiBearerAuth,
12
4
  ApiCreatedResponse,
@@ -14,120 +6,126 @@ import {
14
6
  ApiOperation,
15
7
  ApiParam,
16
8
  ApiTags,
17
- } from "@nestjs/swagger";
18
- import { ApiErrorResponses } from "../../../common/swagger/api-error-responses";
19
- import { PermissionGuard } from "../../access-control/application/services/permission.guard";
20
- import { RequirePermissions } from "../../access-control/presentation/permissions.decorator";
21
- import { JwtAuthGuard } from "../../auth/infrastructure/passport/jwt-auth.guard";
22
- import { CurrentUser } from "../../auth/presentation/current-user.decorator";
23
- import { AuthenticatedUser } from "../../auth/types/authenticated-user";
24
- import { OrgScopeGuard } from "../../request-context/presentation/org-scope.guard";
25
- import { InvitationsService } from "../application/services/invitations.service";
26
- import { AcceptInvitationDto } from "../dto/accept-invitation.dto";
27
- import { CreateInvitationDto } from "../dto/create-invitation.dto";
28
- import { InvitationTokenDto } from "../dto/invitation-token.dto";
9
+ } from '@nestjs/swagger';
10
+ import { ApiErrorResponses } from '../../../common/swagger/api-error-responses';
11
+ import { PaginationQueryDto } from '../../../common/dto/pagination-query.dto';
12
+ import { PermissionGuard } from '../../access-control/application/services/permission.guard';
13
+ import { RequirePermissions } from '../../access-control/presentation/permissions.decorator';
14
+ import { JwtAuthGuard } from '../../auth/infrastructure/passport/jwt-auth.guard';
15
+ import { CurrentUser } from '../../auth/presentation/current-user.decorator';
16
+ import { AuthenticatedUser } from '../../auth/types/authenticated-user';
17
+ import { OrgScopeGuard } from '../../request-context/presentation/org-scope.guard';
18
+ import { InvitationsService } from '../application/services/invitations.service';
19
+ import { AcceptInvitationDto } from '../dto/accept-invitation.dto';
20
+ import { CreateInvitationDto } from '../dto/create-invitation.dto';
21
+ import { InvitationTokenDto } from '../dto/invitation-token.dto';
29
22
  import {
30
23
  AcceptInvitationResponseDto,
24
+ InvitationListResponseDto,
31
25
  InvitationResponseDto,
32
26
  InvitationWithTokenResponseDto,
33
- } from "../dto/invitation-response.dto";
27
+ } from '../dto/invitation-response.dto';
34
28
 
35
- @ApiTags("Invitations")
29
+ @ApiTags('Invitations')
36
30
  @Controller()
37
31
  export class InvitationsController {
38
32
  constructor(private readonly invitationsService: InvitationsService) {}
39
33
 
40
- @Post("organisations/:orgId/invitations")
34
+ @Post('organisations/:orgId/invitations')
41
35
  @UseGuards(JwtAuthGuard, OrgScopeGuard, PermissionGuard)
42
- @RequirePermissions("memberships.invite")
36
+ @RequirePermissions('memberships.invite')
43
37
  @ApiBearerAuth()
44
- @ApiParam({ name: "orgId", description: "Organisation ID.", format: "uuid" })
38
+ @ApiParam({ name: 'orgId', description: 'Organisation ID.', format: 'uuid' })
45
39
  @ApiOperation({
46
- summary: "Create an invitation for an email or mobile target.",
40
+ summary: 'Create an invitation for an email or mobile target.',
47
41
  })
48
42
  @ApiCreatedResponse({
49
- description: "Invitation created. The inviteToken is shown once.",
43
+ description: 'Invitation created. The inviteToken is shown once.',
50
44
  type: InvitationWithTokenResponseDto,
51
45
  })
52
46
  @ApiErrorResponses(400, 401, 403, 404, 409)
53
47
  create(
54
48
  @CurrentUser() user: AuthenticatedUser,
55
- @Param("orgId") orgId: string,
49
+ @Param('orgId') orgId: string,
56
50
  @Body() dto: CreateInvitationDto,
57
51
  ) {
58
52
  return this.invitationsService.createInvitation(user, orgId, dto);
59
53
  }
60
54
 
61
- @Get("organisations/:orgId/invitations")
55
+ @Get('organisations/:orgId/invitations')
62
56
  @UseGuards(JwtAuthGuard, OrgScopeGuard, PermissionGuard)
63
- @RequirePermissions("memberships.read")
57
+ @RequirePermissions('memberships.read')
64
58
  @ApiBearerAuth()
65
- @ApiParam({ name: "orgId", description: "Organisation ID.", format: "uuid" })
66
- @ApiOperation({ summary: "List invitations for an organisation." })
59
+ @ApiParam({ name: 'orgId', description: 'Organisation ID.', format: 'uuid' })
60
+ @ApiOperation({ summary: 'List invitations for an organisation.' })
67
61
  @ApiOkResponse({
68
- description: "Organisation invitations.",
69
- type: [InvitationResponseDto],
62
+ description: 'Organisation invitations.',
63
+ type: InvitationListResponseDto,
70
64
  })
71
65
  @ApiErrorResponses(400, 401, 403)
72
- list(@CurrentUser() user: AuthenticatedUser, @Param("orgId") orgId: string) {
73
- return this.invitationsService.listInvitations(user, orgId);
66
+ list(
67
+ @CurrentUser() user: AuthenticatedUser,
68
+ @Param('orgId') orgId: string,
69
+ @Query() query: PaginationQueryDto,
70
+ ) {
71
+ return this.invitationsService.listInvitations(user, orgId, query);
74
72
  }
75
73
 
76
- @Post("organisations/:orgId/invitations/:invitationId/revoke")
74
+ @Post('organisations/:orgId/invitations/:invitationId/revoke')
77
75
  @HttpCode(200)
78
76
  @UseGuards(JwtAuthGuard, OrgScopeGuard, PermissionGuard)
79
- @RequirePermissions("memberships.revoke")
77
+ @RequirePermissions('memberships.revoke')
80
78
  @ApiBearerAuth()
81
- @ApiParam({ name: "orgId", description: "Organisation ID.", format: "uuid" })
79
+ @ApiParam({ name: 'orgId', description: 'Organisation ID.', format: 'uuid' })
82
80
  @ApiParam({
83
- name: "invitationId",
84
- description: "Invitation ID.",
85
- format: "uuid",
81
+ name: 'invitationId',
82
+ description: 'Invitation ID.',
83
+ format: 'uuid',
86
84
  })
87
- @ApiOperation({ summary: "Revoke a pending invitation." })
85
+ @ApiOperation({ summary: 'Revoke a pending invitation.' })
88
86
  @ApiOkResponse({
89
- description: "Revoked invitation.",
87
+ description: 'Revoked invitation.',
90
88
  type: InvitationResponseDto,
91
89
  })
92
90
  @ApiErrorResponses(400, 401, 403, 404, 409, 410)
93
91
  revoke(
94
92
  @CurrentUser() user: AuthenticatedUser,
95
- @Param("orgId") orgId: string,
96
- @Param("invitationId") invitationId: string,
93
+ @Param('orgId') orgId: string,
94
+ @Param('invitationId') invitationId: string,
97
95
  ) {
98
96
  return this.invitationsService.revokeInvitation(user, orgId, invitationId);
99
97
  }
100
98
 
101
- @Post("organisations/:orgId/invitations/:invitationId/resend")
99
+ @Post('organisations/:orgId/invitations/:invitationId/resend')
102
100
  @HttpCode(200)
103
101
  @UseGuards(JwtAuthGuard, OrgScopeGuard, PermissionGuard)
104
- @RequirePermissions("memberships.invite")
102
+ @RequirePermissions('memberships.invite')
105
103
  @ApiBearerAuth()
106
- @ApiParam({ name: "orgId", description: "Organisation ID.", format: "uuid" })
104
+ @ApiParam({ name: 'orgId', description: 'Organisation ID.', format: 'uuid' })
107
105
  @ApiParam({
108
- name: "invitationId",
109
- description: "Invitation ID.",
110
- format: "uuid",
106
+ name: 'invitationId',
107
+ description: 'Invitation ID.',
108
+ format: 'uuid',
111
109
  })
112
- @ApiOperation({ summary: "Resend a pending or expired invitation." })
110
+ @ApiOperation({ summary: 'Resend a pending or expired invitation.' })
113
111
  @ApiOkResponse({
114
- description: "Invitation resent. The new inviteToken is shown once.",
112
+ description: 'Invitation resent. The new inviteToken is shown once.',
115
113
  type: InvitationWithTokenResponseDto,
116
114
  })
117
115
  @ApiErrorResponses(400, 401, 403, 404, 409)
118
116
  resend(
119
117
  @CurrentUser() user: AuthenticatedUser,
120
- @Param("orgId") orgId: string,
121
- @Param("invitationId") invitationId: string,
118
+ @Param('orgId') orgId: string,
119
+ @Param('invitationId') invitationId: string,
122
120
  ) {
123
121
  return this.invitationsService.resendInvitation(user, orgId, invitationId);
124
122
  }
125
123
 
126
- @Post("invitations/accept")
124
+ @Post('invitations/accept')
127
125
  @HttpCode(200)
128
- @ApiOperation({ summary: "Accept an invitation token." })
126
+ @ApiOperation({ summary: 'Accept an invitation token.' })
129
127
  @ApiOkResponse({
130
- description: "Invitation accepted and membership created.",
128
+ description: 'Invitation accepted and membership created.',
131
129
  type: AcceptInvitationResponseDto,
132
130
  })
133
131
  @ApiErrorResponses(400, 401, 409, 410)
@@ -135,11 +133,11 @@ export class InvitationsController {
135
133
  return this.invitationsService.acceptInvitation(dto);
136
134
  }
137
135
 
138
- @Post("invitations/decline")
136
+ @Post('invitations/decline')
139
137
  @HttpCode(200)
140
- @ApiOperation({ summary: "Decline an invitation token." })
138
+ @ApiOperation({ summary: 'Decline an invitation token.' })
141
139
  @ApiOkResponse({
142
- description: "Declined invitation.",
140
+ description: 'Declined invitation.',
143
141
  type: InvitationResponseDto,
144
142
  })
145
143
  @ApiErrorResponses(400, 401, 409, 410)