## perf-data-optimization
- Add @@index([name]) on User model (migration)
- Add WEATHER_HISTORY_LIMIT=90 constant, apply take/orderBy on weather history queries
- Replace deep includes with explicit select on all 6 list service queries
- Add unstable_cache layer with revalidateTag on all list service functions
- Add cache-tags.ts helpers (sessionTag, sessionsListTag, userStatsTag)
- Invalidate sessionsListTag in all create/delete Server Actions
## perf-realtime-scale
- Create src/lib/broadcast.ts: generic createBroadcaster factory with shared polling
(one interval per active session, starts on first subscriber, stops on last)
- Migrate all 6 SSE routes to use createBroadcaster — removes per-connection setInterval
- Add broadcastToXxx() calls in all Server Actions after mutations for immediate push
- Add SESSIONS_PAGE_SIZE=20, pagination on sessions page with loadMoreSessions action
- Add "Charger plus" button with loading state and "X sur Y" counter in WorkshopTabs
## Tests
- Add 19 unit tests for broadcast.ts (polling lifecycle, userId filtering,
formatEvent, error resilience, session isolation)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Introduced new test scripts in package.json: "test", "test:watch", and "test:coverage".
- Added Vitest and vite-tsconfig-paths as dependencies for improved testing capabilities.
- Updated pnpm-lock.yaml to reflect new dependencies and their versions.
- Eliminate N+1 on resolveCollaborator: add batchResolveCollaborators() in
auth.ts (2 DB queries max regardless of session count), update all 4
workshop services to use post-batch mapping
- Debounce router.refresh() in useLive.ts (300ms) to group simultaneous
SSE events and avoid cascade re-renders
- Call cleanupOldEvents fire-and-forget in createEvent to purge old SSE
events inline without blocking the response
- Add loading.tsx skeletons on /sessions and /users matching actual page
layout (PageHeader + content structure)
- Lazy-load ShareModal via next/dynamic in BaseSessionLiveWrapper to reduce
initial JS bundle
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Introduced a new configuration file `config.yaml` for specifying project context and artifact rules.
- Added `.openspec.yaml` files for tracking changes related to performance improvements.
- Created design documents outlining the context, goals, decisions, and migration plans for optimizing session performance.
- Proposed changes include batching database queries, debouncing event refreshes, purging old events, and implementing loading states for better user experience.
- Added tasks and specifications to ensure proper implementation and validation of the new features.
These enhancements aim to improve the scalability and responsiveness of the application during collaborative sessions.
- Introduced `OPSX: Apply` to implement tasks from OpenSpec changes.
- Added `OPSX: Archive` for archiving completed changes in the experimental workflow.
- Created `OPSX: Explore` for a thinking partner mode to investigate ideas and clarify requirements.
- Implemented `OPSX: Propose` to generate change proposals and associated artifacts in one step.
- Developed skills for `openspec-apply-change` and `openspec-archive-change` to facilitate task implementation and archiving processes.
These additions enhance the workflow capabilities and provide structured approaches for managing changes within the OpenSpec framework.
Replace EditableSessionTitle, EditableMotivatorTitle, EditableYearReviewTitle,
EditableWeatherTitle, EditableWeeklyCheckInTitle, EditableGifMoodTitle individual
files with a single EditableTitles.tsx using spread props. Same public API.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Redesign session cards with colored left border (Figma-style), improved
visual hierarchy, hover states, and stats in footer
- Add 4 switchable view modes: grid, list, sortable table, and timeline
- Table view: unified flat table with clickable column headers for sorting
(Type, Titre, Créateur, Participant, Stats, Date)
- Add Créateur column showing the workshop owner with Gravatar avatar
- Widen Type column to 160px for better readability
- Improve tabs navigation with pill-shaped active state and shadow
- Fix TypeFilterDropdown to exclude 'Équipe' from type list
- Make filter tabs visually distinct with bg-card + border + shadow-sm
- Split WorkshopTabs.tsx into 4 focused modules:
workshop-session-types.ts, workshop-session-helpers.ts,
SessionCard.tsx, WorkshopTabs.tsx
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a collapsible SVG line graph on weather session pages displaying
the evolution of all 4 indicators (Performance, Moral, Flux, Création
de valeur) across sessions, with per-session average scores, hover
tooltips, and a marker on the current session.
Also fixes pre-existing lint errors: non-null assertion on optional
chain in Header and eslint-disable for intentional hydration pattern
in ThemeToggle.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New workshop where each team member shares up to 5 GIFs with notes to express their weekly mood
- Per-user week rating (1-5 stars) visible next to each member's section
- Masonry-style grid with adjustable column count (3/4/5) toggle
- Handwriting font (Caveat) for GIF notes
- Full real-time collaboration via SSE
- Clean migration (add_gif_mood_workshop) safe for production deploy
- DB backup via cp before each migration in docker-entrypoint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Server doesn't know localStorage theme, so defer emoji rendering until
after mount to avoid server/client text mismatch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move session check from client-side useSession() to server-side auth(),
so the authenticated state is known at initial render. Extract interactive
parts (ThemeToggle, UserMenu, WorkshopsDropdown, NavLinks) into small
client components.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix resolveCollaborator N+1: replace full User table scan with findFirst
- Fix getAllUsersWithStats N+1: use groupBy instead of per-user count queries
- Cache getTeamMemberIdsForAdminTeams and isAdminOfUser with React.cache
- Increase SSE poll interval from 1s to 2s across all 5 subscribe routes
- Add cleanupOldEvents method to session-share-events for event table TTL
- Add React.memo to all card components (Swot, Motivator, Weather, WeeklyCheckIn, YearReview)
- Fix WeatherCard useEffect+setState lint error with idiomatic prop sync pattern
- Add optimizePackageImports for DnD libs and poweredByHeader:false in next.config
- Add inline theme script in layout.tsx to prevent dark mode FOUC
- Remove unused Next.js template SVGs from public/
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reintroduced the WeatherAverageBar component in the WeatherSessionPage to display team averages. Updated the styling of the WeatherAverageBar for improved spacing. Enhanced the EvolutionIndicator component to use dynamic background colors for better visibility of status indicators.
Replace plain text-xs arrows with 20×20px colored circular badges
(green ↑, red ↓, muted →) to ensure they are clearly visible next
to emoji cells. Also widen emoji columns from w-24 → w-28 to give
the badge room without overflow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- WeatherBoard: change previousEntries type from Map<string, PreviousEntry> to Record<string, PreviousEntry> and update lookup from .get() to bracket notation
- page.tsx: wrap previousEntries with Object.fromEntries() before passing as prop, remove unused currentUser prop
- WeatherCard: remove spurious eslint-disable-next-line comment for non-existent rule react-hooks/set-state-in-effect
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>