Commit Graph

74 Commits

Author SHA1 Message Date
0ade13d50d feat: apply golden/beige theme across all pages and fix header layout
Design Updates:
- Apply consistent golden/beige color scheme to all pages
- Update client dashboard, contact, FAQ, history, game, lots, profile, rules, terms, and privacy pages
- Replace green/orange colors with golden palette (#d4a574, #c4956a)
- Add golden gradient backgrounds and borders throughout

Header Improvements:
- Fix button layout to maintain proper form when page is zoomed
- Remove hover:scale-105 effects that caused deformation
- Add whitespace-nowrap to prevent text wrapping
- Add flex-shrink-0 to prevent element shrinking
- Add gap-4 to main header container for proper spacing
- Fix user info card with text ellipsis for long names/emails
- Improve spacing between "Participer" button and user card

Profile Page Updates:
- Remove "Dernière modification" field
- Update all colors to golden theme

API Endpoints:
- Fix user profile endpoint from /user/profile to /users/profile

Statistics Icons:
- Update dashboard statistics icons with distinct colors
- Total Participations: blue
- Gains réclamés: green
- En attente: yellow
- Rejetés: red

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 23:44:49 +01:00
aee6658cd7 fix: resolve React Hook dependency warnings in useEffect
Fixed all 5 ESLint warnings by wrapping functions with useCallback and adding proper dependencies:
- app/admin/tirages/page.tsx: checkExistingDraw, loadParticipants
- app/admin/utilisateurs/[id]/page.tsx: loadUserDetails
- app/historique/page.tsx: loadUserTickets, filterTickets
- app/mes-lots/page.tsx: loadTickets
- components/admin/UserManagement.tsx: loadUsers

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 01:48:26 +01:00
7febb137e9 feat: add SonarQube integration, cookie consent, and authentication improvements
- Add SonarQube configuration for code quality analysis
  - sonar-project.properties with TypeScript/Next.js settings
  - .sonarignore to exclude build artifacts and dependencies
  - npm run sonar script
  - Jenkins pipeline stages for SonarQube analysis and quality gate

- Implement cookie consent banner
  - New CookieConsent component with matching site colors
  - localStorage persistence for user choice
  - Accept/Reject buttons with proper styling
  - Link to cookies policy page

- Add strict authentication protection for game page
  - Redirect unauthenticated users to login from /jeux
  - Clean up redundant auth checks and UI elements
  - Preserve redirect parameter for post-login navigation

- Implement smart navigation with auth-aware redirects
  - "Jouer maintenant" button redirects based on auth status
  - "Participer au jeu" footer link with conditional routing
  - Authenticated users go to /jeux, others to /register

- UI improvements and cleanup
  - Remove "Voir les lots" button from homepage
  - Remove "Gestion des cookies" from footer
  - Remove "À propos" from footer navigation
  - Consistent design across components

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 01:23:50 +01:00
c8fdd59553 feat: enhance login/register pages with animated backgrounds and unified design
- Add animated tea icon backgrounds to login and register pages (35 icons)
- Update color scheme from green to golden/beige theme matching header
- Change header navigation text from "Loto à gagner" to "Lots à gagner"
- Update form placeholders to lowercase French (prénom, nom, email, etc.)
- Standardize Facebook login button style to match Google button
- Update all focus rings and button colors to #d4a574 (golden) theme

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 21:35:57 +01:00
7e079dfede fix: restart icon animations from top on page refresh
Add animation restart mechanism using React key prop to ensure tea icons
always begin their falling animation from the top of the viewport when
the page is refreshed, providing a consistent user experience.

Changes:
- Add useState and useEffect to manage animation restart
- Set unique key based on timestamp on component mount
- Icons container remounts on each page load, resetting CSS animations
- All 35 tea icons now restart their descent from -100vh on refresh

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 20:11:08 +01:00
510eab7794 feat: enhance homepage with animated tea icons and improve branding
Add animated tea icons background with 35 falling icons, update styling to match theme, and streamline branding across header and footer.

Changes:
- Add 35 animated tea icons with falling animation (no rotation)
- Create fallDown animation with gentle horizontal oscillation
- Add new homepage components (CountdownTimer, GamePeriod, GrandPrize, AboutContest)
- Include tea icon images (teapot-green, tea-cup, gift-box, tea-leaves, teapot-pink)
- Remove "Thé Tip Top" text branding from header and footer (keep logo only)
- Add Pinterest social media icon to footer
- Update button color scheme to match golden/beige theme (#d4a574, #c4956a)
- Increase icon opacity to 50% for better visibility

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 16:46:57 +01:00
815af82eba feat: remove winners page and navigation link
Completely removed the /gagnants page and its navigation link from the
header menu. This simplifies the application structure by removing the
winners showcase functionality.

Changes:
- Deleted app/gagnants/page.tsx and entire directory
- Removed "Gagnants" link from Header navigation
- Build verified successfully without the page

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 16:30:36 +01:00
1d55571017 refactor: remove winners list table from winners page
Removed the detailed winners list table showing individual winners with
dates, names, prizes, and boutiques. The page now only displays:
- Summary statistics (total winners, active days, cities)
- Winner testimonials
- Call-to-action section

This simplifies the page while maintaining social proof through
testimonials and statistics.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 16:14:01 +01:00
a3e0227e41 fix: improve Facebook login error handling and add setup documentation
Enhanced error handling for Facebook Login to provide clearer messages when
the service is unavailable. Added comprehensive setup documentation for
configuring Facebook OAuth properly.

Changes:
- Improved error messages in Facebook SDK for unavailable service
- Updated login page to display specific error messages to users
- Added FACEBOOK_LOGIN_SETUP.md with step-by-step configuration guide
- Documented alternatives (email/Google login) while Facebook is being configured

This addresses the "Fonctionnalité indisponible" error users are seeing
when attempting to use Facebook Login.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 15:44:21 +01:00
3456657ae5 feat: add user details page and getUserById service method
Created comprehensive user details page at /admin/utilisateurs/[id] that
displays contact information, personal data, account status, and ticket
statistics. Added getUserById method to admin service to fetch detailed
user information from the backend API. Fixes the "Détails" button that
was previously navigating to a non-existent page.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 15:09:00 +01:00
9e55042d1f style: change 'Voir les lots' button to green on homepage
- Update button color from orange to green (#1a4d2e)
- Add hover effect to darker green (#2d5a3d)
- 'Participer maintenant' stays orange for CTA emphasis

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 03:28:57 +01:00
6be8c9f20d fix: remove price display from client dashboard
- Remove prize value display in client page tickets table
- Keep only prize name for consistency with history page

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 03:27:19 +01:00
d0ef196c0d style: apply modern design to remaining pages
- Update about, contact, FAQ, forgot-password, lots, register, rules pages
- Apply consistent styling with bg-gray-50 and modern cards
- Update footer and layout with new design
- Add gagnants (winners) page

All pages now have consistent modern design matching homepage and dashboard

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 03:18:43 +01:00
21ccce0f3a style: update homepage buttons to orange and balance spacing
- Change "Voir les lots" button to orange to match "Participer maintenant"
- Add horizontal padding for balanced spacing
- Make buttons responsive (full width on mobile, auto on desktop)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 02:52:40 +01:00
34e0bb1f1a fix: convert prize value to number for comparison
- Fix TypeScript error where prize.value (string) was compared with number
- Use Number() conversion before comparison

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 02:41:55 +01:00
70f61fca88 feat: modern UI redesign with SVG icons and improved styling
- Update client dashboard with modern cards, SVG statistics icons, and prize icons
- Add roulette animation with colored prize icons during ticket draw
- Redesign history page with 4 statistics cards and SVG icons
- Add "Rejetés" filter button in history page
- Update profile page with modern card styling
- Redesign header with clickable user name/email button
- Add Facebook login button with green border styling
- Update game page with roulette animation and prize display
- Add prize values to constants (15€, 25€, 39€, 69€)
- Replace all emoji icons with professional SVG icons
- Apply consistent color scheme: green (#1a4d2e, #2d5a3d) and orange (#f59e0b)
- Improve button styles and hover effects across all pages

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 02:29:41 +01:00
f822077f51 fix: remove white spaces and gaps on homepage
- Removed white space between header and hero section (-mt-[4.5rem])
- Removed side margins on hero section (w-full px-0)
- Removed side margins on stats section (w-full px-0)
- Removed bottom padding on stats section (pb-0)
- Hero and stats sections now extend to full screen width
- No gap between stats section and footer

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 00:13:33 +01:00
0ebcf80155 refactor: remove final CTA section and enhance footer branding
- Removed "Prêt à tenter votre chance?" final CTA section from homepage
- Added "Thé Tip Top" title in orange/gold to footer
- Updated footer description text
- Logo already present in header and footer

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 23:59:38 +01:00
c0d67ebc06 feat: complete homepage redesign with modern green theme
Created brand new homepage matching design requirements:
- Hero section with dark green gradient background (#1a4d2e)
- "Un code, un gain garanti!" main title with orange accent
- Trust badges (100% sécurisé, 100% gagnants, 500 000 codes)
- 3-step participation process with yellow/gold icons
- 5 prize cards with percentages and modern design
- Stats section with key metrics (100%, 500k, 10, 360€)
- Final CTA section with registration buttons
- Consistent green (#1a4d2e) and orange/gold (#f59e0b) color scheme
- Professional shadows, gradients, and hover effects
- Fully responsive layout

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 23:36:46 +01:00
4e2ab858b6 Revert "feat: apply homepage green gradient style to login/register pages"
This reverts commit 512c4e1365.
2025-11-18 23:29:54 +01:00
512c4e1365 feat: apply homepage green gradient style to login/register pages
Match homepage design with professional green gradient background:
- Dark green gradient (from-[#1a4d2e] via-[#2d5a3d] to-[#1a4d2e])
- Clean white card with strong shadow (shadow-2xl)
- Brand green color for titles (#1a4d2e)
- Full screen height for better visual impact
- Consistent with homepage branding

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 23:24:03 +01:00
59379ea300 Revert "feat: apply homepage design style to login and register pages"
This reverts commit c14f40607a.
2025-11-18 23:09:02 +01:00
c14f40607a feat: apply homepage design style to login and register pages
Updated login and register pages with homepage branding:
- Dark green gradient background (from-[#1a3d2e] to-[#2d5a45])
- Semi-transparent white card (bg-white/95 backdrop-blur-sm)
- Enhanced shadow for depth (shadow-2xl)
- Brand color for titles (#1a3d2e)
- Consistent with homepage visual identity

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 23:02:41 +01:00
85b952ed24 feat: add Thé Tip Top logo to login and register pages
Added logo display at the top of both login and register forms
- Added Next.js Image component for optimized logo rendering
- Logo size: 120x120px, centered above page title
- Fixed Card padding consistency on register page (added p-8)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 22:38:37 +01:00
cdf0b2dc4a feat: add data deletion instructions page for Facebook compliance
- Create comprehensive data deletion page at /data-deletion
- Include GDPR-compliant deletion instructions
- Provide multiple deletion methods (account and email)
- Detail data retention policies and legal obligations
- Add instructions for OAuth provider (Google/Facebook) data removal

This page is required by Facebook to enable the app to go Live.

URL: https://dev.dsp5-archi-o24a-15m-g3.fr/data-deletion

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 20:46:58 +01:00
660bf32fdc fix: ensure GoogleOAuthProvider is always available to prevent context errors
- Update providers to always render GoogleOAuthProvider with dummy ID when not configured
- This prevents "must be used within GoogleOAuthProvider" errors during SSR
- The login page still checks for valid client ID before showing Google button
- Fixes dev mode errors and ensures consistent behavior

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 20:10:25 +01:00
935258a54a fix: resolve SSR prerender errors for login and profil pages
- Fix window.location usage in tirages page by adding SSR check
- Fix router.push call during SSR in profil page using useEffect
- Extract GoogleLoginButton to separate component to fix OAuth provider context
- Add null safety check for user object in profil page
- All pages now prerender successfully without errors

This fixes the 404 page not found error by ensuring proper SSR/CSR separation.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 19:45:35 +01:00
38f7e126d9 fix: remove invalid dynamicParams and revalidate exports 2025-11-18 19:25:57 +01:00
666fb1a1ac fix: move GoogleOAuthProvider to client component to fix SSR errors 2025-11-18 19:03:33 +01:00
7995b65ebe fix: revert to standard Docker build (standalone incompatible with SSR errors) 2025-11-18 17:13:21 +01:00
867c574451 fix: disable SSR for login and profile pages to fix build errors
- Add export const dynamic = 'force-dynamic' to login and profile pages
- Fixes 'Google OAuth components must be used within GoogleOAuthProvider' error
- Fixes 'location is not defined' error during static generation
- Both pages now render client-side only
2025-11-18 16:17:29 +01:00
615bba1be9 fix: resolve ESLint errors and React Hooks violations
- Disable react/no-unescaped-entities rule (cosmetic)
- Fix React Hook rules-of-hooks violation in login page
- Move useGoogleLogin call outside conditional logic
- All ESLint errors resolved, only warnings remain

ESLint now passes successfully with exit code 0.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 15:56:10 +01:00
34474cc275 fix: use API_BASE_URL constant instead of direct env access
Replace all instances of process.env.NEXT_PUBLIC_API_URL with
API_BASE_URL constant for consistency and to ensure the API URL
is properly defined at runtime.

Files updated:
- app/admin/marketing-data/page.tsx
- app/admin/tirages/page.tsx
- app/employe/dashboard/page.tsx
- app/employe/gains-client/page.tsx
- app/employe/historique/page.tsx
- components/admin/TicketManagement.tsx

This fixes the "undefined" API URL issue that was preventing
API calls from working correctly.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 15:07:49 +01:00
6a772eead6 fix: clean up about page formatting
Remove trailing whitespace for code consistency.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 14:41:02 +01:00
f82985f84e fix: make Google and Facebook OAuth optional to prevent errors
- Make GoogleOAuthProvider conditional in layout.tsx (only render if clientId exists)
- Add hasGoogleAuth and hasFacebookAuth flags in login page
- Conditionally render OAuth buttons and section only when configured
- Add fallback message when OAuth is not configured
- Prevents "Missing required parameter client_id" error when NEXT_PUBLIC_GOOGLE_CLIENT_ID is not set

This allows the app to run without OAuth credentials configured, making deployment easier when OAuth is not yet set up.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 02:52:33 +01:00
7347d77ec6 fix: add padding to login card and create forgot-password page
- Add padding (p-8) and responsive px-4 to login page Card for better layout
- Create forgot-password page to fix 404 error when clicking "Mot de passe oublié?"
- Implement basic password reset form with email validation
- Add success state showing confirmation message after email submission

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 02:39:44 +01:00
6f236ed1ce fix: correct Google login handler function name
Rename handleGoogleLoginSuccess to handleGoogleLogin and update the onClick handler to use the correct function name. This fixes the client-side exception on the login page.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 02:30:01 +01:00
c0839dd081 fix: correct indentation in homepage prizes section
Fix missing indentation that was causing a 500 error on the homepage. The grid div wrapper was incorrectly indented.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 02:22:26 +01:00
f73a84501e feat: replace placeholder homepage with proper Thé Tip Top landing page
Replace Next.js default template page with a complete landing page featuring:
- Hero section with main CTA buttons
- "How to Play" section explaining the 3-step participation process
- Updated prizes showcase section
- Enhanced final CTA section with dual action buttons

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 02:20:24 +01:00
1e6a4a0f6e fix: prevent localStorage access during SSR in debug page
Add useEffect hook to check for auth token in localStorage only on client-side, preventing "localStorage is not defined" error during static page generation. Use state variable hasToken to display token presence in the UI.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 02:07:10 +01:00
a7c7b705df fix: change button variant from 'default' to 'primary' in test-tickets page
The Button component only accepts: 'primary' | 'secondary' | 'outline' |
'danger' | 'success'. Changed 'default' to 'primary' as the closest equivalent.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 01:21:50 +01:00
e121c705cf fix: use uppercase role values in profile page quick actions
Change role comparisons from lowercase to uppercase to match User type:
- "client" → "CLIENT"
- "employee" → "EMPLOYEE"
- "admin" → "ADMIN"

The User type only defines uppercase role values.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 01:13:23 +01:00
dd951d65e1 fix: handle undefined updatedAt in profile page
Add null check for user.updatedAt before passing to formatDate function.
The User type defines updatedAt as optional (string | undefined), so we
need to handle the undefined case to prevent TypeScript compilation errors.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 01:09:13 +01:00
d3caf36203 fix: use correct User property isVerified instead of isEmailVerified
Change user.isEmailVerified to user.isVerified to match the User type
definition. The User type has isVerified property, not isEmailVerified.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 01:05:57 +01:00
3d7dd7212b fix: add type assertion for PRIZE_CONFIG access in historique page
Add type assertion to handle prize types that may not exist in PRIZE_CONFIG.
This is the same fix applied to app/client/page.tsx to prevent TypeScript
compilation errors when accessing PRIZE_CONFIG with dynamic prize types
(PHYSICAL, DISCOUNT, GRAND_PRIZE).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 01:02:34 +01:00
00f5d432dc fix: remove all snake_case property accesses in modal section
Remove invalid snake_case property accesses in the ticket details modal:
- selectedTicket.user_name → selectedTicket.user (with firstName/lastName)
- selectedTicket.user_email → selectedTicket.user?.email
- selectedTicket.user_phone → selectedTicket.user?.phone
- selectedTicket.prize_name → selectedTicket.prize?.name
- selectedTicket.prize_value → selectedTicket.prize?.value
- selectedTicket.played_at → selectedTicket.playedAt

All properties now match the Ticket type definition.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 00:58:56 +01:00
ecdfb826be fix: use correct Ticket type properties in verification page
Fix property access to match the Ticket type definition:
- ticket.user_name → ticket.user?.firstName + lastName
- ticket.user_email → ticket.user?.email
- ticket.prize_name → ticket.prize?.name
- ticket.played_at → ticket.playedAt

The Ticket type uses camelCase and nested objects (user, prize),
not snake_case flat properties.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 00:52:12 +01:00
7f04ae5eca fix: add type annotation to badges object in verification page
Add Record<string, React.ReactElement> type to badges object to allow
dynamic string indexing in app/employe/verification/page.tsx.

This matches the fix already applied to page-new.tsx and resolves the
TypeScript compilation error.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 00:47:45 +01:00
a40eb7b5d1 fix: add type annotation to badges object in getStatusBadge
Add Record<string, React.ReactElement> type to badges object to allow
dynamic string indexing. This fixes TypeScript error where status string
parameter cannot be used to index the badges object.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 00:42:31 +01:00
279556cb72 fix: use correct action values for validateTicket function
Change validateTicket action parameters from lowercase "validate"/"reject"
to uppercase "APPROVE"/"REJECT" to match the function signature.

The employeeService.validateTicket function expects action type of
'APPROVE' | 'REJECT', not 'validate' | 'reject'.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 00:38:53 +01:00