remove deduplication as default
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import os
|
||||
|
||||
DEDUP_WINDOW_OFFSET_DAYS = 90
|
||||
|
||||
USER_TABLE: str = os.getenv('USER_TABLE') # type: ignore
|
||||
ORDER_TABLE: str = os.getenv('ORDER_TABLE') # type: ignore
|
||||
ENROLLMENT_TABLE: str = os.getenv('ENROLLMENT_TABLE') # type: ignore
|
||||
|
||||
@@ -5,9 +5,10 @@ from enum import Enum
|
||||
from typing import NotRequired, TypedDict
|
||||
|
||||
from layercake.dateutils import now, ttl
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer
|
||||
from layercake.strutils import md5_hash
|
||||
|
||||
from config import DEDUP_WINDOW_OFFSET_DAYS
|
||||
from schemas import Enrollment
|
||||
|
||||
Org = TypedDict(
|
||||
@@ -124,33 +125,38 @@ def enroll(
|
||||
|
||||
# Prevents the user from enrolling in the same course again until
|
||||
# the deduplication window expires or is removed.
|
||||
offset_days = (
|
||||
int(deduplication_window['offset_days'])
|
||||
if deduplication_window
|
||||
else DEDUP_WINDOW_OFFSET_DAYS
|
||||
)
|
||||
ttl_ = ttl(
|
||||
start_dt=now_,
|
||||
days=course.access_period - offset_days,
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': 'LOCK',
|
||||
'sk': lock_hash,
|
||||
'enrollment_id': enrollment.id,
|
||||
'created_at': now_,
|
||||
'ttl': ttl_,
|
||||
},
|
||||
cond_expr='attribute_not_exists(sk)',
|
||||
exc_cls=DeduplicationConflictError,
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': enrollment.id,
|
||||
'sk': 'LOCK',
|
||||
'hash': lock_hash,
|
||||
'created_at': now_,
|
||||
'ttl': ttl_,
|
||||
},
|
||||
)
|
||||
|
||||
# The deduplication window can be recalculated based on user settings.
|
||||
if deduplication_window:
|
||||
offset_days = int(deduplication_window['offset_days'])
|
||||
ttl_ = ttl(
|
||||
start_dt=now_,
|
||||
days=course.access_period - offset_days,
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': 'LOCK',
|
||||
'sk': lock_hash,
|
||||
'enrollment_id': enrollment.id,
|
||||
'created_at': now_,
|
||||
'ttl': ttl_,
|
||||
},
|
||||
cond_expr='attribute_not_exists(sk)',
|
||||
exc_cls=DeduplicationConflictError,
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': enrollment.id,
|
||||
'sk': 'LOCK',
|
||||
'hash': lock_hash,
|
||||
'created_at': now_,
|
||||
'ttl': ttl_,
|
||||
},
|
||||
)
|
||||
# Deduplication window can be recalculated if needed
|
||||
transact.put(
|
||||
item={
|
||||
'id': enrollment.id,
|
||||
@@ -159,11 +165,5 @@ def enroll(
|
||||
'created_at': now_,
|
||||
},
|
||||
)
|
||||
else:
|
||||
transact.condition(
|
||||
key=KeyPair('LOCK', lock_hash),
|
||||
cond_expr='attribute_not_exists(sk)',
|
||||
exc_cls=DeduplicationConflictError,
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
@@ -92,7 +92,6 @@ def _handler(record: Course, context: dict) -> Enrollment:
|
||||
enroll(
|
||||
enrollment,
|
||||
persistence_layer=enrollment_layer,
|
||||
deduplication_window={'offset_days': 90},
|
||||
linked_entities=frozenset(
|
||||
{
|
||||
LinkedEntity(
|
||||
|
||||
@@ -3,7 +3,7 @@ from datetime import datetime, timedelta
|
||||
from typing import NotRequired, TypedDict
|
||||
|
||||
import requests
|
||||
from aws_lambda_powertools import Logger
|
||||
from aws_lambda_powertools import Logger, Tracer
|
||||
from aws_lambda_powertools.utilities.data_classes import (
|
||||
EventBridgeEvent,
|
||||
event_source,
|
||||
@@ -21,12 +21,14 @@ from config import (
|
||||
PAPERFORGE_API,
|
||||
)
|
||||
|
||||
tracer = Tracer()
|
||||
logger = Logger(__name__)
|
||||
dyn = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)
|
||||
|
||||
|
||||
@event_source(data_class=EventBridgeEvent)
|
||||
@logger.inject_lambda_context
|
||||
@tracer.capture_lambda_handler
|
||||
@event_source(data_class=EventBridgeEvent)
|
||||
def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
|
||||
new_image = event.detail['new_image']
|
||||
now_ = now()
|
||||
|
||||
@@ -23,18 +23,25 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
|
||||
new_image = event.detail['new_image']
|
||||
metadata = dyn.collection.get_items(
|
||||
TransactKey(new_image['id'])
|
||||
+ SortKey('METADATA#SUBSCRIPTION_COVERED', rename_key='subscription')
|
||||
+ SortKey(
|
||||
'METADATA#SUBSCRIPTION_COVERED',
|
||||
rename_key='subscription',
|
||||
)
|
||||
+ SortKey(
|
||||
'METADATA#DEDUPLICATION_WINDOW',
|
||||
path_spec='offset_days',
|
||||
rename_key='dedup_window_offset_days',
|
||||
)
|
||||
+ SortKey('ORG', rename_key='org'),
|
||||
+ SortKey(
|
||||
'ORG',
|
||||
rename_key='org',
|
||||
),
|
||||
flatten_top=False,
|
||||
)
|
||||
user = User.model_validate(new_image['user'])
|
||||
course = Course.model_validate(new_image['course'])
|
||||
subscription = metadata['subscription'] if 'subscription' in metadata else None
|
||||
offset_days = metadata.get('dedup_window_offset_days', None)
|
||||
enrollment = Enrollment(
|
||||
id=uuid4(),
|
||||
course=course,
|
||||
@@ -45,9 +52,7 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
|
||||
enrollment,
|
||||
org=metadata.get('org', None),
|
||||
subscription=subscription,
|
||||
deduplication_window={
|
||||
'offset_days': metadata['dedup_window_offset_days'],
|
||||
},
|
||||
deduplication_window={'offset_days': offset_days} if offset_days else None,
|
||||
linked_entities=frozenset(
|
||||
{
|
||||
LinkedEntity(
|
||||
|
||||
@@ -31,12 +31,12 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool | No
|
||||
)
|
||||
|
||||
target_month = expires_at.strftime('%Y-%m')
|
||||
now_ = now()
|
||||
pk = f'CERT#REPORTING#ORG#{org_id}'
|
||||
now_ = now(tz)
|
||||
pk = f'CERT_REPORTING#ORG#{org_id}'
|
||||
|
||||
try:
|
||||
if now_ > expires_at:
|
||||
raise InvalidDateError()
|
||||
raise InvalidDateError('Invalid date')
|
||||
|
||||
# The reporting month is the month before the certificate expires
|
||||
report_month = (expires_at.replace(day=1) - timedelta(days=1)).replace(day=1)
|
||||
@@ -52,7 +52,7 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool | No
|
||||
'created_at': now_,
|
||||
},
|
||||
cond_expr='attribute_not_exists(sk)',
|
||||
exc_cls=ReportingConflictError,
|
||||
exc_cls=ReportExistsError,
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
@@ -64,7 +64,7 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool | No
|
||||
},
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.exception(exc)
|
||||
logger.info(exc)
|
||||
|
||||
try:
|
||||
dyn.put_item(
|
||||
@@ -89,4 +89,6 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool | No
|
||||
class InvalidDateError(Exception): ...
|
||||
|
||||
|
||||
class ReportingConflictError(Exception): ...
|
||||
class ReportExistsError(Exception):
|
||||
def __init__(self, *args: object) -> None:
|
||||
super().__init__('Report already exists')
|
||||
|
||||
@@ -49,7 +49,7 @@ user_layer = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client)
|
||||
@logger.inject_lambda_context
|
||||
def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
|
||||
old_image = event.detail['old_image']
|
||||
# Key pattern `CERT#REPORTING#ORG#{org_id}`
|
||||
# Key pattern `CERT_REPORTING#ORG#{org_id}`
|
||||
*_, org_id = old_image['id'].split('#')
|
||||
# Key pattern `MONTH#{month}#SCHEDULE#SEND_REPORT_EMAIL`
|
||||
_, month, *_ = old_image['sk'].split('#')
|
||||
|
||||
Reference in New Issue
Block a user