38 Commits
Author SHA1 Message Date
Jeroen SchweitzerandClaude Opus 4.5 b35f495537 feat(auth): extract user info from JWT, skip core-api sync
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 2m59s
- Decode JWT claims (name, email, groups) directly in Flutter
- No longer calls /auth/sync endpoint (avoids CORS preflight issues)
- Bearer token used for subsequent API authentication

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 13:38:19 +01:00
Jeroen SchweitzerandClaude Opus 4.5 346ca75d68 fix(auth): callback route redirect order + favicon.ico
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 2m59s
- Move callback route exception check BEFORE auth redirect check
- This was preventing OIDC token exchange from ever happening
- Add favicon.ico to web root for browser tab icon

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 13:17:03 +01:00
Jeroen SchweitzerandClaude Opus 4.5 0c27c10a2c fix(auth): defer OIDC callback processing to post-frame
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 3m1s
Wraps _processCallback() in addPostFrameCallback to avoid Riverpod
"Tried to modify a provider while the widget tree was building" error.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 13:03:35 +01:00
Jeroen SchweitzerandClaude Opus 4.5 ff5df30c53 feat(web): switch to path-based URL strategy
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 2m58s
Remove hash from URLs (/#/login -> /login) using usePathUrlStrategy().
Uses conditional imports to only apply on web, keeping mobile/desktop
builds unaffected.

Required for OIDC callback to work - Authentik redirects to /callback
which Flutter now recognizes as a route.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 12:55:36 +01:00
Jeroen SchweitzerandClaude Opus 4.5 0a6e9de4a8 fix(auth): persist PKCE state in sessionStorage
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 2m58s
Store OIDC code_verifier and state in sessionStorage instead of
static memory variables. This fixes the "No code verifier" error
that occurred after Authentik redirect because the Flutter app
restarts and loses in-memory state.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 12:40:38 +01:00
Jeroen Schweitzer 8494b4ad7f add version debug print to console on start 2026-01-04 12:15:05 +01:00
Jeroen SchweitzerandClaude Opus 4.5 e596b99e39 chore: stop tracking generated files
- Remove version.g.dart and health.json from git
- These are now regenerated during CI/CD build from pubspec.yaml
- Fixes version mismatch issue in deployments

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 12:12:10 +01:00
Jeroen SchweitzerandClaude Opus 4.5 9c41a8805d chore: release v1.0.5
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 3m0s
Web authentication now uses OIDC Authorization Code flow with PKCE
instead of NPM forward auth. Added callback route and web utilities.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 12:01:42 +01:00
Jeroen SchweitzerandClaude Opus 4.5 2fe6067085 fix(auth): correct endpoint path /auth/me → /auth/users/me
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 23:42:07 +01:00
Jeroen SchweitzerandClaude Opus 4.5 672f497733 fix(auth): enable cookie credentials for web API requests
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 2m56s
Configure Dio with BrowserHttpClientAdapter and withCredentials: true
for web platform, allowing session cookies to be sent with XHR requests.
This fixes NPM forward auth not working for API calls.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 22:56:56 +01:00
Jeroen SchweitzerandClaude Opus 4.5 f1b2b0430f feat(auth): implement dual-flow authentication (web + mobile)
Add complete authentication system supporting both web (NPM forward auth)
and mobile (OIDC) authentication flows.

Web flow:
- Check /auth/me on startup to detect NPM forward auth session
- Cookies handled by proxy, no Bearer tokens needed

Mobile flow:
- flutter_appauth for OIDC Authorization Code + PKCE
- POST /auth/sync to get user profile and roles
- Token storage in SharedPreferences

Shared:
- Permission system with Domain/Action enums and Role class
- PermissionGate and AdminGate widgets for UI permission checks
- Route guards redirecting unauthenticated users to login
- Login page with platform-specific messaging

Platform config:
- iOS: CFBundleURLTypes for net.schweitz.tatlock://
- Android: appAuthRedirectScheme, minSdk 23

Docs:
- Added Freezed 3.x sealed class documentation

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 21:56:11 +01:00
Jeroen SchweitzerandClaude Opus 4.5 6c271489a9 refactor: add shared StoplightColors for consistent status colors
- Add StoplightColors class with green/orange/red pastel colors
- Update dashboard gauges to use StoplightColors.forPercent()
- Update air quality levels to use shared stoplight colors
- Provides consistent color scheme for all threshold-based indicators

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 18:33:42 +01:00
Jeroen SchweitzerandClaude Opus 4.5 67fed18cb0 feat(dashboard): wire system stats to Core API with live gauges
Build and Push / build (release) Successful in 2m59s
- Add SystemStats freezed models matching Core API response
- Add systemStatsProvider to fetch stats from /tools/system/stats
- Update dashboard to display CPU, RAM, VRAM, and disk usage gauges
- Implement color-coded gauges: green ≤50%, orange 51-75%, red >75%
- Add auto-refresh every 30 seconds
- Improve gauge widget: speedometer style, icons below labels
- Update weather widget to match air quality vertical layout

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 18:24:04 +01:00
Jeroen SchweitzerandClaude Opus 4.5 bdced8739c chore: release v0.3.3
Build and Push / build (release) Successful in 3m6s
Features:
- Health check endpoint for Portainer monitoring
- Local search filtering in DataGrid
- Container status badges reflect health (green/orange/blue)

Improvements:
- Standardized 56px header heights across panels
- Container grid parses Docker API format correctly
- Search bar styling improvements
- Status badges have consistent width

Fixes:
- Quick links persistence (link type, form refresh)
- Iframe switching closes existing content first
- ContainerState type conflict resolved

Branding:
- Updated favicon and icons with Tatlock bucket logo

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:12:18 +01:00
Jeroen SchweitzerandClaude Opus 4.5 0d15d3dbb5 feat(front-hall): wire quick links to Core API dashboard endpoint
Update quick links integration to use new /dashboard/quick-links API:
- Change API path from /front-hall/quick-links to /dashboard/quick-links
- Update field mappings: name→title, icon_name→icon, sort_order→position, is_active→is_visible
- Change ID type from String to int with conversion in provider
- Parse new response format {"links": [...], "total": N}
- Update reorder endpoint from PUT to POST with link_ids

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 13:17:16 +01:00
Jeroen SchweitzerandClaude Opus 4.5 1d68402067 feat(front-hall): add drag-to-reorder for quick links in settings mode
- Add ReorderableListView in settings mode for drag-to-reorder support
- Create _ReorderableLinkTile with drag handle indicator
- Show flat list with categories as subtitles when reordering
- Call reorder API when items are dragged to new position
- Keep grouped view with category headers in normal mode

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 10:18:01 +01:00
Jeroen SchweitzerandClaude Opus 4.5 327b4a1233 feat(front-hall): add link management with form and icon picker
- Create IconPicker widget with searchable grid of Material icons
- Create QuickLinkForm with full CRUD support (create, edit, delete)
- Update QuickLinkSettingsContent to use real form instead of placeholder
- Update QuickLinksPanel to use shared getIconData function
- Form includes name, URL, category, icon, type, and active toggle
- Validation for required fields and URL format

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 23:19:03 +01:00
Jeroen SchweitzerandClaude Opus 4.5 9c9ec472ef feat(dashboard): add gauge, weather, and air quality widgets
- Create shared GaugeWidget with circular progress and customizable colors
- Add GaugeRow for displaying multiple gauges in a responsive layout
- Create WeatherWidget with temperature, condition, and details
- Create AirQualityWidget with AQI levels and pollutant readings
- Update DashboardContent with System Stats gauges and Environment section
- Both widgets use mock data, ready for API integration

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 23:09:15 +01:00
Jeroen SchweitzerandClaude Opus 4.5 40db92d9d5 feat(front-hall): implement three-mode layout with quick links panel
Phase 2 of Organizr Migration - Front Hall restructure:

- Add FrontHallState provider with three modes (dashboard, iframe, settings)
- Create QuickLinksPanel widget with categorized links and overflow menus
- Add IframeView with platform-aware implementation (web iframe, mobile fallback)
- Extract DashboardContent from FrontHallPage
- Add QuickLinkSettingsContent placeholder for Phase 4 link editor
- Implement QuickLink entity and data layer with Core API datasource
- Add default quick links fallback when API unavailable
- Update UI_LAYOUT.md with Front Hall panel configurations

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 22:24:20 +01:00
Jeroen SchweitzerandClaude Opus 4.5 6989241ae7 chore: upgrade to riverpod 3.x and freezed 3.x
- Upgrade flutter_riverpod to 3.1.0, riverpod_annotation to 4.0.0
- Upgrade freezed to 3.2.3, freezed_annotation to 3.1.0
- Migrate freezed classes to use sealed keyword (freezed 3.x)
- Update provider naming (*NotifierProvider → *Provider)
- Add legacy.dart import for StateNotifierProvider compatibility
- Fix valueOrNull → value for AsyncValue
- Remove unused imports and fields
- Add sync from Authentik button to users/groups pages
- Suppress invalid_annotation_target warning in analysis_options

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 00:07:01 +01:00
Jeroen SchweitzerandClaude 88e8848953 refactor: convert Control Room views to DataGrid pattern
- Refactor containers_list_page to use shared DataGrid component
- Refactor proxy_hosts_page to use shared DataGrid component
- Add ContainerStatusBadge.fromString() factory for string state values
- Extend CoreApiDataSource to handle raw array API responses
- Simplify data classes (no freezed, just fromJson factories)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-01 22:56:37 +01:00
Jeroen SchweitzerandClaude a5a8e7ba88 feat: add Security room with Users and Groups sections
- Add Security room accessible from main navigation
- Implement Users list page with DataGrid (fetches from /auth/users)
- Implement Groups list page with DataGrid (fetches from /auth/groups)
- Move user/group management from Control Room to dedicated Security room
- Remove Authentik section from Control Room navigation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-01 22:55:37 +01:00
Jeroen SchweitzerandClaude Opus 4.5 2adb50b352 feat: implement NPM Proxy Hosts section with reusable entity patterns
Add full Proxy Hosts feature for Control Room:
- Data layer: datasource, model with custom JSON converters for NPM API quirks
- Domain layer: ProxyHost entity with SSL, caching, websocket support
- Presentation: list page, detail/edit page, form widget

Add reusable entity page patterns for Control Room sections:
- EntityPageScaffold, EntitySection, EntitySettingRow components
- EntityForm with create/view/edit mode support
- EntityPageModeMixin for consistent mode management
- CreateOnlyField for immutable-after-creation fields

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 15:02:06 +01:00
Jeroen SchweitzerandClaude Opus 4.5 ae2bbcd58d feat: add NPM and Authentik sections to Control Room navigation
- Add ControlRoomNav enum with section grouping (Portainer, NPM, Authentik)
- Update NavPanel to support conditional section headers
- Rename NavSection to NavItem with optional section field
- Add routes for NPM: Proxy Hosts, Redirections, Streams, SSL Certificates
- Add routes for Authentik: Users, Groups, Applications
- Section headers auto-show when multiple sections exist

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 16:52:10 +01:00
Jeroen SchweitzerandClaude Opus 4.5 b189c3518b feat: add Nav Panel with URL-routed section navigation
- Add NavPanel widget for room-level section navigation
- Add Control Room feature router with URL routes:
  - /control-room/containers
  - /control-room/networks
  - /control-room/volumes
  - /control-room/images
- Sections: Containers, Networks, Volumes, Images
- Navigation updates URL and vice versa (deep-linkable)
- Remove redundant Stacks section (handled by filter panel)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 16:28:01 +01:00
Jeroen SchweitzerandClaude Opus 4.5 865b69f960 fix: enable scrolling in CodeEditor widget
Wrap CodeField in SingleChildScrollView with minLines: 1 to prevent
overflow when YAML content exceeds available height.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 15:03:48 +01:00
Jeroen SchweitzerandClaude Opus 4.5 282e81634a refactor: convert relative imports to package imports
Replace all relative imports (../../) with package imports
(package:tatlock_ui/) across 29 files for cleaner, more
maintainable import paths.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 14:54:59 +01:00
Jeroen SchweitzerandClaude Opus 4.5 948e104ce5 feat: add reusable panel system with FilterPanel widget
- Update UI_LAYOUT.md with comprehensive panel taxonomy
- Document Nav Panel, Filter Panel, Detail Panel, Chat Dock specs
- Add panel header behavior (bottom-docked for left panels)
- Add responsive breakpoints with panel folding summary
- Create PanelHeader widget with dockToBottom option
- Create FilterPanel widget for data filtering sidebars
- Refactor Control Room to use FilterPanel
- Remove external links from sidebar (cleanup)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 14:54:14 +01:00
Jeroen SchweitzerandClaude Opus 4.5 de739e8f7a feat: redesign header with logo bulge and room navigation
- Move room navigation from sidebar to top header bar as icons
- Add circular "bulge" extending below header for larger logo (120px)
- Logo centered in bulge with 20% circle below header line
- Profile dropdown with Settings and Logout options
- Header overlays content (Stack layout) instead of pushing it down
- Remove AppBar from FrontHallPage (provided by AppScaffold)
- Add transparent logo asset

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 14:52:40 +01:00
Jeroen SchweitzerandClaude Opus 4.5 5c09bac3d2 feat: add stack detail view with YAML and env vars editor
When a stack is selected, the right pane now shows a split view:
- Top: Stack editor with tabs for Compose YAML and Environment Variables
- Bottom: Docked compact container list for the selected stack

Includes Deploy button to redeploy stack with updated configuration.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 02:18:07 +01:00
Jeroen SchweitzerandClaude Opus 4.5 3b89ed8c18 feat: add Control Room with containers and stacks management
- Add Control Room page with stacks sidebar and containers list
- Implement container actions (start/stop/restart) with snackbars
- Add container logs viewer dialog
- Add search/filter for both stacks and containers lists
- Add external links for Portainer and Netdata (url_launcher)
- Add VS Code launch configuration for Flutter web debugging

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 02:01:01 +01:00
jpmschweitzerandClaude Opus 4.5 dd6bcbdbda feat: LAN-first development with optional auth
- Default API URLs now use LAN IPs (192.168.86.149)
- Auth interceptor skips auth when using LAN endpoints
- Production builds override with --dart-define

Development: flutter run -d chrome (no auth needed on LAN)
Production:  flutter build web --dart-define=CORE_API_URL=https://api.schweitz.net

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 00:04:04 +01:00
jpmschweitzerandClaude Opus 4.5 220ca9bb2a chore: bump version to 0.3.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 23:28:34 +01:00
jpmschweitzerandClaude Opus 4.5 a4aaea33b8 refactor: rename features to room-based directory structure
- Rename features/dashboard → features/front_hall
- Update routes: /, /control-room, /parlor, /settings
- Update navigation to 4 rooms (removed chat tab - will be omnipresent dock)
- Add docs/UI_LAYOUT.md with wireframes and responsive specs
- Update ARCHITECTURE.md and PLAN.md to reflect room structure

Directory structure now mirrors "Rooms of the Estate" UI navigation:
- front_hall/ (dashboard)
- control_room/ (infrastructure - containers, stacks, etc.)
- parlor/ (home automation)
- library/ (future)
- study/ (future, hidden)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 23:14:40 +01:00
jpmschweitzerandClaude Opus 4.5 4b0c6b292a feat: automate version.g.dart generation via build_runner
Replace manual generate_version.dart script with a custom build_runner
builder that automatically generates lib/version.g.dart from pubspec.yaml
during the build process. This eliminates manual steps and ensures version
info stays in sync.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 17:27:10 +01:00
jpmschweitzerandClaude Opus 4.5 3af4fd16f8 feat: Phase 1 foundation - core infrastructure and navigation
Clean Architecture structure:
- core/config - Environment configuration
- core/theme - Material 3 theming with FlexColorScheme
- core/error - Typed exception hierarchy
- core/api - Dio HTTP clients with interceptors
- core/auth - Authentication state management
- routing - go_router with shell navigation
- shared/layouts - Adaptive scaffold

Dependencies added:
- flutter_riverpod, riverpod_annotation, riverpod_generator
- freezed, freezed_annotation, json_serializable
- dio, go_router, shared_preferences
- flex_color_scheme, flutter_adaptive_scaffold

Features:
- Responsive navigation (rail on desktop, bottom on mobile)
- Dashboard placeholder with welcome card
- Theme switching infrastructure
- API client ready for Core API and Tatlock API

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 17:15:54 +01:00
jpmschweitzerandClaude Opus 4.5 0c3239f4b0 docs: add Phase 0 documentation
- docs/ARCHITECTURE.md - Clean Architecture patterns and conventions
- docs/API_INTEGRATION.md - Core API and Tatlock API endpoints
- docs/DEPLOYMENT.md - Docker, NPM, Portainer setup
- docs/DATAGRID.md - DataGrid component specification
- docs/THEMING.md - Material 3 theming guide

Also update seed color to teal for consistency.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 16:26:44 +01:00
jpmschweitzerandClaude Opus 4.5 b4ec857a8f feat: initialize Flutter project with version management
- Initialize Flutter 3.38 project with all platforms
- Add build-time version generation from pubspec.yaml
- Print version to console on app startup
- Create CHANGELOG.md following Keep a Changelog format
- Update .gitignore for Flutter + generated files
- Basic app scaffold with Material 3 theming

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 16:09:36 +01:00