@longtq2501/next-spring-skills 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +3 -0
- package/README.md +7 -0
- package/package.json +1 -1
- package/skills/SKILL.md +9 -0
- package/skills/nextjs/monorepo.md +116 -0
- package/skills/nextjs/testing.md +86 -0
- package/skills/spring/testing.md +104 -0
package/AGENT.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Agent Instructions
|
|
2
2
|
|
|
3
|
+
> [!IMPORTANT]
|
|
4
|
+
> **MANDATORY STARTUP STEP**: Upon starting a new session or entering this project, the AI Agent **MUST** immediately read `skills/SKILL.md` to index all available standards and architectural patterns. Do not proceed with code generation until you have understood the patterns in the `skills/` directory.
|
|
5
|
+
|
|
3
6
|
Rules for contributing to this repository.
|
|
4
7
|
|
|
5
8
|
## Style Guidelines
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Next-Spring Skills
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@longtq2501/next-spring-skills)
|
|
4
|
+
|
|
3
5
|
Modular best practices, code templates, and interaction protocols for full-stack projects using **Next.js** and **Spring Boot**.
|
|
4
6
|
|
|
5
7
|
## Key Directories
|
|
@@ -11,6 +13,11 @@ Modular best practices, code templates, and interaction protocols for full-stack
|
|
|
11
13
|
|
|
12
14
|
---
|
|
13
15
|
|
|
16
|
+
## NPM Package
|
|
17
|
+
📦 **Registry**: [https://www.npmjs.com/package/@longtq2501/next-spring-skills](https://www.npmjs.com/package/@longtq2501/next-spring-skills)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
14
21
|
## Installation
|
|
15
22
|
You can instantly add these skills to any project using `npx`:
|
|
16
23
|
|
package/package.json
CHANGED
package/skills/SKILL.md
CHANGED
|
@@ -66,6 +66,12 @@ See [threejs.md](./nextjs/threejs.md) for high-performance 3D development and R3
|
|
|
66
66
|
### WebRTC & P2P
|
|
67
67
|
See [webrtc.md](./nextjs/webrtc.md) for real-time media and signaling.
|
|
68
68
|
|
|
69
|
+
### Quality Assurance
|
|
70
|
+
See [testing.md](./nextjs/testing.md) for Vitest and React Testing Library patterns.
|
|
71
|
+
|
|
72
|
+
### Architecture & Monorepo
|
|
73
|
+
See [monorepo.md](./nextjs/monorepo.md) for Turborepo and code-sharing strategies.
|
|
74
|
+
|
|
69
75
|
### Accessibility (a11y)
|
|
70
76
|
See [accessibility.md](./nextjs/accessibility.md) for semantic HTML and ARIA.
|
|
71
77
|
|
|
@@ -118,6 +124,9 @@ High-performance, stateless REST API patterns using Spring Boot, JPA, and JWT.
|
|
|
118
124
|
- [WebSocket & STOMP](./spring/websocket.md)
|
|
119
125
|
- [Server-Sent Events (SSE)](./spring/sse.md)
|
|
120
126
|
|
|
127
|
+
### Quality Assurance
|
|
128
|
+
- [Backend Testing](./spring/testing.md)
|
|
129
|
+
|
|
121
130
|
---
|
|
122
131
|
|
|
123
132
|
**Templates:** See the [spring/templates/](./spring/templates/) directory for production-ready boilerplates.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Skill: Monorepo Management - Turborepo (Production Blueprint)
|
|
2
|
+
|
|
3
|
+
Guidelines for building a scalable, high-performance monorepo for enterprise-level multi-platform projects.
|
|
4
|
+
|
|
5
|
+
## TL;DR - Quick Reference
|
|
6
|
+
|
|
7
|
+
### Critical Rules
|
|
8
|
+
1. **Orchestration**: Use Turborepo for build pipeline and remote caching.
|
|
9
|
+
2. **Modular Packages**: Extract logic to `packages/` to ensure 95%+ code reusability.
|
|
10
|
+
3. **Internal Linking**: Use `workspace:*` for local package dependencies.
|
|
11
|
+
4. **Consistency**: Share ESLint, Prettier, Tailwind, and TS configs across all apps.
|
|
12
|
+
5. **Types First**: Shared DTOs in `packages/types` are the single source of truth for FE/BE sync.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. Enterprise Directory Structure
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
/my-monorepo/
|
|
20
|
+
├── apps/ # Deployable Applications
|
|
21
|
+
│ ├── web/ # Next.js 14 App Router
|
|
22
|
+
│ ├── admin/ # Admin Dashboard
|
|
23
|
+
│ ├── mobile/ # React Native (Expo)
|
|
24
|
+
│ ├── desktop/ # Electron
|
|
25
|
+
│ └── api/ # Spring Boot (Backend)
|
|
26
|
+
├── packages/ # Shared Domain Logic
|
|
27
|
+
│ ├── ui/ # Core UI (Shadcn/React)
|
|
28
|
+
│ ├── types/ # Shared Interfaces & DTOs
|
|
29
|
+
│ ├── validators/ # Zod/Validation Logic
|
|
30
|
+
│ ├── utils/ # Shared Helpers (Date, String)
|
|
31
|
+
│ ├── api-client/ # Axios/Fetch Wrapper
|
|
32
|
+
│ └── database/ # Prisma/DB Client
|
|
33
|
+
├── infra/ # Shared Configuration
|
|
34
|
+
│ ├── tailwind-config/
|
|
35
|
+
│ ├── eslint-config/
|
|
36
|
+
│ └── typescript-config/
|
|
37
|
+
├── turbo.json # Build Pipeline Config
|
|
38
|
+
└── package.json # Workspace Definition
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 2. Core Configurations
|
|
44
|
+
|
|
45
|
+
### turbo.json (The Brain)
|
|
46
|
+
Defines task dependencies and caching outputs.
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"$schema": "https://turbo.build/schema.json",
|
|
51
|
+
"pipeline": {
|
|
52
|
+
"build": {
|
|
53
|
+
"dependsOn": ["^build"],
|
|
54
|
+
"outputs": [".next/**", "dist/**", "out/**"]
|
|
55
|
+
},
|
|
56
|
+
"lint": {},
|
|
57
|
+
"test": {
|
|
58
|
+
"cache": true
|
|
59
|
+
},
|
|
60
|
+
"dev": {
|
|
61
|
+
"cache": false,
|
|
62
|
+
"persistent": true
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### package.json (The Workspace)
|
|
69
|
+
Must include `workspaces` (npm/yarn) or `pnpm-workspace.yaml`.
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"private": true,
|
|
74
|
+
"workspaces": ["apps/*", "packages/*"],
|
|
75
|
+
"scripts": {
|
|
76
|
+
"dev": "turbo dev",
|
|
77
|
+
"build": "turbo build",
|
|
78
|
+
"test": "turbo test"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 3. Shared Packages Pattern
|
|
86
|
+
|
|
87
|
+
### How to share a package (ex: Types)
|
|
88
|
+
1. Create `packages/types/package.json` with a scoped name like `@repo/types`.
|
|
89
|
+
2. Export your types/interfaces from `index.ts`.
|
|
90
|
+
3. In `apps/web/package.json`, add `"@repo/types": "workspace:*"`.
|
|
91
|
+
|
|
92
|
+
// Good: Shared DTO Example
|
|
93
|
+
export interface OrderDTO {
|
|
94
|
+
id: string;
|
|
95
|
+
status: 'PENDING' | 'DONE';
|
|
96
|
+
items: string[];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 4. Scaling & Efficiency
|
|
102
|
+
|
|
103
|
+
### Remote Caching
|
|
104
|
+
Enable `turbo login` and `turbo link` in CI/CD to share build artifacts across the team, reducing build times from minutes to seconds.
|
|
105
|
+
|
|
106
|
+
### Monolith to Monorepo Migration
|
|
107
|
+
- **Step 1**: Move your monolithic `src/` to `apps/main-app/`.
|
|
108
|
+
- **Step 2**: Identify shared logic (utils, constants) and move them to `packages/`.
|
|
109
|
+
- **Step 3**: Introduce internal packages and replace local imports with `@repo/...`.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Related Skills
|
|
114
|
+
- **Frontend Testing**: `skills/nextjs/testing.md`
|
|
115
|
+
- **Performance**: `skills/nextjs/performance.md`
|
|
116
|
+
- **Agent Workflow**: `skills/agent-workflow.md`
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Skill: Frontend Testing - Vitest & RTL
|
|
2
|
+
|
|
3
|
+
Guidelines for testing React components and logic using Vitest and React Testing Library (RTL).
|
|
4
|
+
|
|
5
|
+
## TL;DR - Quick Reference
|
|
6
|
+
|
|
7
|
+
### Critical Rules
|
|
8
|
+
1. **User-Centric Testing**: Test how the user interacts with the app (e.g., clicking buttons), not implementation details (e.g., state).
|
|
9
|
+
2. **Vitest**: Use Vitest for speed and compatibility with Vite/Next.js.
|
|
10
|
+
3. **Screen Queries**: Prefer `getByRole`, `getByLabelText`, and `getByText` over `test-id`.
|
|
11
|
+
4. **Mocking**: Use `vi.mock()` for modules and **MSW (Mock Service Worker)** for API calls.
|
|
12
|
+
5. **Async Handling**: Use `findBy...` or `waitFor` to handle elements that appear after an async operation.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. Utility & Logic Testing (Vitest)
|
|
17
|
+
Test pure JavaScript/TypeScript functions and logic.
|
|
18
|
+
|
|
19
|
+
// Good: Testing a utility function
|
|
20
|
+
import { describe, it, expect } from 'vitest';
|
|
21
|
+
import { calculateTotal } from './math';
|
|
22
|
+
|
|
23
|
+
describe('calculateTotal', () => {
|
|
24
|
+
it('should sum items correctly with tax', () => {
|
|
25
|
+
const items = [{ price: 100 }, { price: 200 }];
|
|
26
|
+
const result = calculateTotal(items, 0.1);
|
|
27
|
+
expect(result).toBe(330);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 2. Component Testing (React Testing Library)
|
|
34
|
+
Test UI behavior and interaction.
|
|
35
|
+
|
|
36
|
+
// Good: Testing a Button component
|
|
37
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
38
|
+
import { Button } from './Button';
|
|
39
|
+
|
|
40
|
+
it('should call onClick when clicked', () => {
|
|
41
|
+
const handleClick = vi.fn();
|
|
42
|
+
render(<Button onClick={handleClick}>Click Me</Button>);
|
|
43
|
+
|
|
44
|
+
fireEvent.click(screen.getByText(/click me/i));
|
|
45
|
+
|
|
46
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 3. Async & API Testing (MSW)
|
|
52
|
+
Using Mock Service Worker to intercept network requests.
|
|
53
|
+
|
|
54
|
+
// Good: Testing a component that fetches data
|
|
55
|
+
it('should display products from API', async () => {
|
|
56
|
+
render(<ProductList />);
|
|
57
|
+
|
|
58
|
+
// findBy queries are async and will wait
|
|
59
|
+
const item = await screen.findByText('Laptop');
|
|
60
|
+
expect(item).toBeInTheDocument();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 4. Hooks Testing
|
|
66
|
+
Use `@testing-library/react-hooks` or the built-in `renderHook` from RTL.
|
|
67
|
+
|
|
68
|
+
// Good: Testing a custom hook
|
|
69
|
+
import { renderHook, act } from '@testing-library/react';
|
|
70
|
+
import { useCounter } from './useCounter';
|
|
71
|
+
|
|
72
|
+
it('should increment counter', () => {
|
|
73
|
+
const { result } = renderHook(() => useCounter());
|
|
74
|
+
|
|
75
|
+
act(() => {
|
|
76
|
+
result.current.increment();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
expect(result.current.count).toBe(1);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Related Skills
|
|
85
|
+
- **Interactivity & Animation**: `skills/nextjs/interactivity.md`
|
|
86
|
+
- **Performance**: `skills/nextjs/performance.md`
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Skill: Backend Testing - Spring Boot
|
|
2
|
+
|
|
3
|
+
Guidelines for implementing a robust testing pyramid (Unit, Integration, and API tests).
|
|
4
|
+
|
|
5
|
+
## TL;DR - Quick Reference
|
|
6
|
+
|
|
7
|
+
### Critical Rules
|
|
8
|
+
1. **Testing Pyramid**: Focus on many Unit tests, fewer Integration tests, and even fewer E2E tests.
|
|
9
|
+
2. **First Law**: Tests must be **Fast**, **Independent**, **Repeatable**, **Self-validating**, and **Timely**.
|
|
10
|
+
3. **Mocking**: Use `@Mock` and `@InjectMocks` for unit tests. Never use `@SpringBootTest` for unit tests.
|
|
11
|
+
4. **Data Isolation**: Always use `@DataJpaTest` for repository testing and avoid modifying production databases.
|
|
12
|
+
5. **Assertions**: Use **AssertJ** (`assertThat`) for readable and powerful assertions.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. Unit Testing (JUnit 5 + Mockito)
|
|
17
|
+
Test business logic in isolation. **No Spring context loaded.**
|
|
18
|
+
|
|
19
|
+
// Good: Testing Service logic with Mocks
|
|
20
|
+
@ExtendWith(MockitoExtension.class)
|
|
21
|
+
class ProductServiceTest {
|
|
22
|
+
@Mock
|
|
23
|
+
private ProductRepository repo;
|
|
24
|
+
|
|
25
|
+
@InjectMocks
|
|
26
|
+
private ProductService service;
|
|
27
|
+
|
|
28
|
+
@Test
|
|
29
|
+
void shouldCalculateTaxCorrect() {
|
|
30
|
+
// Given
|
|
31
|
+
Product p = new Product(100.0);
|
|
32
|
+
when(repo.findById(1L)).thenReturn(Optional.of(p));
|
|
33
|
+
|
|
34
|
+
// When
|
|
35
|
+
double result = service.getTaxedPrice(1L);
|
|
36
|
+
|
|
37
|
+
// Then
|
|
38
|
+
assertThat(result).isEqualTo(110.0);
|
|
39
|
+
verify(repo).findById(1L);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 2. Slice/API Testing (@WebMvcTest)
|
|
46
|
+
Testing controllers without booting the whole application. Uses **MockMvc**.
|
|
47
|
+
|
|
48
|
+
// Good: Testing Controller endpoints
|
|
49
|
+
@WebMvcTest(ProductController.class)
|
|
50
|
+
class ProductControllerTest {
|
|
51
|
+
@Autowired
|
|
52
|
+
private MockMvc mockMvc;
|
|
53
|
+
|
|
54
|
+
@MockBean
|
|
55
|
+
private ProductService service;
|
|
56
|
+
|
|
57
|
+
@Test
|
|
58
|
+
void shouldReturnProductList() throws Exception {
|
|
59
|
+
when(service.getAll()).thenReturn(List.of(new ProductDTO("PC")));
|
|
60
|
+
|
|
61
|
+
mockMvc.perform(get("/api/products"))
|
|
62
|
+
.andExpect(status().isOk())
|
|
63
|
+
.andExpect(jsonPath("$[0].name").value("PC"));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 3. Integration Testing (@SpringBootTest)
|
|
70
|
+
Testing the full application stack, including database and security.
|
|
71
|
+
|
|
72
|
+
// Good: Integration test with Testcontainers
|
|
73
|
+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
|
74
|
+
@Testcontainers
|
|
75
|
+
class OrderIntegrationTest {
|
|
76
|
+
|
|
77
|
+
@Container
|
|
78
|
+
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16");
|
|
79
|
+
|
|
80
|
+
@Autowired
|
|
81
|
+
private TestRestTemplate restTemplate;
|
|
82
|
+
|
|
83
|
+
@Test
|
|
84
|
+
void shouldCreateOrderRealInDB() {
|
|
85
|
+
OrderRequest req = new OrderRequest("User1", 500);
|
|
86
|
+
ResponseEntity<OrderResponse> res = restTemplate.postForEntity("/api/orders", req, OrderResponse.class);
|
|
87
|
+
|
|
88
|
+
assertThat(res.getStatusCode()).isEqualTo(HttpStatus.CREATED);
|
|
89
|
+
assertThat(res.getBody().getId()).isNotNull();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 4. Best Practices Checklist
|
|
96
|
+
- **Coverage**: Aim for 80%+ line coverage in Services, but focus on the "Happy Path" and "Edge Cases" rather than just the number.
|
|
97
|
+
- **Naming**: Use `should_DoSomething_When_Scenario` or `methodName_stateUnderTest_expectedBehavior`.
|
|
98
|
+
- **No Flaky Tests**: Avoid tests that depend on system time, random numbers, or network latency without mocking.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Related Skills
|
|
103
|
+
- **Service Design**: `skills/spring/service_design.md`
|
|
104
|
+
- **Error Handling**: `skills/spring/error_handling.md`
|