Database Schema

Overview

This document describes the database schema and data persistence layer for the Absence Management module. The system uses MongoDB as the primary database with Mongoose as the ODM layer.

Database Schema

Absence Collection

Collection Name: absence

The absence collection stores all absence records with the following schema structure:

{
  _id: ObjectId,                    // Primary key
  note: String,                     // Optional description
  start: String,                    // Start date/time (ISO string) - REQUIRED
  end: String,                      // End date/time (ISO string) - REQUIRED
  entireBusiness: Boolean,          // Affects entire business flag
  members: [ObjectId],              // References to Member collection
  memberIds: [String],              // Array of member ID strings
  locations: [LocationSchema],      // Embedded location documents
  type: String,                     // Absence type (vacation, holiday, break) - REQUIRED
  timeZone: String,                 // Timezone identifier - REQUIRED
  meta: MetaSchema,                 // Metadata information
  stateHistory: [StateHistorySchema], // State tracking for soft deletes
  createdAt: Date,                  // Auto-generated creation timestamp
  updatedAt: Date                   // Auto-generated update timestamp
}

Schema Definition

Field Specifications

Required Fields

Field
Type
Description
Validation

start

String

Start date/time in ISO format

Must be valid ISO date string

end

String

End date/time in ISO format

Must be valid ISO date string, must be after start

type

String

Type of absence

Must be one of: 'vacation', 'holiday', 'break'

timeZone

String

IANA timezone identifier

Must be valid timezone string

Optional Fields

Field
Type
Description
Default

note

String

Description or notes about the absence

null

entireBusiness

Boolean

Whether this affects the entire business

false

members

ObjectId[]

References to assigned members

[]

memberIds

String[]

Member IDs as strings

[]

locations

LocationSchema[]

Affected locations

[]

System Fields

Field
Type
Description
Auto-Generated

_id

ObjectId

Primary key

Yes

meta

MetaSchema

Metadata information

Partial

stateHistory

StateHistorySchema[]

State change tracking

Yes

createdAt

Date

Creation timestamp

Yes

updatedAt

Date

Last modification timestamp

Yes

Embedded Schemas

LocationSchema

MetaSchema

StateHistorySchema

Relationships

Member Relationship

  • Type: One-to-Many (Absence โ†’ Members)

  • Implementation: Array of ObjectId references

  • Collection: member

  • Lookup: Populated during queries when member details are needed

Location Relationship

  • Type: Embedded Documents

  • Implementation: Array of LocationSchema subdocuments

  • Storage: Denormalized within absence document

Indexing Strategy

Primary Indexes

Composite Indexes

Query Patterns

Common Queries

Find Absences by Date Range

Find Member-Specific Absences

Paginated Query with Population

Repository Implementation

AbsenceRepository

The repository class extends BaseRepository and implements IAbsenceRepository:

Key Repository Methods

Standard CRUD Operations

  • createItem(absence: IAbsence): Promise<IAbsence>

  • updateItem(id: string, absence: IAbsence): Promise<IAbsence>

  • findById(id: string): Promise<IAbsence | null>

  • deleteItem(id: string): Promise<void> (soft delete)

Specialized Queries

  • getAbsencesWithFilter(params): Promise<ISlot[]>

  • findByDateRange(start: string, end: string): Promise<IAbsence[]>

  • findByMember(memberId: string): Promise<IAbsence[]>

Data Consistency

Soft Delete Pattern

Absences use soft deletion through the state history mechanism:

State History Tracking

All state changes are tracked in the stateHistory array:

  • Initial state: 'active'

  • Soft delete: 'deleted'

  • Future states: 'archived', 'suspended', etc.

Query Filtering

Non-deleted records are filtered using aggregation expressions:

Multi-Tenancy

Tenant Isolation

Data isolation is achieved through the meta.tenantId field:

  • All queries must include tenant filter

  • Indexes include meta.tenantId for performance

  • Application layer enforces tenant boundary

Tenant-Aware Queries

Performance Considerations

Query Optimization

  1. Index Usage: Ensure queries use appropriate indexes

  2. Projection: Select only needed fields

  3. Population: Use selective field population

  4. Aggregation: Use aggregation pipelines for complex queries

Scaling Strategies

  1. Sharding: Consider sharding by meta.tenantId

  2. Read Replicas: Use read replicas for query-heavy operations

  3. Caching: Implement Redis caching for frequently accessed data

  4. Archive Strategy: Archive old absences to separate collection

Data Migration

Schema Evolution

When schema changes are needed:

  1. Backward Compatible: Add optional fields

  2. Migration Scripts: Create scripts for data transformation

  3. Versioning: Use meta.version for schema versioning

  4. Rollback: Maintain rollback procedures

Example Migration Script

Backup and Recovery

Backup Strategy

  1. Regular Snapshots: Daily MongoDB snapshots

  2. Point-in-Time Recovery: Enable oplog for PITR

  3. Cross-Region Replication: For disaster recovery

  4. Testing: Regular backup restoration testing

Data Retention

  1. Active Data: Keep in primary collection

  2. Archived Data: Move to archive collection after retention period

  3. Deleted Data: Hard delete after legal retention requirements

Monitoring and Alerts

Database Metrics

  • Query performance

  • Index usage statistics

  • Document growth rate

  • Connection pool utilization

Alert Conditions

  • Slow queries (>100ms)

  • Index misses

  • High memory usage

  • Replication lag

Security Considerations

Data Protection

  1. Encryption at Rest: Enable MongoDB encryption

  2. Encryption in Transit: Use TLS for connections

  3. Field-Level Encryption: For sensitive data

  4. Access Control: Role-based database access

Audit Trail

State history provides audit trail for:

  • Who modified the absence

  • When changes occurred

  • What the previous state was

  • Reason for changes

Last updated

Was this helpful?