{"id":23421176,"url":"https://github.com/nhsdigital/connecting-party-manager","last_synced_at":"2025-04-09T09:34:56.912Z","repository":{"id":203796348,"uuid":"697180281","full_name":"NHSDigital/connecting-party-manager","owner":"NHSDigital","description":"Connecting Party Manager","archived":false,"fork":false,"pushed_at":"2024-10-29T11:28:10.000Z","size":2741,"stargazers_count":1,"open_issues_count":12,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-10-29T11:38:13.835Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NHSDigital.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-27T08:06:30.000Z","updated_at":"2024-10-28T16:54:14.000Z","dependencies_parsed_at":"2023-12-04T11:29:16.614Z","dependency_job_id":"74cfa993-1de8-4624-b808-5b433552d8fa","html_url":"https://github.com/NHSDigital/connecting-party-manager","commit_stats":null,"previous_names":["nhsdigital/connecting-party-manager"],"tags_count":80,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NHSDigital%2Fconnecting-party-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NHSDigital%2Fconnecting-party-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NHSDigital%2Fconnecting-party-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NHSDigital%2Fconnecting-party-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NHSDigital","download_url":"https://codeload.github.com/NHSDigital/connecting-party-manager/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248013120,"owners_count":21033311,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-23T02:14:18.644Z","updated_at":"2025-04-09T09:34:56.897Z","avatar_url":"https://github.com/NHSDigital.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Connecting Party Manager\n\n## Overview\n\n## Table of Contents\n\n1. [TLDR](#tldr)\n   1. [Requirements](#requirements)\n   2. [Building a local environment](#building-a-local-environment)\n   3. [Testing](#testing)\n   4. [Destroying a local environment](#destroying-a-local-environment)\n1. [Setup](#setup)\n   1. [Prerequisites](#prerequisites)\n   2. [Useful tools](#useful-tools)\n   3. [Project build](#project-build)\n   4. [Proxygen](#proxygen)\n      1. [Temporary Proxies](#temporary-proxies)\n   5. [AWS SSO Setup](#aws-sso-setup)\n   6. [Build a local workspace on AWS (DEV)](#build-a-local-workspace-on-aws-dev)\n   7. [Build a local workspace on AWS (QA)](#build-a-local-workspace-on-aws-qa)\n   8. [Destroy a local workspace on AWS](#destroy-a-local-workspace-on-aws)\n   9. [Automated workspace destroys](#automated-workspace-destroys)\n   10. [Destroy Expired Workspaces](#destroy-expired-workspaces)\n   11. [Destroy Redundant Workspaces](#destroy-redundant-workspaces)\n   12. [Destroy Corrupted Workspaces](#destroy-corrupted-workspaces)\n   13. [Updating Roles](#updating-roles)\n   14. [Other helpful commands](#other-helpful-commands)\n1. [Tests](#tests)\n   1. [pytest tests](#pytest-tests)\n   2. [End-to-End feature tests](#end-to-end-feature-tests)\n   3. [Local](#local)\n   4. [Integration](#integration)\n   5. [Generate the Feature Test Postman collection](#generate-the-feature-test-postman-collection)\n1. [Data modelling](#data-modelling)\n   1. [Domain models](#domain-models)\n   2. [Database models](#database-models)\n   3. [Response models](#response-models)\n   4. [Request models](#request-models)\n1. [Workflow](#workflow)\n1. [Deployment](#deployment)\n1. [Swagger](#swagger)\n1. [Setting Lamba permissions](#setting-lambda-permissions)\n1. [Terraform](#terraform)\n1. [Administration](#administration)\n1. [SBOM](#sbom)\n1. [Extras](#extras)\n   1. [Archive](#archive)\n\n---\n\n## TLDR\n\nIf you want to get up and running as quickly as possible then read this section. However it is advisable to read the full README when possible.\n\n### Requirements\n\n- Ensure you have `AWS SSO` setup. For more information please read the [AWS SSO Setup](#aws-sso-setup) section.\n- Ensure you have `asdf` installed and the `docker engine` running. For more information please read the [Setup](#setup) section.\n\n### Building a local environment\n\n- Inside the connecting party manager root directory, run...\n- `make terraform--apply`\n- For more information please read the [Build a local workspace on AWS (DEV)](#build-a-local-workspace-on-aws-dev) section.\n\n### Testing\n\n- Inside the connecting party manager root directory, run any of the following commands...\n- `make test--unit`\n- `make test--integration`\n- `make test--feature--local`\n- `make test--feature--integration`\n- `make test--smoke`\n\n### Destroying a local environment\n\n- Provided you haven't changed the workspace name, then.\n- Inside the connecting party manager root directory, run...\n- `make terraform--destroy`\n- For more information please read the [Destroy a local workspace on AWS](#destroy-a-local-workspace-on-aws) section.\n\n## Setup\n\n### Prerequisites\n\nWe use `asdf` to fetch the required versions of prerequisite libraries instead of your system's default version. To get it up and running go to \u003chttps://asdf-vm.com/guide/getting-started.html\u003e. You can check it installed properly by using the command `asdf --version`.\n\nYou will also need to install the `docker engine` separately\n\nAdditionally you will need `wget` (doing `which wget` will return blank if not installed). Please Google \"how to install wget on my operating system\", if you don't already have this installed.\n\nUpdate any dependencies on your system as required.\n\nOtherwise `asdf` should do the work for you.\n\n### Useful tools\n\n`VScode` is a useful IDE and we have a workspace file setup to allow easy integration\n\n`Postman` \u0026/or `Newman`. Feature tests create a postman.collection which can be used for manual testing.\n\n### Project build\n\nDo `make build` every time you would like to pick up and install new local/project dependencies and artifacts. This will always detect changes to:\n\n- `.tool-versions` (project prerequisites)\n- `pyproject.toml` (python dependencies)\n- non-development files in the `src` directory\n\nThe first time it will also set up your pre-commit hooks.\n\n### Proxygen\n\nWe use [Proxygen](https://github.com/NHSDigital/proxygen-cli) to deploy our proxies and specs to APIM which we have wrapped up into a make command:\n\n- `make apigee--deploy`\n\nWhen you run this locally you will need to have done a local `terraform--plan` and `terraform--apply` (as it will read some details from the output files)\n\nCaveats\n\n- At present we have one set of credentials that we use across PTL and PROD (so that the name of the api remains constant)\n- We are temporarily using the apikey method of authentication, which requires the deployment of a key that is used in the swagger - example below:\n  - `proxygen secret put sandbox cpm-1 --apikey --secret-value=iamsecret`\n  - We plan on replacing this with MTLS as soon as we can\n\n#### Temporary Proxies\n\nTo avoid us having too many proxies deployed that we fail to manage, for anything that isnt a Persistent Environment or equivalent sandbox (dev, dev-sandbox) - then the Proxy will be tagged as `temporary`. This means that it will be deleted after a period of time determined by APIM and the code can be found in the swagger generation files under the `x-nhsd-apim` header\n\n### AWS SSO Setup\n\nThis project uses Single Sign On (SSO) for consuming AWS services.\n\nTo configure SSO run the following command\n\n```\naws configure sso\n```\n\nusing the following parameters, where \u003cREPLACE_ME\u003e matches the URL of the SSO app you should have as a bookmark:\n\n```\nSSO session name (Recommended): NHS\nSSO start URL [None]: https://\u003cREPLACE_ME\u003e.awsapps.com/start#\nSSO region [None]: eu-west-2\nSSO registration scopes [sso:account:access]: sso:account:access\n```\n\nA browser window should appear. To progress you will need to click \"Confirm and continue\" and then \"Allow\", after reading and understanding the instructions. Once complete you will be returned to the console.\n\nYou can now configure your first profile, by selecting a value from the list and answering the prompts. You should setup `NHS Digital Spine Core CPM MGMT` first. Successive profiles can be added by repeating `aws configure sso` but this time the SSO session name exists and will not be recreated.\n\nEntries will now be visible in your `~/.aws/config` file.\n\nYou may now login to AWS via SSO using:\n\n```\naws sso login --sso-session NHS\n```\n\nYou may now switch between profiles by using, where \u003cprofile\u003e is taken from the entry in your `~/.aws/config` file:\n\n```\nexport AWS_PROFILE=\u003cprofile\u003e\n```\n\nThis is the preferred method of switching between profiles, as it will cause the profile name to appear in your BASH prompt.\n\n### Build a local workspace on AWS (DEV)\n\nYou can build a working copy of the CPM service in your own workspace within the `dev` environment. To do this follow these steps. (You must have SSO setup on your system and have MGMT admin access)\n\nYour workspace will build with an 8 digit hash of your system username by default. Therefore you do not need to provide a workspace name, however, if you would like to give your workspace a specific name then you must pass a `TERRAFORM_WORKSPACE` variable to each command. It is recommended that you use the format `YOUR_SHORTCODE_AND_JIRA_NUMBER`, but it will accept any name, however this variable must not contain spaces, but can contain underscores and hyphens. `e.g. jobl3-PI-100`\n\n```shell\nmake terraform--init TERRAFORM_WORKSPACE=\"\u003cYOUR_SHORTCODE_AND_JIRA_NUMBER\u003e\" # Will attempt to login to AWS first using SSO\nmake terraform--plan TERRAFORM_WORKSPACE=\"\u003cYOUR_SHORTCODE_AND_JIRA_NUMBER\u003e\" # Will attempt to build the project first\nmake terraform--apply TERRAFORM_WORKSPACE=\"\u003cYOUR_SHORTCODE_AND_JIRA_NUMBER\u003e\"\n```\n\n### Build a local workspace on AWS (QA)\n\nFor testing purposes we have another command to allow testers to deploy to QA (to avoid the often change heavy dev) - very similar to the above except the command hard codes the QA environment behind the scenes.\n\n```shell\nmake terraform--init TERRAFORM_WORKSPACE=\"\u003cYOUR_SHORTCODE_AND_JIRA_NUMBER\u003e\" # Will attempt to login to AWS first using SSO\nmake terraform--plan--qa TERRAFORM_WORKSPACE=\"\u003cYOUR_SHORTCODE_AND_JIRA_NUMBER\u003e\" # Will attempt to build the project first\nmake terraform--apply--qa TERRAFORM_WORKSPACE=\"\u003cYOUR_SHORTCODE_AND_JIRA_NUMBER\u003e\"\n```\n\n### Destroy a local workspace on AWS\n\nDestroy the local workspace and it's corresponding state file on mgmt\n\n```shell\nmake terraform--destroy TERRAFORM_WORKSPACE=\"\u003cYOUR_SHORTCODE_AND_JIRA_NUMBER\u003e\" # Will attempt to login to AWS first using SSO\n```\n\n### Automated workspace destroys\n\nWe have some automated behaviour for destroying our workspaces - we build off a new commit each time we deploy and there are times where we forget to destroy old workspaces or have CI workspaces be removed. So we have two processes:\n\n#### Destroy Expired Workspaces\n\n- This is run on a cron job as a github workflow every evening and scans the workspaces in dev (local deployments) and ref (CI deployments)\n- Each deployment is deployed with a resource group that has an expiration date on it, the workspace is destroyed if its past that date\n- Each deploy or change within a workspace extends the expiration date\n- Can be run adhoc by using the command: `make destroy--expired TERRAFORM_WORKSPACE=\"dev\"`\n\n#### Destroy Redundant Workspaces\n\n- This is part of the Pull Request github workflow and checks to destroy previous commits on the same workspace leaving only the latest\n- When you run locally you can override this with the `KILL_ALL` flag which destroys the current commit too\n- Can be run adhoc with the command: `make destroy--redundant-workspaces BRANCH_NAME=mybranch DESTROY_ALL_COMMITS_ON_BRANCH=false KILL_ALL=false`\n\n#### Destroy Corrupted Workspaces\n\n- This is a way to destroy a workspace on dev if terraform is not destroying it. This is not fool-proof as there are many different \"chicken and egg\" scenarios to infrastructure. But it should go some way to having a destroyed environment\n- Can be run manually by using the command: `make destroy--corrupted TERRAFORM_WORKSPACE=\"\u003cWORKSPACE_TO_DESTROY\u003e\" TERRAFORM_ROLE_NAME=\"NHSDeploymentRole\"`\n\n## Updating Roles\n\nWe have several roles that we currently handle outside of terraform as its needed to deploy the terraform:\n\n- NHSDeploymentRole\n- NHSDevelopmentRole\n- NHSTestCIRole\n- NHSSmokeTestRole\n\nTo update any of the roles used for SSO then you need to do the following command which should prompt you to log in via SSO:\n\n`make manage--non-mgmt-policies MGMT_ACCOUNT_ID=\u003cID\u003e SSO_PROFILE=\"dev-admin\"`\n\u0026\n`make manage--non-mgmt-test-policies MGMT_ACCOUNT_ID=\u003cID\u003e SSO_PROFILE=\"dev-admin\"`\n\nWhere:\n\n- MGMT ACCOUNT ID = The account id for mgmt so that it can be substituted into the role trust policy\n- SSO_PROFILE = This is the profile in you .aws/config file where you will specify the details for each environment\n  - dev-admin\n  - qa-admin\n  - ref-admin\n  - int-admin\n  - prod-admin\n\n### Other helpful commands\n\nRun `make` to get a list of helpful commands.\n\n## Tests\n\n### `pytest` tests\n\nThere are three types of `pytest` in this project:\n\n- Unit: these _do not have_ any `@pytest.mark` markers;\n- Integration: these have `@pytest.mark.integration` markers;\n- Smoke: these have `@pytest.mark.smoke` markers;\n\nIn order to run these you can do one of:\n\n```shell\nmake test--unit\nmake test--integration   # Will attempt to log you into AWS first\nmake test--smoke         # Will attempt to log you into AWS first\n```\n\nIf you would like to rerun all failed tests, you can append `--rerun` to the test command, e.g.:\n\n```shell\nmake test--unit--rerun\n```\n\nIf you would like to pass `pytest` flags you can do e.g. to \\[stop after the first failure\\] with \\[very\\] \\[verbose\\] feedback:\n\n```shell\nmake test--unit PYTEST_FLAGS=\"-xvv\"\n```\n\nOtherwise, feel free to run `pytest` from your `poetry` shell for more fine-grained control (see Google for more info!).\n\nThe VSCode settings for \"Run and Debug\" are also set up to run these tests if your prefer.\n\nAdd `PYTEST_FLAGS='-sv'`.\n\n### End-to-End feature tests\n\nThe Feature tests use `behave` (rather than `pytest`) to execute cucumber/gherkin-style end-to-end tests of specific features, in principle\ngiving full end-to-end test coverage for API operations.\n\nExecuting feature tests locally will give you a good idea whether you have implemented a well-behaved feature whilst in development (i.e. no need to redeploy whilst developing).\n\nExecuting feature tests in integration mode will then give you confidence that the feature is ready to deploy in production, but has a much slower development cycle as it will need a full redeploy after codebase or infrastructure changes are implemented.\n\n#### Local\n\nTo execute the feature tests entirely locally (executing lambdas directly, and otherwise mocking databases and responses to a high standard) you can do:\n\n```shell\nmake test--feature--local\n```\n\nIf you would like to pass `behave` flags, e.g. to \\[stop after the first failure\\]:\n\n```shell\nmake test--feature--local BEHAVE_FLAGS=\"--stop\"\n```\n\n#### Integration\n\nTo execute the feature tests across the entire stack (including Apigee and AWS) you can do\n\n```shell\nmake test--feature--integration\n```\n\n### Generate the Feature Test Postman collection\n\nOur [end-to-end feature tests](#end-to-end-feature-tests) also generate working Postman collections. To generate the Postman collection quickly, without Apigee credentials, you can run the local feature tests. If you would like the Apigee\ncredentials generating then you should run the integration feature tests. The generated files are:\n\n- `src/api/tests/feature_tests/postman-collection.json`\n- `src/api/tests/feature_tests/postman-environment.json`\n\nYou can drag and drop `postman-collection.json` into the `Collections` tab on Postman,\nand `postman-environment.json` on to the `Environments` tab (remember to activate it). If you generated these\nwith the local feature tests, then you will need to manually update the Apigee `baseUrl` and `apiKey` fields\nin the environment (but these are filled out already if generated with the integration feature tests).\n\n💡 **The feature tests are only guaranteed to work out-of-the-box with an empty database**\n\n## Data modelling\n\nModelling in Connecting Party Manager is split into four partially-decoupled components:\n\n- Domain models: The conceptual entities of Connecting Party Manager, without any reference to database indexing, and request / response syntax.\n- Database models: A wrapper on the domain models that we persist to database (DynamoDB), indicating write-integrity (primary keys) and a read/search interface (indexing).\n- Response models: Deviations from the domain model (error handling, search result wrapping, private field exclusion, etc)\n- Request models: API-specific models indicating the expected request bodies of create/update/search operations.\n\n### Domain models\n\nWe have two Domain models, ProductTeam and Product.\n\n```\nclass ProductTeam()\n    id: str\n    name: str\n    ods_code: str\n    status: enum(ACTIVE, INACTIVE)\n    created_on: datetime\n    updated_on: datetime\n    deleted_on: datetime\n    keys: list[{\n      key_type: str,\n      key_value: uuid\n    }]\n```\n\n```\nclass CpmProduct(AggregateRoot):\n    id: str\n    cpm_product_team_id: str\n    product_team_id: str\n    name: str\n    ods_code: str\n    status: enum(ACTIVE, INACTIVE)\n    created_on: datetime\n    updated_on: datetime\n    deleted_on: datetime\n    keys: list[{\n      key_type: str,\n      key_value: str\n    }]\n```\n\n### Database models\n\n#### Write-integrity (primary keys)\n\nThe Partition Key (`pk`) that we use for all objects\\* in the database is a unique combination of prefix (aligned with the object type, e.g. `PT#` for `ProductTeam`) and identifier (generally a UUID). The Sort Key (`sk`) that we use is the id of the entity itself. We inject 2 columns into the row of each entity during writing and do not display on the domain classes themselves. These are `row_type` and `root`\n\nThe table is structured as below. (For purposes of clarity extra \"entity specific\" attributes have been left out.)\n\n|    PK     |     SK      |      row_type      |    Id     |      name      |            created_on            | updated_on | deleted_on | status |  pk_read_1  |  sk_read_1  | pk_read_2 |  sk_read_2  | root  |\n| :-------: | :---------: | :----------------: | :-------: | :------------: | :------------------------------: | :--------: | :--------: | :----: | :---------: | :---------: | :-------: | :---------: | :---: |\n| PT#12345  |  PT#12345   |    product_team    |   12345   | A Product Team | 2025-01-30T14:30:18.191643+00:00 |    null    |    null    | active |  PT#12345   |  PT#12345   | ORG#AB123 |  PT#12345   | true  |\n| PT#12345  | P#P.123-XYZ |      product       | P.123-XYZ |   A product    | 2025-01-30T14:30:18.191643+00:00 |    null    |    null    | active | P#P.123-XYZ | P#P.123-XYZ | ORG#AB123 | P#P.123-XYZ | true  |\n| PT#FOOBAR |  PT#FOOBAR  | product_team_alias |   12345   | A Product Team | 2025-01-30T14:30:18.191643+00:00 |    null    |    null    | active |  PT#FOOBAR  |  PT#FOOBAR  |   NULL    |    NULL     | false |\n\nProduct Teams can additionally be indexed by any keys (see [Domain models](#domain-models)) that they have. For a key in an domain object, that is of type product_team_id,\na copy is made in the database with the index being that key, rather\nthan the object's identifier. Such copies are referred to as non-root\nobjects, whereas the \"original\" (indexed by identifier) is referred to\nas the root object.\n\n#### Read/search interface\n\nWe have implemented 2 Global Secondary Indexes (GSI) for attributes named `pk_read_1`, `sk_read_1`, `pk_read_2` and `sk_read_2`. The pattern that is place is as follows:\n\nA `read` and `search` is available on all `Repository` patterns (almost) for free (the base `_read` and `_search` require a shallow wrapper).\n\n### Response models\n\nFor all response models please refer to the Swagger/OAS spec\n\n### Request models\n\nFor all request models please refer to the Swagger/OAS spec\n\n## Workflow\n\nIn order to create new branches, use the commands listed below. Note that the commands will throw an error if\nyou attempt to use them without rebasing on `origin/main`. If you need to rebase, then please do so carefully. We recommend\nthat you first inspect your divergent branch with:\n\n```shell\ngit log --all --decorate --oneline --graph\n```\n\nIf you branch is irreparably divergent from `origin/main`, you may find it easier to recreate your base branch and to pull in relevant changes.\n\n### Create new feature branch\n\nFrom `main` (or a branch based from `main`) do:\n\n```shell\nmake workflow--create-feature-branch JIRA_TICKET=\"PI-123\" DESCRIPTION=\"this Is MY ticKET\"\n```\n\nwhich will create a branch of the form `feature/PI-123-this_is_my_ticket`.\n\n### Create new release branch\n\nFrom `main` (or a branch based from `main`) do:\n\n```shell\nmake workflow--create-release-branch\n```\n\nwhich will create a branch of the form `release/YYYY-MM-DD`. If this branch name has already been taken it will append a patch version to the branch name.\n\nThis command will also:\n\n- Update the version in `pyproject.toml` with the release branch version.\n- Update the VERSION file with the release branch version number.\n\n## Deployment\n\n### Create a Release branch\n\nWhen requested by QA\n\n- Create a release branch using the make command described in the previous section\n- Create a new changelog file with the correct date in the changelog directory. (Follow the patterns used in previous files.)\n- merge the required branches through the command line into the release branch. i.e. `git merge origin/feature/PI-123-A_branch_for_qa`\n- commit and push the release branch to github and create a PR.\n- Use the workflow on the #platforms-connecting-party-manager Slack channel to notify of the new release branch.\n\n### After QA has approved the changes\n\nQA should approve the release branch PR and notify developers on the #platforms-connecting-party-manager slack channel of a request to merge the release branch.\n\n- Merge the release branch within the github UI. This will merge the release and close any feature branches that are associated with it.\n- Reply to the QA notification on slack that its has been merged and to rebase. Make sure this reply also appears on the main feed. `Merged, rebase rebase :alert:` is usually enough.\n- Now we need to deploy to all environments.\n- In the github UI, navigate to the actions tab Select `Deploy: Workspace - Nonprod` and select the dropdown `Run workflow`\n- Select the `Tag` to deploy (This is the release branch that has just been merged.)\n- Select the Account to deploy to as well as if it should be the sandbox or not.\n- You must do this for all the environments.\n- Now navigate to the `Deploy: Workspace - Production` on the left\n- Run workflow. Select the Tag to deploy and Run.\n- In production you will need to approve the deployment once the terraform plan has run. All other environments will deploy until finish without any user interaction.\n- Once all environments are deployed successfully you can move any Jira tickets to \"Done\"\n\n## Swagger\n\nThis is all done by `make build`. For more details on how to update the Swagger, please see [the swagger README](infrastructure/swagger/README.md).\n\n## Setting Lambda permissions\n\nLambda permissions are able to be set individually, To do this,\n\n- Inside the lambda src code. e.g. `src/api/createProductTeam` there is a subfolder called `policies`\n- In here create a `json` file named after the aws resource type that you wish to create permissions for. For example if you wanted to add permissions to access s3 buckets then you would add a file called `s3.json`\n- In this file add a list of permissions for s3 access. e.g. `[\"s3:ListBucket\", \"s3:GetObject\"]`\n- Finally in `infrastructure/terraform/per_workspace/locals.tf` there is a mapping `permission_resource_map`. Add the mapping to the resources that these permissions need access to. e.g.`s3 = \"${module.s3.s3_arn}\"`\n\n## Terraform\n\nIf you find yourself with a locked terraform state, do:\n\n```\nmake terraform--unlock TERRAFORM_ARGS=\u003clock_id\u003e\n```\n\n## Administration\n\n### Generating Ids\n\nIn order to generate a persistent list of Ids across environments then run... (The example given will generate 100 ids.)\n\n```\nmake admin--generate-ids--product SET_GENERATOR_COUNT=100\n```\n\nAny previously generated ids will not be overwritten.\n\n### Documentation\n\nWe have several locations for the Swagger to keep things as visible as possible\n\nIn this repository there is a folder that contains the most recent Public facing swagger.yaml\n\n`docs/public_swagger/swagger.yaml`\n\nWe also have a confluence page\n\n`https://nhsd-confluence.digital.nhs.uk/display/SPINE/CPM+Swagger+Docs`\n\nThe Spec is also available on the NHS API Catalogue.\n\n`https://digital.nhs.uk/developer/api-catalogue/connecting-party-manager/content`\n\n## SBOM (Service Bill of Materials)\n\nAs a stop gap for now - you should download Syft and Grype to your machine (ASDF doesnt do grype for some reason)\n\n`brew install syft`\n\n`brew tap anchore/grype`\n`brew install grype`\n\nTo run the SBOM commands there are some make commands that currently handle this:\n\n`make generate--sbom`\n`make validate--sbom`\n\n## Extras\n\n### Archive\n\nThe project originally was designed to have a concept of an EPRv2. This did not work out but we have kept the remains of the EPR work in an archive folder located in the `root/archived_epr`. The EPR code was supposed to fit into the structure of our existing CPM model but it became apparent as requirements came through that this would not be possible. You will find in this folder `swagger/OAS spec`, `lambdas`, `ETL` and `tests`.\n\nThis has been left in for future reference. The code would need to be transferred back into the root of the project, changing `src_old` back to `src` and merging into the existing `src` directory.\n\n### Secrets\n\nThere are some secrets that we have left within CPM that were needed in order to make connections to LDAP and HSCN - if we were to delete them then the specific details we had obtained as CPM would be lost.\nWe have left them in the code for potential future use, if you want to delete them and start afresh that is also fine - below are the secrets, they exist in each environment:\n\n\"sds-hscn-endpoint\"\n\"ldap-host\"\n\"ldap-changelog-user\"\n\"ldap-changelog-password\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnhsdigital%2Fconnecting-party-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnhsdigital%2Fconnecting-party-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnhsdigital%2Fconnecting-party-manager/lists"}