Skip to content

Commit ea968d4

Browse files
authored
Merge pull request #13828 from ohcnetwork/release
2 parents 59759f6 + 5f2be7b commit ea968d4

File tree

333 files changed

+36118
-11715
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

333 files changed

+36118
-11715
lines changed

.copilot/copilot-instructions.md

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
# Project Structure
2+
3+
This React TypeScript application follows a modular architecture with clear separation of concerns.
4+
5+
## Main Entry Points
6+
- [src/index.tsx](mdc:src/index.tsx) - Application bootstrap
7+
- [src/App.tsx](mdc:src/App.tsx) - Root component
8+
- [src/vite.config.mts](mdc:vite.config.mts) - Vite configuration
9+
10+
## Key Directories
11+
- `src/components/` - Reusable UI components
12+
- `src/components/ui/` - ShadCN UI components
13+
- `src/pages/` - Page components and routes
14+
- `src/Utils/` - Utility functions and helpers
15+
- `src/hooks/` - Custom React hooks
16+
- `src/context/` - React context providers
17+
- `src/types/` - TypeScript type definitions and typed API definitions
18+
- `src/Locale/` - Internationalization files
19+
- `src/CAREUI/` - Custom UI component library
20+
21+
## Configuration Files
22+
- [tailwind.config.js](mdc:tailwind.config.js) - Tailwind CSS configuration
23+
- [tsconfig.json](mdc:tsconfig.json) - TypeScript configuration
24+
- [components.json](mdc:components.json) - Shadcn UI configuration
25+
26+
# Coding Standards
27+
28+
## TypeScript Guidelines
29+
- Use TypeScript for all new code
30+
- Prefer interfaces over types for object definitions
31+
- Use functional components with proper type definitions
32+
- Avoid using `any` type; use proper type definitions
33+
- Use type inference where possible
34+
35+
## Component Structure
36+
- One component per file is preferred.
37+
- Prefer default exports for components
38+
- Follow the component naming pattern: `ComponentName.tsx`
39+
- Place components in appropriate feature directories
40+
- Keep components small and focused
41+
42+
## Styling Guidelines
43+
- Use Tailwind CSS for styling
44+
- Follow mobile-first responsive design
45+
- Use Shadcn UI components when available
46+
47+
## State Management
48+
- Use TanStack Query for API data management
49+
- Prefer React Context for global state
50+
- Use local state for component-specific data
51+
52+
## File Naming
53+
- Use kebab-case for directories: `auth-wizard/`
54+
- Use PascalCase for component files: `AuthWizard.tsx`
55+
- Use camelCase for utility files: `useAuth.ts`
56+
57+
## Testing
58+
- Write tests in Cypress for E2E testing
59+
- Follow testing guidelines in `cypress/docs/`
60+
- Test components in isolation
61+
- Write meaningful test descriptions
62+
63+
# Data Fetching and API Guidelines
64+
65+
## TanStack Query Usage
66+
67+
- Use TanStack Query with the `query` and `mutate` utilities from `@/Utils/request/`
68+
- Use appropriate query keys following the resource pattern
69+
- Leverage built-in features for pagination and debouncing
70+
- Implement proper error handling using the global error handler
71+
72+
## API Route Definitions
73+
74+
### Modern Route Pattern
75+
76+
Routes are defined in dedicated API files (`*Api.ts`) within the corresponding type directory:
77+
78+
```typescript
79+
// src/types/user/userApi.ts
80+
export default {
81+
list: {
82+
path: "/api/v1/users/",
83+
method: HttpMethod.GET,
84+
TRes: Type<PaginatedResponse<UserReadMinimal>>(),
85+
},
86+
create: {
87+
path: "/api/v1/users/",
88+
method: HttpMethod.POST,
89+
TRes: Type<UserReadMinimal>(),
90+
TBody: Type<UserCreate>(),
91+
},
92+
} as const;
93+
94+
// src/types/facility/facilityApi.ts
95+
export default {
96+
getFacility: {
97+
path: "/api/v1/facility/{id}/",
98+
method: HttpMethod.GET,
99+
TRes: Type<FacilityRead>(),
100+
},
101+
updateMonetaryComponents: {
102+
path: "/api/v1/facility/{facilityId}/set_monetary_codes/",
103+
method: HttpMethod.POST,
104+
TRes: Type<FacilityRead>(),
105+
TBody: Type<{
106+
discount_codes: Code[];
107+
discount_monetary_components: MonetaryComponentRead[];
108+
}>(),
109+
},
110+
} as const;
111+
```
112+
113+
### Legacy Route Pattern
114+
115+
Legacy routes are defined in `src/Utils/api.tsx`:
116+
117+
```typescript
118+
export const routes = {
119+
auth: {
120+
login: {
121+
path: "/api/v1/auth/login/",
122+
method: "POST",
123+
} as ApiRoute<LoginResponse, never, LoginData>,
124+
logout: {
125+
path: "/api/v1/auth/logout/",
126+
method: "POST",
127+
} as ApiRoute<void>,
128+
},
129+
} as const;
130+
```
131+
132+
## Query Patterns
133+
134+
### Basic Queries
135+
136+
```typescript
137+
const { data } = useQuery({
138+
queryKey: ['users'],
139+
queryFn: query(userApi.list)
140+
});
141+
```
142+
143+
### With Parameters
144+
145+
```typescript
146+
// Path parameters
147+
const { data } = useQuery({
148+
queryKey: ['user', username],
149+
queryFn: query(userApi.get, {
150+
pathParams: { username }
151+
})
152+
});
153+
154+
// Query parameters
155+
const { data } = useQuery({
156+
queryKey: ['facilities', searchTerm],
157+
queryFn: query(facilityApi.getAllFacilities, {
158+
queryParams: { search: searchTerm }
159+
})
160+
});
161+
```
162+
163+
## Mutation Patterns
164+
165+
```typescript
166+
const { mutate: createUser } = useMutation({
167+
mutationFn: mutate(userApi.create),
168+
onSuccess: () => {
169+
queryClient.invalidateQueries(["users"]);
170+
},
171+
});
172+
```
173+
174+
## Error Handling
175+
176+
- Errors are handled globally by default
177+
- Common scenarios are automatically handled:
178+
- Session expiry → Redirects to /session-expired
179+
- Bad requests (400/406) → Shows error notification
180+
- Use `silent: true` option to suppress error notifications
181+
- Custom error handling can be implemented using `onError` callbacks
182+
183+
184+
# UI Component Guidelines
185+
186+
## Component Library Usage
187+
- Use Shadcn UI components as the primary component library
188+
- NEVER modify the shadcn component files directly in `components/ui/*`
189+
- Follow the component documentation for proper usage
190+
- Customize components using Tailwind CSS
191+
- Maintain consistent styling across components
192+
193+
## Routing with Raviger
194+
195+
### Route Definition
196+
```typescript
197+
// src/Routers/routes/FacilityRoutes.tsx
198+
const FacilityRoutes: AppRoutes = {
199+
"/facility/:facilityId/overview": ({ facilityId }) => (
200+
<FacilityOverview facilityId={facilityId} />
201+
),
202+
"/facility/:facilityId/services/:serviceId": ({ facilityId, serviceId }) => (
203+
<HealthcareServiceShow facilityId={facilityId} serviceId={serviceId} />
204+
)
205+
};
206+
207+
// Type-safe route parameters
208+
type RouteParams<T extends string> =
209+
T extends `${string}:${infer Param}/${infer Rest}`
210+
? { [_ in Param | keyof RouteParams<Rest>]: string }
211+
: T extends `${string}:${infer Param}`
212+
? { [_ in Param]: string }
213+
: Record<string, never>;
214+
```
215+
216+
### Navigation and Hooks
217+
```typescript
218+
// Navigation
219+
import { navigate, useRedirect } from "raviger";
220+
221+
// Redirect from old to new route
222+
useRedirect("/user", "/users");
223+
224+
// Programmatic navigation
225+
navigate(`/facility/${facilityId}/services`);
226+
227+
// Route matching
228+
const routes = useRoutes(Routes);
229+
```
230+
231+
### Route Organization
232+
- Define routes in dedicated files under `src/Routers/routes/`
233+
- Group related routes in feature-specific files (e.g., `FacilityRoutes.tsx`)
234+
- Combine routes in `AppRouter.tsx`
235+
- Use proper typing with `AppRoutes` type
236+
- Support plugin routes through `usePluginRoutes` hook
237+
238+
### Layout and Navigation
239+
```typescript
240+
// Conditional sidebar rendering
241+
const PATHS_WITHOUT_SIDEBAR = [
242+
"/",
243+
"/session-expired",
244+
/^\/facility\/[^/]+\/services_requests\/[^/]+$/,
245+
];
246+
247+
// Route wrapper with error boundary
248+
<ErrorBoundary fallback={<ErrorPage />}>
249+
{routes}
250+
</ErrorBoundary>
251+
```
252+
253+
## Responsive Design
254+
- Use Tailwind's responsive classes
255+
- Follow mobile-first approach
256+
- Test components across different screen sizes
257+
- Use proper breakpoints as defined in `tailwind.config.js`
258+
259+
## Accessibility
260+
- Implement proper ARIA attributes
261+
- Ensure keyboard navigation works
262+
- Maintain proper color contrast
263+
- Support screen readers
264+
- Test with accessibility tools
265+
266+
## Component Structure
267+
```typescript
268+
// Example component structure
269+
interface ComponentProps {
270+
title: string;
271+
onAction: () => void;
272+
}
273+
274+
export function Component({ title, onAction }: ComponentProps) {
275+
const [state, setState] = useState(false);
276+
277+
return (
278+
<div className="p-4 space-y-4">
279+
<h2 className="text-xl font-bold">{title}</h2>
280+
<Button onClick={onAction}>
281+
Action
282+
</Button>
283+
</div>
284+
);
285+
}
286+
```
287+
288+
## Internationalization
289+
- Use translation keys from `src/Locale/`
290+
- Support RTL languages
291+
- Use proper date/time formatting
292+
- Support multiple languages

.cursor/rules/03-data-fetching.mdc

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,10 @@ export const routes = {
7878
### Basic Queries
7979

8080
```typescript
81-
// Using modern routes
8281
const { data } = useQuery({
8382
queryKey: ['users'],
8483
queryFn: query(userApi.list)
8584
});
86-
87-
// Using legacy routes
88-
const { data } = useQuery({
89-
queryKey: [routes.auth.me.path],
90-
queryFn: query(routes.auth.me)
91-
});
9285
```
9386

9487
### With Parameters
@@ -114,18 +107,12 @@ const { data } = useQuery({
114107
## Mutation Patterns
115108

116109
```typescript
117-
// Using modern routes
118110
const { mutate: createUser } = useMutation({
119111
mutationFn: mutate(userApi.create),
120112
onSuccess: () => {
121113
queryClient.invalidateQueries(["users"]);
122114
},
123115
});
124-
125-
// Using legacy routes
126-
const { mutate: login } = useMutation({
127-
mutationFn: mutate(routes.auth.login),
128-
});
129116
```
130117

131118
## Error Handling

.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ REACT_RECAPTCHA_SITE_KEY=6LcedK8qAAAAAM2PpuqlqhZUxQpmIqHqluL74dDs
1212
REACT_CARE_API_URL=https://care-api.do.ohc.network
1313
REACT_SBOM_BASE_URL=https://sbom.ohc.network
1414

15+
# Default payment terms for invoices
16+
REACT_DEFAULT_PAYMENT_TERMS=""
17+
1518
# Dev envs
1619
ESLINT_NO_DEV_ERRORS=true
1720
CARE_CDN_URL="https://egov-s3-facility-10bedicu.s3.amazonaws.com https://egov-s3-patient-data-10bedicu.s3.amazonaws.com http://localhost:4566"

.example.env

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ REACT_ENABLE_MINIMAL_PATIENT_REGISTRATION=true
4848
# If not set, disables the requirement
4949
REACT_PATIENT_REG_MIN_GEO_ORG_LEVELS_REQUIRED=
5050

51+
# Default govt. organization to be selected when registering a patient
52+
# If not set, does not selects anything
53+
REACT_PATIENT_REGISTRATION_DEFAULT_GEO_ORG="c272cd4e-6f55-4538-8d05-602f40f13c4e"
54+
5155
# JWT token refresh interval (in milliseconds) (default: 5 minutes)
5256
REACT_JWT_TOKEN_REFRESH_INTERVAL=
5357

@@ -73,4 +77,7 @@ REACT_MAPS_FALLBACK_URL_TEMPLATE=
7377
REACT_APP_RESEND_OTP_TIMEOUT=
7478

7579
# Maximum image upload size allowed (in megabytes)
76-
REACT_APP_MAX_IMAGE_UPLOAD_SIZE_MB=
80+
REACT_APP_MAX_IMAGE_UPLOAD_SIZE_MB=
81+
82+
# Default payment terms for invoices
83+
REACT_DEFAULT_PAYMENT_TERMS=

AGENTS.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# AGENTS.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Build/Lint/Test Commands
6+
- `npm run dev`: Start development server
7+
- `npm run build`: Build for production
8+
- `npm run lint`: Run ESLint
9+
- `npm run lint-fix`: Run ESLint with auto-fix
10+
- `npm run format`: Format code with Prettier
11+
- `npm run cypress:open`: Open Cypress UI for interactive testing
12+
- Single test: `npm run cypress:run -- --spec "cypress/e2e/path/to/spec.cy.ts"`
13+
14+
## Code Style Guidelines
15+
- **TypeScript**: Strict mode, ES2022 target, path aliases (`@/*` for src)
16+
- **Formatting**: Double quotes, 2-space indent, semicolons required
17+
- **Imports**: Order by 3rd-party → library → CAREUI → UI → components → hooks → utils → relative
18+
- **Types**: Use `interface` for objects, avoid explicit `any`, proper nullability
19+
- **Naming**: PascalCase for components/classes, camelCase for variables/functions
20+
- **Components**: Organized by feature, maintain separation of concerns
21+
- **Testing**: Follow Page Object Model, use data-cy attributes, AAA pattern (Arrange-Act-Assert)
22+
- **Error Handling**: Use dedicated error handlers, TypeScript strict null checks

0 commit comments

Comments
 (0)