Commit Graph

10 Commits

Author SHA1 Message Date
99e53f5d70 refactor: rename Step Library → Solutions Library site-wide
User-facing text updated across page title, sidebar, command palette,
quick launch, quick actions, post-step modal, empty state, and
procedural editor. File paths/component names unchanged — those
will be renamed when the full Solutions Library feature ships.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 04:09:19 +00:00
Michael Chihlas
303a558432 refactor: replace hardcoded hex values with Tailwind semantic tokens
3,200+ hardcoded color values replaced with CSS variable-backed
Tailwind classes (bg-card, text-foreground, border-border, etc.).
Enables light mode via CSS variable swap. Only syntax highlighting
colors and intentional one-offs remain hardcoded (~15 values).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 04:34:35 -04:00
Michael Chihlas
e4ef904707 refactor: migrate page components to Design System v4
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 02:04:16 -04:00
chihlasm
5095b0d8df refactor: adopt shared Input/Textarea components (#101)
* refactor: adopt shared Input/Textarea components across 15 files

Replace 42 raw <input>/<textarea> elements with <Input>/<Textarea>
from components/ui/. Consistent focus states, error handling, and
styling across all form fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: replace hardcoded rgba/hex colors with Tailwind tokens

- rgba(255,255,255,0.xx) → bg-white/[0.xx], border-white/[0.xx]
- rgba(6,182,212,0.3) → border-primary/30 (focus states)
- #0a0a0a → bg-background
- Inline style hex colors → var(--color-primary), var(--color-brand-gradient-to)
- 28 files updated, zero hardcoded rgba() patterns remaining

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add PageMeta to 16 pages for SEO and proper browser tab titles

Public pages (Login, Register, Forgot/Reset Password, Verify Email,
Survey Thank You) get descriptions for SEO. Authenticated pages
(Dashboard, Flow Library, My Flows, Session History, AI Assistant,
Account Settings, Step Library, My Shares, Feedback, Guides) get
proper tab titles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add page transitions and staggered list animations

- ViewTransitionOutlet: wraps Outlet with fade-in-up animation keyed
  to route path. Sidebar/topbar stay still, only content area animates.
- StaggerList: reusable component that cascades children with
  incremental delay (50ms default). Pure CSS via @utility stagger-item.
- Applied stagger to TreeGridView, MyTreesPage cards, SessionHistoryPage.
- New stagger-fade-in keyframe in @theme block.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: ViewTransitionOutlet needs h-full for React Flow canvas

The wrapper div broke the height chain needed by TreeEditorPage's
h-full layout, causing React Flow canvas to collapse to zero height.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: main-content flex layout for tree editor + scrollable pages

Main content area is now flex-col so the ViewTransitionOutlet wrapper
gets an explicit computed height via flex-1 min-h-0. This makes h-full
resolve correctly in the tree editor (React Flow canvas) while still
allowing overflow-y-auto scrolling for normal pages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve ESLint errors in Button and Skeleton components

- Button: suppress react-refresh/only-export-components for buttonVariants re-export
- Skeleton: replace empty interface with type alias, replace Math.random() with static widths array

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add PageMeta, animation classes, and layout fixes to remaining pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 16:12:21 -04:00
chihlasm
94b428d168 refactor: enforce shared Modal component (#100)
* refactor: enforce shared Modal component in remaining custom modals

- ShareSessionModal: replaced custom modal markup with <Modal>
- CreateCategoryModal: replaced custom modal markup with <Modal>
- EditCategoryModal: replaced custom modal markup with <Modal>
- All now get focus trapping, Escape close, body scroll lock for free

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: adopt shared Button component in 18 modal components

Replace raw <button> elements with <Button> from ui/Button.tsx:
- Primary buttons (bg-gradient-brand) → <Button variant="primary">
- Secondary buttons (border-border) → <Button variant="secondary">
- Ghost buttons → <Button variant="ghost">
- Loading states use loading prop instead of manual Loader2 spinner

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: adopt shared Button component in 20 page/component files

Replace raw <button> elements with <Button> across pages and remaining
components. 38 total files now use the shared Button component consistently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 00:25:50 -05:00
chihlasm
d365c38b61 chore: Tailwind CSS v3 → v4 migration (#99)
* chore: run Tailwind v4 upgrade tool (Phase 1)

- Upgraded tailwindcss v3 → v4.2.1, postcss plugin to @tailwindcss/postcss
- Deleted tailwind.config.js, migrated theme to CSS @theme block in index.css
- Replaced @tailwind directives with @import 'tailwindcss'
- Added @custom-variant dark, @utility blocks for custom utilities
- Updated class names across 128 files (shadow-sm → shadow-xs, etc.)
- Removed autoprefixer (built into v4)
- Added migration plan doc

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: switch from @tailwindcss/postcss to @tailwindcss/vite (Phase 2)

- Replaced @tailwindcss/postcss with @tailwindcss/vite plugin
- Deleted postcss.config.js (no longer needed)
- Tailwind now runs as a native Vite plugin for faster HMR

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: convert to OKLCH colors, move keyframes into @theme (Phase 3-4)

- Replaced all HSL color indirection with direct OKLCH values in @theme
- Moved all keyframes inside @theme block (v4 pattern)
- Eliminated hsl(var(--x)) double-indirection across 17 component files
- Replaced hsl() inline styles with var(--color-*) theme references
- Cleaned up redundant rdp-* utility blocks
- Fixed @custom-variant dark syntax to use :where()
- Added sidebar/glass/shadow vars as OKLCH in :root

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:10:44 -05:00
chihlasm
f31058fc3f fix: resolve CI failures — ESLint unused vars and AI chat tests in CI
Frontend: suppress unused-vars ESLint errors for callback params in
MaintenanceFlowDetailPage and StepLibraryPage.

Backend: add autouse fixture to mock settings.ai_enabled=True in
test_ai_chat.py so tests pass in CI where no ANTHROPIC_API_KEY is set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:21:48 -05:00
chihlasm
1f77b7fc32 fix: surface errors and polish UX across Step Library and Batch pages (#92)
- StepLibraryPage: replace silent console.error with toast.error on edit/save
  failures; replace manual setTimeout toast with toast.success helper
- BatchStatusPage: add error state with retry button for failed session loads
  instead of showing ambiguous "No sessions found"
- StepDetailModal: guard clipboard copy against browser denial (no false
  "Copied!" state on permission error); fix dead "See all reviews" button
  with inline expand/collapse toggle
- StepLibraryBrowser: add "Try again" retry button to error state; retry
  increments a counter that re-triggers both load effects

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 03:00:14 -05:00
chihlasm
e6a0c0549b feat: Step Library sync + service account for default tree ownership
* feat: maintenance flow UX redesign — batch status hub, context strip, detail page upgrades (#85)

- Add BatchStatusPage (/flows/:id/batches/:batchId): per-target Start/Resume/View cards, progress bar, 5s polling while in-progress, completion outcome summary
- Add BatchStatusCard: handles not-started/in-progress/complete states with step progress for in-progress targets
- Add ActiveBatchBanner: amber banner on detail page when a batch is running, links to BatchStatusPage
- Add MaintenanceContextStrip: amber strip in ProceduralNavigationPage for maintenance flows showing target name, batch progress (X/Y complete), and Back to Batch nav
- Update MaintenanceFlowDetailPage: active batch banner, clickable run history rows with mini progress dots and outcome summaries, Run button loading state, post-launch navigates to BatchStatusPage
- Update ProceduralNavigationPage: renders MaintenanceContextStrip between top bar and content when tree_type === 'maintenance'; fetches batch progress once on mount
- Add batch_id filter to GET /sessions backend endpoint and SessionListParams frontend type
- Add /flows/:id/batches/:batchId route to router

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: session detail page — completion action + outcome summary card

- In-progress sessions: amber banner with "Complete Session" button opens
  SessionOutcomeModal to set outcome/notes/next-steps and finalize
- Completed sessions: colored outcome summary card (icon + outcome label +
  duration + notes + next steps) replaces dense header metadata; "Copy for
  Ticket" promoted to primary action inside the card
- Export toolbar de-emphasized to secondary row of smaller controls below
  the summary card

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add library-page action props to StepCard (edit/delete/save)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: pass library-page action props through StepLibraryBrowser + refreshKey

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: StepFormModal wrapper + submitLabel/isSubmitting props on StepForm

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: Step Library page — create, edit, delete, save-to-library

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add RuntimeStep union type for procedural custom steps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: StepChecklist accepts RuntimeStep[], renders amber Custom badge

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: StepDetail accepts RuntimeStep, renders Custom Step badge for custom steps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: custom step insertion in procedural flow sessions

Engineers can add custom steps inline during execution. Steps are
persisted to session.custom_steps and restored on resume.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: suppress StepFeedback on custom steps, fix resume stepState seeding, functional updater for step index

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add tree forking UI design doc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add tree fork UI implementation plan

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add ForkInfo type and fork fields to Tree/TreeListItem

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: align ForkInfo type with backend schema, remove redundant fork fields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: ForkInfo placement, required fork_info field, add JSDoc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add ForkModal component with name and reason fields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: ForkModal accessibility and UX (escape, click-outside, labels, maxLength)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: open ForkModal on fork action in TreeLibraryPage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add ForkModal to MyTreesPage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: show Fork chip badge on forked tree cards

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add flow-to-library step sync design doc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add flow-to-library sync implementation plan

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add sync tracking columns to step_library

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add sync columns and source_tree relationship to StepLibrary model

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add group_label to StepContent, is_flow_synced/source_tree_name to StepLibraryResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: include is_flow_synced and source_tree_name in step list/detail responses

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: add is_flow_synced and source_tree_name to step list response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: add selectinload and sync fields to search and get_step endpoints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add step_sync module with extraction and upsert logic

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: safe NOT IN placeholders for asyncpg, add deactivate docstring

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: trigger step library sync on tree publish and deactivate on delete

- Call sync_steps_from_tree in update_tree whenever the tree is published
  (status transitions to 'published' or is already published and structure changes)
- Call deactivate_synced_steps_for_tree in delete_tree before db.commit()
  so the FK SET NULL does not nullify source_tree_id before the WHERE clause runs
- Fix ::jsonb cast syntax in step_sync.py (asyncpg rejects :: operator in text()
  queries; replaced with CAST(:content AS jsonb))
- Add UniqueConstraint('source_tree_id','source_node_id') to StepLibrary model
  so Base.metadata.create_all (used by tests) creates the constraint that the
  ON CONFLICT clause in sync_steps_from_tree depends on

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add is_flow_synced and source_tree_name to Step types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: show From Flow badge and lock icon on flow-synced StepCard

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: show source flow name in StepDetailModal for synced steps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add Library Visibility select to procedural StepEditor

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: address code review issues in flow-to-library sync

- Fix sync trigger: only fire on publish transition, not every PUT
- Add TestSyncOnPublish integration tests (2 tests, 16 total passing)
- Add group_label to frontend StepContent interface
- Guard Library Visibility select to procedure_step nodes only
- Block API edits to flow-synced steps (400 read-only guard)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: handle None author_id in step sync to avoid invalid UUID error

When a system/default tree has no author (author_id is None),
str(None) produces the literal string 'None' which asyncpg
rejects as an invalid UUID for the created_by column.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: add ResolutionFlow service account to own default tree steps in library

Default/system trees had no author_id (NULL), causing a NOT NULL violation
when syncing steps to step_library.created_by on publish.

- Add is_service_account flag to users table (migration 4f4137ce)
- Add service_account.py: idempotent ensure_service_account() creates
  noreply@resolutionflow.com with unusable password on startup
- Cache service account ID on app.state at lifespan startup
- Add get_service_account_id() FastAPI dep (returns None in tests)
- sync_steps_from_tree: resolve author_id or service_account_id as created_by
- create_tree: set author_id=service_account_id for is_default trees
- Migration 1490781700bc: backfill author_id on 31 existing default trees

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 23:17:29 -05:00
chihlasm
aef40078d0 fix: UX deep dive — 28 fixes across authoring, navigation, consistency, and cleanup (#86)
* fix: tree editor authoring blockers - scroll trap, form density, branching hint

- Replace fixed viewport height with flex layout in NodeEditorPanel
- Make footer sticky so Save/Cancel always reachable
- Compact root node banner to single-line with InfoTip tooltip
- Reduce resolution note from callout box to inline text
- Add answer-first branching hint below options label

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: broken functionality - auth errors, toast logic, role update, routing, step library

- Extract backend error detail in auth store login/register
- Fix inverted 4xx toast logic and add 429 rate limit handling
- Send account_role field to match backend schema in role update
- Use type-aware routing for Repeat Last Session button
- Add step library placeholder page and route, remove dot badge

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: navigation correctness - back buttons, exit dialog, dedup nav, redirects

- Standardize all procedural back/exit paths to /trees (not /my-trees)
- Add exit button with ConfirmDialog to procedural session top bar
- Consolidate duplicate account links in sidebar and topbar
- Auto-redirect non-owners to personal analytics
- Add toast feedback before silent permission redirects in tree editor
- Delete orphaned AdminCategoriesPage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: shared components, ConfirmDialog migration, pinned flow fixes

- Create shared Spinner component with sm/md/lg sizes
- Migrate 13 page-level spinners to shared Spinner
- Promote EmptyState to shared component, adopt in MyShares and SessionHistory
- Replace window.confirm with ConfirmDialog in 3 files
- Fix PinnedFlow.tree_type to include maintenance, update emoji display
- Verify sidebar unpin handler already correct (no-op)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: visual consistency - toasts, typography, focus rings, container padding

- Remove richColors from Sonner toasts, limit stacking to 3
- Add font-heading to all page H1s (7 files)
- Add font-label (Outfit) to TagBadges component
- Fix focus ring tokens on analytics pages
- Replace deprecated glass-stat with design system tokens
- Standardize container padding on analytics pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: backend alignment - remove drafts toggle, clean dead code, truncation indicator

- Remove non-functional drafts toggle and clean TreeFilters type
- Fix AccountInvite type to match backend schema
- Remove dead API methods: pinnedFlows.pin/reorder, trees.getSharedTree
- Remove unused types: SessionListResponse, RatingCreate.is_verified_use
- Add session list truncation indicator with size=51 lookahead

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: remove bg-black from PageLoader and RouteError, fix PageLoader height

PageLoader used h-screen inside a grid cell, causing it to overflow.
Changed to h-full so it fits within the main-content area. Removed
bg-black from both PageLoader and RouteError in favor of theme-aware
bg-background to prevent black flash during lazy loading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: guard against Pydantic validation error objects in toast/error messages

FastAPI returns `detail` as an array of objects for 422 validation errors,
not a string. Passing these objects to toast.error() or rendering them in
JSX crashes React with Error #31 ("Objects are not valid as a React child").
Now checks typeof detail === 'string' before using it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: toast styling, node editor first-click, action node placeholder pattern

1. Toast fixes: Add theme="dark" to Sonner, use !important CSS overrides
   instead of zero-specificity :where() selectors, suppress noisy 4xx
   global toasts (pages handle their own errors)

2. Node editor first-click: Add node.type to draft initialization
   useEffect deps so draft resets when answer stub converts to real type

3. Action node redesign: Remove NodePicker dropdown, auto-create answer
   placeholder on save (matching decision node pattern). Users click the
   placeholder on canvas to choose type and fill in details.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: auto-seed test users when release command fails on PR envs

The background seeder now creates users directly via DB if login fails,
instead of silently aborting. This handles Railway PR environments where
the releaseCommand may not execute properly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: remove categories/tags from sidebar to prevent footer clipping

Categories and Tags sections were pushing Feedback, Account, and
Collapse off-screen when All Flows expanded its children. These
filters already exist on the TreeLibraryPage, so the sidebar
duplicates were removed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 22:10:47 -05:00