workflow-agent-cli 1.1.2
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/dist/chunk-VFN3BY56.js +120 -0
- package/dist/chunk-VFN3BY56.js.map +1 -0
- package/dist/chunk-X2NQJ2ZY.js +170 -0
- package/dist/chunk-X2NQJ2ZY.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1206 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/index.d.ts +8 -0
- package/dist/config/index.js +11 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/schema-CiJ4W7in.d.ts +97 -0
- package/dist/scripts/postinstall.d.ts +1 -0
- package/dist/scripts/postinstall.js +73 -0
- package/dist/scripts/postinstall.js.map +1 -0
- package/dist/validators/index.d.ts +16 -0
- package/dist/validators/index.js +17 -0
- package/dist/validators/index.js.map +1 -0
- package/package.json +80 -0
- package/templates/AGENT_EDITING_INSTRUCTIONS.md +887 -0
- package/templates/BRANCHING_STRATEGY.md +442 -0
- package/templates/COMPONENT_LIBRARY.md +611 -0
- package/templates/CUSTOM_SCOPE_TEMPLATE.md +228 -0
- package/templates/DEPLOYMENT_STRATEGY.md +509 -0
- package/templates/Guidelines.md +62 -0
- package/templates/LIBRARY_INVENTORY.md +615 -0
- package/templates/PROJECT_TEMPLATE_README.md +347 -0
- package/templates/SCOPE_CREATION_WORKFLOW.md +286 -0
- package/templates/SELF_IMPROVEMENT_MANDATE.md +298 -0
- package/templates/SINGLE_SOURCE_OF_TRUTH.md +492 -0
- package/templates/TESTING_STRATEGY.md +801 -0
- package/templates/_TEMPLATE_EXAMPLE.md +28 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
# Single Source of Truth
|
|
2
|
+
|
|
3
|
+
> **Purpose**: This document defines the canonical locations for all imperative services, utilities, and architectural patterns in the codebase. When making changes, always reference the correct source files to maintain consistency.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Supabase Clients](#supabase-clients)
|
|
10
|
+
2. [Authorization](#authorization)
|
|
11
|
+
3. [Types & Schemas](#types--schemas)
|
|
12
|
+
4. [Context Providers](#context-providers)
|
|
13
|
+
5. [Server Actions](#server-actions)
|
|
14
|
+
6. [Hooks](#hooks)
|
|
15
|
+
7. [Components](#components)
|
|
16
|
+
8. [Testing Infrastructure](#testing-infrastructure)
|
|
17
|
+
9. [Configuration](#configuration)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Supabase Clients
|
|
22
|
+
|
|
23
|
+
All Supabase client creation MUST go through these files. Never create clients directly.
|
|
24
|
+
|
|
25
|
+
| File | Purpose | Usage Context |
|
|
26
|
+
| ---------------------------- | ----------------------------- | -------------------------------------- |
|
|
27
|
+
| `lib/supabase/client.ts` | Browser client (singleton) | Client components, hooks |
|
|
28
|
+
| `lib/supabase/server.ts` | Server client (async cookies) | Server components, server actions |
|
|
29
|
+
| `lib/supabase/admin.ts` | Admin client (bypasses RLS) | Server actions needing elevated access |
|
|
30
|
+
| `lib/supabase/middleware.ts` | Session refresh | `middleware.ts` only |
|
|
31
|
+
|
|
32
|
+
### Usage Patterns
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
// ❌ WRONG - Never create clients directly
|
|
36
|
+
import { createClient } from '@supabase/supabase-js';
|
|
37
|
+
const supabase = createClient(url, key);
|
|
38
|
+
|
|
39
|
+
// ✅ CORRECT - Use the appropriate helper
|
|
40
|
+
// In client components:
|
|
41
|
+
import { getSupabaseClient } from '@/lib/supabase/client';
|
|
42
|
+
const supabase = getSupabaseClient();
|
|
43
|
+
|
|
44
|
+
// In server actions/components:
|
|
45
|
+
import { createServerClient } from '@/lib/supabase/server';
|
|
46
|
+
const supabase = await createServerClient();
|
|
47
|
+
|
|
48
|
+
// For admin operations (bypasses RLS):
|
|
49
|
+
import { createAdminClient } from '@/lib/supabase/admin';
|
|
50
|
+
const supabase = createAdminClient();
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Authorization
|
|
56
|
+
|
|
57
|
+
Authorization logic is centralized in these files. Never implement permission checks inline.
|
|
58
|
+
|
|
59
|
+
| File | Purpose | Usage Context |
|
|
60
|
+
| ------------------------------- | ----------------------------------------- | ----------------- |
|
|
61
|
+
| `utils/authorization.ts` | Role constants, hierarchy, client helpers | Client components |
|
|
62
|
+
| `utils/authorization.server.ts` | Server-side verification functions | Server actions |
|
|
63
|
+
| `hooks/useAuthorization.tsx` | React hook for permission checks | Client components |
|
|
64
|
+
|
|
65
|
+
### Role Constants (from `utils/authorization.ts`)
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// Role types
|
|
69
|
+
export type OrgRole = 'super_admin' | 'owner' | 'admin' | 'manager' | 'developer' | 'viewer';
|
|
70
|
+
|
|
71
|
+
// Role hierarchy (higher index = more permissions)
|
|
72
|
+
export const ROLE_HIERARCHY: OrgRole[] = [
|
|
73
|
+
'viewer',
|
|
74
|
+
'developer',
|
|
75
|
+
'manager',
|
|
76
|
+
'admin',
|
|
77
|
+
'owner',
|
|
78
|
+
'super_admin',
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
// Role groups for permission checks
|
|
82
|
+
export const ADMIN_ROLES: OrgRole[] = ['super_admin', 'owner', 'admin'];
|
|
83
|
+
export const PRIVILEGED_ROLES: OrgRole[] = ['super_admin', 'owner', 'admin', 'manager'];
|
|
84
|
+
export const CONTRIBUTOR_ROLES: OrgRole[] = [
|
|
85
|
+
'super_admin',
|
|
86
|
+
'owner',
|
|
87
|
+
'admin',
|
|
88
|
+
'manager',
|
|
89
|
+
'developer',
|
|
90
|
+
];
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Server-Side Authorization (from `utils/authorization.server.ts`)
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import {
|
|
97
|
+
verifyBoardAccess,
|
|
98
|
+
verifyTaskAccess,
|
|
99
|
+
verifyWorkspaceAccess,
|
|
100
|
+
requireAdminAccess,
|
|
101
|
+
requirePrivilegedAccess,
|
|
102
|
+
requireContributorAccess,
|
|
103
|
+
} from '@/utils/authorization.server';
|
|
104
|
+
|
|
105
|
+
// In server actions - always verify access FIRST
|
|
106
|
+
export async function getTask(taskId: string) {
|
|
107
|
+
const access = await verifyTaskAccess(taskId);
|
|
108
|
+
if (!access.hasAccess) {
|
|
109
|
+
return { data: null, error: access.error || 'Access denied' };
|
|
110
|
+
}
|
|
111
|
+
// ... proceed with data access
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// For role-restricted operations
|
|
115
|
+
export async function deleteBoard(boardId: string) {
|
|
116
|
+
const { profile } = await requireAdminAccess(); // Throws if not admin
|
|
117
|
+
// ... proceed with deletion
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Client-Side Authorization (using `useAuthorization` hook)
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { useAuthorization } from "@/hooks/useAuthorization";
|
|
125
|
+
|
|
126
|
+
function TaskActions({ task }) {
|
|
127
|
+
const { can, currentUserRole, isRestricted } = useAuthorization();
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<>
|
|
131
|
+
{can.editTask() && <Button onClick={handleEdit}>Edit</Button>}
|
|
132
|
+
{can.deleteTask() && <Button onClick={handleDelete}>Delete</Button>}
|
|
133
|
+
{can.manageUsers() && <Button onClick={handleManage}>Manage</Button>}
|
|
134
|
+
</>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Types & Schemas
|
|
142
|
+
|
|
143
|
+
### Type Definitions
|
|
144
|
+
|
|
145
|
+
| File | Contents | When to Update |
|
|
146
|
+
| ------------------- | ------------------------------- | ----------------------------------------- |
|
|
147
|
+
| `types/index.ts` | Application types (camelCase) | Adding new entities, changing data shapes |
|
|
148
|
+
| `types/supabase.ts` | Database types (auto-generated) | After running `pnpm supabase:gen` |
|
|
149
|
+
|
|
150
|
+
### Key Types in `types/index.ts`
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Entity types
|
|
154
|
+
export interface Task { id: string; title: string; ticketId: string; ... }
|
|
155
|
+
export interface Board { id: string; name: string; columns: Column[]; ... }
|
|
156
|
+
export interface Sprint { id: string; name: string; startDate: string; ... }
|
|
157
|
+
export interface Epic { id: string; title: string; color: string; ... }
|
|
158
|
+
export interface Organization { id: string; name: string; slug: string; ... }
|
|
159
|
+
export interface Team { id: string; name: string; members?: TeamMember[]; ... }
|
|
160
|
+
export interface Project { id: string; name: string; prefix: string; ... }
|
|
161
|
+
|
|
162
|
+
// Role types
|
|
163
|
+
export type UserRole = "super_admin" | "owner" | "admin" | "manager" | "developer" | "viewer";
|
|
164
|
+
export type OrgRole = UserRole;
|
|
165
|
+
export type TeamRole = "admin" | "member" | "viewer";
|
|
166
|
+
|
|
167
|
+
// Status/Priority enums
|
|
168
|
+
export type TaskStatus = "backlog" | "todo" | "in_progress" | "in_review" | "done" | "blocked" | "cancelled";
|
|
169
|
+
export type Priority = "low" | "medium" | "high" | "critical";
|
|
170
|
+
export type TaskType = "story" | "task" | "bug" | "epic";
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Zod Schemas
|
|
174
|
+
|
|
175
|
+
| Location | Purpose |
|
|
176
|
+
| ----------------------------- | -------------------------------------- |
|
|
177
|
+
| `lib/validations/*.schema.ts` | Validation schemas with type inference |
|
|
178
|
+
| `lib/validations/index.ts` | Central export of all schemas |
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// lib/validations/task.schema.ts
|
|
182
|
+
import { z } from 'zod';
|
|
183
|
+
|
|
184
|
+
export const TaskSchema = z.object({
|
|
185
|
+
id: z.string().uuid(),
|
|
186
|
+
ticketId: z.string().regex(/^[A-Z]{1,6}-\d{4}$/),
|
|
187
|
+
title: z.string().min(1).max(255),
|
|
188
|
+
priority: z.enum(['low', 'medium', 'high', 'critical']),
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
export type Task = z.infer<typeof TaskSchema>;
|
|
192
|
+
|
|
193
|
+
// lib/validations/index.ts
|
|
194
|
+
export { TaskSchema, type Task } from './task.schema';
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Context Providers
|
|
200
|
+
|
|
201
|
+
### Current Structure (Monolithic)
|
|
202
|
+
|
|
203
|
+
Currently, all providers are in `app/providers.tsx` (2500+ lines). This file exports:
|
|
204
|
+
|
|
205
|
+
| Context | Hook | Purpose |
|
|
206
|
+
| ---------------------- | -------------------- | --------------------------------- |
|
|
207
|
+
| `AuthContext` | `useAuth()` | User authentication state |
|
|
208
|
+
| `OrganizationContext` | `useOrganization()` | Current org, members, permissions |
|
|
209
|
+
| `NotificationsContext` | `useNotifications()` | Notification state and actions |
|
|
210
|
+
| `TeamsContext` | `useTeams()` | Team membership and management |
|
|
211
|
+
| `PreferencesContext` | `usePreferences()` | User preferences |
|
|
212
|
+
| `ImpersonationContext` | `useImpersonation()` | Super admin impersonation |
|
|
213
|
+
| `ProjectsContext` | `useProjects()` | Project management |
|
|
214
|
+
|
|
215
|
+
### Target Structure (Modular)
|
|
216
|
+
|
|
217
|
+
The providers should be refactored into `app/providers/`:
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
app/providers/
|
|
221
|
+
├── index.tsx # Composite provider (exports Providers)
|
|
222
|
+
├── AuthProvider.tsx # Authentication context
|
|
223
|
+
├── OrganizationProvider.tsx # Organization context
|
|
224
|
+
├── NotificationProvider.tsx # Notifications context
|
|
225
|
+
├── PreferencesProvider.tsx # User preferences context
|
|
226
|
+
├── TeamsProvider.tsx # Teams context
|
|
227
|
+
├── ImpersonationProvider.tsx # Impersonation context
|
|
228
|
+
├── ProjectsProvider.tsx # Projects context
|
|
229
|
+
└── types.ts # Shared provider types
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Usage Pattern
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
// Always import hooks from the providers module
|
|
236
|
+
import { useAuth, useOrganization, useNotifications } from '@/app/providers';
|
|
237
|
+
|
|
238
|
+
function MyComponent() {
|
|
239
|
+
const { user, loading } = useAuth();
|
|
240
|
+
const { organization, canManageUsers } = useOrganization();
|
|
241
|
+
const { notifications, markAsRead } = useNotifications();
|
|
242
|
+
// ...
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Server Actions
|
|
249
|
+
|
|
250
|
+
All server actions live in `app/actions/` with a central export.
|
|
251
|
+
|
|
252
|
+
| File | Purpose |
|
|
253
|
+
| ------------------------------- | ----------------------------- |
|
|
254
|
+
| `app/actions/index.ts` | Central export of all actions |
|
|
255
|
+
| `app/actions/tasks.ts` | Task CRUD operations |
|
|
256
|
+
| `app/actions/boards.ts` | Board management |
|
|
257
|
+
| `app/actions/sprints.ts` | Sprint management |
|
|
258
|
+
| `app/actions/epics.ts` | Epic management |
|
|
259
|
+
| `app/actions/comments.ts` | Comment operations |
|
|
260
|
+
| `app/actions/organizations.ts` | Organization management |
|
|
261
|
+
| `app/actions/teams.ts` | Team operations |
|
|
262
|
+
| `app/actions/projects.ts` | Project management |
|
|
263
|
+
| `app/actions/projectMembers.ts` | Project membership |
|
|
264
|
+
| `app/actions/notifications.ts` | Notification operations |
|
|
265
|
+
| `app/actions/invites.ts` | Invite system |
|
|
266
|
+
| `app/actions/profile.ts` | User profile operations |
|
|
267
|
+
| `app/actions/impersonation.ts` | Super admin impersonation |
|
|
268
|
+
| `app/actions/userManagement.ts` | User administration |
|
|
269
|
+
|
|
270
|
+
### Action Pattern
|
|
271
|
+
|
|
272
|
+
Every action file MUST:
|
|
273
|
+
|
|
274
|
+
1. Start with `'use server'` directive
|
|
275
|
+
2. Verify authorization before data access
|
|
276
|
+
3. Return `{ data, error }` or `{ success, error }` pattern
|
|
277
|
+
4. Transform snake_case DB fields to camelCase
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
'use server';
|
|
281
|
+
|
|
282
|
+
import { createServerClient } from '@/lib/supabase/server';
|
|
283
|
+
import { verifyBoardAccess } from '@/utils/authorization.server';
|
|
284
|
+
import { revalidatePath } from 'next/cache';
|
|
285
|
+
|
|
286
|
+
export async function getTasks(boardId: string) {
|
|
287
|
+
const access = await verifyBoardAccess(boardId);
|
|
288
|
+
if (!access.hasAccess) {
|
|
289
|
+
return { data: null, error: access.error };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const supabase = await createServerClient();
|
|
293
|
+
const { data, error } = await supabase.from('tasks').select('*').eq('board_id', boardId);
|
|
294
|
+
|
|
295
|
+
if (error) return { data: null, error: error.message };
|
|
296
|
+
|
|
297
|
+
return { data: data.map(transformTask), error: null };
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Hooks
|
|
304
|
+
|
|
305
|
+
Custom React hooks live in `hooks/`.
|
|
306
|
+
|
|
307
|
+
| Hook | Purpose | File |
|
|
308
|
+
| ------------------ | -------------------------------- | ---------------------------- |
|
|
309
|
+
| `useAuthorization` | Permission checking | `hooks/useAuthorization.tsx` |
|
|
310
|
+
| `useTheme` | Color theme management | `hooks/useTheme.tsx` |
|
|
311
|
+
| `useRealtime` | Supabase real-time subscriptions | `hooks/useRealtime.tsx` |
|
|
312
|
+
| `useMediaQuery` | Responsive breakpoints | `hooks/useMediaQuery.tsx` |
|
|
313
|
+
| `useMobile` | Mobile device detection | `hooks/useMobile.tsx` |
|
|
314
|
+
| `useDebounce` | Debounced values | `hooks/useDebounce.tsx` |
|
|
315
|
+
| `useLocalStorage` | Persistent local state | `hooks/useLocalStorage.tsx` |
|
|
316
|
+
|
|
317
|
+
### Hook Pattern
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
321
|
+
|
|
322
|
+
export function useHookName(param: string) {
|
|
323
|
+
const [data, setData] = useState<DataType | null>(null);
|
|
324
|
+
const [loading, setLoading] = useState(true);
|
|
325
|
+
const [error, setError] = useState<string | null>(null);
|
|
326
|
+
|
|
327
|
+
useEffect(() => {
|
|
328
|
+
// Effect logic
|
|
329
|
+
}, [param]);
|
|
330
|
+
|
|
331
|
+
const action = useCallback(() => {
|
|
332
|
+
// Action logic
|
|
333
|
+
}, []);
|
|
334
|
+
|
|
335
|
+
return { data, loading, error, action };
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Components
|
|
342
|
+
|
|
343
|
+
> **📚 Canonical Reference**: See `guidelines/COMPONENT_LIBRARY.md` for complete component documentation, usage patterns, and decision tree.
|
|
344
|
+
|
|
345
|
+
### Component Library Resources
|
|
346
|
+
|
|
347
|
+
| Resource | Location | Purpose |
|
|
348
|
+
| ----------------------- | --------------------------------- | --------------------------------------------------------- |
|
|
349
|
+
| Component Library Guide | `guidelines/COMPONENT_LIBRARY.md` | Full component inventory, usage patterns, audit checklist |
|
|
350
|
+
| Design Tokens | `lib/design-tokens.ts` | Centralized colors, sizes, gradients |
|
|
351
|
+
| Feature Flags | `lib/feature-flags.ts` | Component rollout control |
|
|
352
|
+
| Storybook | `pnpm storybook` (localhost:6006) | Visual component documentation |
|
|
353
|
+
|
|
354
|
+
### Directory Structure
|
|
355
|
+
|
|
356
|
+
| Directory | Purpose |
|
|
357
|
+
| ------------------------- | --------------------------------- |
|
|
358
|
+
| `components/` | Feature components |
|
|
359
|
+
| `components/ui/` | Base UI components (shadcn) |
|
|
360
|
+
| `components/auth/` | Authentication-related components |
|
|
361
|
+
| `components/settings/` | Settings page components |
|
|
362
|
+
| `components/super-admin/` | Super admin panel components |
|
|
363
|
+
| `components/skeletons/` | Loading skeleton components |
|
|
364
|
+
| `.storybook/` | Storybook configuration |
|
|
365
|
+
|
|
366
|
+
### Component Testing
|
|
367
|
+
|
|
368
|
+
| Pattern | Location |
|
|
369
|
+
| --------------- | --------------------------------- |
|
|
370
|
+
| Component tests | `components/*.test.tsx` |
|
|
371
|
+
| Snapshot tests | `components/__snapshots__/*.snap` |
|
|
372
|
+
| Stories | `components/*.stories.tsx` |
|
|
373
|
+
|
|
374
|
+
### Key Components
|
|
375
|
+
|
|
376
|
+
| Component | Purpose |
|
|
377
|
+
| ----------------------- | ------------------------------------- |
|
|
378
|
+
| `Dashboard.tsx` | Main dashboard layout |
|
|
379
|
+
| `DashboardApp.tsx` | Dashboard application wrapper |
|
|
380
|
+
| `Header.tsx` | Top navigation header |
|
|
381
|
+
| `Sidebar.tsx` | Navigation sidebar |
|
|
382
|
+
| `KanbanBoardView.tsx` | Kanban board display |
|
|
383
|
+
| `TableView.tsx` | Table view for tasks |
|
|
384
|
+
| `TaskCard.tsx` | Task card component |
|
|
385
|
+
| `TaskDialog.tsx` | Task creation/editing dialog |
|
|
386
|
+
| `TaskDetailPanel.tsx` | Task detail side panel |
|
|
387
|
+
| `SprintDialog.tsx` | Sprint management dialog |
|
|
388
|
+
| `BoardDialog.tsx` | Board configuration |
|
|
389
|
+
| `CommentsSection.tsx` | Task comments |
|
|
390
|
+
| `NotificationPanel.tsx` | Notifications dropdown |
|
|
391
|
+
| `ErrorBoundary.tsx` | Error boundary wrapper |
|
|
392
|
+
| `PriorityBadge.tsx` | Priority indicator badge |
|
|
393
|
+
| `StatusBadge.tsx` | Status indicator badge (feature flag) |
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## Testing Infrastructure
|
|
398
|
+
|
|
399
|
+
### Unit Testing
|
|
400
|
+
|
|
401
|
+
| File/Directory | Purpose |
|
|
402
|
+
| -------------------------- | -------------------------------------------- |
|
|
403
|
+
| `vitest.config.ts` | Vitest configuration (bail: 1 for fail-fast) |
|
|
404
|
+
| `test/setup.ts` | Test setup (mocks, MSW) |
|
|
405
|
+
| `test/fixtures.tsx` | Mock data factories |
|
|
406
|
+
| `lib/test-utils/` | Test utilities |
|
|
407
|
+
| `lib/test-utils/handlers/` | MSW API handlers |
|
|
408
|
+
| `lib/test-utils/db.ts` | Mock database |
|
|
409
|
+
|
|
410
|
+
### Component Testing
|
|
411
|
+
|
|
412
|
+
| File/Directory | Purpose |
|
|
413
|
+
| --------------------------- | -------------------------------------------- |
|
|
414
|
+
| `components/*.test.tsx` | Component unit tests |
|
|
415
|
+
| `components/__snapshots__/` | Snapshot test files |
|
|
416
|
+
| `lib/*.test.ts` | Utility tests (design tokens, feature flags) |
|
|
417
|
+
|
|
418
|
+
### E2E Testing
|
|
419
|
+
|
|
420
|
+
| File/Directory | Purpose |
|
|
421
|
+
| ---------------------------- | ------------------------ |
|
|
422
|
+
| `playwright.config.ts` | Playwright configuration |
|
|
423
|
+
| `e2e/` | E2E test files |
|
|
424
|
+
| `e2e/critical-tests.spec.ts` | Critical path tests |
|
|
425
|
+
| `e2e/impersonation.spec.ts` | Impersonation flow tests |
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## Configuration
|
|
430
|
+
|
|
431
|
+
### Application Config
|
|
432
|
+
|
|
433
|
+
| File | Purpose |
|
|
434
|
+
| ---------------- | --------------------------------- |
|
|
435
|
+
| `next.config.ts` | Next.js configuration |
|
|
436
|
+
| `middleware.ts` | Route middleware (auth redirects) |
|
|
437
|
+
| `tsconfig.json` | TypeScript configuration |
|
|
438
|
+
| `vercel.json` | Vercel deployment config |
|
|
439
|
+
|
|
440
|
+
### Styling Config
|
|
441
|
+
|
|
442
|
+
| File | Purpose |
|
|
443
|
+
| -------------------- | ------------------------------- |
|
|
444
|
+
| `postcss.config.mjs` | PostCSS/Tailwind config |
|
|
445
|
+
| `app/globals.css` | Global CSS variables and styles |
|
|
446
|
+
|
|
447
|
+
### Database
|
|
448
|
+
|
|
449
|
+
| Directory | Purpose |
|
|
450
|
+
| ---------------------- | --------------------- |
|
|
451
|
+
| `supabase/migrations/` | SQL migration files |
|
|
452
|
+
| `supabase/config.toml` | Supabase local config |
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## Quick Reference: Import Paths
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
// Supabase clients
|
|
460
|
+
import { getSupabaseClient } from '@/lib/supabase/client';
|
|
461
|
+
import { createServerClient } from '@/lib/supabase/server';
|
|
462
|
+
import { createAdminClient } from '@/lib/supabase/admin';
|
|
463
|
+
|
|
464
|
+
// Authorization
|
|
465
|
+
import { ROLE_HIERARCHY, ADMIN_ROLES } from '@/utils/authorization';
|
|
466
|
+
import { verifyBoardAccess, requireAdminAccess } from '@/utils/authorization.server';
|
|
467
|
+
import { useAuthorization } from '@/hooks/useAuthorization';
|
|
468
|
+
|
|
469
|
+
// Types
|
|
470
|
+
import type { Task, Board, Sprint, Organization } from '@/types';
|
|
471
|
+
import type { Database } from '@/types/supabase';
|
|
472
|
+
|
|
473
|
+
// Providers/Context
|
|
474
|
+
import { useAuth, useOrganization, useTeams } from '@/app/providers';
|
|
475
|
+
|
|
476
|
+
// UI Components
|
|
477
|
+
import { Button, Input, Dialog } from '@/components/ui';
|
|
478
|
+
|
|
479
|
+
// Schemas
|
|
480
|
+
import { TaskSchema, CreateTaskSchema } from '@/lib/validations';
|
|
481
|
+
|
|
482
|
+
// Test utilities
|
|
483
|
+
import { mockTasks, createMockTask, seedTasks } from '@test/fixtures';
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
## Related Documents
|
|
489
|
+
|
|
490
|
+
- [AGENT_EDITING_INSTRUCTIONS.md](AGENT_EDITING_INSTRUCTIONS.md) - Editing rules and patterns
|
|
491
|
+
- [LIBRARY_INVENTORY.md](LIBRARY_INVENTORY.md) - Approved dependencies
|
|
492
|
+
- [TESTING_STRATEGY.md](TESTING_STRATEGY.md) - Testing patterns
|