web
Rules for the React Web frontend application (apps/web)
Install / Use
npx skills add bayesimpact/bayes-platformInstalls into whichever agent you are using.
Cursor Rules
Cursor IDE rules (v2)
Quality Score
Category
Development & EngineeringSupported Platforms
Our assessment of web
web scores 72/100 on our quality scale, 3770th of 4,650 Development & Engineering skills we index.
Its Cursor Rules is 10 KB long, well organised into 10 sections with 4 code examples: a thorough specification that gives an agent plenty to work with.
It has no GitHub stars yet, so there is no community track record; judge it on its content.
Maintenance, license and trust
- The repository was last updated 8 days ago, so web is actively maintained.
- Our last check on 2026-10-18 found the source still online.
- No license is declared. By default that means all rights are reserved: you can read it, but reusing or redistributing it is not clearly permitted. Ask the author before building on it commercially.
- Its trust signals score 80/100, with 2 cautions from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Safety scan
No issues foundOur scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful.
AI review by kimi-k2.7-code on 2026-09-24. Automated pattern scan on 2026-09-24. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.
web compared with similar skills
All 4 of these similar skills score higher than web; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| web (this skill)by bayesimpact | 72 | 0 | 8d ago | Cursor Rules |
| taste-skillby Leonxlnx | 100 | 111.7k | today | CLAUDE.md |
| ai-job-searchby ai-job-search-dev | 100 | 70.3k | today | CLAUDE.md |
| claude-howtoby luongnv89 | 100 | 46.7k | 5d ago | CLAUDE.md |
| lobehubby lobehub | 100 | 84.4k | today | MCP Server |
Frequently asked questions
- How do I install web?
- Run
npx skills add bayesimpact/bayes-platform. The install tabs above show the steps for each supported agent. - Which AI agents does web work with?
- It is written for Cursor, as a Cursor Rules file. Other agents that read the same format can often use it too.
- Is web safe to use?
- Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful. It declares no license and scores 80/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is web still maintained?
- The repository was last updated 8 days ago, so web is actively maintained.
Skill content
View source on GitHubdescription: Rules for the React Web frontend application (apps/web) globs:
- "apps/web/**/*" alwaysApply: false
Cursor Agent Rules for CaseAI Connect - Web
Redux & Feature Architecture
API Calls Must Go Through Redux + Services
Rule: All API calls MUST go through React-Redux thunks, which in turn MUST use the shared services object. React components MUST NOT call the API client (Axios, fetch, etc.) directly.
Requirements:
- All API calls must use Redux thunks (
createAsyncThunk) - Thunks call
extra.services.{feature}methods only (neveraxios/fetchdirectly) - Components dispatch thunks, never call API directly
- API routes and DTOs come from
@caseai-connect/api-contracts - The Axios client is centralized in
external/axios.ts - The feature services registry is centralized in
external/axios.services.tsand exposed viadi/services.ts
Structure:
- Redux slices:
features/{domain}/{domain}.slice.ts - Redux thunks:
features/{domain}/{domain}.thunks.ts - Redux selectors:
features/{domain}/{domain}.selectors.ts - Axios client:
external/axios.ts(singleton Axios with auth interceptors) - Services registry:
external/axios.services.ts(builds concrete services) anddi/services.ts(typedServices+getServices())
Store wiring:
store/index.ts:- Registers feature reducers under their domain keys (e.g.
me,projects,organizations,agents, etc.) - Configures
thunk.extraArgumentwith{ services: getServices() }(typed asThunkExtraArg) - Middleware and listeners must assume all side-effectful work goes through these services
- Registers feature reducers under their domain keys (e.g.
Feature Service Pattern (SPI + External API + Models)
Rule: Each feature MUST follow the "me" feature architecture as the canonical pattern for defining and organizing objects inside a feature.
Canonical Example (Me Feature):
features/me/me.models.ts- Defines domain-level types (
User,Me, etc.) - These are the types slices and components should depend on (not raw DTOs)
- Defines domain-level types (
features/me/me.spi.ts- Declares the Service Provider Interface for the feature (
IMeSpi) - Only exposes domain models (
Me) in its API surface
- Declares the Service Provider Interface for the feature (
features/me/external/me.api.ts- Concrete implementation of the SPI using Axios +
@caseai-connect/api-contracts - Uses
satisfies IMeSpito ensure the implementation matches the SPI contract - Performs DTO → domain mapping via small helpers (e.g.
fromDto(dto: MeResponseDto): Me)
- Concrete implementation of the SPI using Axios +
external/axios.services.ts- Wires the feature implementation into the global
servicesobject:me: meApi(wheremeApiis the SPI implementation fromfeatures/me/external/me.api.ts)
- Wires the feature implementation into the global
di/services.ts- Declares the
Servicestype (e.g.me: IMeSpi,projects: IProjectsApi, etc.) - Exposes
getServices()which returns the concreteservicesinstance
- Declares the
features/me/me.thunks.ts- Uses
createAsyncThunk<Me, void, { state: RootState; extra: ThunkExtraArg }> - Accesses the SPI through
extra.services.meonly
- Uses
features/me/me.slice.ts- Stores domain state based on
Me/Me["user"]types - Handles pending/fulfilled/rejected states of the feature thunks
- Stores domain state based on
features/me/me.selectors.ts- Selectors read from the slice and return domain models, not DTOs
Requirements for New or Refactored Features:
- Define domain models in
features/{domain}/{domain}.models.ts- Components and slices should use these models, not raw DTOs
- Define a feature SPI in
features/{domain}/{domain}.spi.ts- The interface should expose domain models and hide transport details
- For resource CRUD, SPI method names MUST match api-contracts route keys:
getAll,getOne,createOne,updateOne,deleteOne(notlist/create/ domain-prefixed names). Non-CRUD methods may stay descriptive (getMe,acceptTerms).
- Implement the SPI in
features/{domain}/external/{domain}.api.ts- Use
@caseai-connect/api-contractsroutes and DTOs - Call
{Domain}Routes.getAll/createOne/ etc. — same keys as the SPI - Perform DTO → domain mapping in small, explicit functions
- Ensure the implementation
satisfies I{Domain}Spi
- Use
- Register the implementation in
external/axios.services.ts- Add
{domain}: {domain}Apito theservicesobject
- Add
- Update
di/services.ts- Add the feature to the
Servicestype
- Add the feature to the
- Write thunks in
features/{domain}/{domain}.thunks.ts- Use
createAsyncThunk<DomainModel, ...>and callextra.services.{domain}
- Use
- Keep Redux slices and selectors feature-local, typed on the domain models
Migration Guidance:
- Legacy features (e.g.
projects,organizations,agents,test) that currently:- Define APIs in
services/{domain}.ts - Return DTOs directly to slices
- Are wired via
build{Domain}Api(getAxiosInstance())inexternal/axios.services.ts
- Define APIs in
- SHOULD be refactored over time to:
- Introduce
*.models.ts+*.spi.ts+external/*.api.ts - Use domain models internally and map from DTOs at the edge
- Use
satisfies I{Domain}Spifor API implementations - Mirror the "me" feature structure and patterns
- Introduce
Example:
// ✅ Correct - Component dispatches thunk
const dispatch = useAppDispatch()
dispatch(fetchMe())
// ❌ Wrong - Component calls API directly
const response = await fetch('/me')
Form Component Architecture
Separation of Create and Update Forms
Rule: A CreateXXXForm component MUST NEVER be used for both creating and updating actions. Always create separate components for create and update operations, and extract shared form logic into a shared component.
Requirements:
CreateXXXFormshould ONLY handle creation logicUpdateXXXFormshould ONLY handle update logic- When forms share common code (fields, validation, layout), extract it into a shared
XXXFormcomponent - The shared form component should be a presentational component that accepts props for different behaviors
Structure:
- Shared form component:
components/{domain}/{Domain}Form.tsx(e.g.,components/projects/ProjectForm.tsx) - Create form:
components/{domain}/Create{Domain}Form.tsx(e.g.,components/projects/CreateProjectForm.tsx) - Update form:
components/{domain}/Update{Domain}Form.tsx(e.g.,components/projects/UpdateProjectForm.tsx)
Example - Correct Pattern:
// ✅ Correct - Shared form component
// components/projects/ProjectForm.tsx
export function ProjectForm({
defaultName,
isLoading,
error,
onSubmit,
submitLabelIdle,
submitLabelLoading,
}: ProjectFormProps) {
// Shared form fields, validation, and layout
}
// ✅ Correct - Create-only form
// components/projects/CreateProjectForm.tsx
export function CreateProjectForm({ organizationId, onSuccess }: CreateProjectFormProps) {
const dispatch = useAppDispatch()
const handleSubmit = async (data) => {
await dispatch(createProject({ name: data.name, organizationId })).unwrap()
onSuccess?.()
}
return <ProjectForm onSubmit={handleSubmit} submitLabelIdle="Create Project" ... />
}
// ✅ Correct - Update-only form
// components/projects/UpdateProjectForm.tsx
export function UpdateProjectForm({ project, onSuccess }: UpdateProjectFormProps) {
const dispatch = useAppDispatch()
const handleSubmit = async (data) => {
await dispatch(updateProject({ projectId: project.id, payload: { name: data.name } })).unwrap()
onSuccess?.()
}
return <ProjectForm defaultName={project.name} onSubmit={handleSubmit} submitLabelIdle="Update Project" ... />
}
Example - Wrong Pattern:
// ❌ Wrong - Single form handling both create and update
export function CreateProjectForm({ organizationId, project, onSuccess }: CreateProjectFormProps) {
const onSubmit = async (data) => {
if (project) {
// Update logic
} else {
// Create logic
}
}
// ...
}
Why this pattern?
- Separation of concerns: Each form has a single, clear responsibility
- Type safety: Create and update forms can have different prop types
- Maintainability: Changes to create logic don't affect update logic and vice versa
- Reusability: Shared form component can be reused in other contexts
- Testability: Easier to test create and update logic independently
TypeScript Type Safety
Never Use any to Fix TypeScript Errors
Rule: NEVER use any type or as any type assertions to fix TypeScript errors. Always use proper types, type guards, or type narrowing instead.
Requirements:
- Never use
anytype annotations - Never use
as anytype assertions - Never use
// @ts-ignoreor// @ts-expect-errorto suppress type errors - Always fix type errors properly by:
- Using correct types from the codebase
- Adding proper type guards
- Using type narrowing
- Creating proper type definitions when needed
- Using
unknownand type guards if the type is truly unknown
Examples:
// ❌ Wrong - Using `any` to fix type errors
const result = someFunction() as any
dispatch(action as any)
// ✅ Correct - Using proper types
const result: ExpectedType = someFunction()
dispatch(action)
// ✅ Correct - Using type guards for unknown types
function isExpectedType(value: unknown): value is ExpectedType {
return typeof value === 'object' && value !== null && 'property' in value
}
if (isExpectedType(unknownValue)) {
// Now TypeScript knows the type
useValue(unknownValue)
}
Why this rule?
anydefeats the purpose of TypeScript's type safetyanycan hide real bugs and lead to runtime errors- Proper types make the code more maintainable and self-documenting
- Type guards and narrowing provide runtime safety checks
Completion Criteria
Required Checks Before Marking Work as Completed
Rule: When working on the web frontend application (apps/web), you MUST run both npm run biome:check and npm run typecheck to confirm that your changes didn't break anything before marking the task as finished.
Why: The frontend application is particularly sensitive to type errors and formatting issues that can break the build or cause runtime errors. These checks must pass before considering the work complete.
Required Steps:
- After making changes to web code, run
npm run biome:check - Then run
npm run typecheck - Fix any errors or warnings that appear
- Only mark the task as complete when both commands pass successfully
Note: These checks ensure code quality, type safety, and that existing functionality continues to work correctly.
Related Skills
taste-skill
111.7kAgent skills that give coding agents taste: art direction, reference images and a browser check instead of generic AI pages
ai-job-search
70.3kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
46.7kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
lobehub
84.4k🤯 LobeHub - Super-Agents on Your Team. Add super-agents to the chats your team already uses.They take on work by themselves and get better every week.
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
