TenantAtlas/specs/097-settings-foundation/tasks.md
ahmido e241e27853 Settings foundation: workspace controls (#119)
Implements the Settings foundation workspace controls.

Includes:
- Settings foundation UI/controls scoped to workspace context
- Related onboarding/consent flow adjustments as included in branch history

Testing:
- `vendor/bin/sail artisan test --compact --no-ansi --filter=SettingsFoundation`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #119
2026-02-16 01:11:24 +00:00

8.0 KiB
Raw Blame History

Tasks: Settings Foundation (Workspace + Optional Tenant Override) (097)

Input: Design documents from specs/097-settings-foundation/ (spec.md, plan.md, research.md, data-model.md, contracts/) Prerequisites: specs/097-settings-foundation/plan.md (required), specs/097-settings-foundation/spec.md (required for user stories)

Tests: REQUIRED (Pest) for all runtime behavior changes in this repo. RBAC: Enforce 404 vs 403 semantics via canonical helpers + capability registry (no raw strings). Audit: DB-only mutations intentionally skip OperationRun; every successful update/reset MUST write a workspace-scoped audit entry.

Phase 1: Setup (Shared Infrastructure)

  • T001 Re-run SpecKit prerequisites and confirm FEATURE_DIR via .specify/scripts/bash/check-prerequisites.sh
  • T002 Review RBAC-UX enforcement patterns in app/Support/Rbac/WorkspaceUiEnforcement.php
  • T003 Review existing capability registry + caching patterns in app/Support/Auth/Capabilities.php and app/Services/Auth/WorkspaceCapabilityResolver.php
  • T004 Review workspace audit patterns + stable action IDs in app/Services/Audit/WorkspaceAuditLogger.php and app/Support/Audit/AuditActionId.php

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Shared primitives (capabilities, persistence, policies) needed by all stories.

  • T005 Add settings capabilities in app/Support/Auth/Capabilities.php (WORKSPACE_SETTINGS_VIEW, WORKSPACE_SETTINGS_MANAGE)
  • T006 Map new capabilities to roles in app/Services/Auth/WorkspaceRoleCapabilityMap.php (Owner/Manager manage; Operator/Readonly view)
  • T007 Create workspace_settings table migration in database/migrations/*_create_workspace_settings_table.php (workspace-owned: MUST NOT include tenant_id)
  • T008 [P] Create tenant_settings table migration in database/migrations/*_create_tenant_settings_table.php (tenant-owned: MUST include tenant_id NOT NULL)
  • T009 [P] Add Eloquent models in app/Models/WorkspaceSetting.php and app/Models/TenantSetting.php
  • T010 [P] Add model factories in database/factories/WorkspaceSettingFactory.php and database/factories/TenantSettingFactory.php
  • T011 Add policy for settings writes in app/Policies/WorkspaceSettingPolicy.php (view/manage using WorkspaceCapabilityResolver)
  • T012 Register policy mapping in app/Providers/AuthServiceProvider.php

Checkpoint: Capabilities + persistence + policies exist; user story work can begin.


Phase 3: User Story 1 — Manage workspace settings safely (Priority: P1) 🎯 MVP

Goal: Workspace managers can update/reset the pilot setting with validation + audit logging.

Independent Test: A manager changes backup.retention_keep_last_default, sees it reflected, and the retention fallback uses it when schedule retention is null.

Tests (write first)

  • T013 [P] [US1] Add manage workflow tests in tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php
  • T014 [P] [US1] Add audit logging tests in tests/Feature/SettingsFoundation/WorkspaceSettingsAuditTest.php
  • T015 [P] [US1] Add resolver caching tests in tests/Unit/SettingsFoundation/SettingsResolverCacheTest.php
  • T016 [P] [US1] Add pilot integration test for retention fallback in tests/Feature/SettingsFoundation/RetentionFallbackUsesWorkspaceDefaultTest.php
  • T038 [P] [US1] Add per-schedule override precedence test (schedule override wins) in tests/Feature/SettingsFoundation/RetentionScheduleOverrideWinsTest.php
  • T039 [P] [US1] Add validation negative-path test: unknown setting key is rejected; no changes persisted; no audit entry created
  • T040 [P] [US1] Add validation negative-path test: invalid value (wrong type/out-of-range) is rejected; no changes persisted; no audit entry created

Implementation

  • T017 [P] [US1] Create setting definition DTO in app/Support/Settings/SettingDefinition.php
  • T018 [P] [US1] Create registry for known settings in app/Support/Settings/SettingsRegistry.php (include backup.retention_keep_last_default default=30 + validation)
  • T019 [P] [US1] Implement resolver with precedence + request-local cache in app/Services/Settings/SettingsResolver.php
  • T020 [P] [US1] Add stable audit action IDs in app/Support/Audit/AuditActionId.php (workspace_setting.updated, workspace_setting.reset)
  • T021 [US1] Implement writer (validate, persist, reset deletes row, audit before/after) in app/Services/Settings/SettingsWriter.php
  • T022 [US1] Add Filament workspace Settings page shell in app/Filament/Pages/Settings/WorkspaceSettings.php (uses WorkspaceUiEnforcement)
  • T023 [US1] Register the Settings page in the admin panel navigation in app/Providers/Filament/AdminPanelProvider.php
  • T024 [US1] Implement Save action via Action::make(...)->action(...) in app/Filament/Pages/Settings/WorkspaceSettings.php
  • T025 [US1] Implement Reset action with ->requiresConfirmation() and ->action(...) in app/Filament/Pages/Settings/WorkspaceSettings.php
  • T026 [US1] Wire retention fallback to resolver when schedule retention is null in app/Jobs/ApplyBackupScheduleRetentionJob.php

Phase 4: User Story 2 — View settings without the ability to change them (Priority: P2)

Goal: Workspace operators/readonly can view settings but cannot save/reset; server-side 403 on mutation.

Independent Test: A view-only member opens the Settings page and can see values, but attempts to save/reset return 403 and no audit entry is created.

Tests (write first)

  • T027 [P] [US2] Add view-only access tests (view OK, mutation forbidden) in tests/Feature/SettingsFoundation/WorkspaceSettingsViewOnlyTest.php
  • T037 [P] [US2] Add non-member deny-as-not-found tests (404) in tests/Feature/SettingsFoundation/WorkspaceSettingsNonMemberNotFoundTest.php

Implementation

  • T028 [US2] Gate page access by view capability and gate mutations by manage capability in app/Filament/Pages/Settings/WorkspaceSettings.php
  • T029 [US2] Ensure Save/Reset actions cannot execute for view-only users (server-side enforcement) in app/Filament/Pages/Settings/WorkspaceSettings.php

Phase 5: User Story 3 — Tenant overrides take precedence (backend-ready) (Priority: P3)

Goal: Resolver supports tenant overrides; tenant override wins over workspace override; rejects tenant/workspace mismatch.

Independent Test: With tenant override present, resolving returns tenant value; without it, returns workspace; without either, returns system default.

Tests (write first)

  • T030 [P] [US3] Add tenant precedence tests (default/workspace/tenant) in tests/Unit/SettingsFoundation/SettingsResolverTenantPrecedenceTest.php
  • T031 [P] [US3] Add tenant/workspace mismatch rejection test in tests/Feature/SettingsFoundation/TenantOverrideScopeSafetyTest.php

Implementation

  • T032 [US3] Extend resolver to read tenant overrides from tenant_settings (same workspace) in app/Services/Settings/SettingsResolver.php
  • T033 [US3] Add tenant override write/reset methods (backend-ready) in app/Services/Settings/SettingsWriter.php

Phase 6: Polish & Cross-Cutting Concerns

  • T034 [P] Run formatting for changed files via vendor/bin/sail bin pint --dirty (see specs/097-settings-foundation/quickstart.md)
  • T035 Run focused tests for this feature via vendor/bin/sail artisan test --compact tests/Feature/SettingsFoundation (see specs/097-settings-foundation/quickstart.md)
  • T036 Run the full suite via vendor/bin/sail artisan test --compact (see specs/097-settings-foundation/quickstart.md)

Dependencies & Execution Order

User Story Dependency Graph

  • Setup → Foundational
  • Foundational → US1
  • US1 → US2
  • US1 → US3

Parallel Opportunities (examples)

  • US1: T013T016 (tests) and T017T020 (core classes + enum) can be executed in parallel.
  • Foundational: T007T012 can be split across DB/model/policy work in parallel.

Example: In US1, execute T013, T014, T017, and T018 concurrently (different files; no dependencies).

MVP Scope Suggestion

  • MVP = Phases 13 (through US1) to ship a workspace settings foundation with the pilot setting wired into retention fallback.