Skip to content

Data Dictionary and Event Schema

Neemias

1. Purpose

This document defines the canonical data contract for storage, event history, and synchronization payloads. It is the source of truth for entity fields, types, constraints, keys, and validation rules. The backend (Cloudflare D1) is the primary store; the local IndexedDB is an offline fallback.

2. Design Rules

  • All timestamps stored in UTC ISO 8601 format.
  • Brazilian Portuguese is default locale for rendering, not storage.
  • Audit events are immutable.
  • Student deletion is soft delete only and requires justification.
  • Admin precedence applies when conflicts involve Admin actions.
  • Non-admin conflicts use last write wins by server timestamp.

3. Enumerations

3.1 Roles

  • ROLL_CALLER
  • REPORT_USER
  • DATA_ENTRY
  • ADMIN_USER

3.2 Sync State

  • PENDING
  • IN_PROGRESS
  • SYNCED
  • FAILED
  • RETRYING

3.3 Attendance Action

  • MARK_PRESENT
  • MARK_ABSENT

3.4 Student Lifecycle State

  • ACTIVE
  • DELETED

3.5 Event Type

  • CREATE
  • UPDATE
  • DELETE
  • MARK_PRESENT
  • MARK_ABSENT

3.6 User Event Type

  • USER_CREATED
  • USER_UPDATED
  • USER_DEACTIVATED
  • USER_PASSWORD_RESET

4. Entity Dictionary

4.1 Student

FieldTypeRequiredKeyConstraints
studentIdUUIDYesPKImmutable
displayNamestringYes1 to 100 chars
photoRefstringYesLocal blob key or remote reference
statusenumYesACTIVE or DELETED
createdAtdatetime UTCYesImmutable
updatedAtdatetime UTCYesUpdated on non-delete changes
createdByUUIDYesFK User.userIdMust exist
deletedAtdatetime UTCNoRequired when status is DELETED
deletedByUUIDNoFK User.userIdRequired when status is DELETED

4.2 AttendanceEvent

FieldTypeRequiredKeyConstraints
eventIdUUIDYesPKImmutable
studentIdUUIDYesFK Student.studentIdMust exist
actionTypeenumYesMARK_PRESENT or MARK_ABSENT
actorIdUUIDYesFK User.userIdMust exist
actorRoleenumYesMust match role at action time
timestampdatetime UTCYesClient event time
serverTimestampdatetime UTCNoSet when synced
syncStateenumYesPENDING, IN_PROGRESS, SYNCED, FAILED, RETRYING
isConflictLoserbooleanYesDefault false
conflictSupersededByUUIDNoFK AttendanceEvent.eventIdSet when superseded

4.3 StudentEvent

FieldTypeRequiredKeyConstraints
eventIdUUIDYesPKImmutable
studentIdUUIDYesFK Student.studentIdMust exist
eventTypeenumYesCREATE, UPDATE, DELETE
actorIdUUIDYesFK User.userIdMust exist
actorRoleenumYesMust match role at action time
timestampdatetime UTCYesClient event time
serverTimestampdatetime UTCNoSet when synced
changePayloadJSONYesBefore and after delta
justificationstringNoRequired for DELETE, 10 to 500 chars
syncStateenumYesPENDING, IN_PROGRESS, SYNCED, FAILED, RETRYING
isConflictLoserbooleanYesDefault false

4.4 Session

FieldTypeRequiredKeyConstraints
sessionIdUUIDYesPKImmutable
userIdUUIDYesFK User.userIdMust exist
roleenumYesSnapshot at login
issuedAtdatetime UTCYesImmutable
expiresAtdatetime UTCYesissuedAt plus 24h policy
stateenumYesACTIVE, EXPIRED, REVOKED
lastValidatedAtdatetime UTCNoUpdated on auth checks
encryptedSessionSecretsJSONNoAES-GCM envelope for refresh token and CSRF token; plaintext fields should be empty when encrypted

4.5 SyncQueueEntry

FieldTypeRequiredKeyConstraints
queueIdUUIDYesPKImmutable
eventIdUUIDYesFK AttendanceEvent.eventId or StudentEvent.eventIdMust exist
entityTypestringYesATTENDANCE_EVENT or STUDENT_EVENT
actionTypeenumYesMust match event payload
actorIdUUIDYesFK User.userIdMust exist
actorRoleenumYesSnapshot at queue time
enqueuedAtdatetime UTCYesImmutable
syncStateenumYesPENDING, IN_PROGRESS, SYNCED, FAILED, RETRYING
retryCountintegerYes0 to 5
failureCodestringNoLast sync error code
failureReasonstringNoLast sync error detail
lastAttemptAtdatetime UTCNoUpdated on each attempt

4.6 User

FieldTypeRequiredKeyConstraints
userIdUUIDYesPKImmutable
usernamestringYesUQ3 to 50 chars, lowercase alphanumeric and hyphen
displayNamestringYes1 to 100 chars
passwordHashstringYesSHA-256 hash only, plaintext forbidden
encryptedCredentialsJSONNoAES-GCM envelope for credential material at rest
cryptoKeyVersionintegerNoPer-user encryption key version
keyRotatedAtdatetime UTCNoLast key rotation time
roleenumYesROLL_CALLER, REPORT_USER, DATA_ENTRY, ADMIN_USER
statusenumYesACTIVE or DEACTIVATED
createdAtdatetime UTCYesImmutable
createdByUUID | nullYesFK User.userIdNull allowed for initial seed only
updatedAtdatetime UTCYesUpdated on non-deactivation changes
deactivatedAtdatetime UTCNoRequired when status is DEACTIVATED
deactivatedByUUIDNoFK User.userIdRequired when status is DEACTIVATED

4.7 UserEvent

FieldTypeRequiredKeyConstraints
eventIdUUIDYesPKImmutable
userIdUUIDYesFK User.userIdMust exist
eventTypeenumYesUSER_CREATED, USER_UPDATED, USER_DEACTIVATED, USER_PASSWORD_RESET
actorIdUUIDYesFK User.userIdMust exist
actorRoleenumYesMust match role at action time
timestampdatetime UTCYesClient event time
changePayloadJSONYesNever include passwordHash
encryptedChangePayloadJSONNoAES-GCM envelope when payload is persisted encrypted
syncStateenumYesPENDING, IN_PROGRESS, SYNCED, FAILED, RETRYING

5. IndexedDB Store Map

StorePrimary KeySecondary IndexesNotes
studentsstudentIdstatus, displayNameActive and deleted records retained
attendanceEventseventIdstudentId, timestamp, syncStateImmutable attendance history
studentEventseventIdstudentId, eventType, timestamp, syncStateImmutable student lifecycle history
syncQueuequeueIdsyncState, enqueuedAt, retryCountPending and retry workloads
sessionssessionIduserId, expiresAt, stateSession and re-auth gating
usersuserIdusername(unique), status, roleUser lifecycle and login lookup
userEventseventIduserId, eventType, timestamp, syncStateImmutable user lifecycle and credential history
localeResourceslocaleCode:keylocaleCodeUI text resources

6. Validation Rules

  • Deletion justification is mandatory for DELETE events and must be 10 to 500 characters.
  • Unauthorized role actions are rejected and logged.
  • Local writes happen before network sync attempts.
  • Protected sync submission requires active session.
  • Expired session allows local read-only mode, but blocks protected submissions until re-authentication.
  • User deactivation is soft only: status becomes DEACTIVATED; physical deletion is forbidden.
  • User deactivation guard rules: self-deactivation blocked and last-active ADMIN_USER deactivation blocked.
  • UserEvent.changePayload must never contain passwordHash; password changes are recorded as redacted markers.

7. Sync Payload Contract

7.1 Request

json
{
  "deviceId": "f32d6ce8-0d1a-4ffd-8e8a-3b7f4f0178a9",
  "sentAt": "2026-04-10T12:00:00Z",
  "events": [
    {
      "eventId": "3d9d2f89-8429-4f95-b0ad-6b849bb7e2e0",
      "timestamp": "2026-04-10T12:00:00Z",
      "action": "MARK_PRESENT",
      "studentId": "a1cc3a6a-8501-4fa8-9ea4-0afc7bb8d2f1",
      "actorId": "8aeb4c77-cbc9-47e6-b5aa-67ca967c7a6f",
      "roleId": "ROLL_CALLER",
      "syncState": "PENDING"
    }
  ]
}

7.2 Response

json
{
  "serverTime": "2026-04-10T12:00:03Z",
  "synced": [
    {
      "eventId": "3d9d2f89-8429-4f95-b0ad-6b849bb7e2e0",
      "serverTimestamp": "2026-04-10T12:00:02Z"
    }
  ],
  "failed": [],
  "conflicts": []
}

7.3 Conflict Response Example

json
{
  "serverTime": "2026-04-10T12:10:00Z",
  "synced": [],
  "failed": [
    {
      "eventId": "9a6ef640-65fa-4958-b281-c81d7e2fcf7e",
      "reason": "Superseded by admin action",
      "winnerEventId": "4ab6f882-f1f3-416a-b1a0-1237a9ed7f66"
    }
  ],
  "conflicts": [
    {
      "entityId": "a1cc3a6a-8501-4fa8-9ea4-0afc7bb8d2f1",
      "policyApplied": "ADMIN_PRECEDENCE",
      "loserEventId": "9a6ef640-65fa-4958-b281-c81d7e2fcf7e",
      "winnerEventId": "4ab6f882-f1f3-416a-b1a0-1237a9ed7f66"
    }
  ]
}

8. Conflict Resolution Rules

  1. If one event actorRole is ADMIN_USER and conflicts with lower-privilege event, admin event wins.
  2. If no admin involved, newest serverTimestamp wins.
  3. Losing events are retained with isConflictLoser equals true.
  4. Every resolved conflict is auditable and visible in history.

9. Compliance and Security Notes

  • Sensitive local data must use browser-compatible encryption at rest.
  • Sensitive session secrets and mutable event payloads should default to encrypted-at-rest envelopes with key version metadata.
  • Access to sensitive data remains role-scoped and action-scoped.
  • Device data retention after session expiry must follow read-only policy until re-authentication.
  • Audit retention must preserve create, update, delete, and attendance events for compliance review.

Distributed under MIT License.