Files
tatlock-ui/CHANGELOG.md
T
Jeroen SchweitzerandClaude Opus 4.5 cc6068b759
Build and Push / release (push) Successful in 2s
Build and Push / build (push) Successful in 3m9s
chore: release v1.5.4
Add user display in environment section header for debugging OIDC
user resolution issues.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 14:05:16 +01:00

470 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.5.4] - 2026-01-07
### Added
- **User display in environment section** - Shows authenticated user in section header for debugging
- Displays `user: {username}` next to "Environment" header when data loads
- Helps diagnose user resolution issues with OIDC authentication
## [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 API
- `ForecastWidget` - Multi-day weather forecast with conditions icons
- `AirQualityWidget` - 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
- `RoomDefinition` class with id, label, icons, routes, and permissions
- `RoomRegistry` singleton 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.dart` uses `roomRegistry.all` instead of hardcoded list
- `app_scaffold.dart` uses 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.dart` and `security/router.dart` now register with registry
- Documentation updated in ARCHITECTURE.md with Room Registry Pattern section
### Removed
- Hardcoded room lists in `top_header_bar.dart` and `app_scaffold.dart`
- `_PlaceholderPage` widget in `app_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-hall` route (was `/`)
## [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)
- `PageUrlState` utility class (`lib/routing/url_state.dart`) for URL ↔ state serialization
- Browser URL updates via `replaceState` without triggering GoRouter rebuilds
- `id` field added to `DataGridColumn` for unique column identification in URLs
- `FilterPanelSemantics` class for filter panel semantic IDs
- TESTING.md documentation for semantic widgets and automation testing
### Changed
- `idSelector` in DataGridController now returns `String` (was `Object`) 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`)
- Router passes `GoRouterState` to 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 constants
- `semantic_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 in `AuthInterceptor.onError`
- 401 errors now propagate to calling code for graceful handling
- Preferences API 401 no longer triggers full logout redirect
## [1.1.15] - 2026-01-05
### Fixed
- Theme toggle causing auth issues due to AuthNotifier auto-dispose
- Applied `@persistentRiverpod` annotation to AuthNotifier
- AuthProvider now persists for app lifetime, preventing rebuild on theme change
## [1.1.14] - 2026-01-04
### Fixed
- Theme toggle causing auth issues due to ThemeProvider auto-dispose
- Added `@persistentRiverpod` annotation for providers that need keepAlive
- ThemeProvider now persists for app lifetime
### Added
- `@persistentRiverpod` annotation in `core/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: true` to 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 `/health` directory - URL is now `/health` instead 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 `/callback` route from Flutter router - AuthController handles callback in main() before app starts
- Removed `_OidcCallbackPage` widget - no visible auth UI needed
## [1.1.6] - 2026-01-04
### Changed
- **Auth moved to standalone controller** - Handles OIDC completely outside Riverpod
- New `AuthController` runs in `main()` before `runApp()` - 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
- `AuthProvider` now just loads stored tokens (no async OIDC logic)
- Fixes "Cannot use Ref after disposed" errors from autoDispose providers
## [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 `/callback` route.
## [1.1.4] - 2026-01-04
### Fixed
- Silent OIDC fallback: when `prompt=none` fails with `login_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=none` to 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/sync` to get user profile and roles from core-api
- API interceptor now adds Bearer token on web (previously skipped)
## [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 clean` before 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:html` with `package:web` in iframe_view_web.dart
- Uses `web.HTMLIFrameElement` instead of `html.IFrameElement`
- Fixes deprecation warnings for Flutter 3.x web builds
## [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 `addPostFrameCallback` to avoid modifying state during widget build
## [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 `OidcServiceWeb` for browser redirect-based Authorization Code flow with PKCE
- Added `/callback` route 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 web utility functions (`web_utils.dart`) with conditional imports for non-web platforms
- Added `crypto` and `web` packages 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.json` generated at build time with app version info
- `health.html` now 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-define` flags for `CORE_API_URL` and `TATLOCK_API_URL`
- This enables `requiresAuth=true` so authentication is actually triggered
- 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
## [1.0.0] - 2026-01-03
### Added
- **Authentication System** - Dual-flow auth supporting web (NPM forward auth) and mobile (OIDC)
- `AuthState` model with roles, permissions, and user preferences
- `AuthProvider` with automatic web session detection via `/auth/me`
- Permission system with Domain/Action enums and hierarchical access levels
- `PermissionGate` and `AdminGate` widgets for UI permission checks
- `Role` model 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)
- `ContainerHealth` enum 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
- `ContainerState` type 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.dart` auto-generated from `pubspec.yaml` during 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 configuration
- `core/theme/app_theme.dart` - Material 3 theming with FlexColorScheme
- `core/theme/theme_provider.dart` - Theme state with persistence
- `core/error/app_exception.dart` - Typed exception hierarchy
- `core/api/api_client.dart` - Dio HTTP clients for Core API and Tatlock API
- `core/api/api_interceptors.dart` - Auth, logging, error interceptors
- `core/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