From 5172c696bd8c0c1e58af3582153fb1f2bd2e78b4 Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Wed, 12 Nov 2025 11:20:15 +0000 Subject: [PATCH] docs: Update CHANGELOG and test mocks for Contract v1 migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Contract v1 breaking changes to CHANGELOG.md - Document field name changes (fetchedAt→fetchTime, url→mediaUrl) - Update test mocks in www/index.html and ios/App/App/public/index.html - Mocks now return Contract v1 format (fetchTime, title, body, ttlSeconds) BREAKING CHANGE: API responses now use Contract v1 field names. See docs/CONTRACT_V1_BREAKING_CHANGES.md for migration guide. --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++ ios/App/App/public/index.html | 7 +++++-- www/index.html | 7 +++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f944c49..2e18385 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,39 @@ All notable changes to the Daily Notification Plugin will be documented in this The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Breaking Changes + +- **Contract v1 Migration**: API responses now use Contract v1 field names + - `fetchedAt` → `fetchTime` (epoch ms) - All content cache API methods now return `fetchTime` instead of `fetchedAt` + - `url` → `mediaUrl` - Media URL field renamed to match Contract v1 + - `payload` (string) → structured fields - Response now includes `title`, `body`, and `metadata` instead of raw `payload` string + - `meta` field removed - Replaced by structured `metadata` object + - **Affected Methods**: `getContentCache()`, `getContentCacheById()`, `getLatestContentCache()`, `getContentCacheHistory()` + - **Migration Guide**: See `docs/CONTRACT_V1_BREAKING_CHANGES.md` for details + - **TypeScript Interface**: `ContentCache` interface updated to match Contract v1 (legacy fields marked as deprecated) + +### Added + +- **Contract v1 Freeze**: Contract v1 directive and validation system + - Contract v1 defined and frozen (`contracts/NotificationContract.v1.ts`) + - Contract validation script (`./scripts/check-contract.sh`) + - Pre-commit hook for contract validation (optional) + - DTOs and mappers for iOS and Android to ensure Contract v1 compliance + - See `docs/0017-Daily-Notification-Contract-Freeze.md` for details + +- **Cross-Platform DTOs**: Data Transfer Objects for Contract v1 + - iOS: `NotificationContentDTO` and `NotificationContentMapper` + - Android: `NotificationContentDTO` and `NotificationContentMapper` + - Ensures consistent field names and types across platforms + +### Changed + +- **API Response Format**: All content cache methods now return Contract v1 format + - Structured response with `title`, `body`, `fetchTime`, `mediaUrl`, `ttlSeconds`, etc. + - Legacy fields (`fetchedAt`, `payload`, `meta`) deprecated but may be present for backward compatibility + ## [2.1.0] - 2025-01-02 ### Added diff --git a/ios/App/App/public/index.html b/ios/App/App/public/index.html index be40a1c..657bff2 100644 --- a/ios/App/App/public/index.html +++ b/ios/App/App/public/index.html @@ -325,8 +325,11 @@ }, getContentCache: async () => { return Promise.resolve({ - 'cache-key-1': { content: 'Mock cached content', timestamp: Date.now() }, - 'cache-key-2': { content: 'Another mock item', timestamp: Date.now() - 3600000 } + id: 'mock-cache-001', + title: 'Mock Notification', + body: 'Mock cached content', + fetchTime: Date.now(), // Contract v1 (epoch ms) + ttlSeconds: 3600 }); }, clearContentCache: async () => { diff --git a/www/index.html b/www/index.html index be40a1c..657bff2 100644 --- a/www/index.html +++ b/www/index.html @@ -325,8 +325,11 @@ }, getContentCache: async () => { return Promise.resolve({ - 'cache-key-1': { content: 'Mock cached content', timestamp: Date.now() }, - 'cache-key-2': { content: 'Another mock item', timestamp: Date.now() - 3600000 } + id: 'mock-cache-001', + title: 'Mock Notification', + body: 'Mock cached content', + fetchTime: Date.now(), // Contract v1 (epoch ms) + ttlSeconds: 3600 }); }, clearContentCache: async () => {