Skip to content

Commit 6a23d40

Browse files
committed
create junie guidelines file
1 parent 1590db0 commit 6a23d40

File tree

1 file changed

+340
-0
lines changed

1 file changed

+340
-0
lines changed

.junie/guidelines.md

Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
# CORD Front-End Development Guidelines
2+
3+
This document provides guidelines for developers working on the CORD Field front-end project, a UI built with React, Material-UI (MUI) v5, and GraphQL, using Yarn and Razzle. The front-end connects to the CORD API v3.
4+
5+
## Overview
6+
7+
The CORD Field front-end enables [describe functionality briefly, e.g., field data management; replace with specific details if available]. It connects to the CORD API v3 by default at `http://localhost:3000`. For a complete setup guide, see the [cord-docs wiki](https://github.com/SeedCompany/cord-docs/wiki#new-hire-on-boarding).
8+
9+
## Build/Configuration Instructions
10+
11+
### Prerequisites
12+
13+
1. NodeJS (current version or LTS recommended, >= 18.x as per `package.json`).
14+
- Check version with `node -v`. If compilation errors occur (e.g., `Buffer` object missing `blob` property), upgrade NodeJS.
15+
2. Corepack enabled (`corepack enable`).
16+
3. Yarn (managed via Corepack).
17+
4. Local CORD API v3 server running (see [Connecting to the API Server](https://github.com/SeedCompany/cord-api-v3)).
18+
19+
### Setup
20+
21+
1. Install dependencies:
22+
23+
```bash
24+
yarn install
25+
```
26+
27+
2. Generate GraphQL schema and TypeScript types:
28+
29+
```bash
30+
yarn gql-gen
31+
```
32+
33+
3. Set up environment variables:
34+
- Copy `.env.example` to `.env.local` and configure as needed (e.g., API endpoint).
35+
36+
### Development
37+
38+
1. Start the development server:
39+
40+
```bash
41+
yarn start
42+
```
43+
44+
2. For production build:
45+
46+
```bash
47+
yarn build
48+
```
49+
50+
3. Clean build artifacts:
51+
```bash
52+
yarn clean
53+
```
54+
55+
### Connecting to the API Server
56+
57+
By default, the front-end connects to the local CORD API v3 server at `http://localhost:3000`. To use a different API server, create an `.env.local` file:
58+
59+
```dotenv
60+
RAZZLE_API_BASE_URL=http://your-api-server-host.com:3000
61+
```
62+
63+
## Testing Information
64+
65+
### Testing Framework
66+
67+
The project uses Jest and React Testing Library for testing:
68+
69+
- Unit tests: Located in `__tests__` folders alongside source code in `src/components` and `src/scenes`.
70+
- End-to-end (E2E) tests: Located in `test` directory (if applicable).
71+
72+
### Running Tests
73+
74+
1. Run unit tests:
75+
76+
```bash
77+
yarn test
78+
```
79+
80+
2. Run tests with coverage:
81+
```bash
82+
yarn test:coverage
83+
```
84+
85+
### Writing Tests
86+
87+
#### Unit Tests
88+
89+
Unit tests should be placed in `__tests__` folders alongside the component or hook, with a `.test.tsx` or `.spec.tsx` extension. For example:
90+
91+
- `src/components/form/UserForm.tsx``src/components/form/__tests__/UserForm.test.tsx`
92+
- `src/hooks/useUser.ts``src/hooks/__tests__/useUser.test.ts`
93+
94+
Example unit test:
95+
96+
```tsx
97+
// src/components/form/__tests__/UserForm.test.tsx
98+
import { render, screen } from '@testing-library/react';
99+
import { Form } from 'react-final-form';
100+
import { UserForm } from '../UserForm';
101+
102+
describe('UserForm', () => {
103+
it('renders name field', () => {
104+
render(<Form onSubmit={jest.fn()} render={() => <UserForm onSubmit={jest.fn()} />} />);
105+
expect(screen.getByLabelText('Name')).toBeInTheDocument();
106+
});
107+
});
108+
```
109+
110+
## Additional Development Information
111+
112+
### Code Style
113+
114+
The project uses ESLint and Prettier for code formatting and linting:
115+
116+
- Run `yarn lint` to check and fix linting issues.
117+
- Run `yarn format` to format code using Prettier.
118+
- Enforce TypeScript strict mode (`tsconfig.json` with `strict: true`).
119+
120+
### GraphQL
121+
122+
The project uses Apollo Client for GraphQL:
123+
124+
- Queries, mutations, and fragments are defined in `src/api` (e.g., `*.ts` or `*.graphql`).
125+
- Use `yarn gql-gen` to generate TypeScript types for queries/mutations.
126+
- Only access properties defined in generated types or `src/api/schema.graphql`.
127+
128+
### Project Structure
129+
130+
- `src/`: Source code
131+
- `src/api/`: GraphQL queries, mutations, Apollo Client setup, and API-related files.
132+
- `src/common/`: Utility TypeScript files (types, interfaces, Yup validation schemas).
133+
- `src/components/`: Reusable React components (mostly TSX, some with GraphQL files), with subfolders (e.g., `form/` for Final Form components).
134+
- `src/hooks/`: Custom React hooks (TypeScript).
135+
- `src/scenes/`: Application-specific, non-reusable components (mostly TSX, some with GraphQL files), with subfolders.
136+
- `src/server/`: Razzle server configuration files.
137+
- `src/theme/`: MUI theme configuration files.
138+
139+
### Coding Standards
140+
141+
- Use camelCase for variables, functions, and methods; ensure names are descriptive.
142+
- Use PascalCase for React components, classes, and enums.
143+
- Use kebab-case for new folders and files.
144+
- Use single quotes for strings, 2 spaces for indentation.
145+
- Prefer arrow functions for callbacks, async/await for GraphQL queries/mutations.
146+
- Use `const` for constants, minimize `let` usage (e.g., except in try/catch).
147+
- Use destructuring for objects/arrays, template literals for strings.
148+
- Follow SOLID principles for modular, reusable, maintainable code.
149+
- Avoid code duplication, deeply nested statements, hard-coded values.
150+
- Use constants/enums instead of magic numbers/strings.
151+
- Avoid mutations (non-GraphQL):
152+
- Prefer `const` over `let`.
153+
- Use spread syntax (e.g., `{ ...object, foo: 'bar' }`) instead of modifying objects.
154+
- Use strict TypeScript:
155+
- Define all object shapes in `src/common` or generated GraphQL types in `src/api`.
156+
- Use optional chaining (`?.`) or type guards for safe property access.
157+
158+
### React Guidelines
159+
160+
- Use `key` attribute only for dynamic lists (e.g., `Array.map`).
161+
- Minimize `useEffect`; prefer other hooks/patterns.
162+
- Avoid `event.preventDefault()` unless necessary.
163+
- For new small components:
164+
- Pass most props to wrapping components for reusability.
165+
- Match designs or comment stop-gap versions.
166+
- Avoid unnecessary HTML elements for styling (e.g., `<MyCard sx={{ m: 1 }} />` instead of `<Box sx={{ m: 1 }}><MyCard /></Box>`).
167+
- Use optional chaining (`?.`) or type guards for object properties.
168+
169+
### Form Development
170+
171+
- Use custom form components with Final Form and react-final-form in `src/components/form`:
172+
- Use `Form`, `Field`, and custom inputs.
173+
- Define TypeScript interfaces in `src/common`.
174+
- Use `react-final-form` hooks (e.g., `useForm`, `useField`).
175+
- Ensure form data properties match defined interfaces.
176+
- Integrate MUI v5 components (`TextField`, `Select`, etc.):
177+
- Use `sx` prop, referencing `src/theme`.
178+
- Pass `sx` and `className` props for flexibility.
179+
- Use Yup for validation:
180+
- Ensure TypeScript compatibility.
181+
182+
### CSS Guidelines
183+
184+
- Use `sx` prop for styling; avoid StyledComponents or `makeStyles`.
185+
- Reference `src/theme` for spacing (1-8), palette colors, typography variants.
186+
- Comment if using magic numbers/colors/fonts.
187+
- Ensure styles are minimal, necessary, and responsive across screen sizes.
188+
- Use `// ai edge-case` for justified deviations (e.g., non-theme colors).
189+
- **Parent components own layout styles**: Apply layout-related styles (e.g., centering, alignment, spacing) to parent components, not children, to ensure encapsulation and reusability.
190+
- Example (Correct):
191+
```tsx
192+
// ai example Parent-owned centering
193+
// src/components/CenteredCard.tsx
194+
import { Box, Card } from '@mui/material';
195+
export const CenteredCard = () => (
196+
<Box sx={{ display: 'flex', justifyContent: 'center', p: 2 }}>
197+
<Card sx={{ width: 300 }}>Content</Card>
198+
</Box>
199+
);
200+
```
201+
_Why_: Parent `<Box>` controls centering, keeping `<Card>` reusable.
202+
- Example (Incorrect):
203+
```tsx
204+
// ai anti-pattern Child-owned centering
205+
// src/components/CenteredCard.tsx
206+
import { Box, Card } from '@mui/material';
207+
export const CenteredCard = () => (
208+
<Box sx={{ p: 2 }}>
209+
<Card sx={{ margin: 'auto', width: 300 }}>Content</Card>
210+
</Box>
211+
);
212+
```
213+
_Why_: `<Card>` assumes parents layout, reducing reusability.
214+
- **Order control styles before appearance styles**: In `sx` prop declarations, list control styles (e.g., `display`, `padding`, `width`) before appearance styles (e.g., `color`, `background`, `fontSize`) for readability.
215+
- Example (Correct):
216+
```tsx
217+
// ai example Ordered sx styles
218+
// src/components/StyledBox.tsx
219+
import { Box } from '@mui/material';
220+
export const StyledBox = () => (
221+
<Box
222+
sx={{
223+
display: 'flex',
224+
justifyContent: 'center',
225+
padding: 2,
226+
width: '100%',
227+
backgroundColor: 'primary.main',
228+
color: 'white',
229+
borderRadius: 1,
230+
fontSize: 16,
231+
}}
232+
>
233+
Content
234+
</Box>
235+
);
236+
```
237+
_Why_: Control styles (`display`, `justifyContent`, `padding`, `width`) precede appearance styles (`backgroundColor`, `color`, `borderRadius`, `fontSize`), enhancing readability.
238+
- Example (Incorrect):
239+
```tsx
240+
// ai anti-pattern Disordered sx styles
241+
// src/components/StyledBox.tsx
242+
import { Box } from '@mui/material';
243+
export const StyledBox = () => (
244+
<Box
245+
sx={{
246+
color: 'white',
247+
display: 'flex',
248+
backgroundColor: 'primary.main',
249+
padding: 2,
250+
fontSize: 16,
251+
justifyContent: 'center',
252+
borderRadius: 1,
253+
width: '100%',
254+
}}
255+
>
256+
Content
257+
</Box>
258+
);
259+
```
260+
_Why_: Mixed style order reduces readability and maintainability.
261+
262+
### API Guidelines
263+
264+
- Avoid over-simplification in queries; consider second-order consequences.
265+
- Ensure `src/api` components have consistent interfaces matching designs.
266+
- Only access properties in generated GraphQL types; use type guards for dynamic data.
267+
268+
### Version Control
269+
270+
- Create branches: `type/MondayTicketID-description` (e.g., `enhancement/1234-new-profile-page`).
271+
- Write commit messages:
272+
- First line: `[TicketID] - [Short Title] - Imperative verb` (e.g., `0654 - IRP - Remove/move Impact Report Date`).
273+
- Optional body: Explain why the change is needed.
274+
- Create PRs for single changes:
275+
- Link Monday ticket in description.
276+
- Use bite-sized, logical commits.
277+
- Demo functionality to reviewers.
278+
- Check entire PR for applicability.
279+
- Verify no incorrect property access; properties must match defined types.
280+
281+
### Security Practices
282+
283+
- Sanitize user inputs to prevent XSS.
284+
- Use Apollo Clients error handling in `src/api`.
285+
- Implement role-based access control (RBAC) via GraphQL context.
286+
- Configure secure cookies (`HttpOnly`, `Secure`, `SameSite=Strict`) in `src/server`.
287+
- Enforce Content Security Policy (CSP) in `src/server`.
288+
- Validate external data (APIs, databases) for expected formats.
289+
- Check dependencies with Snyk before adding via Yarn.
290+
291+
### Common Errors to Avoid
292+
293+
- **Accessing Non-Existent Properties**:
294+
- Never assume properties exist without type verification.
295+
- Reference TypeScript interfaces in `src/common` or generated GraphQL types in `src/api`.
296+
- Use optional chaining (`?.`) or type guards (e.g., `if ('foo' in obj)`).
297+
- Example (Correct):
298+
```tsx
299+
// ai type-safety Safe property access with optional chaining
300+
interface User {
301+
name?: string;
302+
}
303+
const user: User = {};
304+
const name = user?.name ?? 'Unknown';
305+
```
306+
_Why_: Prevents runtime errors by checking property existence.
307+
- Example (Incorrect):
308+
```tsx
309+
// ai anti-pattern Assumes non-existent property
310+
const user = {};
311+
const name = user.name; // Error: Property 'name' does not exist
312+
```
313+
_Why_: Causes runtime errors due to unverified property access.
314+
315+
### Type Checking
316+
317+
Run `yarn type-check` to check for TypeScript errors without compiling the code.
318+
319+
### Debugging
320+
321+
- Use browser dev tools for React component debugging.
322+
- Enable Razzles server-side logging in `src/server` for SSR issues.
323+
- Use Jest debugger for tests: `yarn test --selectProjects Unit` with debugger attached.
324+
325+
### Tagged Comments
326+
327+
- Use `// ai tag` to mark code for reference:
328+
- `example`: Best practice or model code.
329+
- `edge-case`: Necessary deviation from standards.
330+
- `best-practice`: Adherence to coding standards.
331+
- `anti-pattern`: Code to avoid (pending refactor).
332+
- `todo`: Needs improvement or refactoring.
333+
- `workaround`: Temporary fix for a limitation.
334+
- `performance`: Optimized code.
335+
- `security`: Security-critical code.
336+
- `test`: Exemplary test case.
337+
- `design-alignment`: Matches or deviates from design specs.
338+
- `type-safety`: Safe property access.
339+
- Optionally add notes after the tag (e.g., `// ai example Reusable form with theme-based styling`).
340+
- Search tags with `git grep "ai "` to collect examples.

0 commit comments

Comments
 (0)