diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 33d89ace..de6c5bd3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,10 +1,10 @@ # NHS Notify Code Owners # Notify default owners -* @NHSDigital/nhs-notify-repository-template +* @NHSDigital/nhs-notify-digital-letters -/.github/ @NHSDigital/nhs-notify-repository-template-admins -*.code-workspace @NHSDigital/nhs-notify-repository-template-admins +/.github/ @NHSDigital/nhs-notify-digital-letters-admins +*.code-workspace @NHSDigital/nhs-notify-digital-letters-admins /infrastructure/terraform/ @NHSDigital/nhs-notify-platform # Codeowners must be final check diff --git a/.github/workflows/stage-1-commit.yaml b/.github/workflows/stage-1-commit.yaml index ececcb36..9fcbccd0 100644 --- a/.github/workflows/stage-1-commit.yaml +++ b/.github/workflows/stage-1-commit.yaml @@ -66,30 +66,30 @@ jobs: fetch-depth: 0 # Full history is needed to compare branches - name: "Check Markdown format" uses: ./.github/actions/check-markdown-format - terraform-docs: - name: "Run terraform-docs" - runs-on: ubuntu-latest - needs: detect-terraform-changes - if: needs.detect-terraform-changes.outputs.terraform_changed == 'true' - permissions: - contents: write - steps: - - name: "Checkout code" - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Full history is needed to compare branches - - name: "Check to see if Terraform Docs are up-to-date" - run: | - make terraform-docs - - name: "Stage changes" - run: | - git add infrastructure/terraform/**/*.md - - name: "Check for changes in Terraform Docs" - run: | - if git diff --cached --name-only | grep -qE '\.md$'; then - echo "Markdown files have changed. Please run 'make terraform-docs' and commit the changes." - exit 1 - fi + # terraform-docs: + # name: "Run terraform-docs" + # runs-on: ubuntu-latest + # needs: detect-terraform-changes + # if: needs.detect-terraform-changes.outputs.terraform_changed == 'true' + # permissions: + # contents: write + # steps: + # - name: "Checkout code" + # uses: actions/checkout@v4 + # with: + # fetch-depth: 0 # Full history is needed to compare branches + # - name: "Check to see if Terraform Docs are up-to-date" + # run: | + # make terraform-docs + # - name: "Stage changes" + # run: | + # git add infrastructure/terraform/**/*.md + # - name: "Check for changes in Terraform Docs" + # run: | + # if git diff --cached --name-only | grep -qE '\.md$'; then + # echo "Markdown files have changed. Please run 'make terraform-docs' and commit the changes." + # exit 1 + # fi check-english-usage: name: "Check English usage" runs-on: ubuntu-latest diff --git a/README.md b/README.md index 2945dea3..8bc3f6f0 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,11 @@ -# NHS Notify Repository Template +# NHS Notify Digital Letters -[![CI/CD Pull Request](https://github.com/nhs-england-tools/repository-template/actions/workflows/cicd-1-pull-request.yaml/badge.svg)](https://github.com/nhs-england-tools/repository-template/actions/workflows/cicd-1-pull-request.yaml) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=repository-template&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=repository-template) - -Start with an overview or a brief description of what the project is about and what it does. For example - - -Welcome to our repository template designed to streamline your project setup! This robust template provides a reliable starting point for your new projects, covering an essential tech stack and encouraging best practices in documenting. - -This repository template aims to foster a user-friendly development environment by ensuring that every included file is concise and adequately self-documented. By adhering to this standard, we can promote increased clarity and maintainability throughout your project's lifecycle. Bundled within this template are resources that pave the way for seamless repository creation. Currently supported technologies are: - -- Terraform -- Docker - -Make use of this repository template to expedite your project setup and enhance your productivity right from the get-go. Enjoy the advantage of having a well-structured, self-documented project that reduces overhead and increases focus on what truly matters - coding! - -Any code files or example documentation that is not used in the new repository should be removed to prevent the proliferation of duplicate copies of redundant code that if not maintained could introduce vulnerabilities (e.g. via un-patched Dependabot issues). +[![CI/CD Pull Request](https://github.com/NHSDigital/nhs-notify-digital-letters/actions/workflows/cicd-1-pull-request.yaml/badge.svg)](https://github.com/NHSDigital/nhs-notify-digital-letters/actions/workflows/cicd-1-pull-request.yaml) ## Table of Contents -- [NHS Notify Repository Template](#nhs-notify-repository-template) +- [NHS Notify Digital Letters](#nhs-notify-digital-letters) - [Table of Contents](#table-of-contents) - - [Documentation](#documentation) - [Setup](#setup) - [Prerequisites](#prerequisites) - [Configuration](#configuration) @@ -28,32 +13,23 @@ Any code files or example documentation that is not used in the new repository s - [Testing](#testing) - [Design](#design) - [Diagrams](#diagrams) - - [Modularity](#modularity) - [Contributing](#contributing) - [Contacts](#contacts) - [Licence](#licence) -## Documentation - -- [Built](/) -- [Source](/docs/README.md) - ## Setup -By including preferably a one-liner or if necessary a set of clear CLI instructions we improve user experience. This should be a frictionless installation process that works on various operating systems (macOS, Linux, Windows WSL) and handles all the dependencies. - Clone the repository ```shell -git clone https://github.com/nhs-england-tools/repository-template.git -cd nhs-england-tools/repository-template +git clone https://github.com/NHSDigital/nhs-notify-digital-letters.git +cd nhs-notify-digital-letters ``` ### Prerequisites The following software packages, or their equivalents, are expected to be installed and configured: -- [Docker](https://www.docker.com/) container runtime or a compatible tool, e.g. [Podman](https://podman.io/), - [asdf](https://asdf-vm.com/) version manager, - [GNU make](https://www.gnu.org/software/make/) 3.82 or later, @@ -85,11 +61,9 @@ make config ## Usage -After a successful installation, provide an informative example of how this project can be used. Additional code snippets, screenshots and demos work well in this space. You may also link to the other documentation resources, e.g. the [User Guide](./docs/user-guide.md) to demonstrate more use cases and to show more features. - ### Testing -There are `make` tasks for you to configure to run your tests. Run `make test` to see how they work. You should be able to use the same entry points for local development as in your CI pipeline. +There are `make` tasks for you to configure to run your tests. Run `make test` to see how they work. You should be able to use the same entry points for local development as in your CI pipeline. ## Design @@ -97,42 +71,18 @@ There are `make` tasks for you to configure to run your tests. Run `make test` The [C4 model](https://c4model.com/) is a simple and intuitive way to create software architecture diagrams that are clear, consistent, scalable and most importantly collaborative. This should result in documenting all the system interfaces, external dependencies and integration points. -![Repository Template](./docs/diagrams/Repository_Template_GitHub_Generic.png) - -The source for diagrams should be in Git for change control and review purposes. Recommendations are [draw.io](https://app.diagrams.net/) (example above in [docs](.docs/diagrams/) folder) and [Mermaids](https://github.com/mermaid-js/mermaid). Here is an example Mermaids sequence diagram: - -```mermaid -sequenceDiagram - User->>+Service: GET /users?params=... - Service->>Service: auth request - Service->>Database: get all users - Database-->>Service: list of users - Service->>Service: filter users - Service-->>-User: list[User] -``` - -### Modularity +![SMS Nudge](./docs/diagrams/SMS_Nudge.drawio.png) -Most of the projects are built with customisability and extendability in mind. At a minimum, this can be achieved by implementing service level configuration options and settings. The intention of this section is to show how this can be used. If the system processes data, you could mention here for example how the input is prepared for testing - anonymised, synthetic or live data. +Main components: ## Contributing -Describe or link templates on how to raise an issue, feature request or make a contribution to the codebase. Reference the other documentation files, like - -- Environment setup for contribution, i.e. `CONTRIBUTING.md` -- Coding standards, branching, linting, practices for development and testing -- Release process, versioning, changelog -- Backlog, board, roadmap, ways of working -- High-level requirements, guiding principles, decision records, etc. +-- ## Contacts -Provide a way to contact the owners of this project. It can be a team, an individual or information on the means of getting in touch via active communication channels, e.g. opening a GitHub discussion, raising an issue, etc. +NHS Notify Team ## Licence -> The [LICENCE.md](./LICENCE.md) file will need to be updated with the correct year and owner - -Unless stated otherwise, the codebase is released under the MIT License. This covers both the codebase and any sample code in the documentation. - -Any HTML or Markdown documentation is [© Crown Copyright](https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/uk-government-licensing-framework/crown-copyright/) and available under the terms of the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). +-- diff --git a/infrastructure/terraform/components/examplecomponent/.tool-versions b/infrastructure/terraform/components/examplecomponent/.tool-versions deleted file mode 100644 index 3874604d..00000000 --- a/infrastructure/terraform/components/examplecomponent/.tool-versions +++ /dev/null @@ -1 +0,0 @@ -terraform 1.9.2 diff --git a/infrastructure/terraform/components/examplecomponent/README.md b/infrastructure/terraform/components/examplecomponent/README.md deleted file mode 100644 index f7da63ac..00000000 --- a/infrastructure/terraform/components/examplecomponent/README.md +++ /dev/null @@ -1,29 +0,0 @@ - - - - -## Requirements - -No requirements. -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | -| [component](#input\_component) | The variable encapsulating the name of this component | `string` | `"examplecomponent"` | no | -| [default\_tags](#input\_default\_tags) | A map of default tags to apply to all taggable resources within the component | `map(string)` | `{}` | no | -| [environment](#input\_environment) | The name of the tfscaffold environment | `string` | n/a | yes | -| [force\_lambda\_code\_deploy](#input\_force\_lambda\_code\_deploy) | If the lambda package in s3 has the same commit id tag as the terraform build branch, the lambda will not update automatically. Set to True if making changes to Lambda code from on the same commit for example during development | `bool` | `false` | no | -| [group](#input\_group) | The group variables are being inherited from (often synonmous with account short-name) | `string` | n/a | yes | -| [log\_retention\_in\_days](#input\_log\_retention\_in\_days) | The retention period in days for the Cloudwatch Logs events to be retained, default of 0 is indefinite | `number` | `0` | no | -| [project](#input\_project) | The name of the tfscaffold project | `string` | n/a | yes | -| [region](#input\_region) | The AWS Region | `string` | n/a | yes | -## Modules - -No modules. -## Outputs - -No outputs. - - - diff --git a/infrastructure/terraform/components/examplecomponent/locals_remote_state.tf b/infrastructure/terraform/components/examplecomponent/locals_remote_state.tf deleted file mode 100644 index 7f87c1fa..00000000 --- a/infrastructure/terraform/components/examplecomponent/locals_remote_state.tf +++ /dev/null @@ -1,40 +0,0 @@ -locals { - bootstrap = data.terraform_remote_state.bootstrap.outputs - acct = data.terraform_remote_state.acct.outputs -} - -data "terraform_remote_state" "bootstrap" { - backend = "s3" - - config = { - bucket = local.terraform_state_bucket - - key = format( - "%s/%s/%s/%s/bootstrap.tfstate", - var.project, - var.aws_account_id, - "eu-west-2", - "bootstrap" - ) - - region = "eu-west-2" - } -} - -data "terraform_remote_state" "acct" { - backend = "s3" - - config = { - bucket = local.terraform_state_bucket - - key = format( - "%s/%s/%s/%s/acct.tfstate", - var.project, - var.aws_account_id, - "eu-west-2", - var.parent_acct_environment - ) - - region = "eu-west-2" - } -} diff --git a/infrastructure/terraform/components/examplecomponent/locals_tfscaffold.tf b/infrastructure/terraform/components/examplecomponent/locals_tfscaffold.tf deleted file mode 100644 index b7cf3217..00000000 --- a/infrastructure/terraform/components/examplecomponent/locals_tfscaffold.tf +++ /dev/null @@ -1,44 +0,0 @@ -locals { - terraform_state_bucket = format( - "%s-tfscaffold-%s-%s", - var.project, - var.aws_account_id, - var.region, - ) - - csi = replace( - format( - "%s-%s-%s", - var.project, - var.environment, - var.component, - ), - "_", - "", - ) - - # CSI for use in resources with a global namespace, i.e. S3 Buckets - csi_global = replace( - format( - "%s-%s-%s-%s-%s", - var.project, - var.aws_account_id, - var.region, - var.environment, - var.component, - ), - "_", - "", - ) - - default_tags = merge( - var.default_tags, - { - Project = var.project - Environment = var.environment - Component = var.component - Group = var.group - Name = local.csi - }, - ) -} diff --git a/infrastructure/terraform/components/examplecomponent/main.tf b/infrastructure/terraform/components/examplecomponent/main.tf deleted file mode 100644 index 86805642..00000000 --- a/infrastructure/terraform/components/examplecomponent/main.tf +++ /dev/null @@ -1 +0,0 @@ -# Create root level resources here... diff --git a/infrastructure/terraform/components/examplecomponent/module_lambda_example_lambda.tf b/infrastructure/terraform/components/examplecomponent/module_lambda_example_lambda.tf deleted file mode 100644 index c23ac4d1..00000000 --- a/infrastructure/terraform/components/examplecomponent/module_lambda_example_lambda.tf +++ /dev/null @@ -1,52 +0,0 @@ -# module "example_lambda" { -# source = "git::https://github.com/NHSDigital/nhs-notify-shared-modules.git//infrastructure/modules/lambda?ref=v2.0.10" - -# function_name = "example-lambda" -# description = "An example lambda function" - -# aws_account_id = var.aws_account_id -# component = var.component -# environment = var.environment -# project = var.project -# region = var.region -# group = var.group - -# log_retention_in_days = var.log_retention_in_days -# kms_key_arn = module.kms.key_arn ## Requires shared kms module - -# iam_policy_document = { -# body = data.aws_iam_policy_document.example_lambda.json -# } - -# function_s3_bucket = local.acct.s3_buckets["lambda_function_artefacts"]["id"] -# function_code_base_path = local.aws_lambda_functions_dir_path -# function_code_dir = "example-lambda/dist" -# function_include_common = true -# handler_function_name = "handler" -# runtime = "nodejs22.x" -# memory = 128 -# timeout = 5 -# log_level = var.log_level - -# force_lambda_code_deploy = var.force_lambda_code_deploy -# enable_lambda_insights = false - -# lambda_env_vars = { -# } -# } - -# data "aws_iam_policy_document" "example_lambda" { -# statement { -# sid = "KMSPermissions" -# effect = "Allow" - -# actions = [ -# "kms:Decrypt", -# "kms:GenerateDataKey", -# ] - -# resources = [ -# module.kms.key_arn, ## Requires shared kms module -# ] -# } -# } diff --git a/infrastructure/terraform/components/examplecomponent/outputs.tf b/infrastructure/terraform/components/examplecomponent/outputs.tf deleted file mode 100644 index 9dcc2f39..00000000 --- a/infrastructure/terraform/components/examplecomponent/outputs.tf +++ /dev/null @@ -1 +0,0 @@ -# Define the outputs for the component. The outputs may well be referenced by other component in the same or different environments using terraform_remote_state data sources... diff --git a/infrastructure/terraform/components/examplecomponent/variables.tf b/infrastructure/terraform/components/examplecomponent/variables.tf deleted file mode 100644 index 1fba9652..00000000 --- a/infrastructure/terraform/components/examplecomponent/variables.tf +++ /dev/null @@ -1,64 +0,0 @@ -## -# Basic Required Variables for tfscaffold Components -## - -variable "project" { - type = string - description = "The name of the tfscaffold project" -} - -variable "environment" { - type = string - description = "The name of the tfscaffold environment" -} - -variable "aws_account_id" { - type = string - description = "The AWS Account ID (numeric)" -} - -variable "region" { - type = string - description = "The AWS Region" -} - -variable "group" { - type = string - description = "The group variables are being inherited from (often synonmous with account short-name)" -} - -## -# tfscaffold variables specific to this component -## - -# This is the only primary variable to have its value defined as -# a default within its declaration in this file, because the variables -# purpose is as an identifier unique to this component, rather -# then to the environment from where all other variables come. -variable "component" { - type = string - description = "The variable encapsulating the name of this component" - default = "examplecomponent" -} - -variable "default_tags" { - type = map(string) - description = "A map of default tags to apply to all taggable resources within the component" - default = {} -} - -## -# Variables specific to the component -## - -variable "log_retention_in_days" { - type = number - description = "The retention period in days for the Cloudwatch Logs events to be retained, default of 0 is indefinite" - default = 0 -} - -variable "force_lambda_code_deploy" { - type = bool - description = "If the lambda package in s3 has the same commit id tag as the terraform build branch, the lambda will not update automatically. Set to True if making changes to Lambda code from on the same commit for example during development" - default = false -} diff --git a/infrastructure/terraform/components/examplecomponent/pre.sh b/infrastructure/terraform/components/pre.sh similarity index 100% rename from infrastructure/terraform/components/examplecomponent/pre.sh rename to infrastructure/terraform/components/pre.sh diff --git a/lambdas/example-lambda/.eslintignore b/lambdas/example-lambda/.eslintignore deleted file mode 100644 index 1521c8b7..00000000 --- a/lambdas/example-lambda/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -dist diff --git a/lambdas/example-lambda/.gitignore b/lambdas/example-lambda/.gitignore deleted file mode 100644 index 80323f7c..00000000 --- a/lambdas/example-lambda/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -coverage -node_modules -dist -.reports diff --git a/lambdas/example-lambda/jest.config.ts b/lambdas/example-lambda/jest.config.ts deleted file mode 100644 index d30f4cd1..00000000 --- a/lambdas/example-lambda/jest.config.ts +++ /dev/null @@ -1,60 +0,0 @@ -import type { Config } from 'jest'; - -export const baseJestConfig: Config = { - preset: 'ts-jest', - - // Automatically clear mock calls, instances, contexts and results before every test - clearMocks: true, - - // Indicates whether the coverage information should be collected while executing the test - collectCoverage: true, - - // The directory where Jest should output its coverage files - coverageDirectory: './.reports/unit/coverage', - - // Indicates which provider should be used to instrument code for coverage - coverageProvider: 'babel', - - coverageThreshold: { - global: { - branches: 100, - functions: 100, - lines: 100, - statements: -10, - }, - }, - - coveragePathIgnorePatterns: ['/__tests__/'], - transform: { '^.+\\.ts$': 'ts-jest' }, - testPathIgnorePatterns: ['.build'], - testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], - - // Use this configuration option to add custom reporters to Jest - reporters: [ - 'default', - [ - 'jest-html-reporter', - { - pageTitle: 'Test Report', - outputPath: './.reports/unit/test-report.html', - includeFailureMsg: true, - }, - ], - ], - - // The test environment that will be used for testing - testEnvironment: 'jsdom', -}; - -const utilsJestConfig = { - ...baseJestConfig, - - testEnvironment: 'node', - - coveragePathIgnorePatterns: [ - ...(baseJestConfig.coveragePathIgnorePatterns ?? []), - 'zod-validators.ts', - ], -}; - -export default utilsJestConfig; diff --git a/lambdas/example-lambda/package.json b/lambdas/example-lambda/package.json deleted file mode 100644 index d4db48fe..00000000 --- a/lambdas/example-lambda/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "//": "PLEASE UPDATE THE NAME APPROPRIATELY.", - "dependencies": { - "esbuild": "^0.25.0" - }, - "devDependencies": { - "@tsconfig/node22": "^22.0.2", - "@types/aws-lambda": "^8.10.148", - "@types/jest": "^29.5.14", - "jest": "^29.7.0", - "jest-mock-extended": "^3.0.7", - "typescript": "^5.8.2" - }, - "name": "nhs-notify-repository-template-example-lambda", - "private": true, - "scripts": { - "lambda-build": "rm -rf dist && npx esbuild --bundle --minify --sourcemap --target=es2020 --platform=node --loader:.node=file --entry-names=[name] --outdir=dist src/index.ts", - "lint": "eslint .", - "lint:fix": "eslint . --fix", - "test:unit": "jest", - "typecheck": "tsc --noEmit" - }, - "version": "0.0.1" -} diff --git a/lambdas/example-lambda/src/__tests__/index.test.ts b/lambdas/example-lambda/src/__tests__/index.test.ts deleted file mode 100644 index 768b0f2c..00000000 --- a/lambdas/example-lambda/src/__tests__/index.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { handler } from '../index'; -import type { Context } from 'aws-lambda'; -import { mockDeep } from 'jest-mock-extended'; - -describe('event-logging Lambda', () => { - it('logs the input event and returns 200', async () => { - const event = { foo: 'bar' }; - const context = mockDeep(); - const callback = jest.fn(); - const result = await handler(event, context, callback); - - expect(result).toEqual({ - statusCode: 200, - body: 'Event logged', - }); - }); -}); diff --git a/lambdas/example-lambda/src/index.ts b/lambdas/example-lambda/src/index.ts deleted file mode 100644 index 3b5a5bff..00000000 --- a/lambdas/example-lambda/src/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Replace me with the actual code for your Lambda function -import { Handler } from 'aws-lambda'; - -export const handler: Handler = async (event) => { - console.log('Received event:', event); - return { - statusCode: 200, - body: 'Event logged', - }; -}; diff --git a/lambdas/example-lambda/tsconfig.json b/lambdas/example-lambda/tsconfig.json deleted file mode 100644 index ea37d696..00000000 --- a/lambdas/example-lambda/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "@tsconfig/node22/tsconfig.json", - "include": [ - "src/**/*", - "jest.config.ts" - ] -} diff --git a/package.json b/package.json index 43f1a052..236a042f 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "ts-node": "^10.9.2", "tsx": "^4.19.3" }, - "name": "nhs-notify-repository-template", + "name": "nhs-notify-digital-letters", "overrides": { "pretty-format": { "react-is": "19.0.0" @@ -48,6 +48,6 @@ "typecheck": "npm run typecheck --workspaces" }, "workspaces": [ - "lambdas/example-lambda" + "lambdas/*" ] } diff --git a/scripts/config/pre-commit.yaml b/scripts/config/pre-commit.yaml index 29397e23..8805392d 100644 --- a/scripts/config/pre-commit.yaml +++ b/scripts/config/pre-commit.yaml @@ -56,13 +56,13 @@ repos: entry: ./scripts/githooks/check-terraform-format.sh language: script pass_filenames: false - - repo: local - hooks: - - id: generate-terraform-docs - name: Generate Terraform Docs - entry: ./scripts/githooks/check-terraform-docs.sh - language: script - pass_filenames: false + # - repo: local + # hooks: + # - id: generate-terraform-docs + # name: Generate Terraform Docs + # entry: ./scripts/githooks/check-terraform-docs.sh + # language: script + # pass_filenames: false - repo: local hooks: - id: check-todo-usage