22 KiB
22 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[1.7.1] - 2026-07-19
Fixed
- Web build failure with dio >= 5.8:
DioExceptionTypeswitch is now exhaustive across dio versions (CI resolves dependencies fresh)
[1.7.0] - 2026-07-19
Changed
- Default Core API and Tatlock API URLs now use the public domains
https://api.schweitz.netandhttps://tatlock.schweitz.net(previously LANhttp://192.168.86.149:8083/:8000), so default builds require OIDC auth; override via--dart-definefor direct LAN development
Removed
- Netdata and Cloud IDE (code-server) quick links — both services are
decommissioned; also dropped the unused
portainerUrl/netdataUrlconfig constants
[1.6.0] - 2026-01-08
Added
- News Ticker Widget - Scrolling news headlines on dashboard
- Full-width ticker between Welcome card and System Stats
- Horizontal auto-scrolling at 40px/second with seamless looping
- Fetches headlines from
/tools/newsendpoint - Placeholder headlines shown when no data (italic, muted style)
- Auto-refresh every 30 minutes
- News data model (
NewsData,NewsHeadline) with Freezed - News datasource calling
GET /tools/news - News provider with
hasNewshelper
[1.5.9] - 2026-01-08
Changed
- Aligned horizon line across all widgets - Consistent visual baseline at 50px from bottom
- Weather and Air Quality dividers now align with Sun Position horizon line
- Forecast card bottoms align with the same horizon
- Creates unified visual rhythm across all environment cards
[1.5.8] - 2026-01-08
Changed
- Bottom-aligned widget content - All environment widgets now align content from the bottom
- Creates consistent visual baseline across Sun Position, Weather, Air Quality, and Forecast cards
- Footers (weather details, pollutants) sit at the same level across cards
Added
- Wind direction in Weather - Wind chip now shows direction (e.g., "SE 14 km/h")
[1.5.7] - 2026-01-08
Fixed
-
Environment widget alignment - Consistent card heights across all environment widgets
- Added
ConstrainedBox(minHeight: 170)to Weather, Air Quality, and Forecast widgets - All cards now match Sun Position widget height when displaying data
- Added
-
Sun position night labels - Swap sunrise/sunset labels at night
- During day: Sunrise on left, Sunset on right (day arc)
- At night: Sunset on left, Sunrise on right (night arc)
Changed
- Weather widget header - Changed from location name to "Weather" for consistency
- Location now displayed in content area below temperature
[1.5.6] - 2026-01-07
Changed
- Environment user logging - Now logs API user only once per session instead of on every refresh
[1.5.5] - 2026-01-07
Fixed
- Sun position arc overflow - Arc now constrained to fit within card boundaries
- Prevents arc and sun/moon from overflowing on wider displays
- Scales radius down when arc height exceeds available space
Added
- Debug logging for environment user - Logs authenticated user on environment data load
[1.5.4] - 2026-01-07
Added
- User display in environment section header (reverted in 1.5.5)
[1.5.3] - 2026-01-07
Changed
- Sun position arc redesign - Arc now touches horizon at sunrise/sunset points
- Arc geometry uses chord-radius calculation for proper horizon intersection
- Sunrise/sunset icons integrated at horizon endpoints (no duplicate labels)
- Daylight duration centered below arc
- Increased card height 20% for better arc visibility (140px → 170px)
- Visual balance improvements - Sunrise/sunset labels raised 10px, daylight label at bottom
[1.5.2] - 2026-01-07
Changed
- Proportional sun/moon arc visualization - Arc angle now proportional to day/night duration
- Day arc: spans (daylight hours / 24) × 360° above horizon
- Night arc: spans (night hours / 24) × 360° with moon traversal
- Horizon points represent sunrise/sunset times
- Gradient colors: yellow/orange for day, blue/indigo for night
- Sun position widget now updates every 10 minutes - Position aligned to clock intervals (0/10/20/30/40/50)
- Converted to StatefulWidget with timer-based updates
- Shows default 7am/5pm sunrise/sunset when API data unavailable (asymmetric for visual effect)
- Always displays times and daylight duration (no more "--:--")
- Environment widgets consistent height - All cards maintain same height in "no data" state
[1.5.1] - 2026-01-07
Changed
- Environment widgets layout redesign - All 4 widgets always visible with responsive layout
- Desktop (>900px): 4-in-a-row with 30/20/20/30 width distribution (Sun | Weather | Air Quality | Forecast)
- Tablet (600-900px): 2x2 grid layout
- Mobile (<600px): Stacked vertically
- Widgets now show "No data available" state instead of being hidden or using mock data
- Sun position widget now calculates position from system clock
- Defaults to 6am/6pm (12-hour day/night cycles) when API sun times unavailable
- Environment data refresh interval changed from 5 minutes to 1 hour
[1.5.0] - 2026-01-06
Added
- Dynamic Environment Widgets - Live weather, sun position, and forecast data from Qdrant
SunPositionWidget- Animated semicircle arc showing sun/moon position based on current time- Gradient colors: yellow for daytime, orange for sunrise/sunset, blue for night
- Displays sunrise, sunset times and daylight duration
WeatherWidget- Current temperature, conditions, humidity from APIForecastWidget- Multi-day weather forecast with conditions iconsAirQualityWidget- AQI display (only shown when data available)
- Environment data provider with auto-refresh every 5 minutes
- Environment datasource calling
GET /tools/environment - Freezed models for environment data (weather, forecast, sun times, air quality)
- Comprehensive widget tests for environment section
Changed
- Dashboard layout now displays dynamic environment data instead of static widgets
- Weather and air quality widgets accept optional API data parameters
[1.4.0] - 2026-01-05
Added
- Decentralized Room Registry - Each room registers itself with central registry
RoomDefinitionclass with id, label, icons, routes, and permissionsRoomRegistrysingleton for managing all rooms- Dynamic navigation tabs built from registry
- Settings dropdown builds from available rooms
- Permission-based room filtering support
- Media Room - New placeholder room for future media management features
- Parlor - Now a proper feature folder with router registration
Changed
- Room navigation is now fully dynamic via registry
top_header_bar.dartusesroomRegistry.allinstead of hardcoded listapp_scaffold.dartuses registry for route matching and navigation- Settings page dropdown populated from
roomRegistry.all
- Routers moved to per-room pattern:
lib/features/front_hall/router.dart(new)lib/features/parlor/router.dart(new)lib/features/media_room/router.dart(new)- Existing
control_room/router.dartandsecurity/router.dartnow register with registry
- Documentation updated in ARCHITECTURE.md with Room Registry Pattern section
Removed
- Hardcoded room lists in
top_header_bar.dartandapp_scaffold.dart _PlaceholderPagewidget inapp_router.dart(each room has its own page)
[1.3.1] - 2026-01-05
Fixed
- Default room preference now applies on app load
- Root
/redirects to user's preferred default room - Front Hall moved to
/front-hallroute (was/)
- Root
[1.3.0] - 2026-01-05
Added
- URL deep-linking for DataGrids - State is now reflected in URL query parameters
?search=- DataGrid search query?sort=- Column ID for sorting?order=desc- Sort direction?id=- Opened document ID (proxy hosts page)
PageUrlStateutility class (lib/routing/url_state.dart) for URL ↔ state serialization- Browser URL updates via
replaceStatewithout triggering GoRouter rebuilds idfield added toDataGridColumnfor unique column identification in URLsFilterPanelSemanticsclass for filter panel semantic IDs- TESTING.md documentation for semantic widgets and automation testing
Changed
idSelectorin DataGridController now returnsString(wasObject) for URL compatibility- All DataGrid pages now support URL deep-linking:
- Containers list (
/control-room/containers) - Proxy hosts (
/control-room/proxy-hosts) - Users (
/security/users) - Groups (
/security/groups)
- Containers list (
- Router passes
GoRouterStateto pages for query parameter access
[1.2.0] - 2026-01-05
Added
- Semantic labels for UI automation (
lib/core/semantics/)semantic_ids.dart- Centralized semantic identifier constantssemantic_widget.dart- Helper widget and extension for adding semantics- Enables browser automation tools (Puppeteer, WebDriver) via accessibility tree
- Semantic IDs added to:
- Profile dropdown button and menu items (theme options, settings, logout)
- Room navigation tabs (Front Hall, Control Room, Security, Parlor)
- NavPanel items (sidebar navigation)
SemanticsBinding.instance.ensureSemantics()enabled on web builds
[1.1.16] - 2026-01-05
Fixed
- Theme toggle causing logout due to AuthInterceptor auto-signout on 401
- Removed aggressive
signOut()call inAuthInterceptor.onError - 401 errors now propagate to calling code for graceful handling
- Preferences API 401 no longer triggers full logout redirect
- Removed aggressive
[1.1.15] - 2026-01-05
Fixed
- Theme toggle causing auth issues due to AuthNotifier auto-dispose
- Applied
@persistentRiverpodannotation to AuthNotifier - AuthProvider now persists for app lifetime, preventing rebuild on theme change
- Applied
[1.1.14] - 2026-01-04
Fixed
- Theme toggle causing auth issues due to ThemeProvider auto-dispose
- Added
@persistentRiverpodannotation for providers that need keepAlive - ThemeProvider now persists for app lifetime
- Added
Added
@persistentRiverpodannotation incore/providers/annotations.dart- Reusable annotation for providers that should not auto-dispose
- Documented in ARCHITECTURE.md
[1.1.13] - 2026-01-04
Added
- Settings page with Appearance, Navigation, and Account sections
- Theme toggle in user profile dropdown (System/Light/Dark)
- Theme syncs with API preferences on login
- Default room preference syncs with backend
Changed
- Theme changes now persist to both local storage and API
[1.1.12] - 2026-01-04
Changed
- Control Room navigation reorganized:
- New "Stack" section with Containers and Proxy Hosts
- New "Data Management" section with PostgreSQL, Redis, Qdrant, Neo4j placeholders
- Removed: Networks, Volumes, Images (Portainer) and Redirections, Streams, Certificates (NPM)
[1.1.11] - 2026-01-04
Fixed
- API client providers now use
keepAlive: trueto prevent Ref invalidation- Fixes "DioException [unknown]: null" error on /security/users and other API pages
- AuthInterceptor's stored Ref was becoming invalid when provider auto-disposed
[1.1.10] - 2026-01-04
Changed
- Removed page swipe transitions - all navigation is now instant (NoTransitionPage)
[1.1.9] - 2026-01-04
Changed
- Moved health check to
/healthdirectory - URL is now/healthinstead of/health.html- Enables NPM forward auth path exclusion for health endpoint
[1.1.8] - 2026-01-04
Changed
- Dark background (
#1a1a2e) on web/index.html to prevent white flash during auth redirects
[1.1.7] - 2026-01-04
Removed
- Removed
/callbackroute from Flutter router - AuthController handles callback in main() before app starts - Removed
_OidcCallbackPagewidget - no visible auth UI needed
[1.1.6] - 2026-01-04
Changed
- Auth moved to standalone controller - Handles OIDC completely outside Riverpod
- New
AuthControllerruns inmain()beforerunApp()- avoids provider lifecycle issues - Handles callback, token exchange, and /auth/sync before app starts
- If auth not ready (redirecting), app doesn't start at all
AuthProvidernow just loads stored tokens (no async OIDC logic)- Fixes "Cannot use Ref after disposed" errors from autoDispose providers
- New
[1.1.5] - 2026-01-04
Fixed
- Race condition in OIDC callback: AuthProvider.build() was initiating silent OIDC while the callback page was processing, causing PKCE state to be cleared. Now skips silent OIDC when on
/callbackroute.
[1.1.4] - 2026-01-04
Fixed
- Silent OIDC fallback: when
prompt=nonefails withlogin_required(no Authentik session), automatically fall back to regular OIDC flow to show login UI
[1.1.3] - 2026-01-04
Changed
- Web auth uses silent OIDC with JWT Bearer tokens
- Uses
prompt=noneto silently obtain JWT when Authentik session exists (via NPM forward auth) - Flutter sends Bearer token to core-api instead of relying on forward auth cookies
- Fixes cross-subdomain cookie issues between home.schweitz.net and api.schweitz.net
- Callback now syncs with
/auth/syncto get user profile and roles from core-api - API interceptor now adds Bearer token on web (previously skipped)
- Uses
[1.1.2] - 2026-01-04
Changed
- Web auth simplified: Skip Flutter OIDC on web - NPM forward auth handles it
- NPM authenticates at proxy level before app loads
- No more redundant OIDC redirect after NPM auth completes
- Fixes "Cannot use Ref after disposed" error from conflicting auth flows
- Mobile still uses Flutter OIDC flow
Added
- Logout now redirects to Authentik to end SSO session
- Clears local tokens AND invalidates Authentik session
- Uses OIDC end_session_endpoint from discovery document
- Redirects back to app after Authentik logout completes
[1.1.0] - 2026-01-04
Changed
- Dockerfile rebuild fix: Added
flutter cleanbefore build to prevent stale cached artifacts- VERSION build arg added for explicit cache busting
- Reordered build steps: clean → pub get → build_runner → health.json → flutter build
- Ensures deployed app always matches the version in health.json
Fixed
- Replaced deprecated
dart:htmlwithpackage:webin iframe_view_web.dart- Uses
web.HTMLIFrameElementinstead ofhtml.IFrameElement - Fixes deprecation warnings for Flutter 3.x web builds
- Uses
[1.0.12] - 2026-01-04
Changed
- Removed login page - auth now auto-initiates from AppScaffold
- No more redirect to /login, just auto-start OIDC if not authenticated
- Shows loading screen during auth, error screen on failure with retry
- Seamless experience when Authentik session exists
Removed
- Removed /login route and _LoginPage widget
[1.0.11] - 2026-01-04
Changed
- Web auth now extracts user info directly from JWT instead of syncing with core-api
- Eliminates CORS preflight issues with /auth/sync endpoint
- Decodes JWT claims (name, email, groups) client-side
- Bearer token will be used for API authentication
[1.0.10] - 2026-01-04
Fixed
- Fixed OIDC callback route being redirected to login before processing
- Moved callback route exception check BEFORE the auth redirect check in router
- This was preventing token exchange from ever happening
- Added favicon.ico to web root for proper browser tab icon display
[1.0.9] - 2026-01-04
Fixed
- Fixed OIDC callback Riverpod state modification error
- Deferred callback processing to
addPostFrameCallbackto avoid modifying state during widget build
- Deferred callback processing to
[1.0.8] - 2026-01-04
Changed
- Switched from hash-based URLs (
/#/login) to path-based URLs (/login)- Required for OIDC callback to work correctly
- Uses conditional import to avoid breaking mobile/desktop builds
[1.0.7] - 2026-01-04
Fixed
- Fixed OIDC PKCE state loss across browser redirect
- Code verifier and state now persist in sessionStorage instead of memory
- Prevents "No code verifier" error after Authentik redirect
[1.0.6] - 2026-01-04
Fixed
- Fixed version generation in CI/CD builds
- Removed generated files (version.g.dart, health.json) from git tracking
- These files are now regenerated from pubspec.yaml during Docker build
[1.0.5] - 2026-01-04
Changed
- Web authentication now uses OIDC instead of NPM forward auth
- Added
OidcServiceWebfor browser redirect-based Authorization Code flow with PKCE - Added
/callbackroute to handle Authentik redirect after login - Login page now shows "Sign in with Authentik" button for both web and mobile
- Tokens stored in SharedPreferences and synced with core-api via
/auth/sync
- Added
- Added web utility functions (
web_utils.dart) with conditional imports for non-web platforms - Added
cryptoandwebpackages for PKCE SHA-256 and browser API access
Fixed
- Removed cross-origin cookie dependency that caused authentication failures on web
[1.0.4] - 2026-01-03
Added
health.jsongenerated at build time with app version infohealth.htmlnow displays version, title, and status from health.json
[1.0.3] - 2026-01-03
Fixed
- Fixed auth endpoint path:
/auth/me→/auth/users/me
[1.0.2] - 2026-01-03
Fixed
- Production Docker build now uses correct API URLs
- Added
--dart-defineflags forCORE_API_URLandTATLOCK_API_URL - This enables
requiresAuth=trueso authentication is actually triggered
- Added
- Updated AGENTS.md with clear service port reference table
[1.0.1] - 2026-01-03
Fixed
- Web authentication now works correctly with NPM forward auth
- Dio client sends cookies with requests via
withCredentials: true - Added platform-specific adapters (native vs web) for proper cookie handling
- Dio client sends cookies with requests via
[1.0.0] - 2026-01-03
Added
- Authentication System - Dual-flow auth supporting web (NPM forward auth) and mobile (OIDC)
AuthStatemodel with roles, permissions, and user preferencesAuthProviderwith automatic web session detection via/auth/me- Permission system with Domain/Action enums and hierarchical access levels
PermissionGateandAdminGatewidgets for UI permission checksRolemodel with{domain}.{category}:{action}format parsing- Route guards redirect unauthenticated users to login page
- Login page with Authentik OAuth redirect
- Mobile auth platform configuration (iOS URL schemes, Android AppAuth)
- Comprehensive auth test suite (60 unit tests)
Changed
- API interceptor skips Bearer tokens on web (uses cookies via NPM forward auth)
- Router integrates auth state for protected route access
- First stable release - Core functionality complete for home lab dashboard
[0.3.3] - 2026-01-03
Added
- Health check endpoint (
/health.html) for Portainer container monitoring - Local search filtering in DataGrid (filters cached data client-side)
- Container status badges now reflect health status (green=healthy, orange=unhealthy)
ContainerHealthenum for parsing Docker health status from status string
Changed
- Standardized header bar heights to 56px across all panels
- Container grid now correctly parses Docker API JSON format (capitalized keys)
- Status column displays clean uptime (stripped health indicators)
- Status badges have consistent minimum width (90px)
- Search bar styling improved (36px height, visible border, proper background)
- Quick links now properly persist link type (iframe vs new tab)
- Iframe switching now closes existing content before loading new link
Fixed
- Quick links form properly saves changes and refreshes panel
ContainerStatetype conflict resolved (removed duplicate enum)- Container data parsing handles null values safely
Branding
- Updated favicon and icons with Tatlock bucket logo
- Updated manifest.json with Tatlock branding
[0.3.2] - 2025-01-02
Changed
- API defaults now use LAN IPs for local development (no auth required)
- Auth interceptor skips authentication when using LAN endpoints
[0.3.0] - 2025-12-30
Added
- docs/UI_LAYOUT.md - Responsive layout specification with "Rooms of the Estate" navigation
Changed
- Directory structure now mirrors room navigation (front_hall/, control_room/, parlor/, library/, study/)
- Chat moved to top-level
lib/chat/(omnipresent, not a room) - Updated ARCHITECTURE.md and PLAN.md to reflect room-based structure
- Version generation now automated via build_runner (replaces manual script)
lib/version.g.dartauto-generated frompubspec.yamlduring build
[0.2.0] - 2024-12-30
Added
- Phase 1: Foundation complete
- Clean Architecture folder structure (
core/,features/,shared/,routing/) - Full dependency stack: Riverpod, Dio, go_router, freezed, flex_color_scheme
- Core infrastructure:
core/config/app_config.dart- Environment configurationcore/theme/app_theme.dart- Material 3 theming with FlexColorSchemecore/theme/theme_provider.dart- Theme state with persistencecore/error/app_exception.dart- Typed exception hierarchycore/api/api_client.dart- Dio HTTP clients for Core API and Tatlock APIcore/api/api_interceptors.dart- Auth, logging, error interceptorscore/auth/auth_provider.dart- Authentication state management
- Routing with go_router and shell route for navigation
- Adaptive scaffold with responsive navigation (rail/bottom nav)
- Dashboard page placeholder with welcome card and stat cards
[0.1.0] - 2024-12-30
Added
- Initial Flutter project setup with all platforms (web, android, ios, macos, linux, windows)
- Build-time version generation from pubspec.yaml (
dart run tool/generate_version.dart) - Version logging on app startup
- Project documentation (PHILOSOPHY.md, README.md, AGENTS.md, PLAN.md)
- Phase 0 technical documentation:
- docs/ARCHITECTURE.md - Clean Architecture patterns
- docs/API_INTEGRATION.md - Backend API reference
- docs/DEPLOYMENT.md - Docker and infrastructure setup
- docs/DATAGRID.md - DataGrid component specification
- docs/THEMING.md - Material 3 theming guide