Commit 060e2bf8 authored by Claudia Carballo Gonzalez's avatar Claudia Carballo Gonzalez
Browse files

feat: add UTC date validation and rule timestamps to response (startsAt/updatedAt)

parent 9320d116
Loading
Loading
Loading
Loading
Loading
+96 −1
Original line number Diff line number Diff line
import uuid
from datetime import datetime, timezone
from db.db import get_mongo
from config import Config

@@ -9,15 +10,72 @@ def get_all_rules():
    rules = list(col.find({}, {"_id": 0}))
    return {"rules": rules}, 200

# def create_new_rule(body):
#     db = get_mongo()
#     col = db.get_col_by_name("visibility_rules")
    
#     # Generamos el ruleId (Server generates it, según tu comentario)
#     body['ruleId'] = str(uuid.uuid4())

#     col.insert_one(body)
#     body.pop('_id', None)
#     return body, 201

def create_new_rule(body):
    db = get_mongo()
    col = db.get_col_by_name("visibility_rules")
    
    # Generamos el ruleId (Server generates it, según tu comentario)
    # 1. Generate a unique ruleId
    body['ruleId'] = str(uuid.uuid4())
    
    # 2. Generate current timestamp in UTC ISO 8601 format with 'Z'
    now = datetime.now(timezone.utc).isoformat().replace('+00:00', 'Z')
    
    # 3. Handle and validate 'startsAt'
    if 'startsAt' not in body or not body['startsAt']:
        # If not provided, default to current time
        body['startsAt'] = now
    else:
        # If provided, validate ISO 8601 format
        try:
            datetime.fromisoformat(body['startsAt'].replace('Z', '+00:00'))
        except ValueError:
            return {
                "title": "Bad Request", 
                "detail": "Invalid startsAt format. Please use ISO 8601 (e.g., 2026-01-23T10:00:00Z)"
            }, 400

    # 4. 'updatedAt' is always set to current time during creation
    body['updatedAt'] = now

    # 5. Logic validation: endsAt must be greater than startsAt
    if 'endsAt' in body and body['endsAt']:
        try:
            # Convert strings to datetime objects for comparison
            start_dt = datetime.fromisoformat(body['startsAt'].replace('Z', '+00:00'))
            end_dt = datetime.fromisoformat(body['endsAt'].replace('Z', '+00:00'))
            
            if end_dt <= start_dt:
                return {
                    "title": "Bad Request", 
                    "detail": "Validation Error: endsAt must be later than startsAt"
                }, 400
        except ValueError:
            return {
                "title": "Bad Request", 
                "detail": "Invalid endsAt format."
            }, 400
    
    # 6. Set 'updatedBy' metadata from providerSelector
    ps = body.get('providerSelector', {})
    body['updatedBy'] = ps.get('createdByUser', 'system')

    # Save to MongoDB
    col.insert_one(body)
    
    # Remove Mongo internal ID before returning the response
    body.pop('_id', None)
    
    return body, 201

def get_rule_by_id(rule_id):
@@ -36,9 +94,46 @@ def delete_rule_by_id(rule_id):
        return None, 204
    return {"title": "Not Found", "detail": "Rule not found"}, 404

# def update_rule_patch(rule_id, body):
#     db = get_mongo()
#     col = db.get_col_by_name("visibility_rules")
#     col.update_one({"ruleId": rule_id}, {"$set": body})
#     updated_rule = col.find_one({"ruleId": rule_id}, {"_id": 0})
#     return updated_rule, 200

def update_rule_patch(rule_id, body):
    db = get_mongo()
    col = db.get_col_by_name("visibility_rules")
    
    # Fetch existing rule for comparison
    existing_rule = col.find_one({"ruleId": rule_id})
    if not existing_rule:
        return {"title": "Not Found", "detail": "Rule not found"}, 404

    # Always update 'updatedAt' timestamp
    now = datetime.now(timezone.utc).isoformat().replace('+00:00', 'Z')
    body['updatedAt'] = now
    
    # Re-validate date logic if dates are being modified
    new_start = body.get('startsAt', existing_rule.get('startsAt'))
    new_end = body.get('endsAt', existing_rule.get('endsAt'))
    
    if new_start and new_end:
        try:
            s = datetime.fromisoformat(new_start.replace('Z', '+00:00'))
            e = datetime.fromisoformat(new_end.replace('Z', '+00:00'))
            if e <= s:
                return {
                    "title": "Bad Request", 
                    "detail": "Validation Error: endsAt must be later than startsAt"
                }, 400
        except ValueError:
            return {"title": "Bad Request", "detail": "Invalid date format."}, 400

    # Update metadata if user info is provided
    if 'providerSelector' in body and 'createdByUser' in body['providerSelector']:
        body['updatedBy'] = body['providerSelector']['createdByUser']

    col.update_one({"ruleId": rule_id}, {"$set": body})
    updated_rule = col.find_one({"ruleId": rule_id}, {"_id": 0})
    return updated_rule, 200
 No newline at end of file