Skip to main content
PropOps Web maintains several distinct logs that together form a complete, tamper-resistant audit trail. Each log serves a specific compliance or operational purpose. This page documents every log that exists, what each entry contains, and why it is kept.
Activity log entries are retained for 12 months by default. Administrators can adjust the retention period in Admin → Settings. The GDPR retention cleanup cron job automatically purges entries older than the configured window.

Log tables at a glance

TablePrimary purposeEncrypted fields
user_activity_logComplete user activity audit trailip_address, activity_details
login_attemptsLogin success and failure trackingNone
security_eventsSecurity-specific guard and auth eventsNone
api_endpoint_usage_logsAPI request usage and performanceip_address
system_security_alertsFile integrity and system health alertsNone

user_activity_log

This is the primary audit log. Every meaningful action performed by or on behalf of a user is written here, including page views, authentication events, admin operations, and guard page outcomes.

Record structure

ColumnTypeDescription
uuidstringUnique identifier for this log entry
account_idintegerThe account that performed or was subject to the action
activity_typestringMachine-readable event category (see Activity types below)
ip_addressencrypted stringThe IP address of the request — PII encrypted at rest
user_agentstringThe browser or client user-agent string
activity_detailsencrypted JSONStructured context for the event — PII encrypted at rest
created_atdatetimeUTC timestamp of the event

Encryption

Two fields in every user_activity_log row are encrypted using the platform’s authenticated PII encryption key:
  • ip_address — encrypted because an IP address is personal data under UK GDPR. Decrypted transparently for authorised staff in the activity log viewer.
  • activity_details — a JSON blob containing event-specific context (page URLs, targeted user identities, action outcomes, etc.). Encrypted because this blob may contain names, emails, and other personal data depending on the event type.
Encrypted values are stored with an enc:v1: prefix. The data is decrypted on-the-fly when rendered in the admin panel and is never written to application or server logs in plain text.

Activity types

Activity types follow a predictable naming pattern. The table below lists every activity type that PropOps writes, grouped by category.

Authentication

Activity typeWhen it firesWhy it is logged
loginSuccessful sign-inEstablishes the start of an authenticated session; supports ICO breach evidence requirements
failed_loginPassword incorrect at sign-inSupports brute-force detection, targeted-account detection, and ICO breach reporting
logoutUser signs outCloses the audit trail for the session

Guard page flows

Guard pages are interstitial security checks shown between login and full platform access (email verification, IP location verification, document approval, and re-authentication). Every stage of every guard flow is logged.

Email verification guard (verify)

Activity typeMeaning
guard_verify_viewedUser landed on the email verification screen
guard_verify_already_verifiedGuard passed immediately — email was already verified
guard_verify_code_sentVerification code emailed successfully
guard_verify_code_send_failedCode could not be sent (email delivery failure)
guard_verify_code_send_exceptionUnexpected error while attempting to send the code
guard_verify_code_invalid_formatSubmitted code was not the correct length or format
guard_verify_code_verification_failedSubmitted code was incorrect or expired
guard_verify_code_verifiedCode matched — email verified successfully
guard_verify_code_verify_exceptionUnexpected error during code verification

IP location verification guard (ip)

Activity typeMeaning
guard_ip_viewedUser landed on the new-location verification screen
guard_ip_pin_rate_limitedPIN resend blocked due to cooldown period
guard_ip_pin_send_skippedPIN not sent — already queued or recently sent
guard_ip_pin_send_failedPIN email delivery failed
guard_ip_pin_sentPIN emailed to user successfully
guard_ip_pin_send_exceptionUnexpected error while sending the PIN
guard_ip_pin_invalid_or_expiredSubmitted PIN was not valid or had expired
guard_ip_pin_attempts_exceededToo many failed PIN attempts — session blocked
guard_ip_pin_failedPIN incorrect
guard_ip_pin_verifiedPIN correct — IP location added to trusted list
guard_ip_pin_verified_trust_failedPIN correct but saving trusted IP failed
guard_ip_pin_verify_exceptionUnexpected error during PIN verification

Document approval guard (documents)

Activity typeMeaning
guard_documents_viewedUser landed on the document approval screen
guard_documents_approve_incompleteApproval attempted but not all documents were checked
guard_documents_approvedUser approved all required documents
guard_documents_approve_exceptionUnexpected error during document approval
guard_documents_approve_failedServer returned an error response to the approval request
guard_documents_rejected_and_terminatedUser rejected the documents — account terminated
guard_documents_reject_exceptionUnexpected error during account termination after rejection
guard_documents_reject_failedServer returned an error response to the rejection request

Re-authentication guard (reauth)

Activity typeMeaning
guard_reauth_viewedUser was redirected to the re-authentication screen
guard_reauth_attempt_blockedAccount locked out or blocked — authentication refused
guard_reauth_attempt_empty_passwordSubmitted password was blank
guard_reauth_attempt_failedPassword was incorrect
guard_reauth_verifiedPassword confirmed — re-authentication passed

Page views

Activity typeWhen it firesWhy it is logged
page_viewAny authenticated page loadSupports data access audit trail under UK GDPR Article 30

User management (staff actions)

These events are written when a staff member performs an action on another user’s account. The activity_details blob includes both the staff member’s identity and the target user’s identity.
Activity typeMeaning
staff_user_status_changeUser’s account status was changed (e.g. suspended, activated)
staff_user_type_changeUser’s account type was changed (e.g. promoted to admin)
staff_user_createNew user account created by staff
staff_user_deleteUser account deleted by staff
staff_session_terminateAll sessions for a user forcibly terminated by staff
staff_email_verification_toggleEmail verification requirement toggled by staff
staff_password_scanPassword breach scan triggered manually for a user
staff_bulk_<operation>A bulk action performed on multiple users simultaneously
button_clickStaff clicked a specific action button in the user management panel

Permissions management

Activity typeMeaning
permission_grantedAn API permission was granted to an account type
permission_revokedAn API permission was revoked from an account type

Branch management

Activity typeMeaning
branch_createdA new branch was created
branch_updatedBranch settings were updated
branch_disabledA branch was disabled
branch_enabledA branch was re-enabled

Tag management

Activity typeMeaning
tag_createdA job tag was created
tag_updatedA job tag was modified
tag_deletedA job tag was removed

Security administration

Activity typeMeaning
file_integrity_check_runA manual file integrity check was triggered
security_alert_resolvedA security alert was marked as resolved
security_alert_deletedA security alert was dismissed and removed
bulk_alerts_resolvedMultiple security alerts resolved in one operation
bulk_alerts_deletedMultiple security alerts deleted in one operation

Error and system events

Activity typeMeaning
403_access_deniedUser attempted to access a page they do not have permission for
404_not_foundUser navigated to a page that does not exist
license_inactiveUser attempted to access the platform while the licence was inactive

login_attempts

A dedicated table for raw login attempt records. This is separate from user_activity_log to allow efficient brute-force detection queries without decryption overhead.
ColumnDescription
user_idAccount ID of the user whose credentials were submitted (NULL for unknown usernames)
emailThe email address that was attempted
ip_addressSource IP of the attempt
successBoolean — whether the login succeeded
attempted_atUTC timestamp
Why it is logged: The security dashboard and brute-force detection logic query this table to identify suspicious IP addresses (5+ failures in 1 hour), targeted accounts (5+ failures in 24 hours), and multi-account spray attacks (3+ accounts from one IP in 24 hours). This data directly supports UK GDPR Article 33 breach notification obligations.

security_events

A secondary security-specific event log used in parallel with user_activity_log. Currently populated by the IP guard PIN verification flow and other low-level auth events.
ColumnDescription
user_idAccount ID associated with the event
event_typeCategory string (e.g. ip_pin_verified, ip_pin_failed)
descriptionHuman-readable event description
metadataJSON context object
created_atUTC timestamp
Why it exists alongside user_activity_log: The security_events table is indexed for fast security-focused queries that span many users, whereas user_activity_log is the per-user audit trail. Both are written for IP guard PIN events so that security dashboards and per-user audit queries can each use the most efficient data source.

api_endpoint_usage_logs

Every API request is logged here for usage analytics, performance monitoring, and anomaly detection.
ColumnDescription
endpointThe API path called (e.g. /api/jobs/manage)
methodHTTP method (GET, POST, etc.)
account_idThe user who made the request
ip_addressEncrypted source IP
response_codeHTTP status code returned
response_time_msServer processing time in milliseconds
requested_atUTC timestamp
Why it is logged: Enables week-over-week API usage comparison, identification of unusual request patterns, and performance regression tracking. The security dashboard shows this week vs last week volume and highlights spikes. ip_address is PII encrypted for the same reason as in user_activity_log.

system_security_alerts

Populated by the file integrity monitoring cron job and related automated checks.
ColumnDescription
alert_typeCategory — currently file_integrity_violation
severitycritical, warning, or info
messageHuman-readable description of the alert
detailsJSON metadata (file path, expected vs actual checksums)
resolvedBoolean — whether a staff member has acknowledged the alert
created_atUTC timestamp
Why it is logged: Any modification to a production application file that was not part of a deployment is a potential security incident. The cron job checksums every PHP file every hour and raises an alert on any unexpected change. All file_integrity_violation alerts are treated as critical by the security dashboard regardless of their severity field.

What is encrypted in the logs

The following fields are encrypted with the platform’s authenticated PII encryption key (enc:v1: prefix):
TableColumnReason
user_activity_logip_addressIP addresses are personal data under UK GDPR
user_activity_logactivity_detailsMay contain names, emails, and other personal identifiers in the JSON payload
api_endpoint_usage_logsip_addressSame reason as above
All other log columns (user agent strings, activity types, timestamps, response codes) are stored unencrypted as they do not constitute personal data in isolation. Encrypted values are decrypted transparently by the admin panel API before being returned to the browser. The raw encrypted values are never exposed to end users.

Retention and data minimisation

LogDefault retentionConfigurable
user_activity_log12 monthsYes — Admin → Settings
login_attemptsCleared after successful login (per-account)No
security_eventsRetained indefinitely (no cron cleanup)No
api_endpoint_usage_logsRetained indefinitely (no cron cleanup)No
system_security_alertsRetained until manually resolved or deletedNo
The GDPR retention cleanup cron job (cleanup_gdpr_data.php) runs on a schedule and removes user_activity_log entries older than the configured retention window. This supports the UK GDPR data minimisation principle.
If your organisation requires longer retention for regulatory or contractual reasons, increase the retention period in Admin → Settings before the default 12-month window elapses. Records that have already been purged cannot be recovered.