-
Notifications
You must be signed in to change notification settings - Fork 318
Mariano/cs 437 #2992
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Marfuen
wants to merge
42
commits into
main
Choose a base branch
from
mariano/cs-437
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Mariano/cs 437 #2992
Changes from all commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
ec63f20
docs(isms): add CS-437 foundational documents design spec
Marfuen a549077
feat(isms): add IsmsDocument data model + Context register (CS-437)
Marfuen da24c23
feat(isms): add ISMS documents API module with PDF/DOCX export (CS-437)
Marfuen 53a3714
feat(isms): framework-grouped Documents IA + Context of the Organizat…
Marfuen c866962
refactor(isms): gate on evidence resource, drop feature flag (CS-437)
Marfuen 4246785
feat(isms): add register tables for Interested Parties, Requirements,…
Marfuen e19969b
feat(isms): add api for all six foundational documents via type dispa…
Marfuen b69bdbc
feat(isms): detail pages for the 5 remaining foundational documents (…
Marfuen cb4ea5b
feat(isms): add IsmsProfile for wizard inputs (CS-438)
Marfuen 569d886
feat(isms): document-creation wizard (CS-438)
Marfuen fcb6eb1
feat(isms): wire "Run setup wizard" entry point into ISMS overview (C…
Marfuen 0b7d7fa
feat(isms): model ISMS document types as framework-editor parts (CS-437)
Marfuen 1427559
feat(isms): map ISMS document types as framework-editor parts (CS-437…
Marfuen b30b7be
feat(isms): add document<->control link junctions (CS-437, Paul)
Marfuen 60c1e88
feat(isms): link documents to individual controls (CS-437, Paul)
Marfuen 6d653c7
feat(isms): polish the ISMS area to be design-system-only and auditor…
Marfuen feb5e05
fix(isms): resolve 11 QA findings from the live walkthrough (CS-437)
Marfuen 3a2e36e
feat(isms): restyle register UIs as read-first cards to match the ove…
Marfuen e305d1d
feat(isms): make the issues registers denser (CS-437)
Marfuen 8d8d4eb
feat(isms): refine register source provenance display (CS-437)
Marfuen 25a98e4
feat(isms): source as a tag pill under the description (CS-437)
Marfuen 9f7dd25
feat(isms): drop redundant "framework" suffix on source pills (CS-437)
Marfuen e8ce2ac
feat(isms): move approval banner to the top of each document (CS-437)
Marfuen f78727a
feat(isms): drop redundant source pill from interested-parties cards …
Marfuen 8074dcd
feat(isms): render context-of-organization as an auditor-ready docume…
Marfuen 175d3c8
feat(documents): gate ISMS tab behind a flag, move SOA to general doc…
Marfuen 613bb14
Merge remote-tracking branch 'origin/main' into mariano/cs-437
Marfuen 34d153f
refactor(isms): consolidate register CRUD into 3 generic endpoints (C…
Marfuen d4404e8
fix(isms): address cubic review findings on PR #2992 (CS-437)
Marfuen 0d720c3
fix(isms): derive ensure-setup org from session; skip blank objective…
Marfuen d9481f8
fix(isms): resolve cubic re-review follow-ups (CS-437)
Marfuen fcfb519
fix(isms): seed narrative when empty on regenerate (CS-437)
Marfuen a9c6db1
refactor(isms): backend red-team remediation — phase 1 (CS-437)
Marfuen 67e0ce5
refactor(isms): frontend red-team remediation — phase 2 (CS-437)
Marfuen 65fb75c
test(isms): add coverage flagged by the red-team review — phase 3 (CS…
Marfuen 1229976
Merge branch 'main' into mariano/cs-437
Marfuen 338f760
fix(isms): resolve post-merge cubic findings (CS-437)
Marfuen f135113
Merge branch 'main' into mariano/cs-437
Marfuen ef221cd
Merge remote-tracking branch 'origin/main' into mariano/cs-437
Marfuen c5a52fc
fix(isms): resolve cubic findings — concurrency, constraint, schemas …
Marfuen 1862c88
Merge branch 'main' into mariano/cs-437
Marfuen e92d083
fix(isms): serialize register position allocation; gate control-link …
Marfuen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
.../api/src/framework-editor/isms-document-template/dto/update-isms-document-template.dto.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { ApiPropertyOptional } from '@nestjs/swagger'; | ||
| import { IsInt, IsOptional, IsString, MaxLength, Min } from 'class-validator'; | ||
|
|
||
| export class UpdateIsmsDocumentTemplateDto { | ||
| @ApiPropertyOptional({ example: 'Context of the Organization' }) | ||
| @IsString() | ||
| @IsOptional() | ||
| @MaxLength(255) | ||
| name?: string; | ||
|
|
||
| @ApiPropertyOptional({ | ||
| example: 'Internal and external issues relevant to the ISMS.', | ||
| }) | ||
| @IsString() | ||
| @IsOptional() | ||
| @MaxLength(5000) | ||
| description?: string; | ||
|
|
||
| @ApiPropertyOptional({ example: '4.1' }) | ||
| @IsString() | ||
| @IsOptional() | ||
| @MaxLength(32) | ||
| clause?: string; | ||
|
|
||
| @ApiPropertyOptional({ example: 0 }) | ||
| @IsInt() | ||
| @IsOptional() | ||
| @Min(0) | ||
| sortOrder?: number; | ||
| } |
102 changes: 102 additions & 0 deletions
102
...api/src/framework-editor/isms-document-template/isms-document-template.controller.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| jest.mock('@db', () => ({ db: {} })); | ||
|
|
||
| import { Test, TestingModule } from '@nestjs/testing'; | ||
| import { PlatformAdminGuard } from '../../auth/platform-admin.guard'; | ||
| import { IsmsDocumentTemplateController } from './isms-document-template.controller'; | ||
| import { IsmsDocumentTemplateService } from './isms-document-template.service'; | ||
|
|
||
| jest.mock('../../auth/platform-admin.guard', () => ({ | ||
| PlatformAdminGuard: class MockPlatformAdminGuard {}, | ||
| })); | ||
|
|
||
| describe('IsmsDocumentTemplateController', () => { | ||
| let controller: IsmsDocumentTemplateController; | ||
|
|
||
| const mockService = { | ||
| findAll: jest.fn(), | ||
| update: jest.fn(), | ||
| linkRequirement: jest.fn(), | ||
| unlinkRequirement: jest.fn(), | ||
| linkControlTemplate: jest.fn(), | ||
| unlinkControlTemplate: jest.fn(), | ||
| }; | ||
|
|
||
| beforeEach(async () => { | ||
| const module: TestingModule = await Test.createTestingModule({ | ||
| controllers: [IsmsDocumentTemplateController], | ||
| providers: [ | ||
| { provide: IsmsDocumentTemplateService, useValue: mockService }, | ||
| ], | ||
| }) | ||
| .overrideGuard(PlatformAdminGuard) | ||
| .useValue({ canActivate: () => true }) | ||
| .compile(); | ||
|
|
||
| controller = module.get(IsmsDocumentTemplateController); | ||
| jest.clearAllMocks(); | ||
| }); | ||
|
|
||
| it('passes the frameworkId filter to findAll', async () => { | ||
| mockService.findAll.mockResolvedValue([]); | ||
|
|
||
| await controller.findAll('fw_1'); | ||
|
|
||
| expect(mockService.findAll).toHaveBeenCalledWith('fw_1'); | ||
| }); | ||
|
|
||
| it('passes id and dto to update', async () => { | ||
| mockService.update.mockResolvedValue({ id: 'tpl_ctx' }); | ||
|
|
||
| await controller.update('tpl_ctx', { name: 'New' }); | ||
|
|
||
| expect(mockService.update).toHaveBeenCalledWith('tpl_ctx', { name: 'New' }); | ||
| }); | ||
|
|
||
| it('maps params + query to linkRequirement', async () => { | ||
| mockService.linkRequirement.mockResolvedValue({ message: 'linked' }); | ||
|
|
||
| await controller.linkRequirement('tpl_ctx', 'req_41', 'fw_1'); | ||
|
|
||
| expect(mockService.linkRequirement).toHaveBeenCalledWith({ | ||
| templateId: 'tpl_ctx', | ||
| requirementId: 'req_41', | ||
| frameworkId: 'fw_1', | ||
| }); | ||
| }); | ||
|
|
||
| it('maps params + query to unlinkRequirement', async () => { | ||
| mockService.unlinkRequirement.mockResolvedValue({ message: 'unlinked' }); | ||
|
|
||
| await controller.unlinkRequirement('tpl_ctx', 'req_41', 'fw_1'); | ||
|
|
||
| expect(mockService.unlinkRequirement).toHaveBeenCalledWith({ | ||
| templateId: 'tpl_ctx', | ||
| requirementId: 'req_41', | ||
| frameworkId: 'fw_1', | ||
| }); | ||
| }); | ||
|
|
||
| it('maps params + query to linkControlTemplate', async () => { | ||
| mockService.linkControlTemplate.mockResolvedValue({ message: 'linked' }); | ||
|
|
||
| await controller.linkControlTemplate('tpl_ctx', 'ct_1', 'fw_1'); | ||
|
|
||
| expect(mockService.linkControlTemplate).toHaveBeenCalledWith({ | ||
| templateId: 'tpl_ctx', | ||
| controlTemplateId: 'ct_1', | ||
| frameworkId: 'fw_1', | ||
| }); | ||
| }); | ||
|
|
||
| it('maps params + query to unlinkControlTemplate', async () => { | ||
| mockService.unlinkControlTemplate.mockResolvedValue({ message: 'unlinked' }); | ||
|
|
||
| await controller.unlinkControlTemplate('tpl_ctx', 'ct_1', 'fw_1'); | ||
|
|
||
| expect(mockService.unlinkControlTemplate).toHaveBeenCalledWith({ | ||
| templateId: 'tpl_ctx', | ||
| controlTemplateId: 'ct_1', | ||
| frameworkId: 'fw_1', | ||
| }); | ||
| }); | ||
| }); |
107 changes: 107 additions & 0 deletions
107
apps/api/src/framework-editor/isms-document-template/isms-document-template.controller.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| import { | ||
| Body, | ||
| Controller, | ||
| Delete, | ||
| Get, | ||
| Param, | ||
| Patch, | ||
| Post, | ||
| Query, | ||
| UseGuards, | ||
| UsePipes, | ||
| ValidationPipe, | ||
| } from '@nestjs/common'; | ||
| import { ApiOperation, ApiTags } from '@nestjs/swagger'; | ||
| import { PlatformAdminGuard } from '../../auth/platform-admin.guard'; | ||
| import { UpdateIsmsDocumentTemplateDto } from './dto/update-isms-document-template.dto'; | ||
| import { IsmsDocumentTemplateService } from './isms-document-template.service'; | ||
|
|
||
| @ApiTags('Framework Editor ISMS Document Templates') | ||
| @Controller({ path: 'framework-editor/isms-document-template', version: '1' }) | ||
| @UseGuards(PlatformAdminGuard) | ||
|
Marfuen marked this conversation as resolved.
|
||
| export class IsmsDocumentTemplateController { | ||
| constructor(private readonly service: IsmsDocumentTemplateService) {} | ||
|
|
||
| @Get() | ||
| @ApiOperation({ summary: 'List ISMS document templates' }) | ||
| async findAll(@Query('frameworkId') frameworkId?: string) { | ||
| return this.service.findAll(frameworkId); | ||
| } | ||
|
|
||
| @Patch(':id') | ||
| @ApiOperation({ summary: 'Update an ISMS document template' }) | ||
| @UsePipes(new ValidationPipe({ whitelist: true, transform: true })) | ||
| async update( | ||
| @Param('id') id: string, | ||
| @Body() dto: UpdateIsmsDocumentTemplateDto, | ||
| ) { | ||
| return this.service.update(id, dto); | ||
| } | ||
|
|
||
| @Post(':id/requirements/:requirementId') | ||
| @ApiOperation({ | ||
| summary: 'Link a requirement to an ISMS document template for a framework', | ||
| }) | ||
| async linkRequirement( | ||
| @Param('id') id: string, | ||
| @Param('requirementId') requirementId: string, | ||
| @Query('frameworkId') frameworkId?: string, | ||
| ) { | ||
| return this.service.linkRequirement({ | ||
| templateId: id, | ||
| requirementId, | ||
| frameworkId, | ||
| }); | ||
| } | ||
|
|
||
| @Delete(':id/requirements/:requirementId') | ||
| @ApiOperation({ | ||
| summary: | ||
| 'Unlink a requirement from an ISMS document template for a framework', | ||
| }) | ||
| async unlinkRequirement( | ||
| @Param('id') id: string, | ||
| @Param('requirementId') requirementId: string, | ||
| @Query('frameworkId') frameworkId?: string, | ||
| ) { | ||
| return this.service.unlinkRequirement({ | ||
| templateId: id, | ||
| requirementId, | ||
| frameworkId, | ||
| }); | ||
| } | ||
|
|
||
| @Post(':id/controls/:controlTemplateId') | ||
| @ApiOperation({ | ||
| summary: | ||
| 'Link a control template to an ISMS document template for a framework', | ||
| }) | ||
| async linkControlTemplate( | ||
| @Param('id') id: string, | ||
| @Param('controlTemplateId') controlTemplateId: string, | ||
| @Query('frameworkId') frameworkId?: string, | ||
| ) { | ||
| return this.service.linkControlTemplate({ | ||
| templateId: id, | ||
| controlTemplateId, | ||
| frameworkId, | ||
| }); | ||
| } | ||
|
|
||
| @Delete(':id/controls/:controlTemplateId') | ||
| @ApiOperation({ | ||
| summary: | ||
| 'Unlink a control template from an ISMS document template for a framework', | ||
| }) | ||
| async unlinkControlTemplate( | ||
| @Param('id') id: string, | ||
| @Param('controlTemplateId') controlTemplateId: string, | ||
| @Query('frameworkId') frameworkId?: string, | ||
| ) { | ||
| return this.service.unlinkControlTemplate({ | ||
| templateId: id, | ||
| controlTemplateId, | ||
| frameworkId, | ||
| }); | ||
| } | ||
| } | ||
12 changes: 12 additions & 0 deletions
12
apps/api/src/framework-editor/isms-document-template/isms-document-template.module.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import { Module } from '@nestjs/common'; | ||
| import { AuthModule } from '../../auth/auth.module'; | ||
| import { IsmsDocumentTemplateController } from './isms-document-template.controller'; | ||
| import { IsmsDocumentTemplateService } from './isms-document-template.service'; | ||
|
|
||
| @Module({ | ||
| imports: [AuthModule], | ||
| controllers: [IsmsDocumentTemplateController], | ||
| providers: [IsmsDocumentTemplateService], | ||
| exports: [IsmsDocumentTemplateService], | ||
| }) | ||
| export class IsmsDocumentTemplateModule {} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.