Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
fd34e41
feat(nutritional-balancings/domain): add model and use cases
Minozzzi Oct 21, 2025
41392a7
feat(nutritional-balancings/data): add use cases
Minozzzi Oct 22, 2025
2269ce1
feat(nutritional-balancings/main): add factories use cases
Minozzzi Oct 23, 2025
4da137f
feat(scripts): add scripts to generate fake data
Minozzzi Oct 22, 2025
f57c292
feat(nutritional-balancings/mocks): add fake endpoint handlers
Minozzzi Oct 23, 2025
58d2abb
feat(nutritional-balancings/domain): change types on nutrition evalua…
Minozzzi Oct 23, 2025
be46731
feat(core/mocks): register nutritional balancing mocks endpoints
Minozzzi Oct 23, 2025
0034e35
feat(nutritional-balancings/presentation): add types
Minozzzi Oct 24, 2025
6cfc12c
feat(nutritional-balancings/presentation): add form schema and valida…
Minozzzi Oct 27, 2025
beedd9d
feat(nutritional-balancings/presentation): add context and use contex…
Minozzzi Oct 27, 2025
558bd73
feat(nutritional-balancings/presentation): add hook queries
Minozzzi Oct 28, 2025
934b6d1
feat(nutritional-balancings/presentation): add data table component
Minozzzi Oct 28, 2025
31bf9c1
feat(nutritional-balancings/presentation): add delete dialog component
Minozzzi Oct 28, 2025
fe65a41
feat(core/mocks/utils): add not in filter
Minozzzi Oct 29, 2025
4553033
feat(core/mocks/utils): add value equals and value includes
Minozzzi Oct 29, 2025
c3f0374
feat(core): filters could be an array
Minozzzi Oct 29, 2025
d2bdab5
feat: add extra data when get all animals and map on domain
Minozzzi Oct 29, 2025
87deb68
feat: add badge component
Minozzzi Oct 29, 2025
2e74cae
fix: storybook styles config
Minozzzi Oct 29, 2025
2fed4e4
fix: badge secondary variant
Minozzzi Oct 29, 2025
c916e2f
feat(nutritional-balancings/presentation): add without nutritional ba…
Minozzzi Oct 30, 2025
b6bf1e3
feat(nutritional-balancings/presentation): add nutritional balancing …
Minozzzi Oct 30, 2025
309d0c5
feat(nutritional-balancings/presentation): add nutritional balancing …
Minozzzi Oct 30, 2025
c63f28c
feat(nutritional-balancings/presentation): add nutritional balancing …
Minozzzi Oct 30, 2025
f56ddd5
feat(nutritional-balancings/presentation): add new nutritional balanc…
Minozzzi Oct 30, 2025
ba99cd7
feat(nutritional-balancings/presentation): add summary tab
Minozzzi Oct 30, 2025
5312d06
feat(nutritional-balancings/presentation): add util function to creat…
Minozzzi Oct 30, 2025
f9a31b1
feat(nutritional-balancings/presentation): add util function to mount…
Minozzzi Oct 31, 2025
9dfc137
feat(nutritional-balancings/presentation): add function to mount nutr…
Minozzzi Oct 31, 2025
cb27c0b
feat(nutritional-balancings/presentation): improvement nutritional ba…
Minozzzi Oct 31, 2025
589509d
refactor: use number for values instead of string on nutritional bala…
Minozzzi Nov 4, 2025
4bd4900
feat: add formatNumber mask
Minozzzi Nov 4, 2025
8485d5f
feat: make pagination and sort on datatable optional
Minozzzi Nov 4, 2025
ea5ee49
feat: add SummaryTab display name
Minozzzi Nov 4, 2025
671461e
feat: add NutritionalRequirementsTable component
Minozzzi Nov 4, 2025
355cbb7
feat: add NutritionalEvaluationTab
Minozzzi Nov 4, 2025
3b35973
feat: add type on cultivations model
Minozzzi Nov 4, 2025
1701f2f
feat: add className on combobox
Minozzzi Nov 4, 2025
e4be491
feat: add noBorder and cell alignment props on datatable
Minozzzi Nov 4, 2025
a192cc0
feat: add ingredients tab with table
Minozzzi Nov 4, 2025
1b36b9c
feat: add ingredients table
Minozzzi Nov 4, 2025
c8414a9
feat: add general cultivation type
Minozzzi Nov 4, 2025
c238ac0
feat: add onlyNumbersAndDecimalMask mask
Minozzzi Nov 4, 2025
033a05a
feat: improve data table not found results message
Minozzzi Nov 4, 2025
fcc62a9
feat: add addIngredientDialog
Minozzzi Nov 4, 2025
97b1472
feat: move new nutritional balancing header logic to custom hook
Minozzzi Nov 4, 2025
47d3ea5
feat: use string on nutritional balancing details
Minozzzi Nov 4, 2025
a828d24
feat: allow remove animal added
Minozzzi Nov 4, 2025
1078182
fix: stop add ingredient submit propagation
Minozzzi Nov 4, 2025
3c6bf94
feat: allow remove ingredient
Minozzzi Nov 4, 2025
f71de7e
feat: add submit hook function with custom error
Minozzzi Nov 4, 2025
03b0b0e
feat: add new nutritional balancing screen
Minozzzi Nov 4, 2025
8ab9205
fix: date picker error
Minozzzi Nov 4, 2025
4c02ab0
feat: add edit nutritional balancing
Minozzzi Nov 4, 2025
2476238
feat: add nutritional balancing module
Minozzzi Nov 4, 2025
fed466e
fix: type errors
Minozzzi Nov 4, 2025
473a773
feat: improve loading
Minozzzi Nov 4, 2025
894f8b0
fix: reset animal selection when navigating and focus on first animal…
Minozzzi Nov 4, 2025
87c3867
feat: merge nutritional evaluation tab with ingredients tab
Minozzzi Nov 6, 2025
bb74775
feat: remove animal removing and add all animals on open nutritional …
Minozzzi Nov 6, 2025
85500f7
feat: add visit id on nutritional balancing model
Minozzzi Nov 7, 2025
982ad54
feat(nutritional-balancings/presentation): allow edit ingredient and …
Minozzzi Nov 7, 2025
0ba9b22
feat: select last animal to copy ingredients
Minozzzi Nov 11, 2025
288d093
feat: allow add nutritional balancing without ingredients
Minozzzi Nov 11, 2025
7f6974f
feat: group nutritional balancings by visits and get the last to fill…
Minozzzi Dec 30, 2025
8cdc1bd
fix: type error
Minozzzi Dec 30, 2025
76ddeb7
fix: copy correct ingredients by each animal
Minozzzi Dec 30, 2025
5f4e3dc
fix: logic to select animal to copy ingredients when change selected …
Minozzzi Dec 30, 2025
61393b7
fix: just call cultivations endpoint with ingredients form open
Minozzzi Dec 30, 2025
71815ac
feat: add all animals domain use case
Minozzzi Jan 2, 2026
e76407b
feat: add all animals data use case
Minozzzi Jan 2, 2026
919333d
feat: add all animals mock endpoint
Minozzzi Jan 2, 2026
591f0ee
feat: add all animals factory
Minozzzi Jan 2, 2026
2061e79
feat: add all animals query hook
Minozzzi Jan 2, 2026
b6a566e
feat: register all animals mock endpoint
Minozzzi Jan 2, 2026
3741985
feat: remove unnecessary parameter when use all animals query hook
Minozzzi Jan 2, 2026
6113204
feat: add all animals with filter hook query
Minozzzi Jan 2, 2026
c1f74fa
chore: add gemini skills
Minozzzi Feb 25, 2026
ec27af3
fix: load correctly quantity of animals from last visit
Minozzzi Feb 26, 2026
d4a8ca5
chore: add gemini.md
Minozzzi Feb 26, 2026
6cfd78f
feat(general-cultivations): add necessary fields to calculate nutriti…
Minozzzi Feb 26, 2026
8585e68
feat(nutritional-balancing): add nutritional calculations
Minozzzi Feb 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,410 changes: 2,410 additions & 0 deletions .gemini/skills/vercel-react-best-practices/AGENTS.md

Large diffs are not rendered by default.

125 changes: 125 additions & 0 deletions .gemini/skills/vercel-react-best-practices/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
name: vercel-react-best-practices
description: React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
license: MIT
metadata:
author: vercel
version: "1.0.0"
---

# Vercel React Best Practices

Comprehensive performance optimization guide for React and Next.js applications, maintained by Vercel. Contains 45 rules across 8 categories, prioritized by impact to guide automated refactoring and code generation.

## When to Apply

Reference these guidelines when:
- Writing new React components or Next.js pages
- Implementing data fetching (client or server-side)
- Reviewing code for performance issues
- Refactoring existing React/Next.js code
- Optimizing bundle size or load times

## Rule Categories by Priority

| Priority | Category | Impact | Prefix |
|----------|----------|--------|--------|
| 1 | Eliminating Waterfalls | CRITICAL | `async-` |
| 2 | Bundle Size Optimization | CRITICAL | `bundle-` |
| 3 | Server-Side Performance | HIGH | `server-` |
| 4 | Client-Side Data Fetching | MEDIUM-HIGH | `client-` |
| 5 | Re-render Optimization | MEDIUM | `rerender-` |
| 6 | Rendering Performance | MEDIUM | `rendering-` |
| 7 | JavaScript Performance | LOW-MEDIUM | `js-` |
| 8 | Advanced Patterns | LOW | `advanced-` |

## Quick Reference

### 1. Eliminating Waterfalls (CRITICAL)

- `async-defer-await` - Move await into branches where actually used
- `async-parallel` - Use Promise.all() for independent operations
- `async-dependencies` - Use better-all for partial dependencies
- `async-api-routes` - Start promises early, await late in API routes
- `async-suspense-boundaries` - Use Suspense to stream content

### 2. Bundle Size Optimization (CRITICAL)

- `bundle-barrel-imports` - Import directly, avoid barrel files
- `bundle-dynamic-imports` - Use next/dynamic for heavy components
- `bundle-defer-third-party` - Load analytics/logging after hydration
- `bundle-conditional` - Load modules only when feature is activated
- `bundle-preload` - Preload on hover/focus for perceived speed

### 3. Server-Side Performance (HIGH)

- `server-cache-react` - Use React.cache() for per-request deduplication
- `server-cache-lru` - Use LRU cache for cross-request caching
- `server-serialization` - Minimize data passed to client components
- `server-parallel-fetching` - Restructure components to parallelize fetches
- `server-after-nonblocking` - Use after() for non-blocking operations

### 4. Client-Side Data Fetching (MEDIUM-HIGH)

- `client-swr-dedup` - Use SWR for automatic request deduplication
- `client-event-listeners` - Deduplicate global event listeners

### 5. Re-render Optimization (MEDIUM)

- `rerender-defer-reads` - Don't subscribe to state only used in callbacks
- `rerender-memo` - Extract expensive work into memoized components
- `rerender-dependencies` - Use primitive dependencies in effects
- `rerender-derived-state` - Subscribe to derived booleans, not raw values
- `rerender-functional-setstate` - Use functional setState for stable callbacks
- `rerender-lazy-state-init` - Pass function to useState for expensive values
- `rerender-transitions` - Use startTransition for non-urgent updates

### 6. Rendering Performance (MEDIUM)

- `rendering-animate-svg-wrapper` - Animate div wrapper, not SVG element
- `rendering-content-visibility` - Use content-visibility for long lists
- `rendering-hoist-jsx` - Extract static JSX outside components
- `rendering-svg-precision` - Reduce SVG coordinate precision
- `rendering-hydration-no-flicker` - Use inline script for client-only data
- `rendering-activity` - Use Activity component for show/hide
- `rendering-conditional-render` - Use ternary, not && for conditionals

### 7. JavaScript Performance (LOW-MEDIUM)

- `js-batch-dom-css` - Group CSS changes via classes or cssText
- `js-index-maps` - Build Map for repeated lookups
- `js-cache-property-access` - Cache object properties in loops
- `js-cache-function-results` - Cache function results in module-level Map
- `js-cache-storage` - Cache localStorage/sessionStorage reads
- `js-combine-iterations` - Combine multiple filter/map into one loop
- `js-length-check-first` - Check array length before expensive comparison
- `js-early-exit` - Return early from functions
- `js-hoist-regexp` - Hoist RegExp creation outside loops
- `js-min-max-loop` - Use loop for min/max instead of sort
- `js-set-map-lookups` - Use Set/Map for O(1) lookups
- `js-tosorted-immutable` - Use toSorted() for immutability

### 8. Advanced Patterns (LOW)

- `advanced-event-handler-refs` - Store event handlers in refs
- `advanced-use-latest` - useLatest for stable callback refs

## How to Use

Read individual rule files for detailed explanations and code examples:

```
rules/async-parallel.md
rules/bundle-barrel-imports.md
rules/_sections.md
```

Each rule file contains:
- Brief explanation of why it matters
- Incorrect code example with explanation
- Correct code example with explanation
- Additional context and references

## Full Compiled Document

For the complete guide with all rules expanded: `AGENTS.md`
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: Store Event Handlers in Refs
impact: LOW
impactDescription: stable subscriptions
tags: advanced, hooks, refs, event-handlers, optimization
---

## Store Event Handlers in Refs

Store callbacks in refs when used in effects that shouldn't re-subscribe on callback changes.

**Incorrect (re-subscribes on every render):**

```tsx
function useWindowEvent(event: string, handler: (e) => void) {
useEffect(() => {
window.addEventListener(event, handler)
return () => window.removeEventListener(event, handler)
}, [event, handler])
}
```

**Correct (stable subscription):**

```tsx
function useWindowEvent(event: string, handler: (e) => void) {
const handlerRef = useRef(handler)
useEffect(() => {
handlerRef.current = handler
}, [handler])

useEffect(() => {
const listener = (e) => handlerRef.current(e)
window.addEventListener(event, listener)
return () => window.removeEventListener(event, listener)
}, [event])
}
```

**Alternative: use `useEffectEvent` if you're on latest React:**

```tsx
import { useEffectEvent } from 'react'

function useWindowEvent(event: string, handler: (e) => void) {
const onEvent = useEffectEvent(handler)

useEffect(() => {
window.addEventListener(event, onEvent)
return () => window.removeEventListener(event, onEvent)
}, [event])
}
```

`useEffectEvent` provides a cleaner API for the same pattern: it creates a stable function reference that always calls the latest version of the handler.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: useLatest for Stable Callback Refs
impact: LOW
impactDescription: prevents effect re-runs
tags: advanced, hooks, useLatest, refs, optimization
---

## useLatest for Stable Callback Refs

Access latest values in callbacks without adding them to dependency arrays. Prevents effect re-runs while avoiding stale closures.

**Implementation:**

```typescript
function useLatest<T>(value: T) {
const ref = useRef(value)
useLayoutEffect(() => {
ref.current = value
}, [value])
return ref
}
```

**Incorrect (effect re-runs on every callback change):**

```tsx
function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
const [query, setQuery] = useState('')

useEffect(() => {
const timeout = setTimeout(() => onSearch(query), 300)
return () => clearTimeout(timeout)
}, [query, onSearch])
}
```

**Correct (stable effect, fresh callback):**

```tsx
function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
const [query, setQuery] = useState('')
const onSearchRef = useLatest(onSearch)

useEffect(() => {
const timeout = setTimeout(() => onSearchRef.current(query), 300)
return () => clearTimeout(timeout)
}, [query])
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: Prevent Waterfall Chains in API Routes
impact: CRITICAL
impactDescription: 2-10× improvement
tags: api-routes, server-actions, waterfalls, parallelization
---

## Prevent Waterfall Chains in API Routes

In API routes and Server Actions, start independent operations immediately, even if you don't await them yet.

**Incorrect (config waits for auth, data waits for both):**

```typescript
export async function GET(request: Request) {
const session = await auth()
const config = await fetchConfig()
const data = await fetchData(session.user.id)
return Response.json({ data, config })
}
```

**Correct (auth and config start immediately):**

```typescript
export async function GET(request: Request) {
const sessionPromise = auth()
const configPromise = fetchConfig()
const session = await sessionPromise
const [config, data] = await Promise.all([
configPromise,
fetchData(session.user.id)
])
return Response.json({ data, config })
}
```

For operations with more complex dependency chains, use `better-all` to automatically maximize parallelism (see Dependency-Based Parallelization).
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
title: Defer Await Until Needed
impact: HIGH
impactDescription: avoids blocking unused code paths
tags: async, await, conditional, optimization
---

## Defer Await Until Needed

Move `await` operations into the branches where they're actually used to avoid blocking code paths that don't need them.

**Incorrect (blocks both branches):**

```typescript
async function handleRequest(userId: string, skipProcessing: boolean) {
const userData = await fetchUserData(userId)

if (skipProcessing) {
// Returns immediately but still waited for userData
return { skipped: true }
}

// Only this branch uses userData
return processUserData(userData)
}
```

**Correct (only blocks when needed):**

```typescript
async function handleRequest(userId: string, skipProcessing: boolean) {
if (skipProcessing) {
// Returns immediately without waiting
return { skipped: true }
}

// Fetch only when needed
const userData = await fetchUserData(userId)
return processUserData(userData)
}
```

**Another example (early return optimization):**

```typescript
// Incorrect: always fetches permissions
async function updateResource(resourceId: string, userId: string) {
const permissions = await fetchPermissions(userId)
const resource = await getResource(resourceId)

if (!resource) {
return { error: 'Not found' }
}

if (!permissions.canEdit) {
return { error: 'Forbidden' }
}

return await updateResourceData(resource, permissions)
}

// Correct: fetches only when needed
async function updateResource(resourceId: string, userId: string) {
const resource = await getResource(resourceId)

if (!resource) {
return { error: 'Not found' }
}

const permissions = await fetchPermissions(userId)

if (!permissions.canEdit) {
return { error: 'Forbidden' }
}

return await updateResourceData(resource, permissions)
}
```

This optimization is especially valuable when the skipped branch is frequently taken, or when the deferred operation is expensive.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
title: Dependency-Based Parallelization
impact: CRITICAL
impactDescription: 2-10× improvement
tags: async, parallelization, dependencies, better-all
---

## Dependency-Based Parallelization

For operations with partial dependencies, use `better-all` to maximize parallelism. It automatically starts each task at the earliest possible moment.

**Incorrect (profile waits for config unnecessarily):**

```typescript
const [user, config] = await Promise.all([
fetchUser(),
fetchConfig()
])
const profile = await fetchProfile(user.id)
```

**Correct (config and profile run in parallel):**

```typescript
import { all } from 'better-all'

const { user, config, profile } = await all({
async user() { return fetchUser() },
async config() { return fetchConfig() },
async profile() {
return fetchProfile((await this.$.user).id)
}
})
```

Reference: [https://github.com/shuding/better-all](https://github.com/shuding/better-all)
Loading