Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
6c808be
Add skeleton for cosmetology backend app
landonshumway-ia Jan 9, 2026
a1bf5bf
Remove fee related configuration fields from compact/jurisdiction con…
landonshumway-ia Jan 12, 2026
98c493f
Add GH actions script for checking cosmetology codebase
landonshumway-ia Jan 12, 2026
768c324
remove unused var
landonshumway-ia Jan 12, 2026
ad4bca2
Remove provider user account related features - part 1
landonshumway-ia Jan 13, 2026
8c06435
Remove provider user account related features - part 2
landonshumway-ia Jan 13, 2026
16e28cc
Remove provider user account related features - part 3
landonshumway-ia Jan 13, 2026
be447b9
formatting/linter
landonshumway-ia Jan 13, 2026
4f3601c
Remove remaining references to attestations
landonshumway-ia Jan 13, 2026
2875385
Fix docs to use correct url path for state api query endpoint
landonshumway-ia Jan 14, 2026
50dd795
Remove provider user account related features - part 4
landonshumway-ia Jan 14, 2026
8dd8859
Remove provider related tests for notification tracker
landonshumway-ia Jan 14, 2026
f196185
linter
landonshumway-ia Jan 14, 2026
a910f14
Remove unused references to S3 client in email service
landonshumway-ia Jan 14, 2026
b31351b
first pass through cleanup of design docs
landonshumway-ia Jan 14, 2026
8fe0916
Remove irrelevant CDK test snapshots/smoke tests
landonshumway-ia Jan 14, 2026
0120754
Remove test logic to load attestation record into test DB
landonshumway-ia Jan 14, 2026
48a5c12
Remove unused import
landonshumway-ia Jan 14, 2026
6ede846
Remove remaining references to ProviderUsers user pool in CDK
landonshumway-ia Jan 15, 2026
b0972c7
remove outdated test for license rollback
landonshumway-ia Jan 15, 2026
ad9784f
Update CDK test snapshots to match updated schemas
landonshumway-ia Jan 15, 2026
a7d4d82
Update ssm parameter namespace to include app id
landonshumway-ia Jan 15, 2026
82ca6b9
Support cross account parameter lookups for frontend deployments
landonshumway-ia Jan 15, 2026
749608d
formatting/linter
landonshumway-ia Jan 15, 2026
138921d
update cdk context examples with cosmetology values
landonshumway-ia Jan 15, 2026
c0eff9b
update sandbox cdk context to use new compact
landonshumway-ia Jan 16, 2026
1b1d0d5
Refactor SSM context to support cosmetology
jusdino Jan 13, 2026
4c81f0d
Deconflict resources for cosmetology pipeline
jusdino Jan 14, 2026
1c771e6
Finalize docs with cosmetology deploy learnings
jusdino Jan 16, 2026
8f22fe9
Update snapshots with new jurisdictions
landonshumway-ia Jan 16, 2026
54f0589
fix ssm parameter name in test
landonshumway-ia Jan 16, 2026
d03258a
WIP - test frontend app deployment with new config
landonshumway-ia Jan 16, 2026
cd25c37
WIP - add test context fields
landonshumway-ia Jan 16, 2026
f643f61
Add frontend role to bootstrap stack
landonshumway-ia Jan 16, 2026
8b788a3
Add lookup role prop for ssm lookup
landonshumway-ia Jan 16, 2026
cbae47e
Simplify ssm lookup through manual setup
landonshumway-ia Jan 19, 2026
c7e3c8f
Add documentation for ssm setup
landonshumway-ia Jan 19, 2026
1530396
formatting
landonshumway-ia Jan 19, 2026
fe31538
Update cosmetology python dependencies to latest
landonshumway-ia Jan 19, 2026
4e51c01
Update cosmetology node dependencies to latest
landonshumway-ia Jan 19, 2026
f129372
Update node tests to use global test matchers
landonshumway-ia Jan 19, 2026
80e0421
update audit command to match compact-connect
landonshumway-ia Jan 19, 2026
c0c6952
Remove test values from frontend app cdk
landonshumway-ia Jan 19, 2026
7d511da
Remove references to unneeded ReCaptcha setup from Cosmetology README
landonshumway-ia Jan 19, 2026
d48a9bd
Remove unneeded python 3.12 layer
landonshumway-ia Jan 19, 2026
3e57498
Remove duplicate SSN flag
landonshumway-ia Jan 19, 2026
d4714f2
namespace example flag
landonshumway-ia Jan 19, 2026
67b83b7
using csg email builder npm package
landonshumway-ia Jan 19, 2026
bfc8f52
Remove unneeded frontend role from trust policy
landonshumway-ia Jan 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions .github/workflows/auto-tag-test-deployments.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ jobs:

echo "Created tag: $TAG_NAME"

- name: Create Cosmetology Test Tag
run: |
SHORT_SHA=$(git rev-parse --short ${{ github.sha }})
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
TAG_NAME="cosm-test-${TIMESTAMP}-${SHORT_SHA}"

git tag -a "$TAG_NAME" -m "Auto-generated test deployment tag for cosmetology service (commit: ${{ github.sha }})"
git push origin "$TAG_NAME"

echo "Created tag: $TAG_NAME"

# We're deploying the backend and UI in parallel here, since that is _usually_ fine. However,
# the UI deployment does have some dependencies on the backend, in the form of parameters like
# S3 bucket urls, cognito domains, etc. If those change, or if new parameters are introduced,
Expand Down
110 changes: 110 additions & 0 deletions .github/workflows/check-cosmetology-app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Check-Cosmetology-Application

on:
pull_request:
paths:
- backend/cosmetology-app/**

env:
AWS_REGION : "us-east-1"

# Permission can be added at job level or workflow level
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout

jobs:
LintPython:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v6
with:
python-version: '3.14'

# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v5

- name: Install dev dependencies
run: "pip install -r backend/cosmetology-app/requirements-dev.txt"

- name: Lint Code
run: "cd backend/cosmetology-app; ruff check $(git ls-files '*.py')"

- name: Check Dependencies
run: "pip-audit"

LintNode:
runs-on: ubuntu-latest

steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v5

- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."

# Setup Node
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: '24.11.1'

# Use any cached yarn dependencies (saves build time)
- uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}

# Install Yarn Dependencies
- name: Install Node.js dependencies
run: yarn install
working-directory: ./backend/cosmetology-app/lambdas/nodejs

# Run Linter Checks
- name: Run linter
run: yarn run lint
working-directory: ./backend/cosmetology-app/lambdas/nodejs

# Audit dependencies for vulnerabilities
- name: Audit dependencies
run: yarn run audit:dependencies
working-directory: ./backend/cosmetology-app/lambdas/nodejs

TestApp:
runs-on: ubuntu-latest
steps:
# Checks-out the repository under $GITHUB_WORKSPACE
- uses: actions/checkout@v5

- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.14'

# Setup Node
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: '24.11.1'

# Use any cached yarn dependencies (saves build time)
- uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}

# Install Yarn Dependencies
- name: Install Node.js dependencies
run: yarn install
working-directory: ./backend/cosmetology-app/lambdas/nodejs

- name: Install dev dependencies
run: "pip install -r backend/cosmetology-app/requirements-dev.txt"
# Note we are currently pinning the pip version to deal with compatibility issues released with pip 25.3
# see https://stackoverflow.com/a/79802727 If this issues is addressed in a later version, we can remove the
# extra pip install command so we stop pinning the pip version
- name: Install all Python dependencies
run: "cd backend/cosmetology-app; pip install -U 'pip<25.3'; bin/sync_deps.sh"

- name: Test backend
run: "cd backend/cosmetology-app; bin/run_tests.sh -l all -no"
32 changes: 9 additions & 23 deletions backend/common-cdk/common_constructs/base_pipeline_stack.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import json
from enum import StrEnum

from aws_cdk import Environment, RemovalPolicy
from aws_cdk.aws_iam import CompositePrincipal, Effect, PolicyStatement, Role, ServicePrincipal
from aws_cdk.aws_s3 import IBucket
from aws_cdk.aws_ssm import StringParameter
from aws_cdk.pipelines import CodePipeline as CdkCodePipeline
from constructs import Construct

from common_constructs.ssm_context import SSMContext
from common_constructs.stack import Stack

TEST_ENVIRONMENT_NAME = 'test'
Expand All @@ -21,18 +20,19 @@
class CCPipelineType(StrEnum):
BACKEND = 'Backend'
FRONTEND = 'Frontend'
COSMETOLOGY = 'Cosmetology'


class BasePipelineStack(Stack):
"""Base stack with common functionality for all pipeline stacks (both backend and frontend)."""
"""Base stack with common functionality for all pipeline stacks."""

def __init__(
self,
scope: Construct,
construct_id: str,
environment_name: str,
env: Environment,
pipeline_type: CCPipelineType,
pipeline_context_parameter_name: str,
removal_policy: RemovalPolicy,
pipeline_access_logs_bucket: IBucket,
**kwargs,
Expand All @@ -45,28 +45,14 @@ def __init__(
self.removal_policy = removal_policy
self.access_logs_bucket = pipeline_access_logs_bucket

if pipeline_type == CCPipelineType.BACKEND:
pipeline_context_parameter_name = f'{self.environment_name}-compact-connect-context'
else:
pipeline_context_parameter_name = f'{self.environment_name}-ui-compact-connect-context'

# Fetch ssm_context if not provided locally
self.parameter = StringParameter.from_string_parameter_name(
ssm_context = SSMContext(
self,
'PipelineContext',
string_parameter_name=pipeline_context_parameter_name,
pipeline_context_parameter_name,
f'cdk.context.{environment_name}-example.json',
)
value = StringParameter.value_from_lookup(self, self.parameter.parameter_name)
# When CDK runs for the first time, it synthesizes fully without actually retrieving the SSM Parameter
# value. It, instead, populates parameters and other look-ups with dummy values, synthesizes, collects all
# the look-ups together, populates them for real, then re-synthesizes with real values.
# To accommodate this pattern, we have to replace this dummy value with one that will actually
# let CDK complete its first round of synthesis, so that it can get to its second, real, synthesis.
if value != f'dummy-value-for-{pipeline_context_parameter_name}':
self.ssm_context = json.loads(value)
else:
with open(f'cdk.context.{environment_name}-example.json') as f:
self.ssm_context = json.load(f)['ssm_context']
self.parameter = ssm_context.parameter
self.ssm_context = ssm_context.context

self.pipeline_environment_context = self.ssm_context['environments']['pipeline']
self.connection_arn = self.pipeline_environment_context['connection_arn']
Expand Down
32 changes: 8 additions & 24 deletions backend/common-cdk/common_constructs/deployment_resources_stack.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import json

from aws_cdk import RemovalPolicy
from aws_cdk.aws_kms import Key
from aws_cdk.aws_ssm import StringParameter
from cdk_nag import NagSuppressions
from constructs import Construct

from common_constructs.access_logs_bucket import AccessLogsBucket
from common_constructs.alarm_topic import AlarmTopic
from common_constructs.base_pipeline_stack import DEPLOY_ENVIRONMENT_NAME, CCPipelineType
from common_constructs.base_pipeline_stack import DEPLOY_ENVIRONMENT_NAME
from common_constructs.ssm_context import SSMContext
from common_constructs.stack import Stack


Expand All @@ -19,33 +17,19 @@ def __init__(
self,
scope: Construct,
construct_id: str,
pipeline_type: CCPipelineType,
pipeline_context_parameter_name: str,
**kwargs,
):
super().__init__(scope, construct_id, environment_name='deploy', **kwargs)

if pipeline_type == CCPipelineType.BACKEND:
pipeline_context_parameter_name = f'{DEPLOY_ENVIRONMENT_NAME}-compact-connect-context'
else:
pipeline_context_parameter_name = f'{DEPLOY_ENVIRONMENT_NAME}-ui-compact-connect-context'

# Fetch ssm_context if not provided locally
self.parameter = StringParameter.from_string_parameter_name(
ssm_context = SSMContext(
self,
'PipelineContext',
string_parameter_name=pipeline_context_parameter_name,
pipeline_context_parameter_name,
f'cdk.context.{DEPLOY_ENVIRONMENT_NAME}-example.json',
)
value = StringParameter.value_from_lookup(self, self.parameter.parameter_name)
# When CDK runs for the first time, it synthesizes fully without actually retrieving the SSM Parameter
# value. It, instead, populates parameters and other look-ups with dummy values, synthesizes, collects all
# the look-ups together, populates them for real, then re-synthesizes with real values.
# To accommodate this pattern, we have to replace this dummy value with one that will actually
# let CDK complete its first round of synthesis, so that it can get to its second, real, synthesis.
if value != f'dummy-value-for-{pipeline_context_parameter_name}':
self.ssm_context = json.loads(value)
else:
with open(f'cdk.context.{DEPLOY_ENVIRONMENT_NAME}-example.json') as f:
self.ssm_context = json.load(f)['ssm_context']
self.parameter = ssm_context.parameter
self.ssm_context = ssm_context.context

self.deploy_environment_context = self.ssm_context['environments'][DEPLOY_ENVIRONMENT_NAME]

Expand Down
Loading
Loading