Skip to content

domain.enums.audit_action

src.domain.enums.audit_action

Audit action types for compliance tracking.

This enum defines all auditable actions in the system for PCI-DSS, SOC 2, and GDPR compliance. Actions are organized by category for clarity and maintainability.

Architectural Decision

Following centralized enum pattern (see docs/architecture/directory-structure.md). All domain enums live in src/domain/enums/ for discoverability.

Extensibility

New actions can be added to enum without database schema changes. Action-specific context is stored in JSONB metadata field.

Categories
  • Authentication: USER_* actions (login, logout, registration, etc.)
  • Authorization: ACCESS_* and permission-related actions
  • Data Operations: DATA_* actions (viewed, exported, deleted, modified)
  • Administrative: ADMIN_* actions (user management, config changes)
  • Provider: PROVIDER_* actions (connections, token refresh, data sync)
Usage

from src.domain.enums import AuditAction

Record audit event

await audit.record( action=AuditAction.USER_LOGIN, user_id=user_id, resource_type="session", context={"method": "password", "mfa": True}, )

Classes

AuditAction

Bases: str, Enum

Audit action types for compliance tracking.

This enum defines all auditable security and data access events in the system. Organized by category for clarity. Add new actions as needed without database schema changes (action-specific context goes in JSONB metadata).

String Enum

Inherits from str for easy serialization and database storage. Values are snake_case strings for consistency.

Categories

Authentication: Login, logout, registration, password changes Authorization: Access control, permissions, roles Data Operations: View, export, delete, modify operations Administrative: System administration and configuration Provider: Financial provider integration events

Compliance

PCI-DSS: Authentication events, cardholder data access SOC 2: Security event tracking, access control GDPR: Personal data access, consent changes, data deletion

Source code in src/domain/enums/audit_action.py
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
class AuditAction(str, Enum):
    """Audit action types for compliance tracking.

    This enum defines all auditable security and data access events in the system.
    Organized by category for clarity. Add new actions as needed without database
    schema changes (action-specific context goes in JSONB metadata).

    String Enum:
        Inherits from str for easy serialization and database storage.
        Values are snake_case strings for consistency.

    Categories:
        Authentication: Login, logout, registration, password changes
        Authorization: Access control, permissions, roles
        Data Operations: View, export, delete, modify operations
        Administrative: System administration and configuration
        Provider: Financial provider integration events

    Compliance:
        PCI-DSS: Authentication events, cardholder data access
        SOC 2: Security event tracking, access control
        GDPR: Personal data access, consent changes, data deletion
    """

    # =========================================================================
    # Authentication Events (PCI-DSS Required)
    # =========================================================================
    # Pattern: ATTEMPTED → (FAILED | SUCCESS)
    # All authentication actions follow attempt/outcome pattern for compliance

    # Login Events
    USER_LOGIN_ATTEMPTED = "user_login_attempted"
    """User attempted to log in.

    Context should include:
        - email: Email address used (for correlation)
        - method: Authentication method attempted (password, oauth, mfa)
    """

    USER_LOGIN_FAILED = "user_login_failed"
    """Failed login attempt (security event).

    Context should include:
        - reason: Why login failed (invalid_password, user_not_found, etc.)
        - attempts: Number of consecutive failed attempts
        - email: Email address attempted
    """

    USER_LOGIN_SUCCESS = "user_login_success"
    """User successfully authenticated.

    Context should include:
        - method: Authentication method (password, oauth, mfa)
        - mfa: Whether MFA was used (boolean)
        - remember_me: Whether "remember me" was selected
    """

    USER_LOGOUT_ATTEMPTED = "user_logout_attempted"
    """User attempted to log out.

    Context should include:
        - session_id: Session being logged out
    """

    USER_LOGOUT = "user_logout"
    """User logged out successfully (SUCCESS).

    Context should include:
        - session_id: Session that was logged out
        - logout_method: How logged out (explicit, timeout, revoked)
    """

    USER_LOGOUT_FAILED = "user_logout_failed"
    """User logout failed (rare - session cleanup failure).

    Context should include:
        - reason: Why logout failed (session_not_found, cleanup_error)
        - session_id: Session attempted to logout
    """

    # Registration Events
    USER_REGISTRATION_ATTEMPTED = "user_registration_attempted"
    """User attempted to register.

    Context should include:
        - email: Email address used
        - registration_method: How user attempted to register (email, oauth, invite)
    """

    USER_REGISTRATION_FAILED = "user_registration_failed"
    """User registration failed.

    Context should include:
        - email: Email address attempted
        - reason: Why registration failed (duplicate_email, weak_password, validation_error)
    """

    USER_REGISTERED = "user_registered"
    """New user account created (SUCCESS).

    Context should include:
        - registration_method: How user registered (email, oauth, invite)
        - email_verified: Whether email was verified during registration
    """

    # Password Change Events
    USER_PASSWORD_CHANGE_ATTEMPTED = "user_password_change_attempted"
    """User attempted to change password.

    Context should include:
        - initiated_by: Who initiated change (user, admin, system)
    """

    USER_PASSWORD_CHANGE_FAILED = "user_password_change_failed"
    """Password change failed.

    Context should include:
        - reason: Why failed (wrong_current_password, weak_new_password, etc.)
        - initiated_by: Who attempted change
    """

    USER_PASSWORD_CHANGED = "user_password_changed"
    """User password was changed (SUCCESS).

    Context should include:
        - initiated_by: Who initiated change (user, admin, system)
        - method: How changed (self_service, admin_reset, forced_reset)
    """

    # Password Reset Events
    PASSWORD_RESET_REQUEST_ATTEMPTED = "password_reset_request_attempted"
    """User attempted to request password reset.

    Context should include:
        - email: Email address for reset request
    """

    USER_PASSWORD_RESET_REQUESTED = "user_password_reset_requested"
    """User successfully requested password reset (SUCCESS).

    Context should include:
        - method: How requested (email_link, security_questions)
        - email: Email address for reset
    """

    PASSWORD_RESET_CONFIRM_ATTEMPTED = "password_reset_confirm_attempted"
    """User attempted to confirm password reset with token.

    Context should include:
        - token: Reset token attempted (truncated for security)
    """

    USER_PASSWORD_RESET_FAILED = "user_password_reset_failed"
    """Password reset confirmation failed.

    Context should include:
        - reason: Why failed (invalid_token, expired_link, weak_password)
    """

    PASSWORD_RESET_CONFIRM_FAILED = "password_reset_confirm_failed"
    """Password reset confirmation failed (alias for clarity).

    Context should include:
        - reason: Why failed (invalid_token, expired_link, weak_password)
        - token: Reset token attempted (truncated)
    """

    USER_PASSWORD_RESET_COMPLETED = "user_password_reset_completed"
    """Password reset was completed successfully (SUCCESS)."""

    # Auth Token Refresh Events (JWT Rotation)
    AUTH_TOKEN_REFRESH_ATTEMPTED = "auth_token_refresh_attempted"
    """Auth token refresh attempted.

    Context should include:
        - user_id: User requesting refresh (if known from token)
    """

    AUTH_TOKEN_REFRESH_FAILED = "auth_token_refresh_failed"
    """Auth token refresh failed.

    Context should include:
        - reason: Why failed (token_expired, token_revoked, token_invalid, user_not_found)
        - user_id: User requesting refresh (if known)
    """

    AUTH_TOKEN_REFRESHED = "auth_token_refreshed"
    """Auth token was refreshed (SUCCESS - JWT rotation completed).

    Context should include:
        - session_id: Session associated with token
    """

    # Token Version Validation (Security Monitoring)
    TOKEN_REJECTED_VERSION_MISMATCH = "token_rejected_version_mismatch"
    """Token rejected due to version mismatch (security monitoring event).

    Emitted during token refresh when version check fails due to
    global token rotation or per-user token rotation.

    Context should include:
        - token_version: Version of the rejected token
        - required_version: Minimum version required
        - rejection_reason: Why token was rejected (global_rotation, user_rotation)
        - user_id: User whose token was rejected (if known)
    """

    # Global Token Rotation Events (Security - Emergency Token Invalidation)
    GLOBAL_TOKEN_ROTATION_ATTEMPTED = "global_token_rotation_attempted"
    """Global token rotation attempt initiated (all tokens).

    Context should include:
        - triggered_by: Who triggered rotation (admin ID or "system")
        - reason: Why rotation triggered (security_breach, scheduled, manual)
    """

    GLOBAL_TOKEN_ROTATION_SUCCEEDED = "global_token_rotation_succeeded"
    """Global token rotation completed successfully (SUCCESS).

    Context should include:
        - triggered_by: Who triggered rotation
        - previous_version: Previous global minimum token version
        - new_version: New global minimum token version
        - reason: Why rotation was triggered
        - grace_period_seconds: Grace period before full enforcement
    """

    GLOBAL_TOKEN_ROTATION_FAILED = "global_token_rotation_failed"
    """Global token rotation failed.

    Context should include:
        - triggered_by: Who triggered rotation
        - reason: Original reason for rotation attempt
        - failure_reason: Why rotation failed (e.g., "config_not_found")
    """

    # User Token Rotation Events (Security - Per-User Token Invalidation)
    USER_TOKEN_ROTATION_ATTEMPTED = "user_token_rotation_attempted"
    """Per-user token rotation attempt initiated.

    Context should include:
        - user_id: User whose tokens are being rotated
        - triggered_by: Who triggered rotation (user_id, admin_id, or "system")
        - reason: Why rotation triggered (password_change, suspicious_activity, manual)
    """

    USER_TOKEN_ROTATION_SUCCEEDED = "user_token_rotation_succeeded"
    """Per-user token rotation completed successfully (SUCCESS).

    Context should include:
        - user_id: User whose tokens were rotated
        - triggered_by: Who triggered rotation
        - previous_version: Previous user minimum token version
        - new_version: New user minimum token version
        - reason: Why rotation was triggered
    """

    USER_TOKEN_ROTATION_FAILED = "user_token_rotation_failed"
    """Per-user token rotation failed.

    Context should include:
        - user_id: User whose tokens were being rotated
        - triggered_by: Who triggered rotation
        - reason: Original reason for rotation attempt
        - failure_reason: Why rotation failed (e.g., "user_not_found")
    """

    # Email Verification Events
    USER_EMAIL_VERIFICATION_ATTEMPTED = "user_email_verification_attempted"
    """User attempted to verify email.

    Context should include:
        - email: Email address being verified
    """

    USER_EMAIL_VERIFICATION_FAILED = "user_email_verification_failed"
    """Email verification failed.

    Context should include:
        - reason: Why failed (invalid_token, expired_token, already_verified)
    """

    USER_EMAIL_VERIFIED = "user_email_verified"
    """User email address was verified (SUCCESS)."""

    # MFA Enable Events
    USER_MFA_ENABLE_ATTEMPTED = "user_mfa_enable_attempted"
    """User attempted to enable MFA.

    Context should include:
        - mfa_method: Type of MFA attempted (totp, sms, email)
    """

    USER_MFA_ENABLE_FAILED = "user_mfa_enable_failed"
    """MFA enable failed.

    Context should include:
        - reason: Why failed (invalid_code, setup_timeout, already_enabled)
        - mfa_method: Type of MFA attempted
    """

    USER_MFA_ENABLED = "user_mfa_enabled"
    """Multi-factor authentication was enabled (SUCCESS).

    Context should include:
        - mfa_method: Type of MFA (totp, sms, email)
    """

    # MFA Disable Events
    USER_MFA_DISABLE_ATTEMPTED = "user_mfa_disable_attempted"
    """User attempted to disable MFA.

    Context should include:
        - initiated_by: Who attempted to disable (user, admin)
    """

    USER_MFA_DISABLE_FAILED = "user_mfa_disable_failed"
    """MFA disable failed.

    Context should include:
        - reason: Why failed (wrong_password, security_check_failed)
        - initiated_by: Who attempted
    """

    USER_MFA_DISABLED = "user_mfa_disabled"
    """Multi-factor authentication was disabled (SUCCESS).

    Context should include:
        - initiated_by: Who disabled MFA (user, admin)
        - reason: Why disabled (lost_device, user_request, etc.)
    """

    # =========================================================================
    # Authorization Events (SOC 2 Required)
    # =========================================================================
    # Pattern: ATTEMPTED → (DENIED | GRANTED)

    # Access Control Events
    ACCESS_ATTEMPTED = "access_attempted"
    """User attempted to access resource.

    Context should include:
        - resource: What was attempted
        - action: What action was attempted (read, write, delete)
    """

    ACCESS_DENIED = "access_denied"
    """Access to resource was denied (security event).

    Context should include:
        - resource: What was attempted
        - reason: Why denied (no_permission, suspended_account, etc.)
        - action: What action was attempted
    """

    ACCESS_GRANTED = "access_granted"
    """Access to resource was granted (SUCCESS).

    Context should include:
        - resource: What was accessed
        - permission_level: Access level granted (read, write, admin)
        - action: What action was granted
    """

    # Permission Change Events
    PERMISSION_CHANGE_ATTEMPTED = "permission_change_attempted"
    """Attempted to change user permissions.

    Context should include:
        - changed_by: Who attempted change
        - target_user_id: User whose permissions would change
        - requested_permissions: New permission set requested
    """

    PERMISSION_CHANGE_FAILED = "permission_change_failed"
    """Permission change failed.

    Context should include:
        - reason: Why failed (insufficient_privileges, invalid_permission)
        - changed_by: Who attempted change
    """

    PERMISSION_CHANGED = "permission_changed"
    """User permissions were modified (SUCCESS).

    Context should include:
        - changed_by: Who modified permissions
        - old_permissions: Previous permission set
        - new_permissions: New permission set
    """

    # Role Assignment Events
    ROLE_ASSIGNMENT_ATTEMPTED = "role_assignment_attempted"
    """Attempted to assign role to user.

    Context should include:
        - role_name: Name of role to assign
        - assigned_by: Who attempted assignment
        - target_user_id: User to receive role
    """

    ROLE_ASSIGNMENT_FAILED = "role_assignment_failed"
    """Role assignment failed.

    Context should include:
        - reason: Why failed (invalid_role, no_permission, already_assigned)
        - role_name: Name of role attempted
    """

    ROLE_ASSIGNED = "role_assigned"
    """Role was assigned to user (SUCCESS).

    Context should include:
        - role_name: Name of role assigned
        - assigned_by: Who assigned the role
    """

    # Role Revocation Events
    ROLE_REVOCATION_ATTEMPTED = "role_revocation_attempted"
    """Attempted to revoke role from user.

    Context should include:
        - role_name: Name of role to revoke
        - revoked_by: Who attempted revocation
        - target_user_id: User to lose role
    """

    ROLE_REVOCATION_FAILED = "role_revocation_failed"
    """Role revocation failed.

    Context should include:
        - reason: Why failed (last_admin_role, no_permission)
        - role_name: Name of role attempted
    """

    ROLE_REVOKED = "role_revoked"
    """Role was revoked from user (SUCCESS).

    Context should include:
        - role_name: Name of role revoked
        - revoked_by: Who revoked the role
        - reason: Why revoked
    """

    # =========================================================================
    # Data Access Events (GDPR Required)
    # =========================================================================
    # Pattern: Use ACCESS_ATTEMPTED/DENIED/GRANTED for view operations
    # Use ATTEMPTED → (FAILED | SUCCESS) for modify operations

    DATA_VIEWED = "data_viewed"
    """Personal or sensitive data was viewed (SUCCESS).

    Note: Use ACCESS_ATTEMPTED → ACCESS_DENIED/GRANTED for access control.
    This event records successful data access after permission check.

    Context should include:
        - data_type: Type of data viewed (profile, financial, etc.)
        - fields_accessed: Specific fields viewed
    """

    # Data Export Events
    DATA_EXPORT_ATTEMPTED = "data_export_attempted"
    """User attempted to export data.

    Context should include:
        - export_format: Requested format (json, csv, pdf)
        - data_scope: What data was requested
    """

    DATA_EXPORT_FAILED = "data_export_failed"
    """Data export failed.

    Context should include:
        - reason: Why failed (too_large, timeout, permission_denied)
        - export_format: Requested format
    """

    DATA_EXPORTED = "data_exported"
    """Data was exported (SUCCESS - GDPR right to data portability).

    Context should include:
        - export_format: Format of export (json, csv, pdf)
        - data_scope: What data was exported
        - export_reason: Why exported (user_request, backup, etc.)
        - file_size: Size of export file
    """

    # Data Deletion Events
    DATA_DELETION_ATTEMPTED = "data_deletion_attempted"
    """Attempted to delete data.

    Context should include:
        - deletion_type: Type requested (soft, hard, anonymization)
        - data_scope: What data deletion was requested
        - requested_by: Who requested deletion
    """

    DATA_DELETION_FAILED = "data_deletion_failed"
    """Data deletion failed.

    Context should include:
        - reason: Why failed (in_use, constraint_violation, insufficient_permission)
        - data_scope: What data deletion was attempted
    """

    DATA_DELETED = "data_deleted"
    """Data was deleted (SUCCESS - GDPR right to be forgotten).

    Context should include:
        - deletion_type: Type of deletion (soft, hard, anonymization)
        - data_scope: What data was deleted
        - requested_by: Who requested deletion
    """

    # Data Modification Events
    DATA_MODIFICATION_ATTEMPTED = "data_modification_attempted"
    """Attempted to modify data.

    Context should include:
        - fields_to_change: Which fields modification was attempted
        - change_reason: Why modification was attempted
    """

    DATA_MODIFICATION_FAILED = "data_modification_failed"
    """Data modification failed.

    Context should include:
        - reason: Why failed (validation_error, constraint_violation, permission_denied)
        - fields_attempted: Which fields were attempted
    """

    DATA_MODIFIED = "data_modified"
    """Personal or sensitive data was modified (SUCCESS).

    Context should include:
        - fields_changed: Which fields were modified
        - change_reason: Why data was modified
        - old_values: Previous values (if appropriate)
        - new_values: New values
    """

    # =========================================================================
    # Administrative Events (SOC 2 Required)
    # =========================================================================
    # Pattern: ATTEMPTED → (FAILED | SUCCESS)

    # Admin User Creation Events
    ADMIN_USER_CREATION_ATTEMPTED = "admin_user_creation_attempted"
    """Administrator attempted to create user account.

    Context should include:
        - created_by: Admin attempting creation
        - email: Email for new user
        - initial_role: Role to be assigned
    """

    ADMIN_USER_CREATION_FAILED = "admin_user_creation_failed"
    """Admin user creation failed.

    Context should include:
        - reason: Why failed (duplicate_email, validation_error, permission_denied)
        - created_by: Admin who attempted
    """

    ADMIN_USER_CREATED = "admin_user_created"
    """Administrator created a new user account (SUCCESS).

    Context should include:
        - created_by: Admin who created account
        - initial_role: Role assigned to new user
        - user_email: Email of created user
    """

    # Admin User Deletion Events
    ADMIN_USER_DELETION_ATTEMPTED = "admin_user_deletion_attempted"
    """Administrator attempted to delete user account.

    Context should include:
        - deleted_by: Admin attempting deletion
        - target_user_id: User to be deleted
        - reason: Why deletion was attempted
    """

    ADMIN_USER_DELETION_FAILED = "admin_user_deletion_failed"
    """Admin user deletion failed.

    Context should include:
        - reason: Why failed (in_use, constraint_violation, permission_denied)
        - deleted_by: Admin who attempted
    """

    ADMIN_USER_DELETED = "admin_user_deleted"
    """Administrator deleted a user account (SUCCESS).

    Context should include:
        - deleted_by: Admin who deleted account
        - reason: Why account was deleted
        - user_email: Email of deleted user
    """

    # Admin User Suspension Events
    ADMIN_USER_SUSPENSION_ATTEMPTED = "admin_user_suspension_attempted"
    """Administrator attempted to suspend user account.

    Context should include:
        - suspended_by: Admin attempting suspension
        - target_user_id: User to be suspended
        - reason: Why suspension was attempted
        - duration: Requested suspension duration
    """

    ADMIN_USER_SUSPENSION_FAILED = "admin_user_suspension_failed"
    """Admin user suspension failed.

    Context should include:
        - reason: Why failed (already_suspended, permission_denied, cannot_suspend_admin)
        - suspended_by: Admin who attempted
    """

    ADMIN_USER_SUSPENDED = "admin_user_suspended"
    """Administrator suspended a user account (SUCCESS).

    Context should include:
        - suspended_by: Admin who suspended account
        - reason: Why account was suspended
        - duration: Suspension duration (if temporary)
    """

    # Admin Config Change Events
    ADMIN_CONFIG_CHANGE_ATTEMPTED = "admin_config_change_attempted"
    """Administrator attempted to change system configuration.

    Context should include:
        - config_key: What configuration change was attempted
        - requested_value: New value requested
        - changed_by: Admin attempting change
    """

    ADMIN_CONFIG_CHANGE_FAILED = "admin_config_change_failed"
    """Admin config change failed.

    Context should include:
        - reason: Why failed (invalid_value, locked_config, permission_denied)
        - config_key: What configuration was attempted
        - changed_by: Admin who attempted
    """

    ADMIN_CONFIG_CHANGED = "admin_config_changed"
    """System configuration was changed by administrator (SUCCESS).

    Context should include:
        - config_key: What configuration was changed
        - old_value: Previous value
        - new_value: New value
        - changed_by: Admin who made change
    """

    ADMIN_BACKUP_CREATED = "admin_backup_created"
    """System backup was created.

    Note: This is a completed system event (no ATTEMPT needed).

    Context should include:
        - backup_type: Type of backup (full, incremental, differential)
        - backup_location: Where backup was stored
        - backup_size: Size of backup
        - initiated_by: Who initiated backup (system, admin)
    """

    # =========================================================================
    # Provider Events (PCI-DSS Required - Cardholder Data Access)
    # =========================================================================
    # Pattern: ATTEMPTED → (FAILED | SUCCESS)

    # Provider Connection Events
    PROVIDER_CONNECTION_ATTEMPTED = "provider_connection_attempted"
    """User attempted to connect financial provider.

    Context should include:
        - provider_name: Name of provider (schwab, chase, etc.)
        - connection_method: Method attempted (oauth, api_key, etc.)
    """

    PROVIDER_CONNECTION_FAILED = "provider_connection_failed"
    """Provider connection failed.

    Context should include:
        - provider_name: Name of provider
        - reason: Why failed (oauth_error, api_error, invalid_credentials)
        - error_code: Provider-specific error code
    """

    PROVIDER_CONNECTED = "provider_connected"
    """Financial provider was connected to user account (SUCCESS).

    Context should include:
        - provider_name: Name of provider (schwab, chase, etc.)
        - connection_method: How connected (oauth, api_key, etc.)
    """

    # Provider Disconnection Events
    PROVIDER_DISCONNECTION_ATTEMPTED = "provider_disconnection_attempted"
    """User attempted to disconnect financial provider.

    Context should include:
        - provider_name: Name of provider
        - disconnection_reason: Why disconnection requested
    """

    PROVIDER_DISCONNECTION_FAILED = "provider_disconnection_failed"
    """Provider disconnection failed.

    Context should include:
        - provider_name: Name of provider
        - reason: Why failed (api_error, pending_transactions)
    """

    PROVIDER_DISCONNECTED = "provider_disconnected"
    """Financial provider was disconnected from user account (SUCCESS).

    Context should include:
        - provider_name: Name of provider
        - disconnection_reason: Why disconnected (user_request, error, etc.)
    """

    # Provider Token Refresh Events
    PROVIDER_TOKEN_REFRESH_ATTEMPTED = "provider_token_refresh_attempted"
    """Attempted to refresh provider access token.

    Context should include:
        - provider_name: Name of provider
        - token_type: Type of token to refresh (access, refresh)
    """

    PROVIDER_TOKEN_REFRESH_FAILED = "provider_token_refresh_failed"
    """Provider token refresh failed (security event).

    Context should include:
        - provider_name: Name of provider
        - error_code: Provider error code
        - error_message: Error description
    """

    PROVIDER_TOKEN_REFRESHED = "provider_token_refreshed"
    """Provider access token was refreshed (SUCCESS).

    Context should include:
        - provider_name: Name of provider
        - token_type: Type of token refreshed (access, refresh)
    """

    # Provider Data Sync Events
    PROVIDER_DATA_SYNC_ATTEMPTED = "provider_data_sync_attempted"
    """Attempted to sync data from financial provider.

    Context should include:
        - provider_name: Name of provider
        - data_types: Types of data to sync (accounts, transactions)
    """

    PROVIDER_DATA_SYNC_FAILED = "provider_data_sync_failed"
    """Provider data sync failed.

    Context should include:
        - provider_name: Name of provider
        - reason: Why failed (api_error, network_error, rate_limit)
        - error_code: Provider error code
    """

    PROVIDER_DATA_SYNCED = "provider_data_synced"
    """Data was synced from financial provider (SUCCESS).

    Context should include:
        - provider_name: Name of provider
        - data_types: Types of data synced (accounts, transactions)
        - records_synced: Number of records synced
    """

    # Provider Data Access Events
    PROVIDER_ACCOUNT_VIEWED = "provider_account_viewed"
    """Financial account data was viewed (SUCCESS - PCI-DSS: cardholder data access).

    Note: Use ACCESS_ATTEMPTED → ACCESS_DENIED/GRANTED for access control.
    This event records successful data access after permission check.

    Context should include:
        - provider_name: Name of provider
        - account_type: Type of account (checking, credit_card, etc.)
        - account_mask: Last 4 digits of account number
    """

    PROVIDER_TRANSACTION_VIEWED = "provider_transaction_viewed"
    """Financial transaction data was viewed (SUCCESS - PCI-DSS: cardholder data access).

    Note: Use ACCESS_ATTEMPTED → ACCESS_DENIED/GRANTED for access control.
    This event records successful data access after permission check.

    Context should include:
        - provider_name: Name of provider
        - account_mask: Last 4 digits of account number
        - transaction_count: Number of transactions viewed
        - date_range: Date range of transactions
    """

    # =========================================================================
    # Session Management Events (Security - Session Lifecycle)
    # =========================================================================
    # Pattern: ATTEMPTED → (SUCCEEDED | FAILED) for 3-state compliance

    SESSION_REVOCATION_ATTEMPTED = "session_revocation_attempted"
    """Session revocation attempt initiated.

    Context should include:
        - session_id: Session being revoked
        - revoked_by: Who attempted revocation (user, admin, system)
        - reason: Why revocation requested
    """

    SESSION_REVOKED = "session_revoked"
    """User session was revoked successfully (SUCCESS).

    Context should include:
        - session_id: Session that was revoked
        - revoked_by: Who/what revoked session (user, admin, system)
        - reason: Why revoked (logout, timeout, security, admin_action)
    """

    SESSION_REVOCATION_FAILED = "session_revocation_failed"
    """Session revocation failed.

    Context should include:
        - session_id: Session that failed to revoke
        - reason: Original reason for revocation
        - failure_reason: Why revocation failed (not_found, not_owner, already_revoked)
    """

    SESSION_EVICTED = "session_evicted"
    """Session was evicted due to limit exceeded (security policy).

    Context should include:
        - session_id: Session that was evicted
        - eviction_reason: Why evicted (limit_exceeded, oldest_session)
        - active_sessions_count: Number of active sessions after eviction
    """

    ALL_SESSIONS_REVOCATION_ATTEMPTED = "all_sessions_revocation_attempted"
    """All sessions revocation attempt initiated.

    Context should include:
        - revoked_by: Who attempted revocation (user, admin, system)
        - reason: Why revocation requested (password_change, security_breach, user_request)
        - except_session_id: Session to exclude from revocation (if any)
    """

    ALL_SESSIONS_REVOKED = "all_sessions_revoked"
    """All user sessions were revoked successfully (SUCCESS).

    Context should include:
        - revoked_by: Who/what revoked all sessions (user, admin, system)
        - reason: Why revoked (password_change, security_breach, user_request)
        - sessions_revoked_count: Number of sessions revoked
    """

    ALL_SESSIONS_REVOCATION_FAILED = "all_sessions_revocation_failed"
    """All sessions revocation failed.

    Context should include:
        - reason: Original reason for revocation
        - failure_reason: Why revocation failed
    """

    SESSION_PROVIDER_ACCESS = "session_provider_access"
    """Session accessed provider data (audit trail for data access).

    Context should include:
        - session_id: Session that accessed provider
        - provider_name: Provider accessed
        - access_type: Type of access (read, sync, update)
    """

    SUSPICIOUS_SESSION_ACTIVITY = "suspicious_session_activity"
    """Suspicious activity detected in session (security alert).

    Context should include:
        - session_id: Session with suspicious activity
        - activity_type: Type of suspicious activity
        - risk_score: Risk assessment score
        - detection_reason: Why flagged as suspicious
    """

    # =========================================================================
    # Data Sync Events (F7.7 Phase 3 - PCI-DSS: Cardholder Data Access)
    # =========================================================================
    # Pattern: ATTEMPTED → (SUCCEEDED | FAILED)
    # Data sync operations with financial providers

    # Account Sync Events
    ACCOUNT_SYNC_ATTEMPTED = "account_sync_attempted"
    """Attempted to sync account data from provider.

    Context should include:
        - connection_id: Provider connection
        - provider_name: Name of provider
    """

    ACCOUNT_SYNC_SUCCEEDED = "account_sync_succeeded"
    """Account data synced successfully (SUCCESS).

    Context should include:
        - connection_id: Provider connection
        - provider_name: Name of provider
        - account_count: Number of accounts synced
    """

    ACCOUNT_SYNC_FAILED = "account_sync_failed"
    """Account data sync failed.

    Context should include:
        - connection_id: Provider connection
        - provider_name: Name of provider
        - reason: Why failed (api_error, auth_failed, network_error)
    """

    # Transaction Sync Events
    TRANSACTION_SYNC_ATTEMPTED = "transaction_sync_attempted"
    """Attempted to sync transaction data from provider.

    Context should include:
        - connection_id: Provider connection
        - provider_name: Name of provider
        - account_id: Specific account if targeted sync
    """

    TRANSACTION_SYNC_SUCCEEDED = "transaction_sync_succeeded"
    """Transaction data synced successfully (SUCCESS - PCI-DSS: cardholder data).

    Context should include:
        - connection_id: Provider connection
        - provider_name: Name of provider
        - account_id: Specific account if targeted sync
        - transaction_count: Number of transactions synced
    """

    TRANSACTION_SYNC_FAILED = "transaction_sync_failed"
    """Transaction data sync failed.

    Context should include:
        - connection_id: Provider connection
        - provider_name: Name of provider
        - account_id: Specific account if targeted sync
        - reason: Why failed (api_error, date_range_invalid, network_error)
    """

    # Holdings Sync Events
    HOLDINGS_SYNC_ATTEMPTED = "holdings_sync_attempted"
    """Attempted to sync holdings (positions) from provider.

    Context should include:
        - account_id: Account to sync holdings for
        - provider_name: Name of provider
    """

    HOLDINGS_SYNC_SUCCEEDED = "holdings_sync_succeeded"
    """Holdings data synced successfully (SUCCESS).

    Context should include:
        - account_id: Account synced
        - provider_name: Name of provider
        - holding_count: Number of holdings synced
    """

    HOLDINGS_SYNC_FAILED = "holdings_sync_failed"
    """Holdings data sync failed.

    Context should include:
        - account_id: Account attempted
        - provider_name: Name of provider
        - reason: Why failed (api_error, holdings_not_supported, network_error)
    """

    # File Import Events
    FILE_IMPORT_ATTEMPTED = "file_import_attempted"
    """Attempted to import financial data from file.

    Context should include:
        - provider_slug: Provider identifier
        - file_name: Original filename
        - file_format: File format (qfx, ofx, csv)
    """

    FILE_IMPORT_SUCCEEDED = "file_import_succeeded"
    """File import completed successfully (SUCCESS).

    Context should include:
        - provider_slug: Provider identifier
        - file_name: Original filename
        - file_format: File format
        - account_count: Accounts created/updated
        - transaction_count: Transactions imported
    """

    FILE_IMPORT_FAILED = "file_import_failed"
    """File import failed.

    Context should include:
        - provider_slug: Provider identifier
        - file_name: Original filename
        - file_format: File format
        - reason: Why failed (parse_error, unsupported_format, invalid_structure)
    """

    # =========================================================================
    # Rate Limit Events (Security - Abuse Prevention)
    # =========================================================================
    # Pattern: ATTEMPTED → (ALLOWED | DENIED)
    # These events track rate limit enforcement for security monitoring.

    RATE_LIMIT_CHECK_ATTEMPTED = "rate_limit_check_attempted"
    """Rate limit check was initiated.

    Context should include:
        - endpoint: Endpoint being rate limited
        - identifier: Rate limit identifier (IP, user_id)
        - scope: Rate limit scope (ip, user, user_provider, global)
        - cost: Token cost for operation
    """

    RATE_LIMIT_CHECK_ALLOWED = "rate_limit_check_allowed"
    """Request was allowed by rate limiter (SUCCESS).

    Context should include:
        - endpoint: Endpoint accessed
        - identifier: Rate limit identifier
        - scope: Rate limit scope
        - remaining_tokens: Tokens remaining in bucket
        - execution_time_ms: Rate limit check duration
    """

    RATE_LIMIT_CHECK_DENIED = "rate_limit_check_denied"
    """Request was denied by rate limiter (security event).

    Context should include:
        - endpoint: Endpoint that was rate limited
        - identifier: Rate limit identifier (IP, user_id)
        - scope: Rate limit scope (ip, user, user_provider, global)
        - retry_after: Seconds until retry allowed
        - limit: Maximum tokens (bucket capacity)
        - remaining: Current tokens (should be 0)
    """
Attributes
USER_LOGIN_ATTEMPTED class-attribute instance-attribute
USER_LOGIN_ATTEMPTED = 'user_login_attempted'

User attempted to log in.

Context should include
  • email: Email address used (for correlation)
  • method: Authentication method attempted (password, oauth, mfa)
USER_LOGIN_FAILED class-attribute instance-attribute
USER_LOGIN_FAILED = 'user_login_failed'

Failed login attempt (security event).

Context should include
  • reason: Why login failed (invalid_password, user_not_found, etc.)
  • attempts: Number of consecutive failed attempts
  • email: Email address attempted
USER_LOGIN_SUCCESS class-attribute instance-attribute
USER_LOGIN_SUCCESS = 'user_login_success'

User successfully authenticated.

Context should include
  • method: Authentication method (password, oauth, mfa)
  • mfa: Whether MFA was used (boolean)
  • remember_me: Whether "remember me" was selected
USER_LOGOUT_ATTEMPTED class-attribute instance-attribute
USER_LOGOUT_ATTEMPTED = 'user_logout_attempted'

User attempted to log out.

Context should include
  • session_id: Session being logged out
USER_LOGOUT class-attribute instance-attribute
USER_LOGOUT = 'user_logout'

User logged out successfully (SUCCESS).

Context should include
  • session_id: Session that was logged out
  • logout_method: How logged out (explicit, timeout, revoked)
USER_LOGOUT_FAILED class-attribute instance-attribute
USER_LOGOUT_FAILED = 'user_logout_failed'

User logout failed (rare - session cleanup failure).

Context should include
  • reason: Why logout failed (session_not_found, cleanup_error)
  • session_id: Session attempted to logout
USER_REGISTRATION_ATTEMPTED class-attribute instance-attribute
USER_REGISTRATION_ATTEMPTED = 'user_registration_attempted'

User attempted to register.

Context should include
  • email: Email address used
  • registration_method: How user attempted to register (email, oauth, invite)
USER_REGISTRATION_FAILED class-attribute instance-attribute
USER_REGISTRATION_FAILED = 'user_registration_failed'

User registration failed.

Context should include
  • email: Email address attempted
  • reason: Why registration failed (duplicate_email, weak_password, validation_error)
USER_REGISTERED class-attribute instance-attribute
USER_REGISTERED = 'user_registered'

New user account created (SUCCESS).

Context should include
  • registration_method: How user registered (email, oauth, invite)
  • email_verified: Whether email was verified during registration
USER_PASSWORD_CHANGE_ATTEMPTED class-attribute instance-attribute
USER_PASSWORD_CHANGE_ATTEMPTED = (
    "user_password_change_attempted"
)

User attempted to change password.

Context should include
  • initiated_by: Who initiated change (user, admin, system)
USER_PASSWORD_CHANGE_FAILED class-attribute instance-attribute
USER_PASSWORD_CHANGE_FAILED = 'user_password_change_failed'

Password change failed.

Context should include
  • reason: Why failed (wrong_current_password, weak_new_password, etc.)
  • initiated_by: Who attempted change
USER_PASSWORD_CHANGED class-attribute instance-attribute
USER_PASSWORD_CHANGED = 'user_password_changed'

User password was changed (SUCCESS).

Context should include
  • initiated_by: Who initiated change (user, admin, system)
  • method: How changed (self_service, admin_reset, forced_reset)
PASSWORD_RESET_REQUEST_ATTEMPTED class-attribute instance-attribute
PASSWORD_RESET_REQUEST_ATTEMPTED = (
    "password_reset_request_attempted"
)

User attempted to request password reset.

Context should include
  • email: Email address for reset request
USER_PASSWORD_RESET_REQUESTED class-attribute instance-attribute
USER_PASSWORD_RESET_REQUESTED = (
    "user_password_reset_requested"
)

User successfully requested password reset (SUCCESS).

Context should include
  • method: How requested (email_link, security_questions)
  • email: Email address for reset
PASSWORD_RESET_CONFIRM_ATTEMPTED class-attribute instance-attribute
PASSWORD_RESET_CONFIRM_ATTEMPTED = (
    "password_reset_confirm_attempted"
)

User attempted to confirm password reset with token.

Context should include
  • token: Reset token attempted (truncated for security)
USER_PASSWORD_RESET_FAILED class-attribute instance-attribute
USER_PASSWORD_RESET_FAILED = 'user_password_reset_failed'

Password reset confirmation failed.

Context should include
  • reason: Why failed (invalid_token, expired_link, weak_password)
PASSWORD_RESET_CONFIRM_FAILED class-attribute instance-attribute
PASSWORD_RESET_CONFIRM_FAILED = (
    "password_reset_confirm_failed"
)

Password reset confirmation failed (alias for clarity).

Context should include
  • reason: Why failed (invalid_token, expired_link, weak_password)
  • token: Reset token attempted (truncated)
USER_PASSWORD_RESET_COMPLETED class-attribute instance-attribute
USER_PASSWORD_RESET_COMPLETED = (
    "user_password_reset_completed"
)

Password reset was completed successfully (SUCCESS).

AUTH_TOKEN_REFRESH_ATTEMPTED class-attribute instance-attribute
AUTH_TOKEN_REFRESH_ATTEMPTED = (
    "auth_token_refresh_attempted"
)

Auth token refresh attempted.

Context should include
  • user_id: User requesting refresh (if known from token)
AUTH_TOKEN_REFRESH_FAILED class-attribute instance-attribute
AUTH_TOKEN_REFRESH_FAILED = 'auth_token_refresh_failed'

Auth token refresh failed.

Context should include
  • reason: Why failed (token_expired, token_revoked, token_invalid, user_not_found)
  • user_id: User requesting refresh (if known)
AUTH_TOKEN_REFRESHED class-attribute instance-attribute
AUTH_TOKEN_REFRESHED = 'auth_token_refreshed'

Auth token was refreshed (SUCCESS - JWT rotation completed).

Context should include
  • session_id: Session associated with token
TOKEN_REJECTED_VERSION_MISMATCH class-attribute instance-attribute
TOKEN_REJECTED_VERSION_MISMATCH = (
    "token_rejected_version_mismatch"
)

Token rejected due to version mismatch (security monitoring event).

Emitted during token refresh when version check fails due to global token rotation or per-user token rotation.

Context should include
  • token_version: Version of the rejected token
  • required_version: Minimum version required
  • rejection_reason: Why token was rejected (global_rotation, user_rotation)
  • user_id: User whose token was rejected (if known)
GLOBAL_TOKEN_ROTATION_ATTEMPTED class-attribute instance-attribute
GLOBAL_TOKEN_ROTATION_ATTEMPTED = (
    "global_token_rotation_attempted"
)

Global token rotation attempt initiated (all tokens).

Context should include
  • triggered_by: Who triggered rotation (admin ID or "system")
  • reason: Why rotation triggered (security_breach, scheduled, manual)
GLOBAL_TOKEN_ROTATION_SUCCEEDED class-attribute instance-attribute
GLOBAL_TOKEN_ROTATION_SUCCEEDED = (
    "global_token_rotation_succeeded"
)

Global token rotation completed successfully (SUCCESS).

Context should include
  • triggered_by: Who triggered rotation
  • previous_version: Previous global minimum token version
  • new_version: New global minimum token version
  • reason: Why rotation was triggered
  • grace_period_seconds: Grace period before full enforcement
GLOBAL_TOKEN_ROTATION_FAILED class-attribute instance-attribute
GLOBAL_TOKEN_ROTATION_FAILED = (
    "global_token_rotation_failed"
)

Global token rotation failed.

Context should include
  • triggered_by: Who triggered rotation
  • reason: Original reason for rotation attempt
  • failure_reason: Why rotation failed (e.g., "config_not_found")
USER_TOKEN_ROTATION_ATTEMPTED class-attribute instance-attribute
USER_TOKEN_ROTATION_ATTEMPTED = (
    "user_token_rotation_attempted"
)

Per-user token rotation attempt initiated.

Context should include
  • user_id: User whose tokens are being rotated
  • triggered_by: Who triggered rotation (user_id, admin_id, or "system")
  • reason: Why rotation triggered (password_change, suspicious_activity, manual)
USER_TOKEN_ROTATION_SUCCEEDED class-attribute instance-attribute
USER_TOKEN_ROTATION_SUCCEEDED = (
    "user_token_rotation_succeeded"
)

Per-user token rotation completed successfully (SUCCESS).

Context should include
  • user_id: User whose tokens were rotated
  • triggered_by: Who triggered rotation
  • previous_version: Previous user minimum token version
  • new_version: New user minimum token version
  • reason: Why rotation was triggered
USER_TOKEN_ROTATION_FAILED class-attribute instance-attribute
USER_TOKEN_ROTATION_FAILED = 'user_token_rotation_failed'

Per-user token rotation failed.

Context should include
  • user_id: User whose tokens were being rotated
  • triggered_by: Who triggered rotation
  • reason: Original reason for rotation attempt
  • failure_reason: Why rotation failed (e.g., "user_not_found")
USER_EMAIL_VERIFICATION_ATTEMPTED class-attribute instance-attribute
USER_EMAIL_VERIFICATION_ATTEMPTED = (
    "user_email_verification_attempted"
)

User attempted to verify email.

Context should include
  • email: Email address being verified
USER_EMAIL_VERIFICATION_FAILED class-attribute instance-attribute
USER_EMAIL_VERIFICATION_FAILED = (
    "user_email_verification_failed"
)

Email verification failed.

Context should include
  • reason: Why failed (invalid_token, expired_token, already_verified)
USER_EMAIL_VERIFIED class-attribute instance-attribute
USER_EMAIL_VERIFIED = 'user_email_verified'

User email address was verified (SUCCESS).

USER_MFA_ENABLE_ATTEMPTED class-attribute instance-attribute
USER_MFA_ENABLE_ATTEMPTED = 'user_mfa_enable_attempted'

User attempted to enable MFA.

Context should include
  • mfa_method: Type of MFA attempted (totp, sms, email)
USER_MFA_ENABLE_FAILED class-attribute instance-attribute
USER_MFA_ENABLE_FAILED = 'user_mfa_enable_failed'

MFA enable failed.

Context should include
  • reason: Why failed (invalid_code, setup_timeout, already_enabled)
  • mfa_method: Type of MFA attempted
USER_MFA_ENABLED class-attribute instance-attribute
USER_MFA_ENABLED = 'user_mfa_enabled'

Multi-factor authentication was enabled (SUCCESS).

Context should include
  • mfa_method: Type of MFA (totp, sms, email)
USER_MFA_DISABLE_ATTEMPTED class-attribute instance-attribute
USER_MFA_DISABLE_ATTEMPTED = 'user_mfa_disable_attempted'

User attempted to disable MFA.

Context should include
  • initiated_by: Who attempted to disable (user, admin)
USER_MFA_DISABLE_FAILED class-attribute instance-attribute
USER_MFA_DISABLE_FAILED = 'user_mfa_disable_failed'

MFA disable failed.

Context should include
  • reason: Why failed (wrong_password, security_check_failed)
  • initiated_by: Who attempted
USER_MFA_DISABLED class-attribute instance-attribute
USER_MFA_DISABLED = 'user_mfa_disabled'

Multi-factor authentication was disabled (SUCCESS).

Context should include
  • initiated_by: Who disabled MFA (user, admin)
  • reason: Why disabled (lost_device, user_request, etc.)
ACCESS_ATTEMPTED class-attribute instance-attribute
ACCESS_ATTEMPTED = 'access_attempted'

User attempted to access resource.

Context should include
  • resource: What was attempted
  • action: What action was attempted (read, write, delete)
ACCESS_DENIED class-attribute instance-attribute
ACCESS_DENIED = 'access_denied'

Access to resource was denied (security event).

Context should include
  • resource: What was attempted
  • reason: Why denied (no_permission, suspended_account, etc.)
  • action: What action was attempted
ACCESS_GRANTED class-attribute instance-attribute
ACCESS_GRANTED = 'access_granted'

Access to resource was granted (SUCCESS).

Context should include
  • resource: What was accessed
  • permission_level: Access level granted (read, write, admin)
  • action: What action was granted
PERMISSION_CHANGE_ATTEMPTED class-attribute instance-attribute
PERMISSION_CHANGE_ATTEMPTED = 'permission_change_attempted'

Attempted to change user permissions.

Context should include
  • changed_by: Who attempted change
  • target_user_id: User whose permissions would change
  • requested_permissions: New permission set requested
PERMISSION_CHANGE_FAILED class-attribute instance-attribute
PERMISSION_CHANGE_FAILED = 'permission_change_failed'

Permission change failed.

Context should include
  • reason: Why failed (insufficient_privileges, invalid_permission)
  • changed_by: Who attempted change
PERMISSION_CHANGED class-attribute instance-attribute
PERMISSION_CHANGED = 'permission_changed'

User permissions were modified (SUCCESS).

Context should include
  • changed_by: Who modified permissions
  • old_permissions: Previous permission set
  • new_permissions: New permission set
ROLE_ASSIGNMENT_ATTEMPTED class-attribute instance-attribute
ROLE_ASSIGNMENT_ATTEMPTED = 'role_assignment_attempted'

Attempted to assign role to user.

Context should include
  • role_name: Name of role to assign
  • assigned_by: Who attempted assignment
  • target_user_id: User to receive role
ROLE_ASSIGNMENT_FAILED class-attribute instance-attribute
ROLE_ASSIGNMENT_FAILED = 'role_assignment_failed'

Role assignment failed.

Context should include
  • reason: Why failed (invalid_role, no_permission, already_assigned)
  • role_name: Name of role attempted
ROLE_ASSIGNED class-attribute instance-attribute
ROLE_ASSIGNED = 'role_assigned'

Role was assigned to user (SUCCESS).

Context should include
  • role_name: Name of role assigned
  • assigned_by: Who assigned the role
ROLE_REVOCATION_ATTEMPTED class-attribute instance-attribute
ROLE_REVOCATION_ATTEMPTED = 'role_revocation_attempted'

Attempted to revoke role from user.

Context should include
  • role_name: Name of role to revoke
  • revoked_by: Who attempted revocation
  • target_user_id: User to lose role
ROLE_REVOCATION_FAILED class-attribute instance-attribute
ROLE_REVOCATION_FAILED = 'role_revocation_failed'

Role revocation failed.

Context should include
  • reason: Why failed (last_admin_role, no_permission)
  • role_name: Name of role attempted
ROLE_REVOKED class-attribute instance-attribute
ROLE_REVOKED = 'role_revoked'

Role was revoked from user (SUCCESS).

Context should include
  • role_name: Name of role revoked
  • revoked_by: Who revoked the role
  • reason: Why revoked
DATA_VIEWED class-attribute instance-attribute
DATA_VIEWED = 'data_viewed'

Personal or sensitive data was viewed (SUCCESS).

Note: Use ACCESS_ATTEMPTED → ACCESS_DENIED/GRANTED for access control. This event records successful data access after permission check.

Context should include
  • data_type: Type of data viewed (profile, financial, etc.)
  • fields_accessed: Specific fields viewed
DATA_EXPORT_ATTEMPTED class-attribute instance-attribute
DATA_EXPORT_ATTEMPTED = 'data_export_attempted'

User attempted to export data.

Context should include
  • export_format: Requested format (json, csv, pdf)
  • data_scope: What data was requested
DATA_EXPORT_FAILED class-attribute instance-attribute
DATA_EXPORT_FAILED = 'data_export_failed'

Data export failed.

Context should include
  • reason: Why failed (too_large, timeout, permission_denied)
  • export_format: Requested format
DATA_EXPORTED class-attribute instance-attribute
DATA_EXPORTED = 'data_exported'

Data was exported (SUCCESS - GDPR right to data portability).

Context should include
  • export_format: Format of export (json, csv, pdf)
  • data_scope: What data was exported
  • export_reason: Why exported (user_request, backup, etc.)
  • file_size: Size of export file
DATA_DELETION_ATTEMPTED class-attribute instance-attribute
DATA_DELETION_ATTEMPTED = 'data_deletion_attempted'

Attempted to delete data.

Context should include
  • deletion_type: Type requested (soft, hard, anonymization)
  • data_scope: What data deletion was requested
  • requested_by: Who requested deletion
DATA_DELETION_FAILED class-attribute instance-attribute
DATA_DELETION_FAILED = 'data_deletion_failed'

Data deletion failed.

Context should include
  • reason: Why failed (in_use, constraint_violation, insufficient_permission)
  • data_scope: What data deletion was attempted
DATA_DELETED class-attribute instance-attribute
DATA_DELETED = 'data_deleted'

Data was deleted (SUCCESS - GDPR right to be forgotten).

Context should include
  • deletion_type: Type of deletion (soft, hard, anonymization)
  • data_scope: What data was deleted
  • requested_by: Who requested deletion
DATA_MODIFICATION_ATTEMPTED class-attribute instance-attribute
DATA_MODIFICATION_ATTEMPTED = 'data_modification_attempted'

Attempted to modify data.

Context should include
  • fields_to_change: Which fields modification was attempted
  • change_reason: Why modification was attempted
DATA_MODIFICATION_FAILED class-attribute instance-attribute
DATA_MODIFICATION_FAILED = 'data_modification_failed'

Data modification failed.

Context should include
  • reason: Why failed (validation_error, constraint_violation, permission_denied)
  • fields_attempted: Which fields were attempted
DATA_MODIFIED class-attribute instance-attribute
DATA_MODIFIED = 'data_modified'

Personal or sensitive data was modified (SUCCESS).

Context should include
  • fields_changed: Which fields were modified
  • change_reason: Why data was modified
  • old_values: Previous values (if appropriate)
  • new_values: New values
ADMIN_USER_CREATION_ATTEMPTED class-attribute instance-attribute
ADMIN_USER_CREATION_ATTEMPTED = (
    "admin_user_creation_attempted"
)

Administrator attempted to create user account.

Context should include
  • created_by: Admin attempting creation
  • email: Email for new user
  • initial_role: Role to be assigned
ADMIN_USER_CREATION_FAILED class-attribute instance-attribute
ADMIN_USER_CREATION_FAILED = 'admin_user_creation_failed'

Admin user creation failed.

Context should include
  • reason: Why failed (duplicate_email, validation_error, permission_denied)
  • created_by: Admin who attempted
ADMIN_USER_CREATED class-attribute instance-attribute
ADMIN_USER_CREATED = 'admin_user_created'

Administrator created a new user account (SUCCESS).

Context should include
  • created_by: Admin who created account
  • initial_role: Role assigned to new user
  • user_email: Email of created user
ADMIN_USER_DELETION_ATTEMPTED class-attribute instance-attribute
ADMIN_USER_DELETION_ATTEMPTED = (
    "admin_user_deletion_attempted"
)

Administrator attempted to delete user account.

Context should include
  • deleted_by: Admin attempting deletion
  • target_user_id: User to be deleted
  • reason: Why deletion was attempted
ADMIN_USER_DELETION_FAILED class-attribute instance-attribute
ADMIN_USER_DELETION_FAILED = 'admin_user_deletion_failed'

Admin user deletion failed.

Context should include
  • reason: Why failed (in_use, constraint_violation, permission_denied)
  • deleted_by: Admin who attempted
ADMIN_USER_DELETED class-attribute instance-attribute
ADMIN_USER_DELETED = 'admin_user_deleted'

Administrator deleted a user account (SUCCESS).

Context should include
  • deleted_by: Admin who deleted account
  • reason: Why account was deleted
  • user_email: Email of deleted user
ADMIN_USER_SUSPENSION_ATTEMPTED class-attribute instance-attribute
ADMIN_USER_SUSPENSION_ATTEMPTED = (
    "admin_user_suspension_attempted"
)

Administrator attempted to suspend user account.

Context should include
  • suspended_by: Admin attempting suspension
  • target_user_id: User to be suspended
  • reason: Why suspension was attempted
  • duration: Requested suspension duration
ADMIN_USER_SUSPENSION_FAILED class-attribute instance-attribute
ADMIN_USER_SUSPENSION_FAILED = (
    "admin_user_suspension_failed"
)

Admin user suspension failed.

Context should include
  • reason: Why failed (already_suspended, permission_denied, cannot_suspend_admin)
  • suspended_by: Admin who attempted
ADMIN_USER_SUSPENDED class-attribute instance-attribute
ADMIN_USER_SUSPENDED = 'admin_user_suspended'

Administrator suspended a user account (SUCCESS).

Context should include
  • suspended_by: Admin who suspended account
  • reason: Why account was suspended
  • duration: Suspension duration (if temporary)
ADMIN_CONFIG_CHANGE_ATTEMPTED class-attribute instance-attribute
ADMIN_CONFIG_CHANGE_ATTEMPTED = (
    "admin_config_change_attempted"
)

Administrator attempted to change system configuration.

Context should include
  • config_key: What configuration change was attempted
  • requested_value: New value requested
  • changed_by: Admin attempting change
ADMIN_CONFIG_CHANGE_FAILED class-attribute instance-attribute
ADMIN_CONFIG_CHANGE_FAILED = 'admin_config_change_failed'

Admin config change failed.

Context should include
  • reason: Why failed (invalid_value, locked_config, permission_denied)
  • config_key: What configuration was attempted
  • changed_by: Admin who attempted
ADMIN_CONFIG_CHANGED class-attribute instance-attribute
ADMIN_CONFIG_CHANGED = 'admin_config_changed'

System configuration was changed by administrator (SUCCESS).

Context should include
  • config_key: What configuration was changed
  • old_value: Previous value
  • new_value: New value
  • changed_by: Admin who made change
ADMIN_BACKUP_CREATED class-attribute instance-attribute
ADMIN_BACKUP_CREATED = 'admin_backup_created'

System backup was created.

Note: This is a completed system event (no ATTEMPT needed).

Context should include
  • backup_type: Type of backup (full, incremental, differential)
  • backup_location: Where backup was stored
  • backup_size: Size of backup
  • initiated_by: Who initiated backup (system, admin)
PROVIDER_CONNECTION_ATTEMPTED class-attribute instance-attribute
PROVIDER_CONNECTION_ATTEMPTED = (
    "provider_connection_attempted"
)

User attempted to connect financial provider.

Context should include
  • provider_name: Name of provider (schwab, chase, etc.)
  • connection_method: Method attempted (oauth, api_key, etc.)
PROVIDER_CONNECTION_FAILED class-attribute instance-attribute
PROVIDER_CONNECTION_FAILED = 'provider_connection_failed'

Provider connection failed.

Context should include
  • provider_name: Name of provider
  • reason: Why failed (oauth_error, api_error, invalid_credentials)
  • error_code: Provider-specific error code
PROVIDER_CONNECTED class-attribute instance-attribute
PROVIDER_CONNECTED = 'provider_connected'

Financial provider was connected to user account (SUCCESS).

Context should include
  • provider_name: Name of provider (schwab, chase, etc.)
  • connection_method: How connected (oauth, api_key, etc.)
PROVIDER_DISCONNECTION_ATTEMPTED class-attribute instance-attribute
PROVIDER_DISCONNECTION_ATTEMPTED = (
    "provider_disconnection_attempted"
)

User attempted to disconnect financial provider.

Context should include
  • provider_name: Name of provider
  • disconnection_reason: Why disconnection requested
PROVIDER_DISCONNECTION_FAILED class-attribute instance-attribute
PROVIDER_DISCONNECTION_FAILED = (
    "provider_disconnection_failed"
)

Provider disconnection failed.

Context should include
  • provider_name: Name of provider
  • reason: Why failed (api_error, pending_transactions)
PROVIDER_DISCONNECTED class-attribute instance-attribute
PROVIDER_DISCONNECTED = 'provider_disconnected'

Financial provider was disconnected from user account (SUCCESS).

Context should include
  • provider_name: Name of provider
  • disconnection_reason: Why disconnected (user_request, error, etc.)
PROVIDER_TOKEN_REFRESH_ATTEMPTED class-attribute instance-attribute
PROVIDER_TOKEN_REFRESH_ATTEMPTED = (
    "provider_token_refresh_attempted"
)

Attempted to refresh provider access token.

Context should include
  • provider_name: Name of provider
  • token_type: Type of token to refresh (access, refresh)
PROVIDER_TOKEN_REFRESH_FAILED class-attribute instance-attribute
PROVIDER_TOKEN_REFRESH_FAILED = (
    "provider_token_refresh_failed"
)

Provider token refresh failed (security event).

Context should include
  • provider_name: Name of provider
  • error_code: Provider error code
  • error_message: Error description
PROVIDER_TOKEN_REFRESHED class-attribute instance-attribute
PROVIDER_TOKEN_REFRESHED = 'provider_token_refreshed'

Provider access token was refreshed (SUCCESS).

Context should include
  • provider_name: Name of provider
  • token_type: Type of token refreshed (access, refresh)
PROVIDER_DATA_SYNC_ATTEMPTED class-attribute instance-attribute
PROVIDER_DATA_SYNC_ATTEMPTED = (
    "provider_data_sync_attempted"
)

Attempted to sync data from financial provider.

Context should include
  • provider_name: Name of provider
  • data_types: Types of data to sync (accounts, transactions)
PROVIDER_DATA_SYNC_FAILED class-attribute instance-attribute
PROVIDER_DATA_SYNC_FAILED = 'provider_data_sync_failed'

Provider data sync failed.

Context should include
  • provider_name: Name of provider
  • reason: Why failed (api_error, network_error, rate_limit)
  • error_code: Provider error code
PROVIDER_DATA_SYNCED class-attribute instance-attribute
PROVIDER_DATA_SYNCED = 'provider_data_synced'

Data was synced from financial provider (SUCCESS).

Context should include
  • provider_name: Name of provider
  • data_types: Types of data synced (accounts, transactions)
  • records_synced: Number of records synced
PROVIDER_ACCOUNT_VIEWED class-attribute instance-attribute
PROVIDER_ACCOUNT_VIEWED = 'provider_account_viewed'

Financial account data was viewed (SUCCESS - PCI-DSS: cardholder data access).

Note: Use ACCESS_ATTEMPTED → ACCESS_DENIED/GRANTED for access control. This event records successful data access after permission check.

Context should include
  • provider_name: Name of provider
  • account_type: Type of account (checking, credit_card, etc.)
  • account_mask: Last 4 digits of account number
PROVIDER_TRANSACTION_VIEWED class-attribute instance-attribute
PROVIDER_TRANSACTION_VIEWED = 'provider_transaction_viewed'

Financial transaction data was viewed (SUCCESS - PCI-DSS: cardholder data access).

Note: Use ACCESS_ATTEMPTED → ACCESS_DENIED/GRANTED for access control. This event records successful data access after permission check.

Context should include
  • provider_name: Name of provider
  • account_mask: Last 4 digits of account number
  • transaction_count: Number of transactions viewed
  • date_range: Date range of transactions
SESSION_REVOCATION_ATTEMPTED class-attribute instance-attribute
SESSION_REVOCATION_ATTEMPTED = (
    "session_revocation_attempted"
)

Session revocation attempt initiated.

Context should include
  • session_id: Session being revoked
  • revoked_by: Who attempted revocation (user, admin, system)
  • reason: Why revocation requested
SESSION_REVOKED class-attribute instance-attribute
SESSION_REVOKED = 'session_revoked'

User session was revoked successfully (SUCCESS).

Context should include
  • session_id: Session that was revoked
  • revoked_by: Who/what revoked session (user, admin, system)
  • reason: Why revoked (logout, timeout, security, admin_action)
SESSION_REVOCATION_FAILED class-attribute instance-attribute
SESSION_REVOCATION_FAILED = 'session_revocation_failed'

Session revocation failed.

Context should include
  • session_id: Session that failed to revoke
  • reason: Original reason for revocation
  • failure_reason: Why revocation failed (not_found, not_owner, already_revoked)
SESSION_EVICTED class-attribute instance-attribute
SESSION_EVICTED = 'session_evicted'

Session was evicted due to limit exceeded (security policy).

Context should include
  • session_id: Session that was evicted
  • eviction_reason: Why evicted (limit_exceeded, oldest_session)
  • active_sessions_count: Number of active sessions after eviction
ALL_SESSIONS_REVOCATION_ATTEMPTED class-attribute instance-attribute
ALL_SESSIONS_REVOCATION_ATTEMPTED = (
    "all_sessions_revocation_attempted"
)

All sessions revocation attempt initiated.

Context should include
  • revoked_by: Who attempted revocation (user, admin, system)
  • reason: Why revocation requested (password_change, security_breach, user_request)
  • except_session_id: Session to exclude from revocation (if any)
ALL_SESSIONS_REVOKED class-attribute instance-attribute
ALL_SESSIONS_REVOKED = 'all_sessions_revoked'

All user sessions were revoked successfully (SUCCESS).

Context should include
  • revoked_by: Who/what revoked all sessions (user, admin, system)
  • reason: Why revoked (password_change, security_breach, user_request)
  • sessions_revoked_count: Number of sessions revoked
ALL_SESSIONS_REVOCATION_FAILED class-attribute instance-attribute
ALL_SESSIONS_REVOCATION_FAILED = (
    "all_sessions_revocation_failed"
)

All sessions revocation failed.

Context should include
  • reason: Original reason for revocation
  • failure_reason: Why revocation failed
SESSION_PROVIDER_ACCESS class-attribute instance-attribute
SESSION_PROVIDER_ACCESS = 'session_provider_access'

Session accessed provider data (audit trail for data access).

Context should include
  • session_id: Session that accessed provider
  • provider_name: Provider accessed
  • access_type: Type of access (read, sync, update)
SUSPICIOUS_SESSION_ACTIVITY class-attribute instance-attribute
SUSPICIOUS_SESSION_ACTIVITY = 'suspicious_session_activity'

Suspicious activity detected in session (security alert).

Context should include
  • session_id: Session with suspicious activity
  • activity_type: Type of suspicious activity
  • risk_score: Risk assessment score
  • detection_reason: Why flagged as suspicious
ACCOUNT_SYNC_ATTEMPTED class-attribute instance-attribute
ACCOUNT_SYNC_ATTEMPTED = 'account_sync_attempted'

Attempted to sync account data from provider.

Context should include
  • connection_id: Provider connection
  • provider_name: Name of provider
ACCOUNT_SYNC_SUCCEEDED class-attribute instance-attribute
ACCOUNT_SYNC_SUCCEEDED = 'account_sync_succeeded'

Account data synced successfully (SUCCESS).

Context should include
  • connection_id: Provider connection
  • provider_name: Name of provider
  • account_count: Number of accounts synced
ACCOUNT_SYNC_FAILED class-attribute instance-attribute
ACCOUNT_SYNC_FAILED = 'account_sync_failed'

Account data sync failed.

Context should include
  • connection_id: Provider connection
  • provider_name: Name of provider
  • reason: Why failed (api_error, auth_failed, network_error)
TRANSACTION_SYNC_ATTEMPTED class-attribute instance-attribute
TRANSACTION_SYNC_ATTEMPTED = 'transaction_sync_attempted'

Attempted to sync transaction data from provider.

Context should include
  • connection_id: Provider connection
  • provider_name: Name of provider
  • account_id: Specific account if targeted sync
TRANSACTION_SYNC_SUCCEEDED class-attribute instance-attribute
TRANSACTION_SYNC_SUCCEEDED = 'transaction_sync_succeeded'

Transaction data synced successfully (SUCCESS - PCI-DSS: cardholder data).

Context should include
  • connection_id: Provider connection
  • provider_name: Name of provider
  • account_id: Specific account if targeted sync
  • transaction_count: Number of transactions synced
TRANSACTION_SYNC_FAILED class-attribute instance-attribute
TRANSACTION_SYNC_FAILED = 'transaction_sync_failed'

Transaction data sync failed.

Context should include
  • connection_id: Provider connection
  • provider_name: Name of provider
  • account_id: Specific account if targeted sync
  • reason: Why failed (api_error, date_range_invalid, network_error)
HOLDINGS_SYNC_ATTEMPTED class-attribute instance-attribute
HOLDINGS_SYNC_ATTEMPTED = 'holdings_sync_attempted'

Attempted to sync holdings (positions) from provider.

Context should include
  • account_id: Account to sync holdings for
  • provider_name: Name of provider
HOLDINGS_SYNC_SUCCEEDED class-attribute instance-attribute
HOLDINGS_SYNC_SUCCEEDED = 'holdings_sync_succeeded'

Holdings data synced successfully (SUCCESS).

Context should include
  • account_id: Account synced
  • provider_name: Name of provider
  • holding_count: Number of holdings synced
HOLDINGS_SYNC_FAILED class-attribute instance-attribute
HOLDINGS_SYNC_FAILED = 'holdings_sync_failed'

Holdings data sync failed.

Context should include
  • account_id: Account attempted
  • provider_name: Name of provider
  • reason: Why failed (api_error, holdings_not_supported, network_error)
FILE_IMPORT_ATTEMPTED class-attribute instance-attribute
FILE_IMPORT_ATTEMPTED = 'file_import_attempted'

Attempted to import financial data from file.

Context should include
  • provider_slug: Provider identifier
  • file_name: Original filename
  • file_format: File format (qfx, ofx, csv)
FILE_IMPORT_SUCCEEDED class-attribute instance-attribute
FILE_IMPORT_SUCCEEDED = 'file_import_succeeded'

File import completed successfully (SUCCESS).

Context should include
  • provider_slug: Provider identifier
  • file_name: Original filename
  • file_format: File format
  • account_count: Accounts created/updated
  • transaction_count: Transactions imported
FILE_IMPORT_FAILED class-attribute instance-attribute
FILE_IMPORT_FAILED = 'file_import_failed'

File import failed.

Context should include
  • provider_slug: Provider identifier
  • file_name: Original filename
  • file_format: File format
  • reason: Why failed (parse_error, unsupported_format, invalid_structure)
RATE_LIMIT_CHECK_ATTEMPTED class-attribute instance-attribute
RATE_LIMIT_CHECK_ATTEMPTED = 'rate_limit_check_attempted'

Rate limit check was initiated.

Context should include
  • endpoint: Endpoint being rate limited
  • identifier: Rate limit identifier (IP, user_id)
  • scope: Rate limit scope (ip, user, user_provider, global)
  • cost: Token cost for operation
RATE_LIMIT_CHECK_ALLOWED class-attribute instance-attribute
RATE_LIMIT_CHECK_ALLOWED = 'rate_limit_check_allowed'

Request was allowed by rate limiter (SUCCESS).

Context should include
  • endpoint: Endpoint accessed
  • identifier: Rate limit identifier
  • scope: Rate limit scope
  • remaining_tokens: Tokens remaining in bucket
  • execution_time_ms: Rate limit check duration
RATE_LIMIT_CHECK_DENIED class-attribute instance-attribute
RATE_LIMIT_CHECK_DENIED = 'rate_limit_check_denied'

Request was denied by rate limiter (security event).

Context should include
  • endpoint: Endpoint that was rate limited
  • identifier: Rate limit identifier (IP, user_id)
  • scope: Rate limit scope (ip, user, user_provider, global)
  • retry_after: Seconds until retry allowed
  • limit: Maximum tokens (bucket capacity)
  • remaining: Current tokens (should be 0)