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

214 lines
6.6 KiB
Markdown

# 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**:
```json
{
"isChristmas": boolean,
"date": "YYYY-MM-DD"
}
```
**Example Responses**:
Non-Christmas Day:
```json
{
"isChristmas": false,
"date": "2025-11-11"
}
```
Christmas Day:
```json
{
"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)