@zigrivers/scaffold 3.6.0 → 3.8.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/README.md +127 -12
- package/content/knowledge/backend/backend-api-design.md +103 -0
- package/content/knowledge/backend/backend-architecture.md +100 -0
- package/content/knowledge/backend/backend-async-patterns.md +101 -0
- package/content/knowledge/backend/backend-auth-patterns.md +100 -0
- package/content/knowledge/backend/backend-conventions.md +105 -0
- package/content/knowledge/backend/backend-data-modeling.md +102 -0
- package/content/knowledge/backend/backend-deployment.md +100 -0
- package/content/knowledge/backend/backend-dev-environment.md +102 -0
- package/content/knowledge/backend/backend-observability.md +102 -0
- package/content/knowledge/backend/backend-project-structure.md +100 -0
- package/content/knowledge/backend/backend-requirements.md +103 -0
- package/content/knowledge/backend/backend-security.md +104 -0
- package/content/knowledge/backend/backend-testing.md +101 -0
- package/content/knowledge/backend/backend-worker-patterns.md +100 -0
- package/content/knowledge/cli/cli-architecture.md +101 -0
- package/content/knowledge/cli/cli-conventions.md +117 -0
- package/content/knowledge/cli/cli-dev-environment.md +121 -0
- package/content/knowledge/cli/cli-distribution-patterns.md +106 -0
- package/content/knowledge/cli/cli-interactivity-patterns.md +116 -0
- package/content/knowledge/cli/cli-output-patterns.md +107 -0
- package/content/knowledge/cli/cli-project-structure.md +124 -0
- package/content/knowledge/cli/cli-requirements.md +101 -0
- package/content/knowledge/cli/cli-shell-integration.md +130 -0
- package/content/knowledge/cli/cli-testing.md +134 -0
- package/content/knowledge/library/library-api-design.md +306 -0
- package/content/knowledge/library/library-architecture.md +247 -0
- package/content/knowledge/library/library-bundling.md +244 -0
- package/content/knowledge/library/library-conventions.md +229 -0
- package/content/knowledge/library/library-dev-environment.md +220 -0
- package/content/knowledge/library/library-documentation.md +300 -0
- package/content/knowledge/library/library-project-structure.md +237 -0
- package/content/knowledge/library/library-requirements.md +173 -0
- package/content/knowledge/library/library-security.md +257 -0
- package/content/knowledge/library/library-testing.md +319 -0
- package/content/knowledge/library/library-type-definitions.md +284 -0
- package/content/knowledge/library/library-versioning.md +300 -0
- package/content/knowledge/mobile-app/mobile-app-architecture.md +283 -0
- package/content/knowledge/mobile-app/mobile-app-conventions.md +180 -0
- package/content/knowledge/mobile-app/mobile-app-deployment.md +298 -0
- package/content/knowledge/mobile-app/mobile-app-dev-environment.md +257 -0
- package/content/knowledge/mobile-app/mobile-app-distribution.md +264 -0
- package/content/knowledge/mobile-app/mobile-app-observability.md +317 -0
- package/content/knowledge/mobile-app/mobile-app-offline-patterns.md +311 -0
- package/content/knowledge/mobile-app/mobile-app-project-structure.md +245 -0
- package/content/knowledge/mobile-app/mobile-app-push-notifications.md +321 -0
- package/content/knowledge/mobile-app/mobile-app-requirements.md +147 -0
- package/content/knowledge/mobile-app/mobile-app-security.md +338 -0
- package/content/knowledge/mobile-app/mobile-app-testing.md +400 -0
- package/content/knowledge/web-app/web-app-api-patterns.md +224 -0
- package/content/knowledge/web-app/web-app-architecture.md +116 -0
- package/content/knowledge/web-app/web-app-auth-patterns.md +256 -0
- package/content/knowledge/web-app/web-app-conventions.md +121 -0
- package/content/knowledge/web-app/web-app-data-patterns.md +218 -0
- package/content/knowledge/web-app/web-app-deployment-workflow.md +143 -0
- package/content/knowledge/web-app/web-app-deployment.md +134 -0
- package/content/knowledge/web-app/web-app-design-system.md +158 -0
- package/content/knowledge/web-app/web-app-dev-environment.md +173 -0
- package/content/knowledge/web-app/web-app-observability.md +221 -0
- package/content/knowledge/web-app/web-app-project-structure.md +160 -0
- package/content/knowledge/web-app/web-app-rendering-strategies.md +133 -0
- package/content/knowledge/web-app/web-app-requirements.md +112 -0
- package/content/knowledge/web-app/web-app-security.md +193 -0
- package/content/knowledge/web-app/web-app-session-patterns.md +214 -0
- package/content/knowledge/web-app/web-app-testing.md +249 -0
- package/content/knowledge/web-app/web-app-ux-patterns.md +162 -0
- package/content/methodology/backend-overlay.yml +73 -0
- package/content/methodology/cli-overlay.yml +69 -0
- package/content/methodology/library-overlay.yml +67 -0
- package/content/methodology/mobile-app-overlay.yml +71 -0
- package/content/methodology/web-app-overlay.yml +79 -0
- package/dist/cli/commands/init.d.ts +21 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +261 -13
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.test.js +206 -0
- package/dist/cli/commands/init.test.js.map +1 -1
- package/dist/config/schema.d.ts +1392 -64
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +82 -5
- package/dist/config/schema.js.map +1 -1
- package/dist/config/schema.test.js +302 -1
- package/dist/config/schema.test.js.map +1 -1
- package/dist/core/assembly/overlay-loader.d.ts.map +1 -1
- package/dist/core/assembly/overlay-loader.js +2 -1
- package/dist/core/assembly/overlay-loader.js.map +1 -1
- package/dist/core/assembly/overlay-loader.test.js +56 -0
- package/dist/core/assembly/overlay-loader.test.js.map +1 -1
- package/dist/e2e/game-pipeline.test.js +1 -0
- package/dist/e2e/game-pipeline.test.js.map +1 -1
- package/dist/e2e/project-type-overlays.test.d.ts +16 -0
- package/dist/e2e/project-type-overlays.test.d.ts.map +1 -0
- package/dist/e2e/project-type-overlays.test.js +834 -0
- package/dist/e2e/project-type-overlays.test.js.map +1 -0
- package/dist/types/config.d.ts +19 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -1
- package/dist/types/index.js.map +1 -1
- package/dist/wizard/questions.d.ts +27 -1
- package/dist/wizard/questions.d.ts.map +1 -1
- package/dist/wizard/questions.js +142 -3
- package/dist/wizard/questions.js.map +1 -1
- package/dist/wizard/questions.test.js +206 -8
- package/dist/wizard/questions.test.js.map +1 -1
- package/dist/wizard/wizard.d.ts +21 -0
- package/dist/wizard/wizard.d.ts.map +1 -1
- package/dist/wizard/wizard.js +27 -1
- package/dist/wizard/wizard.js.map +1 -1
- package/package.json +1 -1
- package/dist/types/wizard.d.ts +0 -14
- package/dist/types/wizard.d.ts.map +0 -1
- package/dist/types/wizard.js +0 -2
- package/dist/types/wizard.js.map +0 -1
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-app-testing
|
|
3
|
+
description: Component testing with Testing Library, SSR testing, E2E testing with Playwright, visual regression, accessibility testing with axe-core, and Lighthouse CI
|
|
4
|
+
topics: [web-app, testing, playwright, testing-library, accessibility, visual-regression, lighthouse, e2e]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Web application testing requires covering multiple distinct layers: component behavior, server rendering correctness, end-to-end user flows, visual appearance, accessibility compliance, and performance budgets. Each layer catches different classes of bugs and has different cost/value characteristics. The correct strategy invests heavily in component and integration tests (fast feedback, high coverage), uses E2E tests for critical user journeys (slow but comprehensive), and enforces visual and performance budgets in CI (catches regressions before users do).
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
### Testing Layers
|
|
12
|
+
|
|
13
|
+
**Component tests (Testing Library):** Test components in isolation from the DOM's perspective — interactions, rendering, and state changes. These form the bulk of the test suite. Use `@testing-library/user-event` for realistic interactions, not `fireEvent`.
|
|
14
|
+
|
|
15
|
+
**Integration tests:** Test pages or feature slices with real data flow but mocked network calls. Verify that components interact correctly. In Next.js: test pages as React components with a mocked router.
|
|
16
|
+
|
|
17
|
+
**SSR tests (render-to-string):** Verify server-rendered HTML is correct and does not throw. Check that SSR and hydration produce consistent output (no hydration mismatches). Use `@testing-library/react`'s `renderToStaticMarkup` or framework-specific utilities.
|
|
18
|
+
|
|
19
|
+
**E2E tests (Playwright):** Test complete user flows in a real browser against a running application. Reserve for high-value, business-critical flows: registration, login, checkout, core product value proposition. Keep the E2E suite small and fast (target under 10 minutes for the critical path).
|
|
20
|
+
|
|
21
|
+
**Visual regression tests:** Screenshot comparison against committed baselines. Catch unintended UI changes from CSS refactors, component updates, or dependency upgrades. Run against a static Storybook deployment for fast, stable comparisons.
|
|
22
|
+
|
|
23
|
+
**Accessibility tests (axe-core):** Automated WCAG compliance checking. Catches ~30–40% of accessibility issues automatically. Not a substitute for manual testing with a screen reader, but essential for catching regressions.
|
|
24
|
+
|
|
25
|
+
**Performance tests (Lighthouse CI):** Enforce performance budgets in CI. Fail the build if LCP, CLS, or INP regressions are detected.
|
|
26
|
+
|
|
27
|
+
### Testing Library Principles
|
|
28
|
+
|
|
29
|
+
Testing Library is designed around the principle that tests should resemble how users interact with the application:
|
|
30
|
+
|
|
31
|
+
- **Query by role first** — `getByRole('button', { name: 'Submit' })` over `getByTestId`
|
|
32
|
+
- **Query by label text** — `getByLabelText('Email address')` for form inputs
|
|
33
|
+
- **Never query by CSS class** — classes are implementation details, not behavior
|
|
34
|
+
- **Use `userEvent` not `fireEvent`** — `userEvent.type()` simulates real keystrokes including focus, blur, and change events; `fireEvent` dispatches synthetic events that skip browser behaviors
|
|
35
|
+
|
|
36
|
+
### Playwright for E2E
|
|
37
|
+
|
|
38
|
+
Playwright supports Chromium, Firefox, and WebKit. Configure it to run against your staging environment in CI and your local dev server locally. Key features:
|
|
39
|
+
- Auto-waiting: Playwright automatically waits for elements to be ready before interacting
|
|
40
|
+
- Network mocking: intercept and mock API responses in tests
|
|
41
|
+
- Trace viewer: visual debugging of test failures with full network and DOM timeline
|
|
42
|
+
- Component testing: Playwright can also test components in isolation (alternative to Testing Library for teams that want one tool)
|
|
43
|
+
|
|
44
|
+
## Deep Guidance
|
|
45
|
+
|
|
46
|
+
### Component Testing Patterns
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// UserProfile.test.tsx — Testing Library patterns
|
|
50
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
51
|
+
import userEvent from '@testing-library/user-event';
|
|
52
|
+
import { UserProfile } from './UserProfile';
|
|
53
|
+
import { server } from '@/mocks/server'; // MSW mock server
|
|
54
|
+
import { http, HttpResponse } from 'msw';
|
|
55
|
+
|
|
56
|
+
describe('UserProfile', () => {
|
|
57
|
+
it('displays user data after loading', async () => {
|
|
58
|
+
render(<UserProfile userId="user-123" />);
|
|
59
|
+
|
|
60
|
+
// Loading state
|
|
61
|
+
expect(screen.getByRole('status')).toBeInTheDocument();
|
|
62
|
+
|
|
63
|
+
// Data loads
|
|
64
|
+
await screen.findByText('Jane Smith'); // Awaits element appearance
|
|
65
|
+
expect(screen.getByText('jane@example.com')).toBeInTheDocument();
|
|
66
|
+
expect(screen.queryByRole('status')).not.toBeInTheDocument();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('allows editing the display name', async () => {
|
|
70
|
+
const user = userEvent.setup();
|
|
71
|
+
render(<UserProfile userId="user-123" />);
|
|
72
|
+
|
|
73
|
+
await screen.findByText('Jane Smith');
|
|
74
|
+
await user.click(screen.getByRole('button', { name: 'Edit profile' }));
|
|
75
|
+
|
|
76
|
+
const nameInput = screen.getByLabelText('Display name');
|
|
77
|
+
await user.clear(nameInput);
|
|
78
|
+
await user.type(nameInput, 'Jane Doe');
|
|
79
|
+
await user.click(screen.getByRole('button', { name: 'Save changes' }));
|
|
80
|
+
|
|
81
|
+
await screen.findByText('Profile updated successfully');
|
|
82
|
+
expect(screen.getByText('Jane Doe')).toBeInTheDocument();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('shows an error message when the save fails', async () => {
|
|
86
|
+
// Override the default MSW handler for this test
|
|
87
|
+
server.use(
|
|
88
|
+
http.patch('/api/users/:id', () =>
|
|
89
|
+
HttpResponse.json({ error: 'Server error' }, { status: 500 })
|
|
90
|
+
)
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const user = userEvent.setup();
|
|
94
|
+
render(<UserProfile userId="user-123" />);
|
|
95
|
+
|
|
96
|
+
await screen.findByText('Jane Smith');
|
|
97
|
+
await user.click(screen.getByRole('button', { name: 'Edit profile' }));
|
|
98
|
+
await user.click(screen.getByRole('button', { name: 'Save changes' }));
|
|
99
|
+
|
|
100
|
+
await screen.findByRole('alert');
|
|
101
|
+
expect(screen.getByText(/something went wrong/i)).toBeInTheDocument();
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Use Mock Service Worker (MSW) for network mocking — it intercepts requests at the network level, making tests work identically in browser and Node environments.
|
|
107
|
+
|
|
108
|
+
### Playwright E2E Tests
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// tests/e2e/auth.spec.ts — Playwright E2E for critical auth flow
|
|
112
|
+
import { test, expect } from '@playwright/test';
|
|
113
|
+
|
|
114
|
+
test.describe('Authentication', () => {
|
|
115
|
+
test('user can register and log in', async ({ page }) => {
|
|
116
|
+
const email = `test-${Date.now()}@example.com`;
|
|
117
|
+
|
|
118
|
+
// Registration
|
|
119
|
+
await page.goto('/register');
|
|
120
|
+
await page.getByLabel('Email address').fill(email);
|
|
121
|
+
await page.getByLabel('Password').fill('SecureP@ss123');
|
|
122
|
+
await page.getByLabel('Confirm password').fill('SecureP@ss123');
|
|
123
|
+
await page.getByRole('button', { name: 'Create account' }).click();
|
|
124
|
+
|
|
125
|
+
// Should redirect to onboarding
|
|
126
|
+
await expect(page).toHaveURL('/onboarding');
|
|
127
|
+
await expect(page.getByText('Welcome')).toBeVisible();
|
|
128
|
+
|
|
129
|
+
// Log out
|
|
130
|
+
await page.getByRole('button', { name: 'Account menu' }).click();
|
|
131
|
+
await page.getByRole('menuitem', { name: 'Sign out' }).click();
|
|
132
|
+
await expect(page).toHaveURL('/');
|
|
133
|
+
|
|
134
|
+
// Log in
|
|
135
|
+
await page.goto('/login');
|
|
136
|
+
await page.getByLabel('Email address').fill(email);
|
|
137
|
+
await page.getByLabel('Password').fill('SecureP@ss123');
|
|
138
|
+
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
139
|
+
|
|
140
|
+
await expect(page).toHaveURL('/dashboard');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test('shows error for invalid credentials', async ({ page }) => {
|
|
144
|
+
await page.goto('/login');
|
|
145
|
+
await page.getByLabel('Email address').fill('nonexistent@example.com');
|
|
146
|
+
await page.getByLabel('Password').fill('wrongpassword');
|
|
147
|
+
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
148
|
+
|
|
149
|
+
await expect(page.getByRole('alert')).toContainText('Invalid email or password');
|
|
150
|
+
await expect(page).toHaveURL('/login');
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Accessibility Testing with axe-core
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// Integrate axe-core into component tests
|
|
159
|
+
import { render } from '@testing-library/react';
|
|
160
|
+
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
161
|
+
|
|
162
|
+
expect.extend(toHaveNoViolations);
|
|
163
|
+
|
|
164
|
+
describe('Accessibility', () => {
|
|
165
|
+
it('LoginForm has no accessibility violations', async () => {
|
|
166
|
+
const { container } = render(<LoginForm />);
|
|
167
|
+
const results = await axe(container);
|
|
168
|
+
expect(results).toHaveNoViolations();
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Playwright accessibility snapshot
|
|
173
|
+
test('dashboard is accessible', async ({ page }) => {
|
|
174
|
+
await page.goto('/dashboard');
|
|
175
|
+
const accessibilityScanResults = await new AxeBuilder({ page })
|
|
176
|
+
.withTags(['wcag2a', 'wcag2aa'])
|
|
177
|
+
.analyze();
|
|
178
|
+
expect(accessibilityScanResults.violations).toEqual([]);
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Axe-core checks: missing alt text, insufficient color contrast, missing form labels, improper heading hierarchy, keyboard navigation issues, and ARIA attribute misuse. Run it against every page in CI.
|
|
183
|
+
|
|
184
|
+
### Lighthouse CI Configuration
|
|
185
|
+
|
|
186
|
+
```yaml
|
|
187
|
+
# lighthouserc.yml
|
|
188
|
+
ci:
|
|
189
|
+
collect:
|
|
190
|
+
url:
|
|
191
|
+
- 'http://localhost:3000/'
|
|
192
|
+
- 'http://localhost:3000/dashboard'
|
|
193
|
+
numberOfRuns: 3 # Average across multiple runs for stability
|
|
194
|
+
settings:
|
|
195
|
+
preset: 'desktop'
|
|
196
|
+
throttling:
|
|
197
|
+
rttMs: 40
|
|
198
|
+
throughputKbps: 10240
|
|
199
|
+
cpuSlowdownMultiplier: 1
|
|
200
|
+
|
|
201
|
+
assert:
|
|
202
|
+
preset: 'lighthouse:no-pwa'
|
|
203
|
+
assertions:
|
|
204
|
+
# Core Web Vitals
|
|
205
|
+
largest-contentful-paint:
|
|
206
|
+
- error
|
|
207
|
+
- maxNumericValue: 2500
|
|
208
|
+
aggregationMethod: optimistic # Use best of N runs
|
|
209
|
+
cumulative-layout-shift:
|
|
210
|
+
- error
|
|
211
|
+
- maxNumericValue: 0.1
|
|
212
|
+
total-blocking-time:
|
|
213
|
+
- warn
|
|
214
|
+
- maxNumericValue: 300
|
|
215
|
+
|
|
216
|
+
# Performance budget
|
|
217
|
+
uses-optimized-images: ['warn', { minScore: 0.9 }]
|
|
218
|
+
uses-text-compression: ['error', { minScore: 1 }]
|
|
219
|
+
render-blocking-resources: ['warn', { minScore: 0.8 }]
|
|
220
|
+
|
|
221
|
+
# Accessibility
|
|
222
|
+
categories:accessibility: ['error', { minScore: 0.9 }]
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Run Lighthouse CI in a separate CI step after deployment to your staging environment. Fail only on errors (hard regressions); warn on improvements.
|
|
226
|
+
|
|
227
|
+
### SSR Hydration Testing
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
// Verify SSR output and hydration consistency
|
|
231
|
+
import { renderToString } from 'react-dom/server';
|
|
232
|
+
import { render } from '@testing-library/react';
|
|
233
|
+
|
|
234
|
+
test('ProductCard renders consistently in SSR and client', () => {
|
|
235
|
+
const props = { name: 'Widget', price: 29.99 };
|
|
236
|
+
|
|
237
|
+
// SSR render
|
|
238
|
+
const ssrHTML = renderToString(<ProductCard {...props} />);
|
|
239
|
+
|
|
240
|
+
// Client render
|
|
241
|
+
const { container } = render(<ProductCard {...props} />);
|
|
242
|
+
|
|
243
|
+
// Compare — normalize whitespace differences
|
|
244
|
+
const normalize = (html: string) => html.replace(/\s+/g, ' ').trim();
|
|
245
|
+
expect(normalize(container.innerHTML)).toBe(normalize(ssrHTML));
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Hydration mismatches produce React warnings in development and can cause visual flicker in production. Test SSR/client consistency for any component that uses `Date.now()`, `Math.random()`, browser APIs, or dynamic imports.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-app-ux-patterns
|
|
3
|
+
description: Responsive design, loading states, error boundaries, offline patterns, optimistic updates, and accessibility (WCAG) for web apps
|
|
4
|
+
topics: [web-app, ux, responsive-design, loading-states, error-handling, accessibility, wcag, offline, optimistic-updates]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
UX patterns are the difference between an app that users trust and one they abandon. The patterns covered here are not visual design choices — they are engineering decisions about how the app communicates state, handles failure, and responds to interaction. Implement them consistently across the entire app or they create a fragmented user experience that signals poor quality.
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
UX patterns cover responsive mobile-first design, loading states (skeletons, progressive loading, optimistic updates), error boundaries at meaningful granularity, offline patterns for PWAs, and accessibility compliance. Implement these consistently across the entire app. Loading states for sub-100ms operations make the app feel slower; omit them.
|
|
12
|
+
|
|
13
|
+
## Deep Guidance
|
|
14
|
+
|
|
15
|
+
### Responsive Design: Mobile-First
|
|
16
|
+
|
|
17
|
+
Design and implement for mobile first, then add complexity for larger screens. This discipline prevents the "desktop first, mobile afterthought" failure mode:
|
|
18
|
+
|
|
19
|
+
```css
|
|
20
|
+
/* Mobile default: full width stack */
|
|
21
|
+
.product-grid {
|
|
22
|
+
display: grid;
|
|
23
|
+
grid-template-columns: 1fr;
|
|
24
|
+
gap: var(--sp-4);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Tablet: 2 columns */
|
|
28
|
+
@media (min-width: 768px) {
|
|
29
|
+
.product-grid {
|
|
30
|
+
grid-template-columns: repeat(2, 1fr);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Desktop: 3 columns */
|
|
35
|
+
@media (min-width: 1024px) {
|
|
36
|
+
.product-grid {
|
|
37
|
+
grid-template-columns: repeat(3, 1fr);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Touch targets must be at least 44 x 44 px (Apple HIG) or 48 x 48 px (Material Design). Smaller tap targets on mobile cause accidental taps and user frustration. This is both a UX and accessibility requirement.
|
|
43
|
+
|
|
44
|
+
Viewport-relative units (`vw`, `vh`, `svh`, `dvh`) handle mobile browser chrome (address bars, bottom navigation) correctly. Use `dvh` for full-height layouts on mobile — `100vh` overflows when the browser chrome is visible.
|
|
45
|
+
|
|
46
|
+
### Loading States
|
|
47
|
+
|
|
48
|
+
Never show a blank screen or unresponsive UI during data fetching. Use the appropriate loading pattern for the context:
|
|
49
|
+
|
|
50
|
+
- **Skeleton screens**: Render a content-shaped placeholder that mirrors the final layout. Reduces perceived load time and prevents layout shift when content arrives. Preferred over spinners for content that has a predictable layout.
|
|
51
|
+
- **Progressive loading**: Render low-quality or partial content immediately, replace with full content as it loads. Image blur-up (blur-hash placeholder to full image) is a common example.
|
|
52
|
+
- **Inline spinners**: For user-triggered actions (button submit, form save) where a skeleton does not make sense. Keep spinners small and contextual — a full-page spinner on a button press is jarring.
|
|
53
|
+
- **Optimistic updates**: Show the result immediately, apply it to the server in the background (see below). Best perceived performance.
|
|
54
|
+
|
|
55
|
+
Never show a loading state for actions that complete under 100 ms. Adding a spinner to fast operations makes the app feel slower.
|
|
56
|
+
|
|
57
|
+
### Error Boundaries
|
|
58
|
+
|
|
59
|
+
React error boundaries prevent a single component crash from destroying the entire page:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
// components/ErrorBoundary.tsx
|
|
63
|
+
class ErrorBoundary extends React.Component<
|
|
64
|
+
{ fallback: ReactNode; children: ReactNode },
|
|
65
|
+
{ hasError: boolean }
|
|
66
|
+
> {
|
|
67
|
+
state = { hasError: false };
|
|
68
|
+
|
|
69
|
+
static getDerivedStateFromError() {
|
|
70
|
+
return { hasError: true };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
componentDidCatch(error: Error, info: ErrorInfo) {
|
|
74
|
+
reportError(error, info); // Send to Sentry, Datadog, etc.
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
render() {
|
|
78
|
+
if (this.state.hasError) return this.props.fallback;
|
|
79
|
+
return this.props.children;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Place error boundaries at meaningful granularity: one per major page section, not one per component (too granular) and not one per app (too coarse). When the sidebar crashes, the main content should still work.
|
|
85
|
+
|
|
86
|
+
Provide actionable fallback UIs: "Something went wrong" with a Retry button, not a blank space. Log errors to your monitoring service with full context (user ID, route, component stack) so you can fix them.
|
|
87
|
+
|
|
88
|
+
### Offline Patterns
|
|
89
|
+
|
|
90
|
+
If the app targets users who may lose connectivity (mobile users, field workers, PWA), design for it explicitly:
|
|
91
|
+
|
|
92
|
+
- **Detect connectivity**: `navigator.onLine` and the `online`/`offline` events. React Query and SWR automatically pause requests while offline and retry on reconnect.
|
|
93
|
+
- **Cache reads**: Service worker with a cache-first or stale-while-revalidate strategy for read operations. Users see the last known state instead of an error page.
|
|
94
|
+
- **Queue writes**: Store mutations locally (IndexedDB via Dexie, or background sync API) and replay them when connectivity restores. Essential for field apps where users must be able to submit forms offline.
|
|
95
|
+
- **Communicate status**: Show a banner when offline. Tell users which data may be stale. Do not silently fail mutations — tell the user the action is queued.
|
|
96
|
+
|
|
97
|
+
Implementing offline support adds significant complexity. Scope it to the specific user journeys that need it, not the entire app.
|
|
98
|
+
|
|
99
|
+
### Optimistic Updates
|
|
100
|
+
|
|
101
|
+
Optimistic updates apply the result of a mutation to the UI immediately, before server confirmation:
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// React Query optimistic update pattern
|
|
105
|
+
const mutation = useMutation({
|
|
106
|
+
mutationFn: updateTodo,
|
|
107
|
+
onMutate: async (newTodo) => {
|
|
108
|
+
await queryClient.cancelQueries({ queryKey: ["todos"] });
|
|
109
|
+
const previousTodos = queryClient.getQueryData(["todos"]);
|
|
110
|
+
queryClient.setQueryData(["todos"], (old) =>
|
|
111
|
+
old.map((t) => t.id === newTodo.id ? { ...t, ...newTodo } : t)
|
|
112
|
+
);
|
|
113
|
+
return { previousTodos };
|
|
114
|
+
},
|
|
115
|
+
onError: (error, variables, context) => {
|
|
116
|
+
queryClient.setQueryData(["todos"], context.previousTodos);
|
|
117
|
+
showError("Failed to save changes.");
|
|
118
|
+
},
|
|
119
|
+
onSettled: () => queryClient.invalidateQueries({ queryKey: ["todos"] }),
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Use optimistic updates for: toggling checkboxes, likes/favorites, reordering, simple field edits. Do not use for: payments, irreversible actions, or anything where showing a false success state is harmful.
|
|
124
|
+
|
|
125
|
+
### Accessibility Implementation
|
|
126
|
+
|
|
127
|
+
WCAG compliance is a legal requirement in many jurisdictions (ADA, EN 301 549, AODA) and a quality signal for all users:
|
|
128
|
+
|
|
129
|
+
**Keyboard navigation:**
|
|
130
|
+
- Every interactive element reachable by Tab key in logical order
|
|
131
|
+
- Focus styles visible and high-contrast (never `outline: none` without a replacement)
|
|
132
|
+
- Modal dialogs trap focus; Escape closes them
|
|
133
|
+
- Custom interactive components (dropdowns, sliders, date pickers) implement ARIA keyboard patterns from the WAI-ARIA Authoring Practices Guide
|
|
134
|
+
|
|
135
|
+
**Screen reader support:**
|
|
136
|
+
- Semantic HTML first: `<button>` not `<div onClick>`, `<nav>` not `<div class="nav">`, `<h1>`–`<h6>` for heading hierarchy
|
|
137
|
+
- `alt` text on all meaningful images; `alt=""` for decorative images
|
|
138
|
+
- `aria-label` or `aria-labelledby` for elements whose text content does not describe their purpose
|
|
139
|
+
- Live regions (`aria-live="polite"`) for dynamic content updates (error messages, notifications)
|
|
140
|
+
- Test with VoiceOver (macOS/iOS) and NVDA (Windows) — automated tools miss 60–70% of real issues
|
|
141
|
+
|
|
142
|
+
**Color and contrast:**
|
|
143
|
+
- Minimum 4.5:1 contrast ratio for normal text, 3:1 for large text (WCAG AA)
|
|
144
|
+
- Do not rely on color alone to convey meaning — add icons, patterns, or text labels
|
|
145
|
+
|
|
146
|
+
### Form UX Patterns
|
|
147
|
+
|
|
148
|
+
Forms are the highest-friction interaction in most apps. Apply these patterns:
|
|
149
|
+
|
|
150
|
+
- **Inline validation**: Validate on blur (not on keystroke) to avoid distracting errors as users type. Show success states to confirm correct input.
|
|
151
|
+
- **Error placement**: Show field-level errors directly below the field, not in a summary banner. Users must not hunt to find which field has an error.
|
|
152
|
+
- **Label positioning**: Labels above inputs, not placeholders-as-labels. Placeholder text disappears when the user types and fails accessibility requirements.
|
|
153
|
+
- **Disabled submit vs. validation feedback**: Do not disable the submit button with no explanation. Instead, allow submission and show validation errors. Disabled buttons with no label are inaccessible and frustrating.
|
|
154
|
+
|
|
155
|
+
### Toast / Notification Patterns
|
|
156
|
+
|
|
157
|
+
Notifications must not interrupt user flow or require dismissal for low-priority information:
|
|
158
|
+
|
|
159
|
+
- **Success toasts**: Auto-dismiss after 4–5 seconds. No action required.
|
|
160
|
+
- **Error toasts**: Persist until dismissed or action taken. User must be able to act on the error.
|
|
161
|
+
- **Placement**: Bottom-right (desktop) or bottom-center (mobile) to avoid covering primary content.
|
|
162
|
+
- **Screen reader**: Announce via `aria-live="polite"` for non-critical messages, `aria-live="assertive"` only for critical errors. Assertive announcements interrupt screen reader narration — use sparingly.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# methodology/backend-overlay.yml
|
|
2
|
+
name: backend
|
|
3
|
+
description: >
|
|
4
|
+
Backend service overlay — injects backend domain knowledge into existing
|
|
5
|
+
pipeline steps for API design, data modeling, authentication, async
|
|
6
|
+
processing, and deployment patterns.
|
|
7
|
+
project-type: backend
|
|
8
|
+
|
|
9
|
+
# ---------------------------------------------------------------------------
|
|
10
|
+
# knowledge-overrides
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
# Map backend knowledge entries into existing pipeline steps so that backend
|
|
13
|
+
# domain expertise is injected during prompt assembly.
|
|
14
|
+
knowledge-overrides:
|
|
15
|
+
# Foundational
|
|
16
|
+
create-prd:
|
|
17
|
+
append: [backend-requirements]
|
|
18
|
+
user-stories:
|
|
19
|
+
append: [backend-requirements]
|
|
20
|
+
coding-standards:
|
|
21
|
+
append: [backend-conventions]
|
|
22
|
+
project-structure:
|
|
23
|
+
append: [backend-project-structure]
|
|
24
|
+
dev-env-setup:
|
|
25
|
+
append: [backend-dev-environment]
|
|
26
|
+
git-workflow:
|
|
27
|
+
append: [backend-deployment]
|
|
28
|
+
|
|
29
|
+
# Architecture & Design
|
|
30
|
+
system-architecture:
|
|
31
|
+
append: [backend-architecture, backend-async-patterns, backend-worker-patterns]
|
|
32
|
+
tech-stack:
|
|
33
|
+
append: [backend-architecture, backend-api-design, backend-auth-patterns]
|
|
34
|
+
adrs:
|
|
35
|
+
append: [backend-architecture]
|
|
36
|
+
domain-modeling:
|
|
37
|
+
append: [backend-data-modeling]
|
|
38
|
+
database-schema:
|
|
39
|
+
append: [backend-data-modeling]
|
|
40
|
+
api-contracts:
|
|
41
|
+
append: [backend-api-design]
|
|
42
|
+
security:
|
|
43
|
+
append: [backend-auth-patterns, backend-security]
|
|
44
|
+
operations:
|
|
45
|
+
append: [backend-deployment, backend-observability, backend-async-patterns, backend-worker-patterns]
|
|
46
|
+
|
|
47
|
+
# Testing
|
|
48
|
+
tdd:
|
|
49
|
+
append: [backend-testing]
|
|
50
|
+
add-e2e-testing:
|
|
51
|
+
append: [backend-testing]
|
|
52
|
+
create-evals:
|
|
53
|
+
append: [backend-testing]
|
|
54
|
+
story-tests:
|
|
55
|
+
append: [backend-testing]
|
|
56
|
+
|
|
57
|
+
# Reviews (mirror authoring steps)
|
|
58
|
+
review-architecture:
|
|
59
|
+
append: [backend-architecture, backend-async-patterns, backend-worker-patterns]
|
|
60
|
+
review-api:
|
|
61
|
+
append: [backend-api-design]
|
|
62
|
+
review-database:
|
|
63
|
+
append: [backend-data-modeling]
|
|
64
|
+
review-security:
|
|
65
|
+
append: [backend-auth-patterns, backend-security]
|
|
66
|
+
review-operations:
|
|
67
|
+
append: [backend-deployment, backend-observability, backend-async-patterns, backend-worker-patterns]
|
|
68
|
+
review-testing:
|
|
69
|
+
append: [backend-testing]
|
|
70
|
+
|
|
71
|
+
# Planning
|
|
72
|
+
implementation-plan:
|
|
73
|
+
append: [backend-architecture]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# methodology/cli-overlay.yml
|
|
2
|
+
name: cli
|
|
3
|
+
description: >
|
|
4
|
+
CLI tool overlay — injects CLI domain knowledge into existing pipeline
|
|
5
|
+
steps for command parsing, distribution, interactive prompts, output
|
|
6
|
+
formatting, and shell integration patterns.
|
|
7
|
+
project-type: cli
|
|
8
|
+
|
|
9
|
+
# ---------------------------------------------------------------------------
|
|
10
|
+
# knowledge-overrides
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
# Map CLI knowledge entries into existing pipeline steps so that CLI tool
|
|
13
|
+
# domain expertise is injected during prompt assembly.
|
|
14
|
+
knowledge-overrides:
|
|
15
|
+
# Foundational
|
|
16
|
+
create-prd:
|
|
17
|
+
append: [cli-requirements]
|
|
18
|
+
user-stories:
|
|
19
|
+
append: [cli-requirements]
|
|
20
|
+
coding-standards:
|
|
21
|
+
append: [cli-conventions]
|
|
22
|
+
project-structure:
|
|
23
|
+
append: [cli-project-structure]
|
|
24
|
+
dev-env-setup:
|
|
25
|
+
append: [cli-dev-environment, cli-shell-integration]
|
|
26
|
+
git-workflow:
|
|
27
|
+
append: [cli-distribution-patterns]
|
|
28
|
+
|
|
29
|
+
# Architecture & Design
|
|
30
|
+
system-architecture:
|
|
31
|
+
append: [cli-architecture, cli-interactivity-patterns]
|
|
32
|
+
tech-stack:
|
|
33
|
+
append: [cli-architecture, cli-distribution-patterns]
|
|
34
|
+
adrs:
|
|
35
|
+
append: [cli-architecture]
|
|
36
|
+
domain-modeling:
|
|
37
|
+
append: [cli-architecture]
|
|
38
|
+
api-contracts:
|
|
39
|
+
append: [cli-output-patterns]
|
|
40
|
+
security:
|
|
41
|
+
append: [cli-conventions]
|
|
42
|
+
operations:
|
|
43
|
+
append: [cli-distribution-patterns, cli-shell-integration]
|
|
44
|
+
|
|
45
|
+
# Testing
|
|
46
|
+
tdd:
|
|
47
|
+
append: [cli-testing]
|
|
48
|
+
add-e2e-testing:
|
|
49
|
+
append: [cli-testing]
|
|
50
|
+
create-evals:
|
|
51
|
+
append: [cli-testing]
|
|
52
|
+
story-tests:
|
|
53
|
+
append: [cli-testing]
|
|
54
|
+
|
|
55
|
+
# Reviews (mirror authoring steps)
|
|
56
|
+
review-architecture:
|
|
57
|
+
append: [cli-architecture, cli-interactivity-patterns]
|
|
58
|
+
review-api:
|
|
59
|
+
append: [cli-output-patterns]
|
|
60
|
+
review-security:
|
|
61
|
+
append: [cli-conventions]
|
|
62
|
+
review-operations:
|
|
63
|
+
append: [cli-distribution-patterns, cli-shell-integration]
|
|
64
|
+
review-testing:
|
|
65
|
+
append: [cli-testing]
|
|
66
|
+
|
|
67
|
+
# Planning
|
|
68
|
+
implementation-plan:
|
|
69
|
+
append: [cli-architecture]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# methodology/library-overlay.yml
|
|
2
|
+
name: library
|
|
3
|
+
description: >
|
|
4
|
+
Library overlay — injects library domain knowledge into existing pipeline
|
|
5
|
+
steps for API design, bundling, type definitions, documentation, and
|
|
6
|
+
versioning patterns.
|
|
7
|
+
project-type: library
|
|
8
|
+
|
|
9
|
+
# ---------------------------------------------------------------------------
|
|
10
|
+
# knowledge-overrides
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
# Map library knowledge entries into existing pipeline steps so that library
|
|
13
|
+
# domain expertise is injected during prompt assembly.
|
|
14
|
+
knowledge-overrides:
|
|
15
|
+
# Foundational
|
|
16
|
+
create-prd:
|
|
17
|
+
append: [library-requirements]
|
|
18
|
+
user-stories:
|
|
19
|
+
append: [library-requirements]
|
|
20
|
+
coding-standards:
|
|
21
|
+
append: [library-conventions, library-documentation]
|
|
22
|
+
project-structure:
|
|
23
|
+
append: [library-project-structure]
|
|
24
|
+
dev-env-setup:
|
|
25
|
+
append: [library-dev-environment]
|
|
26
|
+
git-workflow:
|
|
27
|
+
append: [library-versioning]
|
|
28
|
+
|
|
29
|
+
# Architecture & Design
|
|
30
|
+
system-architecture:
|
|
31
|
+
append: [library-architecture]
|
|
32
|
+
tech-stack:
|
|
33
|
+
append: [library-architecture, library-bundling, library-type-definitions]
|
|
34
|
+
adrs:
|
|
35
|
+
append: [library-architecture]
|
|
36
|
+
api-contracts:
|
|
37
|
+
append: [library-api-design]
|
|
38
|
+
security:
|
|
39
|
+
append: [library-security]
|
|
40
|
+
operations:
|
|
41
|
+
append: [library-versioning, library-documentation]
|
|
42
|
+
|
|
43
|
+
# Testing
|
|
44
|
+
tdd:
|
|
45
|
+
append: [library-testing]
|
|
46
|
+
add-e2e-testing:
|
|
47
|
+
append: [library-testing]
|
|
48
|
+
create-evals:
|
|
49
|
+
append: [library-testing]
|
|
50
|
+
story-tests:
|
|
51
|
+
append: [library-testing]
|
|
52
|
+
|
|
53
|
+
# Reviews (mirror authoring steps)
|
|
54
|
+
review-architecture:
|
|
55
|
+
append: [library-architecture]
|
|
56
|
+
review-api:
|
|
57
|
+
append: [library-api-design]
|
|
58
|
+
review-security:
|
|
59
|
+
append: [library-security]
|
|
60
|
+
review-operations:
|
|
61
|
+
append: [library-versioning, library-documentation]
|
|
62
|
+
review-testing:
|
|
63
|
+
append: [library-testing]
|
|
64
|
+
|
|
65
|
+
# Planning
|
|
66
|
+
implementation-plan:
|
|
67
|
+
append: [library-architecture]
|