create-win-project 1.3.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/LICENSE +21 -0
- package/README.md +187 -0
- package/ci/expo.yml +28 -0
- package/ci/laravel.yml +49 -0
- package/ci/nextjs.yml +29 -0
- package/ci/springboot.yml +33 -0
- package/ci/vite.yml +36 -0
- package/compatibility/profiles.json +237 -0
- package/docs/ARCHITECTURE.md +118 -0
- package/docs/CONTENT_MODEL.md +36 -0
- package/docs/DEPENDENCY_MAINTENANCE.md +31 -0
- package/index.js +431 -0
- package/lib/application-shapes.js +95 -0
- package/lib/banner.js +45 -0
- package/lib/catalog.js +343 -0
- package/lib/compatibility.js +116 -0
- package/lib/constants.js +3 -0
- package/lib/doctor.js +45 -0
- package/lib/files.js +158 -0
- package/lib/generator.js +366 -0
- package/lib/interview.js +77 -0
- package/lib/laravel-scaffold.js +3 -0
- package/lib/playbooks.js +172 -0
- package/lib/project-location.js +18 -0
- package/lib/scaffold.js +467 -0
- package/lib/stacks/context.js +27 -0
- package/lib/stacks/contract.js +142 -0
- package/lib/stacks/index.js +8 -0
- package/lib/stacks/laravel/architecture.js +27 -0
- package/lib/stacks/laravel/auth/oidc.js +13 -0
- package/lib/stacks/laravel/auth/public.js +28 -0
- package/lib/stacks/laravel/auth/sanctum.js +14 -0
- package/lib/stacks/laravel/auth/session.js +17 -0
- package/lib/stacks/laravel/composer.js +50 -0
- package/lib/stacks/laravel/generate.js +362 -0
- package/lib/stacks/laravel/index.js +18 -0
- package/lib/stacks/laravel/ui/blade.js +15 -0
- package/lib/stacks/laravel/ui/index.js +29 -0
- package/lib/stacks/laravel/ui/inertia-react.js +35 -0
- package/lib/stacks/laravel/ui/livewire.js +39 -0
- package/lib/stacks/laravel/ui/shared.js +14 -0
- package/lib/stacks/registry.js +42 -0
- package/lib/stacks/shared/contributions.js +25 -0
- package/lib/template.js +62 -0
- package/package.json +49 -0
- package/playbooks/INDEX.md +58 -0
- package/playbooks/capabilities/auth/oidc-resource-server.md +15 -0
- package/playbooks/capabilities/auth/spring-session.md +15 -0
- package/playbooks/capabilities/ci/github-actions.manifest.json +10 -0
- package/playbooks/capabilities/ci/github-actions.md +61 -0
- package/playbooks/capabilities/docker/docker.manifest.json +11 -0
- package/playbooks/capabilities/docker/overview.md +55 -0
- package/playbooks/capabilities/flyway/environments.md +5 -0
- package/playbooks/capabilities/flyway/flyway.manifest.json +12 -0
- package/playbooks/capabilities/flyway/migrations.md +7 -0
- package/playbooks/capabilities/flyway/testing.md +5 -0
- package/playbooks/capabilities/laravel/database.md +8 -0
- package/playbooks/capabilities/laravel/migrations.md +15 -0
- package/playbooks/capabilities/laravel/observability.md +8 -0
- package/playbooks/capabilities/laravel/oidc-resource-server.md +10 -0
- package/playbooks/capabilities/laravel/queues.md +8 -0
- package/playbooks/capabilities/laravel/sanctum-spa.md +8 -0
- package/playbooks/capabilities/laravel/scheduler.md +7 -0
- package/playbooks/capabilities/laravel/session-auth.md +8 -0
- package/playbooks/capabilities/laravel/storage-uploads.md +7 -0
- package/playbooks/capabilities/postgresql/architecture.md +5 -0
- package/playbooks/capabilities/postgresql/migrations.md +5 -0
- package/playbooks/capabilities/postgresql/postgresql.manifest.json +15 -0
- package/playbooks/capabilities/postgresql/schema-design.md +7 -0
- package/playbooks/capabilities/postgresql/security.md +5 -0
- package/playbooks/capabilities/postgresql/testing.md +5 -0
- package/playbooks/capabilities/prisma/architecture.md +5 -0
- package/playbooks/capabilities/prisma/migrations.md +11 -0
- package/playbooks/capabilities/prisma/prisma.manifest.json +14 -0
- package/playbooks/capabilities/prisma/runtime.md +5 -0
- package/playbooks/capabilities/prisma/schema.md +5 -0
- package/playbooks/capabilities/prisma/testing.md +5 -0
- package/playbooks/capabilities/supabase/architecture.md +5 -0
- package/playbooks/capabilities/supabase/authentication.md +5 -0
- package/playbooks/capabilities/supabase/expo.md +16 -0
- package/playbooks/capabilities/supabase/migrations.md +7 -0
- package/playbooks/capabilities/supabase/nextjs.md +24 -0
- package/playbooks/capabilities/supabase/rls.md +7 -0
- package/playbooks/capabilities/supabase/supabase.manifest.json +32 -0
- package/playbooks/capabilities/supabase/testing.md +5 -0
- package/playbooks/capabilities/supabase/vite.md +14 -0
- package/playbooks/concerns/axios.md +123 -0
- package/playbooks/concerns/next-safe-action.md +66 -0
- package/playbooks/concerns/next-themes.md +87 -0
- package/playbooks/concerns/nuqs.md +59 -0
- package/playbooks/concerns/t3-env.md +48 -0
- package/playbooks/concerns/tanstack-query.md +145 -0
- package/playbooks/concerns/zod.md +174 -0
- package/playbooks/concerns/zustand.md +93 -0
- package/playbooks/devops/makefile.manifest.json +10 -0
- package/playbooks/devops/makefile.md +556 -0
- package/playbooks/devops/pr-template.manifest.json +10 -0
- package/playbooks/devops/pr-template.md +106 -0
- package/playbooks/platform/laravel-ui/blade/architecture.md +5 -0
- package/playbooks/platform/laravel-ui/blade/runtime.md +5 -0
- package/playbooks/platform/laravel-ui/blade/security.md +5 -0
- package/playbooks/platform/laravel-ui/blade/structure.md +5 -0
- package/playbooks/platform/laravel-ui/blade/testing.md +5 -0
- package/playbooks/platform/laravel-ui/inertia-react/architecture.md +5 -0
- package/playbooks/platform/laravel-ui/inertia-react/runtime.md +5 -0
- package/playbooks/platform/laravel-ui/inertia-react/security.md +5 -0
- package/playbooks/platform/laravel-ui/inertia-react/structure.md +5 -0
- package/playbooks/platform/laravel-ui/inertia-react/testing.md +5 -0
- package/playbooks/platform/laravel-ui/livewire/architecture.md +5 -0
- package/playbooks/platform/laravel-ui/livewire/runtime.md +5 -0
- package/playbooks/platform/laravel-ui/livewire/security.md +5 -0
- package/playbooks/platform/laravel-ui/livewire/structure.md +5 -0
- package/playbooks/platform/laravel-ui/livewire/testing.md +5 -0
- package/playbooks/platform/mobile.manifest.json +17 -0
- package/playbooks/platform/mobile.md +15 -0
- package/playbooks/platform/web.manifest.json +17 -0
- package/playbooks/platform/web.md +17 -0
- package/playbooks/stack/expo/architecture.md +27 -0
- package/playbooks/stack/expo/runtime.md +14 -0
- package/playbooks/stack/expo/security.md +18 -0
- package/playbooks/stack/expo/structure.md +26 -0
- package/playbooks/stack/expo/testing.md +13 -0
- package/playbooks/stack/laravel/architecture.md +34 -0
- package/playbooks/stack/laravel/runtime.md +27 -0
- package/playbooks/stack/laravel/security.md +23 -0
- package/playbooks/stack/laravel/structure.md +29 -0
- package/playbooks/stack/laravel/testing.md +22 -0
- package/playbooks/stack/laravel-ui.manifest.json +42 -0
- package/playbooks/stack/laravel.manifest.json +35 -0
- package/playbooks/stack/nextjs/architecture.md +62 -0
- package/playbooks/stack/nextjs/runtime.md +31 -0
- package/playbooks/stack/nextjs/security.md +32 -0
- package/playbooks/stack/nextjs/structure.md +50 -0
- package/playbooks/stack/nextjs/testing.md +20 -0
- package/playbooks/stack/nextjs.manifest.json +49 -0
- package/playbooks/stack/no-frontend.manifest.json +25 -0
- package/playbooks/stack/none.manifest.json +21 -0
- package/playbooks/stack/react-native.manifest.json +49 -0
- package/playbooks/stack/react-vite/architecture.md +33 -0
- package/playbooks/stack/react-vite/runtime.md +13 -0
- package/playbooks/stack/react-vite/security.md +16 -0
- package/playbooks/stack/react-vite/structure.md +23 -0
- package/playbooks/stack/react-vite/testing.md +12 -0
- package/playbooks/stack/react-vite.manifest.json +46 -0
- package/playbooks/stack/springboot/architecture.md +40 -0
- package/playbooks/stack/springboot/runtime.md +28 -0
- package/playbooks/stack/springboot/security.md +28 -0
- package/playbooks/stack/springboot/structure.md +30 -0
- package/playbooks/stack/springboot/testing.md +22 -0
- package/playbooks/stack/springboot.manifest.json +38 -0
- package/playbooks/styling/css-modules-extensions.md +267 -0
- package/playbooks/styling/css-modules.manifest.json +11 -0
- package/playbooks/styling/native-styles.manifest.json +9 -0
- package/playbooks/styling/native-styles.md +29 -0
- package/playbooks/styling/tailwind-extensions.md +182 -0
- package/playbooks/styling/tailwind.manifest.json +11 -0
- package/playbooks/universal/accessibility.manifest.json +11 -0
- package/playbooks/universal/accessibility.md +45 -0
- package/playbooks/universal/coding-rules.manifest.json +12 -0
- package/playbooks/universal/coding-rules.md +281 -0
- package/playbooks/universal/error-handling.manifest.json +10 -0
- package/playbooks/universal/error-handling.md +21 -0
- package/playbooks/universal/git-conventions.manifest.json +10 -0
- package/playbooks/universal/git-conventions.md +186 -0
- package/playbooks/universal/observability.manifest.json +10 -0
- package/playbooks/universal/observability.md +29 -0
- package/playbooks/universal/security.manifest.json +11 -0
- package/playbooks/universal/security.md +30 -0
- package/playbooks/universal/typescript.manifest.json +11 -0
- package/playbooks/universal/typescript.md +272 -0
- package/scripts/compatibility-matrix.mjs +48 -0
- package/scripts/validate-content.mjs +76 -0
- package/scripts/verify-generated.mjs +153 -0
- package/templates/agents/nextjs.md +47 -0
- package/templates/agents/react-native.md +48 -0
- package/templates/agents/react-vite.md +48 -0
- package/templates/docker/compose/postgres.yml +29 -0
- package/templates/docker/compose/springboot.yml +69 -0
- package/templates/docker/compose/supabase.yml +18 -0
- package/templates/docker/compose-prod/springboot.yml +64 -0
- package/templates/docker/dockerfile/laravel-inertia.dev.dockerfile +21 -0
- package/templates/docker/dockerfile/laravel.dev.dockerfile +12 -0
- package/templates/docker/dockerfile/laravel.prod.dockerfile +13 -0
- package/templates/docker/dockerfile/nextjs.dev.dockerfile +6 -0
- package/templates/docker/dockerfile/nextjs.prod.dockerfile +18 -0
- package/templates/docker/dockerfile/springboot.dev.dockerfile +5 -0
- package/templates/docker/dockerfile/springboot.prod.dockerfile +10 -0
- package/templates/docker/dockerfile/vite.dev.dockerfile +6 -0
- package/templates/docker/dockerfile/vite.prod.dockerfile +12 -0
- package/templates/gitignore/base.gitignore +32 -0
- package/templates/gitignore/nextjs.gitignore +40 -0
- package/templates/gitignore/react-native.gitignore +43 -0
- package/templates/gitignore/react-vite.gitignore +39 -0
- package/templates/makefile/frontend.mk +31 -0
- package/templates/makefile/laravel.mk +47 -0
- package/templates/makefile/postgres.mk +40 -0
- package/templates/makefile/springboot.mk +125 -0
- package/templates/makefile/supabase.mk +42 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Coding Rules (Universal)
|
|
2
|
+
|
|
3
|
+
Applies to every project regardless of stack.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Core Principle
|
|
8
|
+
```
|
|
9
|
+
simple + explicit + consistent
|
|
10
|
+
over
|
|
11
|
+
complex + abstract + theoretically pure
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Complexity must earn abstraction. Start simple. Add layers only when justified.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Naming
|
|
19
|
+
|
|
20
|
+
### Files
|
|
21
|
+
```
|
|
22
|
+
React components: PascalCase UserCard.tsx
|
|
23
|
+
Hooks: camelCase useUserData.ts
|
|
24
|
+
Utilities: camelCase formatDate.ts
|
|
25
|
+
Constants: camelCase apiEndpoints.ts
|
|
26
|
+
Types: camelCase userTypes.ts
|
|
27
|
+
CSS Modules: PascalCase UserCard.module.css
|
|
28
|
+
Java classes: PascalCase UserService.java
|
|
29
|
+
SQL migrations: snake_case V1__create_users_table.sql
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Variables and Functions
|
|
33
|
+
```
|
|
34
|
+
Variables: camelCase userName, isLoading, hasError
|
|
35
|
+
Functions: camelCase getUser(), createOrder(), formatDate()
|
|
36
|
+
Constants: SCREAMING MAX_RETRIES, API_BASE_URL
|
|
37
|
+
React components: PascalCase UserCard, LoginForm
|
|
38
|
+
Types/Interfaces: PascalCase UserResponse, ApiError
|
|
39
|
+
Enums: PascalCase UserRole, OrderStatus
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Name for what it does, not what it is
|
|
43
|
+
```
|
|
44
|
+
❌ getData(), handleThing(), doStuff(), temp, x
|
|
45
|
+
✅ getUserById(), handleLoginSubmit(), formatCurrency()
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Boolean naming
|
|
49
|
+
```
|
|
50
|
+
❌ user, loading, error
|
|
51
|
+
✅ isLoading, hasError, isAuthenticated, canEdit
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Functions
|
|
57
|
+
- One responsibility per function
|
|
58
|
+
- Max 3 parameters — if more, use an options object
|
|
59
|
+
- Return early to avoid deep nesting
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
// ❌
|
|
63
|
+
function processUser(user, role, permissions, sendEmail, notify) { ... }
|
|
64
|
+
|
|
65
|
+
// ✅
|
|
66
|
+
function processUser(user: User, options: ProcessUserOptions) { ... }
|
|
67
|
+
|
|
68
|
+
// ❌ deep nesting
|
|
69
|
+
function getUser(id) {
|
|
70
|
+
if (id) {
|
|
71
|
+
if (isValid(id)) {
|
|
72
|
+
// logic
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ✅ early return
|
|
78
|
+
function getUser(id) {
|
|
79
|
+
if (!id) return null
|
|
80
|
+
if (!isValid(id)) return null
|
|
81
|
+
// logic
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Imports
|
|
88
|
+
|
|
89
|
+
### Frontend
|
|
90
|
+
- Always use absolute imports with `@/` prefix
|
|
91
|
+
- Never use relative `../../` imports
|
|
92
|
+
- Barrel exports (`index.ts`) for public API of a feature only
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// ❌
|
|
96
|
+
import { UserCard } from '../../../components/ui/UserCard'
|
|
97
|
+
|
|
98
|
+
// ✅
|
|
99
|
+
import { UserCard } from '@/components/ui/UserCard'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Import Order (enforced by ESLint)
|
|
103
|
+
```
|
|
104
|
+
1. External libraries
|
|
105
|
+
2. Internal absolute (@/)
|
|
106
|
+
3. Types
|
|
107
|
+
4. Styles / assets
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Constants
|
|
113
|
+
- No magic numbers or strings in logic
|
|
114
|
+
- All constants in `src/constants/index.ts` or feature-level constants file
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// ❌
|
|
118
|
+
if (role === 'ADMIN') { ... }
|
|
119
|
+
setTimeout(fn, 900000)
|
|
120
|
+
|
|
121
|
+
// ✅
|
|
122
|
+
import { ROLES, TOKEN_EXPIRY } from '@/constants'
|
|
123
|
+
if (role === ROLES.ADMIN) { ... }
|
|
124
|
+
setTimeout(fn, TOKEN_EXPIRY.ACCESS)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Async / Error Handling
|
|
130
|
+
|
|
131
|
+
### Frontend
|
|
132
|
+
- Always async/await — never `.then()` chains
|
|
133
|
+
- Always handle errors at the hook level, not component level
|
|
134
|
+
- Never swallow errors silently
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// ❌
|
|
138
|
+
fetchUser().then(data => setUser(data)).catch(e => console.log(e))
|
|
139
|
+
|
|
140
|
+
// ✅
|
|
141
|
+
try {
|
|
142
|
+
const user = await fetchUser()
|
|
143
|
+
setUser(user)
|
|
144
|
+
} catch (error) {
|
|
145
|
+
logger.error('fetchUser failed:', error)
|
|
146
|
+
throw error
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Backend
|
|
151
|
+
- Always throw `AppException` — never raw `RuntimeException`
|
|
152
|
+
- Never expose stack traces in API responses
|
|
153
|
+
- Always catch at the `GlobalExceptionHandler` level
|
|
154
|
+
|
|
155
|
+
```java
|
|
156
|
+
// ❌
|
|
157
|
+
throw new RuntimeException("User not found");
|
|
158
|
+
|
|
159
|
+
// ✅
|
|
160
|
+
throw new AppException("USER_NOT_FOUND", HttpStatus.NOT_FOUND);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Logging
|
|
166
|
+
- NEVER use `console.log` directly
|
|
167
|
+
- Always use `lib/logger.ts` on frontend
|
|
168
|
+
- Always use SLF4J logger on backend
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
// ❌
|
|
172
|
+
console.log('user:', user)
|
|
173
|
+
console.error('error:', error)
|
|
174
|
+
|
|
175
|
+
// ✅
|
|
176
|
+
import { logger } from '@/lib/logger'
|
|
177
|
+
logger.info('user fetched:', user)
|
|
178
|
+
logger.error('fetch failed:', error)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
```java
|
|
182
|
+
// ❌
|
|
183
|
+
System.out.println("user: " + user);
|
|
184
|
+
|
|
185
|
+
// ✅
|
|
186
|
+
private static final Logger log = LoggerFactory.getLogger(UserService.class);
|
|
187
|
+
log.info("user fetched: {}", userId);
|
|
188
|
+
log.error("fetch failed for userId: {}", userId, e);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Comments
|
|
194
|
+
- Comment WHY, not WHAT
|
|
195
|
+
- Code should be readable enough to not need WHAT comments
|
|
196
|
+
- Remove all debug/TODO comments before committing
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
// ❌ explains what (obvious from code)
|
|
200
|
+
// increment counter
|
|
201
|
+
count++
|
|
202
|
+
|
|
203
|
+
// ✅ explains why (not obvious from code)
|
|
204
|
+
// Retry once — server returns 503 on cold start for ~200ms
|
|
205
|
+
await retry(fetchUser, { times: 1, delay: 300 })
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## No Debug Code in Commits
|
|
211
|
+
```
|
|
212
|
+
❌ console.log
|
|
213
|
+
❌ debugger
|
|
214
|
+
❌ TODO comments
|
|
215
|
+
❌ hardcoded test values
|
|
216
|
+
❌ commented-out code blocks
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
ESLint and Husky enforce this — build fails if present.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## One Thing Per File
|
|
224
|
+
```
|
|
225
|
+
❌ UserCardAndForm.tsx — two components in one file
|
|
226
|
+
❌ userUtils.ts — 30 unrelated utility functions
|
|
227
|
+
|
|
228
|
+
✅ UserCard.tsx
|
|
229
|
+
✅ UserForm.tsx
|
|
230
|
+
✅ formatDate.ts
|
|
231
|
+
✅ formatCurrency.ts
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Exception: small helper types or constants directly related to the file.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Exports
|
|
239
|
+
|
|
240
|
+
### Frontend
|
|
241
|
+
- Named exports everywhere except page/route components
|
|
242
|
+
- Page components use default export (Next.js / React Router requirement)
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
// ❌ default export for reusable components
|
|
246
|
+
export default function UserCard() { ... }
|
|
247
|
+
|
|
248
|
+
// ✅ named export
|
|
249
|
+
export function UserCard() { ... }
|
|
250
|
+
|
|
251
|
+
// ✅ default export for pages only
|
|
252
|
+
export default function UserPage() { ... }
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Backend
|
|
256
|
+
- Spring-managed beans: `@Service`, `@Repository`, `@RestController` — Spring handles export
|
|
257
|
+
- Utility classes: `public static` methods
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Agent Rules
|
|
262
|
+
```
|
|
263
|
+
Before writing any code:
|
|
264
|
+
1. Check if the functionality already exists
|
|
265
|
+
2. Check which layer owns this responsibility
|
|
266
|
+
3. Choose the simplest correct implementation
|
|
267
|
+
4. Follow existing patterns in the codebase — don't introduce new ones
|
|
268
|
+
|
|
269
|
+
Before creating a new file:
|
|
270
|
+
1. Check if an existing file should be extended instead
|
|
271
|
+
2. Follow the selected stack's structure playbook and current feature ownership
|
|
272
|
+
|
|
273
|
+
Before adding a dependency:
|
|
274
|
+
1. Check if existing tools already solve it
|
|
275
|
+
2. Prefer what the playbook recommends over personal preference
|
|
276
|
+
|
|
277
|
+
Naming:
|
|
278
|
+
1. Name things for what they do
|
|
279
|
+
2. Booleans start with is/has/can
|
|
280
|
+
3. No abbreviations unless universally understood (id, url, dto)
|
|
281
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "error-handling",
|
|
3
|
+
"kind": "universal",
|
|
4
|
+
"label": "Error Handling",
|
|
5
|
+
"required": true,
|
|
6
|
+
"folders": [],
|
|
7
|
+
"concerns": [
|
|
8
|
+
{ "id": "errors", "required": true, "sections": ["Error Contract", "Boundary Handling", "Security Rules for Errors"] }
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Error Handling
|
|
2
|
+
|
|
3
|
+
## Error Contract
|
|
4
|
+
|
|
5
|
+
Failures crossing a process boundary use the protocol’s standard error mechanism plus a stable application code. HTTP APIs should use RFC 9457 `ProblemDetail` unless a selected external service defines its own contract. Successful responses are ordinary DTOs; do not wrap every success in a universal envelope.
|
|
6
|
+
|
|
7
|
+
Keep status mapping in the transport/web layer. Application services raise application errors without importing HTTP concepts. Record public error codes in `docs/api/errors.md` with meaning, status, retry behavior, and safe client handling.
|
|
8
|
+
|
|
9
|
+
## Boundary Handling
|
|
10
|
+
|
|
11
|
+
- Validate requests before side effects and report field errors without echoing secrets.
|
|
12
|
+
- Convert expected domain/application failures once at the outer boundary.
|
|
13
|
+
- Let cancellation remain cancellation; do not display it as a user-visible failure.
|
|
14
|
+
- Retry only transient, idempotent operations with a bound and jitter. Authentication refresh follows its selected auth adapter, not a generic error interceptor.
|
|
15
|
+
- Preserve the original cause in internal diagnostics while returning a safe public detail and correlation identifier.
|
|
16
|
+
|
|
17
|
+
## Security Rules for Errors
|
|
18
|
+
|
|
19
|
+
Never expose stack traces, SQL, filesystem paths, internal hostnames, credentials, tokens, session data, or raw third-party responses. Log PII-safe structured context, and do not route client behavior by mutable human-readable messages.
|
|
20
|
+
|
|
21
|
+
Test stable codes/statuses, validation failures, not-found and conflict races, authorization denial, dependency timeouts, and unexpected-error redaction at the boundary that emits the response.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Git Conventions (Universal)
|
|
2
|
+
|
|
3
|
+
Applies to every project regardless of stack.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Branch Structure
|
|
8
|
+
| Branch | Purpose |
|
|
9
|
+
|--------------|-----------------------------------------------|
|
|
10
|
+
| `main` | Production — always stable, always deployable |
|
|
11
|
+
| `dev` | Integration — all features merge here first |
|
|
12
|
+
| `feature/*` | New capability |
|
|
13
|
+
| `fix/*` | Bug fix |
|
|
14
|
+
| `refactor/*` | Restructure without behavior change |
|
|
15
|
+
| `chore/*` | Dependencies, config, tooling |
|
|
16
|
+
| `docs/*` | Documentation only |
|
|
17
|
+
| `test/*` | Adding or updating tests only |
|
|
18
|
+
|
|
19
|
+
## Branch Rules
|
|
20
|
+
- NEVER commit directly to `main` or `dev`
|
|
21
|
+
- ALWAYS branch off `dev` — never off `main`
|
|
22
|
+
- NEVER merge or create PRs unless explicitly asked
|
|
23
|
+
- NEVER push to remote unless explicitly asked
|
|
24
|
+
- One logical change per branch — keep branches small and focused
|
|
25
|
+
|
|
26
|
+
## Starting a Branch
|
|
27
|
+
```bash
|
|
28
|
+
git checkout dev
|
|
29
|
+
git pull origin dev
|
|
30
|
+
git checkout -b <type>/<short-description>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Examples
|
|
34
|
+
```bash
|
|
35
|
+
git checkout -b feature/user-profile-page
|
|
36
|
+
git checkout -b fix/token-expiry-race
|
|
37
|
+
git checkout -b refactor/auth-feature-module
|
|
38
|
+
git checkout -b chore/update-dependencies
|
|
39
|
+
git checkout -b docs/update-api-endpoints
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Commit Convention
|
|
45
|
+
|
|
46
|
+
### Format
|
|
47
|
+
```
|
|
48
|
+
type(scope): short description
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Rules
|
|
52
|
+
- Lowercase only — no uppercase anywhere
|
|
53
|
+
- No period at the end
|
|
54
|
+
- Present tense — "add" not "added", "fix" not "fixed"
|
|
55
|
+
- Under 72 characters
|
|
56
|
+
- One logical change per commit
|
|
57
|
+
|
|
58
|
+
### Types
|
|
59
|
+
| Type | When to use |
|
|
60
|
+
|------------|---------------------------------------------------|
|
|
61
|
+
| `feat` | New feature or capability |
|
|
62
|
+
| `fix` | Bug fix |
|
|
63
|
+
| `refactor` | Restructure without behavior change |
|
|
64
|
+
| `chore` | Deps, config, tooling — no production code change |
|
|
65
|
+
| `docs` | Documentation only |
|
|
66
|
+
| `test` | Adding or updating tests |
|
|
67
|
+
| `ci` | GitHub Actions or CI/CD workflow changes |
|
|
68
|
+
| `style` | Formatting, whitespace — no logic change |
|
|
69
|
+
|
|
70
|
+
### Scopes (React + Spring Boot)
|
|
71
|
+
| Scope | When to use |
|
|
72
|
+
|------------|------------------------------------|
|
|
73
|
+
| `frontend` | Anything inside /frontend |
|
|
74
|
+
| `backend` | Anything inside /backend |
|
|
75
|
+
| `docker` | Dockerfile or docker-compose |
|
|
76
|
+
| `ci` | GitHub Actions workflows |
|
|
77
|
+
| `docs` | Anything inside /docs |
|
|
78
|
+
| `deps` | Dependency updates (either side) |
|
|
79
|
+
|
|
80
|
+
### Scopes (Next.js projects)
|
|
81
|
+
| Scope | When to use |
|
|
82
|
+
|------------|------------------------------------|
|
|
83
|
+
| `app` | Next.js app router, pages, layouts |
|
|
84
|
+
| `api` | API routes or server actions |
|
|
85
|
+
| `db` | Database schema, migrations |
|
|
86
|
+
| `auth` | Authentication logic |
|
|
87
|
+
| `ci` | GitHub Actions workflows |
|
|
88
|
+
| `docs` | Anything inside /docs |
|
|
89
|
+
| `deps` | Dependency updates |
|
|
90
|
+
|
|
91
|
+
### Examples
|
|
92
|
+
```bash
|
|
93
|
+
feat(frontend): add user profile page
|
|
94
|
+
feat(backend): add paper download endpoint
|
|
95
|
+
fix(backend): resolve token expiry race condition
|
|
96
|
+
fix(frontend): correct redirect after logout
|
|
97
|
+
refactor(backend): move auth logic into feature module
|
|
98
|
+
refactor(frontend): restructure features folder
|
|
99
|
+
chore(deps): update spring boot to 3.5.1
|
|
100
|
+
chore(docker): add maven cache volume
|
|
101
|
+
docs(api): update error contract with traceId field
|
|
102
|
+
test(backend): add unit tests for auth service
|
|
103
|
+
test(frontend): add vitest tests for useAuth hook
|
|
104
|
+
ci(backend): add postgresql service to ci workflow
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Daily Workflow
|
|
110
|
+
```bash
|
|
111
|
+
# 1. Always start from updated dev
|
|
112
|
+
git checkout dev
|
|
113
|
+
git pull origin dev
|
|
114
|
+
|
|
115
|
+
# 2. Create your branch
|
|
116
|
+
git checkout -b <type>/<description>
|
|
117
|
+
|
|
118
|
+
# 3. Work in small, logical commits
|
|
119
|
+
git add .
|
|
120
|
+
git commit -m "type(scope): description"
|
|
121
|
+
|
|
122
|
+
# 4. Push your branch
|
|
123
|
+
git push origin <branch-name>
|
|
124
|
+
|
|
125
|
+
# 5. Open PR → dev (only when explicitly asked)
|
|
126
|
+
# 6. Merge dev → main (only when explicitly asked)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## .gitignore — Always Include
|
|
132
|
+
```
|
|
133
|
+
# Environment
|
|
134
|
+
.env
|
|
135
|
+
.env.local
|
|
136
|
+
.env.production
|
|
137
|
+
|
|
138
|
+
# Dependencies
|
|
139
|
+
node_modules/
|
|
140
|
+
.mvn/
|
|
141
|
+
|
|
142
|
+
# Build outputs
|
|
143
|
+
dist/
|
|
144
|
+
build/
|
|
145
|
+
target/
|
|
146
|
+
.next/
|
|
147
|
+
|
|
148
|
+
# IDE
|
|
149
|
+
.idea/
|
|
150
|
+
.vscode/
|
|
151
|
+
*.iml
|
|
152
|
+
|
|
153
|
+
# OS
|
|
154
|
+
.DS_Store
|
|
155
|
+
Thumbs.db
|
|
156
|
+
|
|
157
|
+
# Logs
|
|
158
|
+
*.log
|
|
159
|
+
logs/
|
|
160
|
+
|
|
161
|
+
# Docker volumes (if local)
|
|
162
|
+
postgres-data/
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Agent Rules
|
|
168
|
+
```
|
|
169
|
+
Never:
|
|
170
|
+
→ commit directly to main or dev
|
|
171
|
+
→ branch off main
|
|
172
|
+
→ push or create PRs unless explicitly asked
|
|
173
|
+
→ put multiple logical changes in one commit
|
|
174
|
+
→ use vague commit messages ("fix stuff", "update code")
|
|
175
|
+
|
|
176
|
+
Always:
|
|
177
|
+
→ branch off dev
|
|
178
|
+
→ one logical change per commit
|
|
179
|
+
→ follow type(scope): description format
|
|
180
|
+
→ present tense in commit messages
|
|
181
|
+
|
|
182
|
+
When asked to commit:
|
|
183
|
+
→ Stage only files relevant to the current task
|
|
184
|
+
→ Write a precise commit message following the convention
|
|
185
|
+
→ Do not push unless explicitly asked
|
|
186
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "observability-baseline",
|
|
3
|
+
"kind": "universal",
|
|
4
|
+
"label": "Observability Baseline",
|
|
5
|
+
"required": true,
|
|
6
|
+
"folders": [],
|
|
7
|
+
"concerns": [
|
|
8
|
+
{ "id": "observability", "required": true, "sections": ["Structured Events", "Health and Readiness", "Errors and Traces"] }
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Observability Baseline
|
|
2
|
+
|
|
3
|
+
## Structured Events
|
|
4
|
+
|
|
5
|
+
- Emit structured logs in deployed environments; use stable event names and fields.
|
|
6
|
+
- Attach a request/correlation ID at the entry point and propagate it through downstream calls.
|
|
7
|
+
- Record outcome, duration, route/operation, and safe identifiers. Never log secrets, tokens, cookies, passwords, or full sensitive request bodies.
|
|
8
|
+
- Log exceptions once at the boundary that owns the failure; avoid duplicate logs at every layer.
|
|
9
|
+
|
|
10
|
+
## Health and Readiness
|
|
11
|
+
|
|
12
|
+
- Liveness answers whether the process should be restarted.
|
|
13
|
+
- Readiness answers whether the instance can serve traffic and may include critical dependency checks.
|
|
14
|
+
- Keep health responses free of credentials, internal topology, and verbose exception details.
|
|
15
|
+
- A Docker healthcheck and deployment probe should call the application's real health endpoint.
|
|
16
|
+
|
|
17
|
+
## Errors and Traces
|
|
18
|
+
|
|
19
|
+
- Return a stable application error code and request ID to clients.
|
|
20
|
+
- Capture uncaught server and client errors in the selected monitoring service.
|
|
21
|
+
- Add distributed tracing when requests cross service boundaries; do not introduce it for a single-process starter without a concrete need.
|
|
22
|
+
- Define alerts from user impact and service objectives, not raw log volume.
|
|
23
|
+
|
|
24
|
+
## Verification
|
|
25
|
+
|
|
26
|
+
- Test the health endpoint and error response shape.
|
|
27
|
+
- Verify redaction with representative authentication and validation failures.
|
|
28
|
+
- Confirm graceful shutdown stops new work and lets in-flight requests complete within the deployment deadline.
|
|
29
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "security-baseline",
|
|
3
|
+
"kind": "universal",
|
|
4
|
+
"label": "Security Baseline",
|
|
5
|
+
"required": true,
|
|
6
|
+
"folders": [],
|
|
7
|
+
"concerns": [
|
|
8
|
+
{ "id": "security-boundaries", "required": true, "sections": ["Trust Boundaries", "Authentication and Authorization"] },
|
|
9
|
+
{ "id": "secret-safety", "required": true, "sections": ["Secrets and Data", "Failure Safety"] }
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Security Baseline
|
|
2
|
+
|
|
3
|
+
Security, validation, accessibility, and secret handling never weaken in Small projects. Stack and capability playbooks decide how these invariants are implemented.
|
|
4
|
+
|
|
5
|
+
## Trust Boundaries
|
|
6
|
+
|
|
7
|
+
- Treat browser, device, network, URL, header, cookie, webhook, file, environment, and database input as untrusted where it enters a trusted component.
|
|
8
|
+
- Validate shape and business constraints at the trusted boundary. Client validation improves usability; it is not authorization.
|
|
9
|
+
- Authenticate identity and separately authorize the requested action and resource beside protected data or side effects.
|
|
10
|
+
- Default to denial. Make public entry points explicit and return only fields the caller needs.
|
|
11
|
+
|
|
12
|
+
## Secrets and Data
|
|
13
|
+
|
|
14
|
+
- Public client configuration is never secret. Keep credentials and privileged keys out of source, logs, generated examples, and client bundles.
|
|
15
|
+
- Use environment or platform secret storage, fail startup when required server configuration is missing, and rotate exposed credentials.
|
|
16
|
+
- Minimize personal data. Structured logs use event names, stable codes, request IDs, and non-sensitive identifiers; redact credentials, tokens, cookies, reset links, and PII.
|
|
17
|
+
- File uploads require size limits, verified content type, generated storage names, isolated storage, and malware/content processing appropriate to risk.
|
|
18
|
+
|
|
19
|
+
## Authentication and Authorization
|
|
20
|
+
|
|
21
|
+
Use a maintained framework or identity provider; do not invent password hashing, sessions, JWT issuance, token rotation, or cryptographic protocols. The selected stack/capability playbook owns session storage, refresh, CSRF/CORS, callback allowlists, expiry, logout, and revocation behavior.
|
|
22
|
+
|
|
23
|
+
For every protected operation, test anonymous access, authenticated-but-unauthorized access, allowed access, another user’s resource, invalid input, and expired/revoked identity where applicable.
|
|
24
|
+
|
|
25
|
+
## Failure Safety
|
|
26
|
+
|
|
27
|
+
- User-facing errors are stable, safe, and actionable. Never return stack traces, SQL details, credentials, or internal exception messages.
|
|
28
|
+
- Apply least privilege to databases, cloud identities, CI tokens, and system operations.
|
|
29
|
+
- Rate-limit abuse-sensitive operations and make retries idempotent where duplicate execution can cause harm.
|
|
30
|
+
- Review dependency and secret scanning results; automated updates are proposals until the generated compatibility matrix passes.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "typescript",
|
|
3
|
+
"kind": "universal",
|
|
4
|
+
"label": "TypeScript",
|
|
5
|
+
"required": true,
|
|
6
|
+
"folders": [],
|
|
7
|
+
"concerns": [
|
|
8
|
+
{ "id": "typescript-strict", "required": true, "sections": ["Strict Mode — Always On", "No any", "Type vs Interface"] },
|
|
9
|
+
{ "id": "validation", "required": false, "when": "Project validates external/runtime input", "sections": ["Zod for Runtime Validation"] }
|
|
10
|
+
]
|
|
11
|
+
}
|