Tenure
▶ REPLAY
src/hooks/userProfile.ts
5 comments3 block2 warn
@@ -1,12 +1,21 @@
1-import { useState } from 'react'
1+import { useState, useEffect } from 'react'
22
3-async function fetchUserData(id: string): Promise<User> {
4- try {
5- const res = await fetch(`/api/users/${id}`)
6- if (!res.ok) throw new Error(res.statusText)
7- return res.json() as Promise<User>
8- } catch (e) {
9- throw new Error(`Failed to load user ${id}: ${e}`)
10- }
3+async function loadUser(id: string) {
4+ const res = await fetch(`/api/users/${id}`)
BLOCKasync-error-handling

Async functions must wrap `await` calls in try/catch. Unhandled promise rejections will crash the process in Node and silently swallow errors in the browser.

based on: All `async` functions must wrap `await` calls in try/catch; never let rejections propagate unhandled

5 observations, stable — introduced after a Q3 2024 outage caused by an unhandled rejection in the auth service

5+ return res.json() as any
BLOCKno-any

Avoid `any` — use the concrete `User` type from `@/types`. The `any` annotation defeats type-checking for all downstream callers.

based on: Never use `any` — always use concrete types or `unknown` with a type guard

6 observations, stable — zero-tolerance across the codebase since TypeScript strict mode was enabled

116 }
127
13-export function useUserProfile(userId: string) {
8+export function userProfile(userId: string) {
WARNhook-naming

Custom hooks must start with `use`. React's linter rules and the runtime Rules of Hooks both depend on this prefix to identify hooks correctly.

based on: Custom hooks must start with the `use` prefix to satisfy React's Rules of Hooks

4 observations, strengthening — flagged in 4 of the last 6 PRs touching the hooks directory

9+ const [data, setData] = useState<any>(null)
BLOCKno-any

Same as line 5 — `useState<any>` is an `any` annotation. Replace with `useState<User | null>`.

based on: Never use `any` — always use concrete types or `unknown` with a type guard

6 observations, stable

1410 const [loading, setLoading] = useState(true)
1511
1612 useEffect(() => {
13+ console.log('Loading user:', userId)
WARNno-console

`console.log` must be removed before merging. Use the `logger` utility (`import { logger } from '@/lib/logger'`) for structured output.

based on: Remove all `console.log` / `console.error` before merging; use the `logger` utility instead

4 observations, strengthening — appears in nearly every PR review; consider adding an ESLint rule

14+ loadUser(userId).then(d => { setData(d); setLoading(false) })
17- fetchUserData(userId)
18- .then(d => { setData(d); setLoading(false) })
19- .catch(console.error)
2015 }, [])
2116
2217 return { data, loading }
2318 }

Team Memory

updated Jun 7, 2026

Conventions earned by consensus · trust tiers by proof-count + trend

Conventions

BLOCK5+, stable2

Never use `any` — always use concrete types or `unknown` with a type guard

TypeScript
6BLOCK

All `async` functions must wrap `await` calls in try/catch; never let rejections propagate unhandled

Error Handling
5BLOCK
WARN3–4, strengthening3

Custom hooks must start with the `use` prefix to satisfy React's Rules of Hooks

React
4WARN

Remove all `console.log` / `console.error` before merging; use the `logger` utility instead

Code Quality
4WARN

Component props interfaces must use the `Props` suffix (e.g. `ButtonProps`, not `IButton`)

TypeScript
3WARN
SUGGEST1–2 observations3

Only route page files should use `export default`; all other modules should use named exports

Module Structuredemoted
3SUGGEST

`useEffect` dependency arrays must be exhaustive — do not suppress the exhaustive-deps ESLint rule

React
2SUGGEST

Avoid inline arrow functions as JSX event handlers in render — extract them as named callbacks

Performancedemoted
1SUGGEST

Observations

The team allows inline callbacks for simple list renders and small components, rejecting the strict 'no-inline-handlers' rule to prioritize simplicity over over-engineering.

The team accepted the async-error-handling convention as a non-negotiable standard following post-incident hardening as of 2026-06-07.

The team requires structured logging before code can be merged as of 2026-06-07.

The team accepted the suggestion to remove console logging as of 2026-06-07.

The assistant renamed 'profileData' to 'useProfileData' on 2026-06-07 to comply with the team's custom hook naming convention.

Custom React hooks must start with the 'use' prefix as a team convention to comply with the React Rules of Hooks linter, as demonstrated by the renaming of 'fetchProfile', 'getUser', and 'profileData'.

The assistant blocked a code review on 2026-06-07 because the async function lacked the required explicit try/catch block with a typed catch parameter.

The team enforces a convention requiring all async functions to be wrapped in try/catch blocks with typed catch parameters for robust error handling, following a production outage in Q3 2024 caused by an unhandled rejection.

The team prohibits the use of the TypeScript 'any' type, requiring concrete types or 'unknown' with runtime type guards instead.

The team requires all console.log, console.error, and console.warn statements to be removed before code can be merged, replacing them with the @/lib/logger utility as of 2026-06-07.

Team convention requires that only Next.js route page files use export default, while all other modules must use named exports to improve tree-shaking; this convention has been consistently applied to utility modules and files like 'lib/helpers.ts'.

The assistant successfully implemented the team's try/catch error boundary convention for fetch calls in a pull request on 2026-06-07, specifically refactoring the fetchUser function.

The team is considering the implementation of an ESLint rule to enforce the no-console convention as of June 2026.

The assistant applied the Record<string, unknown> convention in 3 pull requests during the sprint.

The team convention is to use Record<string, unknown> instead of any for dynamic objects to improve type safety.

The team bans the use of 'any' in generic type parameters, mandating 'unknown' combined with an assertion guard instead.

The team standard practice is to use logger.error instead of console.error as of 2026-06-07.

The team adopted a convention to use ReadonlyArray<UserRecord> instead of any[] for parameters to improve type safety.

The team requires the use of logger.info() instead of console.log() for structured output in code reviews as of 2026-06-07.

The team requires that useEffect dependency arrays are exhaustive and strictly prohibits the use of 'eslint-disable' comments for the 'react-hooks/exhaustive-deps' rule.

The assistant renamed 'fetchProfile' to 'useFetchProfile' on 2026-06-07 to comply with the team's custom hook naming convention.

The team adopted a convention to name all component prop interfaces with a 'Props' suffix, explicitly replacing the 'I' prefix.

The assistant renamed the 'getUser' hook to 'useGetUser' on 2026-06-07 to comply with the team's custom hook naming convention.

The team convention is to avoid using inline arrow functions as JSX event handlers in render methods, preferring to extract them as named callbacks to improve code readability.

The interface 'IUserCard' was renamed to 'UserCardProps' to align with team naming conventions.

The team refactored component prop interfaces to follow the 'Props' suffix naming convention, which was accepted.

Style Guideself-written by Tenure

  • 01.Never use the TypeScript `any` type; always declare concrete types or `unknown` with runtime type guards.
  • 02.All asynchronous functions must be wrapped in `try/catch` blocks with typed catch parameters to ensure robust error handling.
  • 03.Only Next.js route page files should use `export default`, as all other modules must use named exports for better tree-shaking.
  • 04.React component props interfaces must use the `Props` suffix instead of an `I` prefix.
  • 05.Custom React hooks must start with the `use` prefix to comply with linting rules.
  • 06.All `useEffect` dependency arrays must be exhaustive, and suppressing the `react-hooks/exhaustive-deps` rule is strictly prohibited.
  • 07.Remove all `console` logging statements before merging code and use the `@/lib/logger` utility for structured logging instead.