Files
Julien Lengrand-Lambert 16ae2a1430 Creating the project
2025-11-11 10:06:56 +01:00

6.6 KiB

Data Model: Christmas Checker Website

Date: 2025-11-11 Feature: Christmas Checker Website Branch: 001-christmas-checker

Overview

This feature has minimal data modeling requirements. No persistent storage is needed. All data is ephemeral and computed in real-time from the current system date.

Entities

1. Date

Description: Represents the current calendar date used to determine if today is Christmas.

Source: System clock (server-side: LocalDate.now(), client-side: new Date())

Attributes:

  • month: Integer (1-12) representing the month of the year
  • day: Integer (1-31) representing the day of the month
  • year: Integer (e.g., 2025) representing the year

Validation Rules:

  • Month MUST be between 1 and 12
  • Day MUST be valid for the given month (1-31, accounting for month lengths)
  • Year MUST be a positive integer

Lifecycle:

  • Created: On each page load or API request
  • Updated: Never (immutable, represents a point in time)
  • Deleted: Immediately after use (no persistence)

Relationships: None


2. ChristmasStatus

Description: A computed boolean state representing whether the current date is Christmas (December 25th or 26th).

Source: Derived from Date entity

Attributes:

  • isChristmas: Boolean (true if month=12 AND (day=25 OR day=26), false otherwise)
  • checkedDate: String (ISO 8601 format, e.g., "2025-12-25") - the date that was checked

Computation Logic:

isChristmas = (date.month == 12) AND (date.day == 25 OR date.day == 26)

Validation Rules:

  • isChristmas MUST be a boolean (true or false)
  • checkedDate MUST be a valid ISO 8601 date string (YYYY-MM-DD)

Lifecycle:

  • Created: On each page load or API request
  • Updated: Never (computed value for a specific point in time)
  • Deleted: Immediately after use (no persistence)

Relationships:

  • Depends on: Date entity (requires Date to compute isChristmas)

Data Flow

Client-Side Flow (Primary)

  1. User loads page in browser
  2. JavaScript executes: const today = new Date()
  3. Extract month and day: today.getMonth() + 1 and today.getDate()
  4. Compute: isChristmas = (month === 12 && (day === 25 || day === 26))
  5. Render UI based on isChristmas:
    • If true: Display "Yes" + snow animation
    • If false: Display "No" + sad smiley

Server-Side Flow (Optional/Fallback)

  1. Client makes GET request to /api/christmas
  2. Backend executes: LocalDate today = LocalDate.now()
  3. Extract month and day: today.getMonthValue() and today.getDayOfMonth()
  4. Compute: isChristmas = (month == 12 && (day == 25 || day == 26))
  5. Return JSON: { "isChristmas": true/false, "date": "YYYY-MM-DD" }
  6. Client renders UI based on response

State Transitions

ChristmasStatus State Machine

┌─────────────┐
│   Initial   │
│  (Unknown)  │
└──────┬──────┘
       │
       │ Check current date
       │
       ├──────────────┬──────────────┐
       │              │              │
       ▼              ▼              ▼
┌──────────┐   ┌──────────┐   ┌──────────┐
│ Not      │   │ Is       │   │ Error    │
│Christmas │   │Christmas │   │(Invalid) │
│(364 days)│   │(1 day)   │   │          │
└──────────┘   └──────────┘   └──────────┘

States:

  • Initial: State before date is checked
  • NotChristmas: Date is not December 25th or 26th (363 days per year)
  • IsChristmas: Date is December 25th or 26th (2 days per year)
  • Error: Invalid date or computation failure (edge case)

Transitions:

  • Initial → NotChristmas: When date is checked and (month != 12 OR (day != 25 AND day != 26))
  • Initial → IsChristmas: When date is checked and month == 12 AND (day == 25 OR day == 26)
  • Initial → Error: When date check fails (system clock unavailable, invalid date)

No Persistent State: Each page load/API call starts from Initial state. No memory of previous checks.

Timezone Considerations

Client-Side (Primary):

  • Uses browser's local timezone via JavaScript Date() object
  • Matches user's expectation of "today" in their location
  • Satisfies FR-001: "System MUST determine current date based on user's local time zone"

Server-Side (Fallback):

  • Uses server's local timezone via Java LocalDate.now()
  • May differ from user's timezone (acceptable for fallback scenario)
  • If precision needed, could accept timezone offset as query parameter

Edge Case: User at midnight on Dec 24/25 or Dec 25/26

  • Client-side handles this naturally (user's local time)
  • Server-side may show different result if in different timezone
  • Recommendation: Use client-side check as authoritative

API Response Schema

GET /api/christmas

Response Body:

{
  "isChristmas": boolean,
  "date": "YYYY-MM-DD"
}

Example Responses:

Non-Christmas Day:

{
  "isChristmas": false,
  "date": "2025-11-11"
}

Christmas Day:

{
  "isChristmas": true,
  "date": "2025-12-25"
}

Storage Requirements

Persistent Storage: NONE

Rationale:

  • All data is computed in real-time from system clock
  • No user data to store
  • No configuration to persist
  • No history tracking required
  • Satisfies "no need for storage" requirement from user

In-Memory Only:

  • Date and ChristmasStatus exist only during request/response cycle
  • Garbage collected immediately after use
  • No caching needed (computation is trivial, <1ms)

Validation Summary

Entity Field Type Validation Error Handling
Date month Integer 1-12 Return error response
Date day Integer 1-31 Return error response
Date year Integer > 0 Return error response
ChristmasStatus isChristmas Boolean true OR false Default to false
ChristmasStatus checkedDate String ISO 8601 format Use fallback date

Performance Characteristics

Computation Cost: O(1) - constant time

  • Two integer comparisons: month == 12 AND day == 25
  • No database queries
  • No network calls
  • No complex calculations

Memory Footprint: Negligible

  • Two integers (month, day): 8 bytes
  • One boolean (isChristmas): 1 byte
  • One date string: ~10 bytes
  • Total: ~20 bytes per request

Scalability: Linear with request count

  • Each request independent (stateless)
  • No shared state between requests
  • Can handle millions of concurrent requests (limited only by HTTP server capacity)