diff --git a/.github/workflows/on_merged_pr.yml b/.github/workflows/on_merged_pr.yml index 8508999..4fb154c 100644 --- a/.github/workflows/on_merged_pr.yml +++ b/.github/workflows/on_merged_pr.yml @@ -7,6 +7,8 @@ on: - completed permissions: + actions: read + contents: read issues: write jobs: diff --git a/unicorn_approvals/src/approvals_service/contract_status_changed_event_handler.py b/unicorn_approvals/src/approvals_service/contract_status_changed_event_handler.py index 11f952d..e1b707b 100644 --- a/unicorn_approvals/src/approvals_service/contract_status_changed_event_handler.py +++ b/unicorn_approvals/src/approvals_service/contract_status_changed_event_handler.py @@ -2,20 +2,18 @@ # SPDX-License-Identifier: MIT-0 import os -from datetime import datetime import boto3 from aws_lambda_powertools.logging import Logger from aws_lambda_powertools.metrics import Metrics from aws_lambda_powertools.tracing import Tracer -from aws_lambda_powertools.event_handler.exceptions import InternalServerError from schema.unicorn_contracts.contractstatuschanged import AWSEvent, ContractStatusChanged, Marshaller # Initialise Environment variables if (SERVICE_NAMESPACE := os.environ.get("SERVICE_NAMESPACE")) is None: - raise InternalServerError("SERVICE_NAMESPACE environment variable is undefined") + raise EnvironmentError("SERVICE_NAMESPACE environment variable is undefined") if (CONTRACT_STATUS_TABLE := os.environ.get("CONTRACT_STATUS_TABLE")) is None: - raise InternalServerError("CONTRACT_STATUS_TABLE environment variable is undefined") + raise EnvironmentError("CONTRACT_STATUS_TABLE environment variable is undefined") # Initialise PowerTools logger: Logger = Logger() @@ -26,10 +24,6 @@ dynamodb = boto3.resource("dynamodb") table = dynamodb.Table(CONTRACT_STATUS_TABLE) # type: ignore -# Get current date -now = datetime.now() -current_date = now.strftime("%d/%m/%Y %H:%M:%S") - @logger.inject_lambda_context(log_event=True) # type: ignore @metrics.log_metrics(capture_cold_start_metric=True) # type: ignore diff --git a/unicorn_contracts/src/contracts_service/contract_event_handler.py b/unicorn_contracts/src/contracts_service/contract_event_handler.py index 93b6a80..2bbb447 100644 --- a/unicorn_contracts/src/contracts_service/contract_event_handler.py +++ b/unicorn_contracts/src/contracts_service/contract_event_handler.py @@ -3,14 +3,14 @@ import os import uuid -from datetime import datetime +from datetime import datetime, timezone import boto3 from boto3.dynamodb.conditions import Attr from botocore.exceptions import ClientError from aws_lambda_powertools.logging import Logger -from aws_lambda_powertools.metrics import Metrics +from aws_lambda_powertools.metrics import Metrics, MetricUnit from aws_lambda_powertools.tracing import Tracer from aws_lambda_powertools.utilities.data_classes import event_source, SQSEvent from aws_lambda_powertools.utilities.typing import LambdaContext @@ -76,7 +76,7 @@ def create_contract(event: dict) -> None: DynamoDB put Item response """ - current_date = datetime.now().strftime("%d/%m/%Y %H:%M:%S") + current_date = datetime.now(timezone.utc).isoformat() contract = { "property_id": event["property_id"], # PK "address": event["address"], @@ -105,6 +105,7 @@ def create_contract(event: dict) -> None: # Annotate trace with contract status tracer.put_annotation(key="ContractStatus", value=contract["contract_status"]) + metrics.add_metric(name="ContractCreated", unit=MetricUnit.Count, value=1) except ClientError as e: code = e.response["Error"]["Code"] @@ -147,13 +148,13 @@ def update_contract(contract: dict) -> None: try: contract["contract_status"] = ContractStatus.APPROVED.name - current_date = datetime.now().strftime("%d/%m/%Y %H:%M:%S") + current_date = datetime.now(timezone.utc).isoformat() response = table.update_item( Key={ "property_id": contract["property_id"], }, - UpdateExpression="set contract_status=:t, modified_date=:m", + UpdateExpression="set contract_status=:t, contract_last_modified_on=:m", ConditionExpression=Attr("property_id").exists() & Attr("contract_status").is_in([ContractStatus.DRAFT.name]), ExpressionAttributeValues={ diff --git a/unicorn_contracts/uv.lock b/unicorn_contracts/uv.lock index f5ee7b3..1226f38 100644 --- a/unicorn_contracts/uv.lock +++ b/unicorn_contracts/uv.lock @@ -241,16 +241,16 @@ dev = [ [package.metadata] requires-dist = [ { name = "arnparse", marker = "extra == 'dev'", specifier = ">=0.0.2" }, - { name = "aws-lambda-powertools", extras = ["all"], marker = "extra == 'dev'", specifier = ">=3.24.0" }, - { name = "aws-lambda-powertools", extras = ["tracer"], specifier = ">=3.24.0" }, + { name = "aws-lambda-powertools", extras = ["all"], marker = "extra == 'dev'", specifier = ">=3.25.0" }, + { name = "aws-lambda-powertools", extras = ["tracer"], specifier = ">=3.25.0" }, { name = "aws-xray-sdk", specifier = ">=2.15.0" }, - { name = "boto3", specifier = ">=1.42.43" }, + { name = "boto3", specifier = ">=1.42.68" }, { name = "importlib-metadata", marker = "extra == 'dev'", specifier = ">=8.7.1" }, - { name = "moto", extras = ["dynamodb", "events", "sqs"], marker = "extra == 'dev'", specifier = ">=5.1.20" }, + { name = "moto", extras = ["dynamodb", "events", "sqs"], marker = "extra == 'dev'", specifier = ">=5.1.22" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=9.0.2" }, { name = "pyyaml", marker = "extra == 'dev'", specifier = ">=6.0.3" }, { name = "requests", marker = "extra == 'dev'", specifier = ">=2.32.5" }, - { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.15.0" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.15.6" }, { name = "tomli", marker = "extra == 'dev'", specifier = ">=2.4.0" }, ] provides-extras = ["dev"] diff --git a/unicorn_web/src/publication_manager_service/publication_evaluation_event_handler.py b/unicorn_web/src/publication_manager_service/publication_evaluation_event_handler.py index 2c252bb..1b137c5 100644 --- a/unicorn_web/src/publication_manager_service/publication_evaluation_event_handler.py +++ b/unicorn_web/src/publication_manager_service/publication_evaluation_event_handler.py @@ -74,14 +74,18 @@ def publication_approved(event_detail, errors): property_id = event_detail.property_id evaluation_result = event_detail.evaluation_result + + valid_results = {"APPROVED", "DECLINED"} + if evaluation_result.upper() not in valid_results: + logger.warning(f"Unknown evaluation_result '{evaluation_result}'; skipping DynamoDB update") + return {"result": "Skipped — unknown evaluation result"} + country, city, street, number = property_id.split("/") pk_details = f"{country}#{city}".replace(" ", "-").lower() pk = f"PROPERTY#{pk_details}" sk = f"{street}#{str(number)}".replace(" ", "-").lower() - metrics.add_metric(name="PropertiesAdded", unit=MetricUnit.Count, value=1) - logger.info(f"Storing new property in DynamoDB with PK {pk} and SK {sk}") dynamodb_response = table.update_item( Key={