feat(spec): complete implementation plan for Halloween event page
Created comprehensive planning documentation following Spec-Kit standards: Phase 0 - Research: - Analyzed 10 technical decisions (HTML5, ASCII art, countdown, responsive design) - Resolved edge cases (post-countdown, post-event, JS disabled, small screens) - Documented rationale and alternatives for each decision Phase 1 - Design: - Defined 4 data entities (Event, Countdown, VisualTheme, Content) - Created JSON schema contract for page content validation - Mapped 35 functional requirements to implementation approach - Generated quickstart testing checklist with 10 test categories Technical decisions: - Single-file HTML architecture (no external dependencies) - Pure CSS animations (blinking cursor) - JavaScript countdown with GMT+8 timezone handling - Responsive ASCII art (desktop/mobile versions) - WCAG 2.1 AA compliance (21:1 contrast ratio) Constitution compliance: PASS - No violations detected - Follows user-centric, professional excellence principles - Minimal technical stack aligns with simplicity requirement Artifacts created: - spec.md: 35 functional requirements - plan.md: Implementation strategy and phases - research.md: 10 technical research decisions - data-model.md: 4 entity definitions with validation - contracts/page-content.schema.json: JSON Schema - quickstart.md: Comprehensive testing checklist Ready for: /tasks command to generate tasks.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
364
specs/001-mcdonald-s-it/contracts/page-content.schema.json
Normal file
364
specs/001-mcdonald-s-it/contracts/page-content.schema.json
Normal file
@@ -0,0 +1,364 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://mcdonald-s-it-halloween.schema.json",
|
||||
"title": "McDonald's IT Halloween Event Page Content Schema",
|
||||
"description": "Schema defining the structure and validation rules for the Halloween 2025 event page content",
|
||||
"type": "object",
|
||||
"required": ["meta", "theme", "event", "countdown", "ascii"],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"type": "object",
|
||||
"description": "Page metadata for browser and SEO",
|
||||
"required": ["title", "description", "favicon"],
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"const": "2025 MITA Halloween",
|
||||
"description": "Browser tab title"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"minLength": 50,
|
||||
"maxLength": 160,
|
||||
"description": "Meta description for SEO",
|
||||
"default": "McDonald's China IT Halloween 2025 - Join 300 MITA developers for cosplay, debugging games, and lucky draw at MITA Building 2F Pantry"
|
||||
},
|
||||
"favicon": {
|
||||
"type": "string",
|
||||
"pattern": "^data:image",
|
||||
"description": "Data URI for favicon (pumpkin emoji)"
|
||||
},
|
||||
"lang": {
|
||||
"type": "string",
|
||||
"enum": ["en", "zh-CN"],
|
||||
"default": "en",
|
||||
"description": "Primary page language"
|
||||
}
|
||||
}
|
||||
},
|
||||
"theme": {
|
||||
"type": "object",
|
||||
"description": "Visual design theme configuration",
|
||||
"required": ["backgroundColor", "primaryColor", "accentColor", "fontFamily"],
|
||||
"properties": {
|
||||
"backgroundColor": {
|
||||
"type": "string",
|
||||
"pattern": "^#[0-9A-Fa-f]{6}$",
|
||||
"const": "#000000",
|
||||
"description": "Pure black background"
|
||||
},
|
||||
"primaryColor": {
|
||||
"type": "string",
|
||||
"pattern": "^#[0-9A-Fa-f]{6}$",
|
||||
"const": "#00FF00",
|
||||
"description": "Terminal green for main text"
|
||||
},
|
||||
"accentColor": {
|
||||
"type": "string",
|
||||
"pattern": "^#[0-9A-Fa-f]{6}$",
|
||||
"const": "#FFBF00",
|
||||
"description": "Amber for key information"
|
||||
},
|
||||
"fontFamily": {
|
||||
"type": "string",
|
||||
"pattern": "monospace",
|
||||
"description": "Monospace font stack"
|
||||
},
|
||||
"fontSize": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"base": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]+(px|rem|em)$",
|
||||
"default": "16px"
|
||||
},
|
||||
"heading": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]+(px|rem|em)$",
|
||||
"default": "20px"
|
||||
},
|
||||
"small": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]+(px|rem|em)$",
|
||||
"default": "14px"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"event": {
|
||||
"type": "object",
|
||||
"description": "Halloween event details",
|
||||
"required": ["title", "date", "startTime", "endTime", "timezone", "location", "organizer", "activities"],
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"const": "2025 MITA Halloween"
|
||||
},
|
||||
"date": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"const": "2025-10-31",
|
||||
"description": "Event date in ISO format"
|
||||
},
|
||||
"startTime": {
|
||||
"type": "string",
|
||||
"pattern": "^([01]?[0-9]|2[0-3]):[0-5][0-9]$",
|
||||
"const": "18:00",
|
||||
"description": "Event start time in 24h format"
|
||||
},
|
||||
"endTime": {
|
||||
"type": "string",
|
||||
"pattern": "^([01]?[0-9]|2[0-3]):[0-5][0-9]$",
|
||||
"const": "21:00",
|
||||
"description": "Event end time in 24h format"
|
||||
},
|
||||
"timezone": {
|
||||
"type": "string",
|
||||
"const": "GMT+8",
|
||||
"description": "Event timezone"
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"const": "MITA Building 2F Pantry",
|
||||
"description": "Physical event location"
|
||||
},
|
||||
"organizer": {
|
||||
"type": "object",
|
||||
"required": ["name", "email"],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"const": "Jessi Pan"
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
"const": "jessi.pan@cn.mcd.com"
|
||||
}
|
||||
}
|
||||
},
|
||||
"activities": {
|
||||
"type": "array",
|
||||
"minItems": 3,
|
||||
"maxItems": 5,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 3
|
||||
},
|
||||
"description": "List of event activities"
|
||||
},
|
||||
"notes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 5
|
||||
},
|
||||
"description": "Additional event information"
|
||||
},
|
||||
"audience": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"department": {
|
||||
"type": "string",
|
||||
"const": "MITA"
|
||||
},
|
||||
"count": {
|
||||
"type": "integer",
|
||||
"const": 300
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"const": "McDonald's China IT team members"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"countdown": {
|
||||
"type": "object",
|
||||
"description": "Countdown timer configuration",
|
||||
"required": ["targetDateTime", "timezone"],
|
||||
"properties": {
|
||||
"targetDateTime": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"const": "2025-10-31T10:00:00Z",
|
||||
"description": "Target datetime in UTC (18:00 GMT+8)"
|
||||
},
|
||||
"eventEndDateTime": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"const": "2025-10-31T13:00:00Z",
|
||||
"description": "Event end datetime in UTC (21:00 GMT+8)"
|
||||
},
|
||||
"timezone": {
|
||||
"type": "string",
|
||||
"const": "GMT+8",
|
||||
"description": "Display timezone"
|
||||
},
|
||||
"updateInterval": {
|
||||
"type": "integer",
|
||||
"minimum": 1000,
|
||||
"maximum": 1000,
|
||||
"default": 1000,
|
||||
"description": "Update interval in milliseconds"
|
||||
},
|
||||
"messages": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"before": {
|
||||
"type": "string",
|
||||
"description": "Message to show before event"
|
||||
},
|
||||
"active": {
|
||||
"type": "string",
|
||||
"const": "🎃 EVENT STARTING NOW! 🎃",
|
||||
"description": "Message when event starts"
|
||||
},
|
||||
"ended": {
|
||||
"type": "string",
|
||||
"const": "👻 EVENT COMPLETED - Thanks for joining! 👻",
|
||||
"description": "Message after event ends"
|
||||
},
|
||||
"noJs": {
|
||||
"type": "string",
|
||||
"const": "Enable JavaScript for live countdown",
|
||||
"description": "Fallback message when JS disabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ascii": {
|
||||
"type": "object",
|
||||
"description": "ASCII art content",
|
||||
"required": ["logo", "decorations"],
|
||||
"properties": {
|
||||
"logo": {
|
||||
"type": "object",
|
||||
"required": ["desktop", "mobile"],
|
||||
"properties": {
|
||||
"desktop": {
|
||||
"type": "string",
|
||||
"minLength": 50,
|
||||
"description": "McDonald's ASCII logo for desktop (with Golden Arches)"
|
||||
},
|
||||
"mobile": {
|
||||
"type": "string",
|
||||
"minLength": 20,
|
||||
"description": "McDonald's ASCII logo for mobile (simplified)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagline": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string",
|
||||
"const": "i'm lovin' IT"
|
||||
},
|
||||
"cursor": {
|
||||
"type": "string",
|
||||
"enum": ["_", "|", "█"],
|
||||
"default": "_"
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorations": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"description": "Halloween-themed ASCII art or emoji"
|
||||
},
|
||||
"description": "Halloween decorations (pumpkins, ghosts, bats)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"type": "object",
|
||||
"description": "Bilingual content pairs",
|
||||
"properties": {
|
||||
"pairs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["section", "english", "chinese"],
|
||||
"properties": {
|
||||
"section": {
|
||||
"type": "string",
|
||||
"enum": ["date", "time", "location", "organizer", "activities", "notes"]
|
||||
},
|
||||
"english": {
|
||||
"type": "string",
|
||||
"minLength": 5
|
||||
},
|
||||
"chinese": {
|
||||
"type": "string",
|
||||
"minLength": 3
|
||||
},
|
||||
"order": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"accessibility": {
|
||||
"type": "object",
|
||||
"description": "Accessibility configuration",
|
||||
"properties": {
|
||||
"wcagLevel": {
|
||||
"type": "string",
|
||||
"enum": ["AA", "AAA"],
|
||||
"const": "AA",
|
||||
"description": "WCAG compliance level"
|
||||
},
|
||||
"contrastRatios": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"primaryOnBackground": {
|
||||
"type": "number",
|
||||
"minimum": 21,
|
||||
"description": "Green (#00FF00) on black (#000000)"
|
||||
},
|
||||
"accentOnBackground": {
|
||||
"type": "number",
|
||||
"minimum": 12,
|
||||
"description": "Amber (#FFBF00) on black (#000000)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ariaLabels": {
|
||||
"type": "object",
|
||||
"description": "ARIA labels for screen readers"
|
||||
}
|
||||
}
|
||||
},
|
||||
"performance": {
|
||||
"type": "object",
|
||||
"description": "Performance requirements",
|
||||
"properties": {
|
||||
"maxFileSize": {
|
||||
"type": "integer",
|
||||
"maximum": 51200,
|
||||
"description": "Maximum file size in bytes (50KB)"
|
||||
},
|
||||
"maxLoadTime": {
|
||||
"type": "integer",
|
||||
"maximum": 1000,
|
||||
"description": "Maximum load time in milliseconds"
|
||||
},
|
||||
"targetFrameRate": {
|
||||
"type": "integer",
|
||||
"const": 60,
|
||||
"description": "Target frame rate for animations"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
Reference in New Issue
Block a user