@tekyzinc/gsd-t 2.46.11 → 2.50.10

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +22 -2
  3. package/bin/debug-ledger.js +193 -0
  4. package/bin/gsd-t.js +259 -1
  5. package/commands/gsd-t-debug.md +26 -1
  6. package/commands/gsd-t-execute.md +31 -3
  7. package/commands/gsd-t-help.md +18 -2
  8. package/commands/gsd-t-integrate.md +16 -0
  9. package/commands/gsd-t-quick.md +18 -1
  10. package/commands/gsd-t-test-sync.md +5 -1
  11. package/commands/gsd-t-verify.md +6 -1
  12. package/commands/gsd-t-wave.md +26 -0
  13. package/docs/GSD-T-README.md +83 -1
  14. package/docs/architecture.md +9 -1
  15. package/docs/requirements.md +30 -0
  16. package/package.json +1 -1
  17. package/templates/CLAUDE-global.md +19 -2
  18. package/templates/stacks/_security.md +243 -0
  19. package/templates/stacks/desktop.ini +2 -0
  20. package/templates/stacks/docker.md +202 -0
  21. package/templates/stacks/firebase.md +166 -0
  22. package/templates/stacks/flutter.md +205 -0
  23. package/templates/stacks/github-actions.md +201 -0
  24. package/templates/stacks/graphql.md +216 -0
  25. package/templates/stacks/neo4j.md +218 -0
  26. package/templates/stacks/nextjs.md +184 -0
  27. package/templates/stacks/node-api.md +196 -0
  28. package/templates/stacks/playwright.md +528 -0
  29. package/templates/stacks/postgresql.md +225 -0
  30. package/templates/stacks/python.md +243 -0
  31. package/templates/stacks/react-native.md +216 -0
  32. package/templates/stacks/react.md +293 -0
  33. package/templates/stacks/redux.md +193 -0
  34. package/templates/stacks/rest-api.md +202 -0
  35. package/templates/stacks/supabase.md +188 -0
  36. package/templates/stacks/tailwind.md +169 -0
  37. package/templates/stacks/typescript.md +176 -0
  38. package/templates/stacks/vite.md +176 -0
  39. package/templates/stacks/vue.md +189 -0
  40. package/templates/stacks/zustand.md +203 -0
@@ -0,0 +1,188 @@
1
+ # Supabase Standards
2
+
3
+ These rules are MANDATORY. Violations fail the task. No exceptions.
4
+
5
+ ---
6
+
7
+ ## 1. Row Level Security (RLS)
8
+
9
+ ```
10
+ MANDATORY:
11
+ ├── Enable RLS on EVERY table — no exceptions
12
+ ├── Default-deny: tables with RLS enabled and no policies block all access
13
+ ├── Write policies per role: anon, authenticated, service_role
14
+ ├── Use auth.uid() for user-scoped policies — NEVER trust client-sent user IDs
15
+ ├── Test policies with different roles before deploying
16
+ └── Service role bypasses RLS — only use server-side, NEVER expose the service key
17
+ ```
18
+
19
+ **GOOD**
20
+ ```sql
21
+ ALTER TABLE user_profiles ENABLE ROW LEVEL SECURITY;
22
+
23
+ -- Users can read their own profile
24
+ CREATE POLICY "Users read own profile"
25
+ ON user_profiles FOR SELECT
26
+ USING (auth.uid() = user_id);
27
+
28
+ -- Users can update their own profile
29
+ CREATE POLICY "Users update own profile"
30
+ ON user_profiles FOR UPDATE
31
+ USING (auth.uid() = user_id)
32
+ WITH CHECK (auth.uid() = user_id);
33
+ ```
34
+
35
+ ---
36
+
37
+ ## 2. Auth Patterns
38
+
39
+ ```
40
+ MANDATORY:
41
+ ├── Use Supabase Auth — don't build custom auth alongside it
42
+ ├── Store user metadata in a separate profiles table — not in auth.users
43
+ ├── Create profile on signup via database trigger or auth hook
44
+ ├── Use auth.uid() in RLS policies — it's the trusted source of identity
45
+ ├── Handle auth state changes with onAuthStateChange listener
46
+ └── NEVER store the service_role key in client code — it bypasses RLS
47
+ ```
48
+
49
+ **GOOD** — trigger to create profile:
50
+ ```sql
51
+ CREATE OR REPLACE FUNCTION handle_new_user()
52
+ RETURNS TRIGGER AS $$
53
+ BEGIN
54
+ INSERT INTO user_profiles (user_id, email, display_name)
55
+ VALUES (NEW.id, NEW.email, COALESCE(NEW.raw_user_meta_data->>'display_name', ''));
56
+ RETURN NEW;
57
+ END;
58
+ $$ LANGUAGE plpgsql SECURITY DEFINER;
59
+
60
+ CREATE TRIGGER on_auth_user_created
61
+ AFTER INSERT ON auth.users
62
+ FOR EACH ROW EXECUTE FUNCTION handle_new_user();
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 3. Client Usage
68
+
69
+ ```
70
+ MANDATORY:
71
+ ├── Initialize client once — export from a shared module
72
+ ├── Use typed client with generated types: supabase-js + supabase gen types
73
+ ├── Handle errors from every Supabase call — check { data, error } response
74
+ ├── Use .select() with specific columns — NEVER .select('*') in production
75
+ ├── Use .single() when expecting one row — throws if 0 or 2+ rows
76
+ └── Regenerate types after every migration: npx supabase gen types typescript
77
+ ```
78
+
79
+ **GOOD**
80
+ ```typescript
81
+ const { data, error } = await supabase
82
+ .from('user_profiles')
83
+ .select('id, email, display_name, role')
84
+ .eq('user_id', userId)
85
+ .single();
86
+
87
+ if (error) throw new DatabaseError('Failed to fetch profile', error);
88
+ ```
89
+
90
+ ---
91
+
92
+ ## 4. Edge Functions
93
+
94
+ ```
95
+ MANDATORY:
96
+ ├── Use for server-side logic that needs secrets or external API calls
97
+ ├── Validate ALL inputs — edge functions are public endpoints
98
+ ├── Use Zod or manual validation at the entry point
99
+ ├── Set CORS headers explicitly
100
+ ├── Handle errors with proper HTTP status codes
101
+ └── Keep functions focused — one concern per function
102
+ ```
103
+
104
+ ---
105
+
106
+ ## 5. Realtime
107
+
108
+ ```
109
+ WHEN USING REALTIME:
110
+ ├── Enable realtime only on tables that need it — not all tables
111
+ ├── Subscribe with filters to reduce message volume
112
+ ├── Unsubscribe on component unmount — prevent memory leaks
113
+ ├── Handle reconnection gracefully
114
+ └── RLS applies to realtime — users only receive rows they can SELECT
115
+ ```
116
+
117
+ **GOOD**
118
+ ```typescript
119
+ const channel = supabase
120
+ .channel('user-orders')
121
+ .on('postgres_changes',
122
+ { event: 'INSERT', schema: 'public', table: 'orders', filter: `user_id=eq.${userId}` },
123
+ (payload) => handleNewOrder(payload.new)
124
+ )
125
+ .subscribe();
126
+
127
+ // Cleanup
128
+ return () => { supabase.removeChannel(channel); };
129
+ ```
130
+
131
+ ---
132
+
133
+ ## 6. Storage
134
+
135
+ ```
136
+ MANDATORY:
137
+ ├── Create separate buckets per use case (avatars, documents, uploads)
138
+ ├── Set bucket-level access policies (public vs private)
139
+ ├── Validate file type and size before upload — client AND server side
140
+ ├── Use signed URLs for private file access — not public URLs
141
+ ├── Set file size limits per bucket
142
+ └── NEVER store sensitive documents in public buckets
143
+ ```
144
+
145
+ ---
146
+
147
+ ## 7. Migrations
148
+
149
+ ```
150
+ MANDATORY:
151
+ ├── Use supabase db diff or manual SQL files for migrations
152
+ ├── One migration per change — don't combine unrelated changes
153
+ ├── Test migrations locally: supabase db reset
154
+ ├── Always regenerate types after migration: supabase gen types typescript
155
+ ├── Include RLS policies in migration files — not applied manually
156
+ └── Seed data in a separate seed.sql file
157
+ ```
158
+
159
+ ---
160
+
161
+ ## 8. Anti-Patterns
162
+
163
+ ```
164
+ NEVER:
165
+ ├── Expose service_role key to client — it bypasses RLS
166
+ ├── Tables without RLS enabled
167
+ ├── .select('*') in production queries
168
+ ├── Trusting client-sent user IDs — use auth.uid()
169
+ ├── Storing user data in auth.users metadata instead of a profiles table
170
+ ├── Realtime on all tables — enable selectively
171
+ ├── Ignoring { error } from Supabase calls
172
+ └── Manual SQL in Supabase dashboard instead of migration files
173
+ ```
174
+
175
+ ---
176
+
177
+ ## Supabase Verification Checklist
178
+
179
+ - [ ] RLS enabled on every table with explicit policies
180
+ - [ ] auth.uid() used in policies — no client-sent user IDs trusted
181
+ - [ ] Service role key only used server-side
182
+ - [ ] Typed client with generated types (supabase gen types)
183
+ - [ ] Specific column selects — no .select('*')
184
+ - [ ] Error handling on every Supabase call
185
+ - [ ] Realtime subscriptions cleaned up on unmount
186
+ - [ ] Storage buckets have access policies and file limits
187
+ - [ ] Migrations in version control — not manual dashboard SQL
188
+ - [ ] Types regenerated after every migration
@@ -0,0 +1,169 @@
1
+ # Tailwind CSS Standards
2
+
3
+ These rules are MANDATORY. Violations fail the task. No exceptions.
4
+
5
+ ---
6
+
7
+ ## 1. Class-Only Styling
8
+
9
+ ```
10
+ MANDATORY:
11
+ ├── Tailwind utility classes ONLY — no inline styles, no CSS modules, no styled-components
12
+ ├── Exception: CSS variables for theme tokens (e.g., bg-[var(--brand-primary)])
13
+ ├── Exception: Animations that require @keyframes — define in tailwind.config or globals.css
14
+ └── NEVER mix Tailwind with other CSS methodologies in the same project
15
+ ```
16
+
17
+ **BAD** — `<div style={{ padding: '16px', color: 'red' }}>`
18
+
19
+ **GOOD** — `<div className="p-4 text-red-500">`
20
+
21
+ ---
22
+
23
+ ## 2. Responsive Design — Mobile First
24
+
25
+ ```
26
+ MANDATORY:
27
+ ├── Default styles target mobile — add breakpoints for larger screens
28
+ ├── Breakpoint order: base → sm: → md: → lg: → xl: → 2xl:
29
+ ├── NEVER use max-width breakpoints — always min-width (Tailwind default)
30
+ └── Test at each breakpoint — don't assume intermediate sizes work
31
+ ```
32
+
33
+ **BAD** — Desktop-first: `<div className="flex lg:flex max-lg:block">`
34
+
35
+ **GOOD** — Mobile-first: `<div className="block md:flex">`
36
+
37
+ ---
38
+
39
+ ## 3. Component Extraction Over @apply
40
+
41
+ ```
42
+ MANDATORY:
43
+ ├── Extract repeated utility patterns into components — NOT @apply classes
44
+ ├── @apply is allowed ONLY in global base styles (body, headings, links)
45
+ ├── Use a cn() helper for conditional classes
46
+ └── NEVER create .btn, .card, etc. utility classes — make components instead
47
+ ```
48
+
49
+ **BAD** — `@apply` in CSS:
50
+ ```css
51
+ .btn-primary { @apply px-4 py-2 bg-blue-500 text-white rounded; }
52
+ ```
53
+
54
+ **GOOD** — React component:
55
+ ```tsx
56
+ function Button({ children, variant = 'primary', className }: ButtonProps) {
57
+ return (
58
+ <button className={cn(
59
+ 'px-4 py-2 rounded font-medium transition-colors',
60
+ variant === 'primary' && 'bg-blue-500 text-white hover:bg-blue-600',
61
+ variant === 'ghost' && 'bg-transparent hover:bg-gray-100',
62
+ className
63
+ )}>
64
+ {children}
65
+ </button>
66
+ );
67
+ }
68
+ ```
69
+
70
+ ---
71
+
72
+ ## 4. The cn() Helper
73
+
74
+ ```
75
+ MANDATORY:
76
+ ├── Use a cn() or clsx() utility for conditional and merged classes
77
+ ├── For Tailwind merge conflicts, use tailwind-merge (twMerge)
78
+ └── Standard pattern: cn = (...classes) => twMerge(clsx(...classes))
79
+ ```
80
+
81
+ ```typescript
82
+ import { clsx, type ClassValue } from 'clsx';
83
+ import { twMerge } from 'tailwind-merge';
84
+
85
+ export function cn(...inputs: ClassValue[]) {
86
+ return twMerge(clsx(inputs));
87
+ }
88
+ ```
89
+
90
+ ---
91
+
92
+ ## 5. Color and Theme System
93
+
94
+ ```
95
+ MANDATORY:
96
+ ├── Define colors as CSS variables — not hardcoded Tailwind colors
97
+ ├── Use semantic names (--color-primary, --color-surface) — not visual (--blue-500)
98
+ ├── Support dark mode via CSS variables or Tailwind dark: prefix
99
+ ├── NEVER use arbitrary color values ([#ff6b35]) — add to theme config
100
+ └── Opacity modifiers via Tailwind (text-primary/80) — not rgba
101
+ ```
102
+
103
+ **GOOD** — `tailwind.config.js`:
104
+ ```js
105
+ theme: {
106
+ extend: {
107
+ colors: {
108
+ primary: 'var(--color-primary)',
109
+ surface: 'var(--color-surface)',
110
+ border: 'var(--color-border)',
111
+ },
112
+ },
113
+ }
114
+ ```
115
+
116
+ ---
117
+
118
+ ## 6. Spacing and Layout
119
+
120
+ ```
121
+ MANDATORY:
122
+ ├── Use Tailwind spacing scale (p-4, gap-3, m-2) — not arbitrary values
123
+ ├── Use Flexbox (flex) or Grid (grid) for layout — not floats or absolute positioning
124
+ ├── gap-* for spacing between flex/grid children — not margins on children
125
+ ├── Consistent spacing: pick a scale (4px base) and stick to it
126
+ └── Arbitrary values ([17px]) only when matching a design spec exactly
127
+ ```
128
+
129
+ ---
130
+
131
+ ## 7. Dark Mode
132
+
133
+ ```
134
+ WHEN SUPPORTING DARK MODE:
135
+ ├── Use class strategy (darkMode: 'class') for user-controlled toggling
136
+ ├── Apply dark: variants alongside base styles — not in separate files
137
+ ├── Test both modes — don't assume dark is just "invert colors"
138
+ └── Ensure sufficient contrast in both modes (WCAG AA: 4.5:1 for text)
139
+ ```
140
+
141
+ **GOOD** — `<div className="bg-white text-gray-900 dark:bg-gray-900 dark:text-gray-100">`
142
+
143
+ ---
144
+
145
+ ## 8. Anti-Patterns
146
+
147
+ ```
148
+ NEVER:
149
+ ├── Inline styles alongside Tailwind classes
150
+ ├── @apply for component-level styles — make components instead
151
+ ├── Arbitrary values when a Tailwind scale value exists (p-[16px] → p-4)
152
+ ├── !important via ! prefix — fix specificity instead
153
+ ├── Overly long class strings (15+ utilities) — extract a component
154
+ ├── Hardcoded colors ([#hex]) — add to theme config
155
+ └── Margin on grid/flex children for spacing — use gap-* on parent
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Tailwind Verification Checklist
161
+
162
+ - [ ] No inline styles — Tailwind classes only
163
+ - [ ] Mobile-first responsive (base → sm → md → lg)
164
+ - [ ] Repeated patterns extracted to components — not @apply
165
+ - [ ] cn() helper used for conditional classes
166
+ - [ ] Colors defined as CSS variables / theme config — no hardcoded hex
167
+ - [ ] Spacing uses Tailwind scale — minimal arbitrary values
168
+ - [ ] Dark mode tested (if applicable)
169
+ - [ ] No class strings longer than ~15 utilities — component extracted
@@ -0,0 +1,176 @@
1
+ # TypeScript Standards
2
+
3
+ These rules are MANDATORY. Violations fail the task. No exceptions.
4
+
5
+ ---
6
+
7
+ ## 1. Strict Mode
8
+
9
+ `tsconfig.json` MUST have `"strict": true`. Never disable strict flags to silence errors — fix the code.
10
+
11
+ ```
12
+ MANDATORY:
13
+ ├── "strict": true in tsconfig.json
14
+ ├── Never use `any` — use `unknown` for truly unknown types, then narrow
15
+ ├── Never use the `object` type — use a specific interface or Record<K, V>
16
+ └── Never leave function params or return values untyped (no implicit any)
17
+ ```
18
+
19
+ ```ts
20
+ // BAD
21
+ function process(data: any) { return data.value; }
22
+
23
+ // GOOD — unknown forces narrowing before use
24
+ function process(data: unknown): string {
25
+ if (typeof data === 'object' && data !== null && 'value' in data) {
26
+ return String((data as { value: unknown }).value);
27
+ }
28
+ throw new Error('Unexpected data shape');
29
+ }
30
+ ```
31
+
32
+ ---
33
+
34
+ ## 2. Interface vs Type
35
+
36
+ ```
37
+ USE INTERFACE: object shapes, extendable contracts, class implementations
38
+ USE TYPE: unions, intersections, utility types, mapped/conditional types
39
+ ```
40
+
41
+ ```ts
42
+ // GOOD
43
+ interface User { id: string; name: string; email: string; }
44
+ interface AdminUser extends User { permissions: string[]; }
45
+ type UserRole = 'admin' | 'editor' | 'viewer';
46
+ type UserSummary = Pick<User, 'id' | 'name'>;
47
+ ```
48
+
49
+ ---
50
+
51
+ ## 3. Generic Components
52
+
53
+ ```ts
54
+ // GOOD — reusable generic table avoids per-type duplication
55
+ interface DataTableProps<T> {
56
+ data: T[];
57
+ columns: Array<{ key: keyof T; label: string }>;
58
+ onRowClick: (row: T) => void;
59
+ }
60
+ function DataTable<T>({ data, columns, onRowClick }: DataTableProps<T>) { /* ... */ }
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 4. Zod Schema-Driven Validation
66
+
67
+ Zod schemas are the single source of truth for runtime validation AND TypeScript types. Never define a type separately when a Zod schema already defines the shape.
68
+
69
+ ```ts
70
+ import { z } from 'zod';
71
+
72
+ // GOOD — schema drives both validation and type
73
+ const UserSchema = z.object({
74
+ id: z.string().uuid(),
75
+ email: z.string().email(),
76
+ role: z.enum(['admin', 'editor', 'viewer']),
77
+ });
78
+ type User = z.infer<typeof UserSchema>; // derive — never duplicate
79
+
80
+ // BAD — separate type diverges from schema over time
81
+ type User = { id: string; email: string; role: string };
82
+ ```
83
+
84
+ Use Zod for: form validation, API response parsing, env variable validation, config files.
85
+
86
+ ---
87
+
88
+ ## 5. Error Typing
89
+
90
+ ```ts
91
+ // BAD
92
+ try { /* ... */ } catch (e: any) { console.log(e.message); }
93
+
94
+ // GOOD — narrow unknown before use
95
+ try { /* ... */ } catch (error: unknown) {
96
+ if (error instanceof Error) console.error(error.message);
97
+ else console.error('Unknown error', error);
98
+ }
99
+ ```
100
+
101
+ ---
102
+
103
+ ## 6. Enums for Fixed Option Sets
104
+
105
+ ```ts
106
+ // GOOD — union for simple status flags
107
+ type OrderStatus = 'pending' | 'processing' | 'shipped' | 'delivered';
108
+
109
+ // GOOD — enum when iteration or key mapping is needed
110
+ enum Direction { Up = 'UP', Down = 'DOWN', Left = 'LEFT', Right = 'RIGHT' }
111
+
112
+ // BAD — magic strings scattered through codebase (typos never caught)
113
+ if (status === 'pndng') { /* ... */ }
114
+ ```
115
+
116
+ ---
117
+
118
+ ## 7. Import Ordering
119
+
120
+ ```ts
121
+ // 1. React / framework
122
+ import React, { useState } from 'react';
123
+ // 2. Third-party libraries
124
+ import { z } from 'zod';
125
+ // 3. Shared / internal aliases
126
+ import { Button } from '@/components/ui/Button';
127
+ // 4. Local / relative
128
+ import { formatDate } from './utils';
129
+ import type { UserFilters } from './types';
130
+ ```
131
+
132
+ ---
133
+
134
+ ## 8. Naming Conventions
135
+
136
+ | Item | Convention | Example |
137
+ |-----------------------|-------------------------|----------------------|
138
+ | React components | PascalCase | `UserList.tsx` |
139
+ | Hooks | camelCase + `use` | `useAuth.ts` |
140
+ | Services | camelCase + `Service` | `userService.ts` |
141
+ | Types / Interfaces | PascalCase | `User`, `UserFilters`|
142
+ | Constants | UPPER_SNAKE_CASE | `API_BASE_URL` |
143
+ | Non-component files | camelCase | `helpers.ts` |
144
+ | Folders | kebab-case | `user-profile/` |
145
+ | CSS classes | kebab-case | `.user-card` |
146
+ | Boolean props/state | `is`/`has`/`can` prefix | `isLoading` |
147
+ | Event handler fns | `handle` prefix | `handleSubmit` |
148
+ | Callback props | `on` prefix | `onSuccess` |
149
+
150
+ ```ts
151
+ // GOOD
152
+ const isLoading = true;
153
+ function handleSubmit(e: React.FormEvent) { /* ... */ }
154
+ <Form onSubmit={handleSubmit} />
155
+
156
+ // BAD
157
+ const loading = true;
158
+ function submitForm() { /* ... */ }
159
+ <Form submitHandler={submitForm} />
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Pre-Commit TypeScript Checklist
165
+
166
+ - [ ] `"strict": true` in `tsconfig.json`
167
+ - [ ] No `any` — `unknown` with narrowing used instead
168
+ - [ ] No bare `object` type — specific interfaces or `Record<K,V>` only
169
+ - [ ] Interfaces for object shapes; types for unions/utilities
170
+ - [ ] Zod schemas drive both validation and types via `z.infer`
171
+ - [ ] Caught errors narrowed before access (`instanceof Error` check)
172
+ - [ ] Enums or union types for all fixed option sets — no magic strings
173
+ - [ ] Imports ordered: React → third-party → shared → local
174
+ - [ ] Boolean props/state use `is`/`has`/`can` prefix
175
+ - [ ] Event handlers use `handle` prefix; callback props use `on` prefix
176
+ - [ ] All files, components, hooks, and services follow naming conventions
@@ -0,0 +1,176 @@
1
+ # Vite Standards
2
+
3
+ These rules are MANDATORY. Violations fail the task. No exceptions.
4
+
5
+ ---
6
+
7
+ ## 1. Environment Variables
8
+
9
+ ```
10
+ MANDATORY:
11
+ ├── Prefix ALL client-exposed env vars with VITE_ — Vite strips others
12
+ ├── Access via import.meta.env.VITE_* — NEVER process.env (that's Node, not Vite)
13
+ ├── Commit .env.development and .env.production — no secrets in either
14
+ ├── Add .env.local to .gitignore — developer-specific overrides only
15
+ └── NEVER put API keys or secrets in VITE_ vars — they're bundled into client code
16
+ ```
17
+
18
+ **BAD**
19
+ ```typescript
20
+ const url = process.env.API_URL; // undefined in browser
21
+ const key = import.meta.env.VITE_API_KEY; // secret exposed to client!
22
+ ```
23
+
24
+ **GOOD**
25
+ ```typescript
26
+ // .env.development
27
+ // VITE_API_BASE_URL=http://localhost:4000/api
28
+
29
+ // src/lib/constants.ts
30
+ export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:4000/api';
31
+ ```
32
+
33
+ ---
34
+
35
+ ## 2. Config File
36
+
37
+ ```
38
+ MANDATORY:
39
+ ├── vite.config.ts (TypeScript) — not .js
40
+ ├── Define resolve.alias for clean imports (@/ → src/)
41
+ ├── Configure server.proxy for API calls in dev — avoid CORS issues
42
+ ├── Set build.sourcemap to true for staging, false for production
43
+ └── Keep plugins list minimal — each plugin adds build time
44
+ ```
45
+
46
+ **GOOD**
47
+ ```typescript
48
+ import { defineConfig } from 'vite';
49
+ import react from '@vitejs/plugin-react';
50
+ import path from 'path';
51
+
52
+ export default defineConfig({
53
+ plugins: [react()],
54
+ resolve: {
55
+ alias: { '@': path.resolve(__dirname, 'src') },
56
+ },
57
+ server: {
58
+ proxy: {
59
+ '/api': { target: 'http://localhost:4000', changeOrigin: true },
60
+ },
61
+ },
62
+ });
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 3. Build Optimization
68
+
69
+ ```
70
+ MANDATORY:
71
+ ├── Code-split route-level components with React.lazy (or framework equivalent)
72
+ ├── Configure manualChunks for large vendor libs (react, lodash, chart libs)
73
+ ├── Check bundle size: npx vite-bundle-visualizer after build
74
+ ├── Tree-shaking: use named imports — not default imports from barrel files
75
+ └── Set chunk size warning limit in config if needed
76
+ ```
77
+
78
+ **GOOD** — manual chunks:
79
+ ```typescript
80
+ build: {
81
+ rollupOptions: {
82
+ output: {
83
+ manualChunks: {
84
+ vendor: ['react', 'react-dom'],
85
+ query: ['@tanstack/react-query'],
86
+ },
87
+ },
88
+ },
89
+ },
90
+ ```
91
+
92
+ ---
93
+
94
+ ## 4. Path Aliases and Imports
95
+
96
+ ```
97
+ MANDATORY:
98
+ ├── Configure @/ alias in vite.config.ts AND tsconfig.json (both must match)
99
+ ├── Use @/ for cross-feature imports — relative for same-directory
100
+ ├── NEVER use deep relative paths (../../../shared/lib/helpers)
101
+ └── Barrel exports (index.ts) for feature public APIs — not for internal modules
102
+ ```
103
+
104
+ **tsconfig.json** must match:
105
+ ```json
106
+ {
107
+ "compilerOptions": {
108
+ "baseUrl": ".",
109
+ "paths": { "@/*": ["src/*"] }
110
+ }
111
+ }
112
+ ```
113
+
114
+ ---
115
+
116
+ ## 5. Dev Server
117
+
118
+ ```
119
+ MANDATORY:
120
+ ├── Use server.proxy for backend API — NEVER hardcode localhost URLs in fetch calls
121
+ ├── Enable server.open only if desired — don't force it
122
+ ├── HMR should work — if it doesn't, check file naming (PascalCase components)
123
+ └── For HTTPS in dev: use @vitejs/plugin-basic-ssl — not self-signed certs
124
+ ```
125
+
126
+ ---
127
+
128
+ ## 6. Testing Integration
129
+
130
+ ```
131
+ MANDATORY:
132
+ ├── Use Vitest (not Jest) — it shares Vite's config and transform pipeline
133
+ ├── Configure test block in vite.config.ts or vitest.config.ts
134
+ ├── Set environment: 'jsdom' for component tests
135
+ ├── Use the same path aliases in tests — Vitest inherits from vite.config
136
+ └── Happy-dom is faster than jsdom — use if no compatibility issues
137
+ ```
138
+
139
+ **GOOD**
140
+ ```typescript
141
+ // vite.config.ts
142
+ export default defineConfig({
143
+ test: {
144
+ environment: 'jsdom',
145
+ globals: true,
146
+ setupFiles: './src/test-setup.ts',
147
+ },
148
+ });
149
+ ```
150
+
151
+ ---
152
+
153
+ ## 7. Anti-Patterns
154
+
155
+ ```
156
+ NEVER:
157
+ ├── process.env in client code (use import.meta.env)
158
+ ├── Secrets in VITE_ env vars — they're in the bundle
159
+ ├── Jest when Vitest is available — Vitest is faster and shares config
160
+ ├── Deep relative imports (../../..) — use @/ alias
161
+ ├── Importing entire libraries (import _ from 'lodash') — use named (import { debounce })
162
+ └── Disabling HMR to "fix" issues — find the root cause
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Vite Verification Checklist
168
+
169
+ - [ ] All client env vars prefixed with VITE_
170
+ - [ ] No secrets in VITE_ variables
171
+ - [ ] import.meta.env used — not process.env
172
+ - [ ] Path alias @/ configured in both vite.config.ts and tsconfig.json
173
+ - [ ] server.proxy configured for API calls
174
+ - [ ] Bundle analyzed — no oversized chunks
175
+ - [ ] Vitest configured (not Jest)
176
+ - [ ] .env.local in .gitignore