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,887 @@
|
|
|
1
|
+
# Agent Editing Instructions
|
|
2
|
+
|
|
3
|
+
> **Purpose**: This document defines the rules and patterns that AI agents (GitHub Copilot, Claude, etc.) must follow when making edits to this codebase. Following these guidelines ensures consistency, prevents regressions, and maintains architectural integrity.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Implementation Plans](#implementation-plans)
|
|
10
|
+
2. [Required File Checklists by Change Type](#required-file-checklists-by-change-type)
|
|
11
|
+
3. [Coding Standards](#coding-standards)
|
|
12
|
+
4. [Architecture Rules](#architecture-rules)
|
|
13
|
+
5. [Library Usage Policy](#library-usage-policy)
|
|
14
|
+
6. [Testing Requirements](#testing-requirements)
|
|
15
|
+
7. [PR Workflow](#pr-workflow)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Implementation Plans
|
|
20
|
+
|
|
21
|
+
### ⚠️ MANDATORY: Create Branch BEFORE Implementation
|
|
22
|
+
|
|
23
|
+
**Before starting ANY implementation plan work, you MUST:**
|
|
24
|
+
|
|
25
|
+
1. Ensure you are on `main` and it is up to date:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git checkout main
|
|
29
|
+
git pull origin main
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
2. Create a new feature branch:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git checkout -b <type>/<scope>/<short-description>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
3. Only THEN begin creating the implementation plan and making code changes
|
|
39
|
+
|
|
40
|
+
> 🚫 **NEVER** start implementing a plan while on `main`. All implementation work MUST be on a dedicated feature branch.
|
|
41
|
+
|
|
42
|
+
### When to Create an Implementation Plan
|
|
43
|
+
|
|
44
|
+
Create an implementation plan for any work that:
|
|
45
|
+
|
|
46
|
+
- Touches **more than 3 files**
|
|
47
|
+
- Implements a **new feature** (not a simple bugfix)
|
|
48
|
+
- Requires **multiple related changes** across the codebase
|
|
49
|
+
- Will be completed over **multiple sessions**
|
|
50
|
+
- Involves **database migrations** or schema changes
|
|
51
|
+
|
|
52
|
+
### File Location and Naming
|
|
53
|
+
|
|
54
|
+
| Type | Location | Naming Convention |
|
|
55
|
+
| --------------- | ------------------ | ---------------------------- |
|
|
56
|
+
| Active plans | `plans/` | `<FEATURE_NAME>_PLAN.md` |
|
|
57
|
+
| Completed plans | `plans/completed/` | Same name, moved after merge |
|
|
58
|
+
|
|
59
|
+
**Naming examples:**
|
|
60
|
+
|
|
61
|
+
- `plans/DUE_DATE_REMINDERS_PLAN.md`
|
|
62
|
+
- `plans/TEAM_PERMISSIONS_PLAN.md`
|
|
63
|
+
- `plans/NOTIFICATION_REFACTOR_PLAN.md`
|
|
64
|
+
|
|
65
|
+
### Required Structure
|
|
66
|
+
|
|
67
|
+
Every implementation plan MUST follow this template:
|
|
68
|
+
|
|
69
|
+
```markdown
|
|
70
|
+
# Implementation Plan: <Feature Name>
|
|
71
|
+
|
|
72
|
+
> **Status**: 🟡 In Progress | 🟢 Complete | 🔴 Blocked
|
|
73
|
+
> **Created**: YYYY-MM-DD
|
|
74
|
+
> **Last Updated**: YYYY-MM-DD
|
|
75
|
+
> **Branch**: `feature/<scope>/<description>`
|
|
76
|
+
|
|
77
|
+
## Overview
|
|
78
|
+
|
|
79
|
+
Brief description of what is being implemented and why.
|
|
80
|
+
|
|
81
|
+
## Checklist
|
|
82
|
+
|
|
83
|
+
### Phase 1: <Phase Name>
|
|
84
|
+
|
|
85
|
+
- [ ] Task description — `path/to/file.ts`
|
|
86
|
+
- [ ] Task description — `path/to/file.ts`
|
|
87
|
+
|
|
88
|
+
### Phase 2: <Phase Name>
|
|
89
|
+
|
|
90
|
+
- [ ] Task description — `path/to/file.ts`
|
|
91
|
+
- [ ] Task description — `path/to/file.ts`
|
|
92
|
+
|
|
93
|
+
### Testing
|
|
94
|
+
|
|
95
|
+
- [ ] Unit tests added
|
|
96
|
+
- [ ] E2E tests added (if applicable)
|
|
97
|
+
- [ ] Manual testing completed
|
|
98
|
+
|
|
99
|
+
### Documentation
|
|
100
|
+
|
|
101
|
+
- [ ] Types updated in `types/index.ts`
|
|
102
|
+
- [ ] LIBRARY_INVENTORY.md updated (if new deps)
|
|
103
|
+
|
|
104
|
+
## Notes
|
|
105
|
+
|
|
106
|
+
Any decisions, blockers, or context for future reference.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Progress Update Rules
|
|
110
|
+
|
|
111
|
+
**Agent MUST update the implementation plan as work progresses:**
|
|
112
|
+
|
|
113
|
+
1. **Mark items complete** — Change `- [ ]` to `- [x]` immediately after completing each task
|
|
114
|
+
2. **Update "Last Updated" date** — Refresh timestamp on every modification
|
|
115
|
+
3. **Update "Status"** — Change from 🟡 to 🟢 when all items complete, or 🔴 if blocked
|
|
116
|
+
4. **Add notes** — Document any deviations, decisions, or blockers in the Notes section
|
|
117
|
+
|
|
118
|
+
### Pushing Changes After Implementation
|
|
119
|
+
|
|
120
|
+
**After completing implementation work, you MUST push to the feature branch:**
|
|
121
|
+
|
|
122
|
+
1. **Verify all changes are ready:**
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
pnpm build # Must pass
|
|
126
|
+
pnpm lint # Must be clean
|
|
127
|
+
pnpm test # Must pass
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
2. **Stage and commit changes:**
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
git add .
|
|
134
|
+
git commit -m "<type>(<scope>): <description>"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
3. **Push to the feature branch:**
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
git push origin <branch-name>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
4. **Create a Pull Request** for review and merge to `main`
|
|
144
|
+
|
|
145
|
+
> ⚠️ **IMPORTANT**: Never push directly to `main`. Always push to your feature branch and create a PR.
|
|
146
|
+
|
|
147
|
+
### Auto-Cleanup Rules
|
|
148
|
+
|
|
149
|
+
| Trigger | Action |
|
|
150
|
+
| ---------------------------- | --------------------------------------------- |
|
|
151
|
+
| All checklist items complete | Update status to 🟢 Complete |
|
|
152
|
+
| PR merged to `main` | Move file from `plans/` to `plans/completed/` |
|
|
153
|
+
| 30 days after completion | Delete from `plans/completed/` |
|
|
154
|
+
| Major release | Archive or delete all completed plans |
|
|
155
|
+
|
|
156
|
+
**Cleanup command** (run periodically):
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Move completed plans older than 30 days to trash
|
|
160
|
+
find plans/completed -name "*.md" -mtime +30 -delete
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Example Workflow
|
|
164
|
+
|
|
165
|
+
1. **Start work**: Create `plans/REMINDER_NOTIFICATIONS_PLAN.md`
|
|
166
|
+
2. **During work**: Update checkboxes as each task completes
|
|
167
|
+
3. **Complete work**: Status changes to 🟢, create PR
|
|
168
|
+
4. **PR merged**: Move to `plans/completed/REMINDER_NOTIFICATIONS_PLAN.md`
|
|
169
|
+
5. **30 days later**: Auto-delete or manual cleanup
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Required File Checklists by Change Type
|
|
174
|
+
|
|
175
|
+
Before completing any change, verify that ALL required files have been touched. This prevents incomplete implementations and data drift.
|
|
176
|
+
|
|
177
|
+
### New Server Action
|
|
178
|
+
|
|
179
|
+
| File | Action Required |
|
|
180
|
+
| ------------------------------------ | ------------------------------------------------------- |
|
|
181
|
+
| `app/actions/<entity>.ts` | Create/update with `'use server'` directive first line |
|
|
182
|
+
| `app/actions/index.ts` | Export new action module: `export * from "./<entity>";` |
|
|
183
|
+
| `types/index.ts` | Add/update TypeScript interfaces for the entity |
|
|
184
|
+
| `lib/validations/<entity>.schema.ts` | Add Zod validation schema |
|
|
185
|
+
| `lib/validations/index.ts` | Export new schema |
|
|
186
|
+
|
|
187
|
+
### New Component
|
|
188
|
+
|
|
189
|
+
| File | Action Required |
|
|
190
|
+
| ------------------------------------- | ----------------------------------------------- |
|
|
191
|
+
| `components/<ComponentName>.tsx` | Create with PascalCase filename |
|
|
192
|
+
| `components/<ComponentName>.test.tsx` | Add unit test (required for complex components) |
|
|
193
|
+
| `types/index.ts` | Add prop interface if types are shared |
|
|
194
|
+
|
|
195
|
+
### New UI Component (Component Library Addition)
|
|
196
|
+
|
|
197
|
+
> **⚠️ MANDATORY**: Before creating ANY new UI component, complete the [UI Component Audit](#ui-component-audit).
|
|
198
|
+
|
|
199
|
+
| File | Action Required |
|
|
200
|
+
| ----------------------------------------------------- | --------------------------------------------------- |
|
|
201
|
+
| Audit | Complete UI Component Audit checklist below |
|
|
202
|
+
| `components/ui/<name>.tsx` or `components/<Name>.tsx` | Create component using design tokens |
|
|
203
|
+
| `components/<Name>.stories.tsx` | Create Storybook story with Controls |
|
|
204
|
+
| `components/<Name>.test.tsx` | Add unit tests with snapshot tests for all variants |
|
|
205
|
+
| `lib/feature-flags.ts` | Add feature flag for rollout control |
|
|
206
|
+
| `.env.example` | Document new `NEXT_PUBLIC_FEATURE_*` variable |
|
|
207
|
+
| `guidelines/COMPONENT_LIBRARY.md` | Add component to appropriate section |
|
|
208
|
+
|
|
209
|
+
### Modifying Existing UI Component
|
|
210
|
+
|
|
211
|
+
| File | Action Required |
|
|
212
|
+
| --------------------------------- | ------------------------------------------------------ |
|
|
213
|
+
| `guidelines/COMPONENT_LIBRARY.md` | Review current documentation |
|
|
214
|
+
| Component file | Make changes using design tokens |
|
|
215
|
+
| Storybook story | Update/add story for new variant |
|
|
216
|
+
| Test file | Add tests for new behavior, update snapshots if needed |
|
|
217
|
+
|
|
218
|
+
### New Database Table/Column
|
|
219
|
+
|
|
220
|
+
| File | Action Required |
|
|
221
|
+
| ----------------------------------------- | ------------------------------------------------------ |
|
|
222
|
+
| `supabase/migrations/YYYYMMDD_<name>.sql` | Create migration file |
|
|
223
|
+
| `types/supabase.ts` | Regenerate: `pnpm supabase:gen` |
|
|
224
|
+
| `types/index.ts` | Add application-level TypeScript interface (camelCase) |
|
|
225
|
+
| `app/actions/<entity>.ts` | Add CRUD server actions |
|
|
226
|
+
| `lib/validations/<entity>.schema.ts` | Add Zod validation schema |
|
|
227
|
+
|
|
228
|
+
### Migration Execution Policy
|
|
229
|
+
|
|
230
|
+
> **⚠️ MANDATORY RULE**: All database migrations MUST be run on BOTH dev and prod databases.
|
|
231
|
+
|
|
232
|
+
**Execution Order:**
|
|
233
|
+
|
|
234
|
+
1. **Run on DEV first** — Always run migrations on the development database first
|
|
235
|
+
2. **If DEV fails, STOP** — Fix the issue and retry on dev before proceeding
|
|
236
|
+
3. **Never proceed to PROD with a failing dev migration**
|
|
237
|
+
4. **Verify status on both databases** after completion
|
|
238
|
+
|
|
239
|
+
**Required Steps:**
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
# Step 1: Run migration on DEV
|
|
243
|
+
./scripts/db.sh link dev
|
|
244
|
+
./scripts/db.sh migrate
|
|
245
|
+
./scripts/db.sh status # Verify success
|
|
246
|
+
|
|
247
|
+
# Step 2: Only if DEV succeeds, run on PROD
|
|
248
|
+
./scripts/db.sh link prod
|
|
249
|
+
./scripts/db.sh migrate
|
|
250
|
+
./scripts/db.sh status # Verify success
|
|
251
|
+
|
|
252
|
+
# OR use the combined command:
|
|
253
|
+
./scripts/db.sh migrate-both
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Failure Handling:**
|
|
257
|
+
|
|
258
|
+
| Scenario | Action |
|
|
259
|
+
| ------------------------ | ---------------------------------------------------------------------- |
|
|
260
|
+
| DEV migration fails | STOP. Fix the migration SQL, then retry `./scripts/db.sh migrate-both` |
|
|
261
|
+
| DEV succeeds, PROD fails | Investigate PROD-specific issue. May need manual intervention. |
|
|
262
|
+
| Both succeed | Verify with `./scripts/db.sh status` on both environments |
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
### New Hook
|
|
267
|
+
|
|
268
|
+
| File | Action Required |
|
|
269
|
+
| ------------------------------ | --------------------------------------------- |
|
|
270
|
+
| `hooks/use<HookName>.tsx` | Create with `use` prefix + PascalCase |
|
|
271
|
+
| `hooks/use<HookName>.test.tsx` | Add unit test (required for hooks with logic) |
|
|
272
|
+
| `types/index.ts` | Add return type interfaces if complex |
|
|
273
|
+
|
|
274
|
+
### New Library Addition
|
|
275
|
+
|
|
276
|
+
| File | Action Required |
|
|
277
|
+
| --------------------------------- | ------------------------------------------ |
|
|
278
|
+
| `package.json` | Add dependency (only after approval) |
|
|
279
|
+
| `guidelines/LIBRARY_INVENTORY.md` | Document: name, version, purpose, patterns |
|
|
280
|
+
| Relevant source file | Add usage example |
|
|
281
|
+
|
|
282
|
+
### New Feature (Full)
|
|
283
|
+
|
|
284
|
+
Combine all applicable checklists above, plus:
|
|
285
|
+
|
|
286
|
+
| File | Action Required |
|
|
287
|
+
| ------------------------- | -------------------------------------------- |
|
|
288
|
+
| `plans/<FEATURE>_PLAN.md` | Create implementation plan with checklist |
|
|
289
|
+
| `e2e/<feature>.spec.ts` | Add E2E test for critical paths |
|
|
290
|
+
| Component files | Add `data-testid` attributes for testability |
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## UI Component Audit
|
|
295
|
+
|
|
296
|
+
> **MANDATORY**: Complete this audit before creating or modifying ANY UI component.
|
|
297
|
+
|
|
298
|
+
### Pre-Work Checklist
|
|
299
|
+
|
|
300
|
+
Before writing any code:
|
|
301
|
+
|
|
302
|
+
- [ ] **Checked `components/ui/`** — Does a primitive already exist?
|
|
303
|
+
- [ ] **Checked Feature Components** in `guidelines/COMPONENT_LIBRARY.md`
|
|
304
|
+
- [ ] **Checked Storybook** — Run `pnpm storybook` and browse existing components
|
|
305
|
+
- [ ] **Verified no existing component** meets the need (even with modifications)
|
|
306
|
+
- [ ] **If modifying**: Reviewed current tests and stories
|
|
307
|
+
|
|
308
|
+
### Decision Flow
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
Need exists?
|
|
312
|
+
├── YES: Existing component with correct behavior → USE IT
|
|
313
|
+
├── YES: Existing component needs variant → ADD VARIANT (not new component)
|
|
314
|
+
├── YES: Existing component needs refactor → REFACTOR with feature flag
|
|
315
|
+
└── NO: No existing component → CREATE NEW (with justification in PR)
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### New Component Requirements
|
|
319
|
+
|
|
320
|
+
Every new component MUST have:
|
|
321
|
+
|
|
322
|
+
1. **Feature Flag** — For controlled rollout (default: `false`)
|
|
323
|
+
2. **Design Tokens** — Use `lib/design-tokens.ts`, never hardcode colors
|
|
324
|
+
3. **Storybook Story** — See [Storybook Story Requirements](#storybook-story-requirements) below
|
|
325
|
+
4. **Unit Tests** — Behavioral tests for all logic
|
|
326
|
+
5. **Snapshot Tests** — One per variant/size combination
|
|
327
|
+
6. **Documentation** — Added to `guidelines/COMPONENT_LIBRARY.md`
|
|
328
|
+
|
|
329
|
+
### Storybook Story Requirements
|
|
330
|
+
|
|
331
|
+
> **⚠️ MANDATORY**: Every component in `components/ui/` or `components/ui/forms/` MUST have a corresponding `.stories.tsx` file.
|
|
332
|
+
|
|
333
|
+
**Story File Location:**
|
|
334
|
+
|
|
335
|
+
- Place stories in `components/` alongside dialog/feature components
|
|
336
|
+
- Example: `FormInput` → `components/FormInput.stories.tsx`
|
|
337
|
+
|
|
338
|
+
**Required Stories:**
|
|
339
|
+
Every component story file MUST include:
|
|
340
|
+
|
|
341
|
+
| Story | Description |
|
|
342
|
+
| ----------------- | --------------------------------------------- |
|
|
343
|
+
| `Default` | Basic usage with minimal props |
|
|
344
|
+
| `WithAllFeatures` | All major props enabled |
|
|
345
|
+
| `SizeVariants` | If component has size prop (sm/md/lg) |
|
|
346
|
+
| `States` | Disabled, error, loading states if applicable |
|
|
347
|
+
| `Controlled` | If component supports controlled mode |
|
|
348
|
+
| `FormExample` | Form integration example for form components |
|
|
349
|
+
|
|
350
|
+
**Story Template:**
|
|
351
|
+
|
|
352
|
+
```tsx
|
|
353
|
+
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
|
354
|
+
import { ComponentName } from './ui/component-name';
|
|
355
|
+
import { mockFeatureFlags } from '@/lib/feature-flags';
|
|
356
|
+
|
|
357
|
+
const meta: Meta<typeof ComponentName> = {
|
|
358
|
+
title: 'Category/ComponentName',
|
|
359
|
+
component: ComponentName,
|
|
360
|
+
tags: ['autodocs'],
|
|
361
|
+
parameters: { layout: 'centered' },
|
|
362
|
+
decorators: [
|
|
363
|
+
(Story) => {
|
|
364
|
+
mockFeatureFlags({ FEATURE_FLAG: true });
|
|
365
|
+
return (
|
|
366
|
+
<div className="w-[400px] p-4">
|
|
367
|
+
<Story />
|
|
368
|
+
</div>
|
|
369
|
+
);
|
|
370
|
+
},
|
|
371
|
+
],
|
|
372
|
+
argTypes: {
|
|
373
|
+
// Define controls for all props
|
|
374
|
+
},
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
export default meta;
|
|
378
|
+
type Story = StoryObj<typeof ComponentName>;
|
|
379
|
+
|
|
380
|
+
export const Default: Story = {
|
|
381
|
+
args: {
|
|
382
|
+
// Minimal props
|
|
383
|
+
},
|
|
384
|
+
};
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**Story Validation Checklist:**
|
|
388
|
+
|
|
389
|
+
- [ ] Meta includes `tags: ["autodocs"]` for auto-generated docs
|
|
390
|
+
- [ ] Feature flag is mocked in decorator
|
|
391
|
+
- [ ] `argTypes` defined for all controllable props
|
|
392
|
+
- [ ] Renders in `pnpm storybook` without errors
|
|
393
|
+
- [ ] Interactive controls work in Storybook
|
|
394
|
+
|
|
395
|
+
### Variant Addition Requirements
|
|
396
|
+
|
|
397
|
+
When adding a variant to existing component:
|
|
398
|
+
|
|
399
|
+
1. **Existing tests pass** — Run `pnpm test:components`
|
|
400
|
+
2. **New variant tested** — Add tests for new behavior
|
|
401
|
+
3. **Snapshot updated** — Run `pnpm test:update-snapshots` if intentional change
|
|
402
|
+
4. **Storybook updated** — Add story or update existing
|
|
403
|
+
5. **Documentation updated** — If variant changes usage patterns
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Retroactive Compliance Rule
|
|
408
|
+
|
|
409
|
+
> **⚠️ CRITICAL**: When ANY new rule, standard, or pattern is added to `/guidelines/`, the codebase MUST be brought into compliance BEFORE continuing other work.
|
|
410
|
+
|
|
411
|
+
### Trigger
|
|
412
|
+
|
|
413
|
+
This rule applies when:
|
|
414
|
+
|
|
415
|
+
- New guideline file is created in `/guidelines/`
|
|
416
|
+
- Existing guideline is updated with new requirements
|
|
417
|
+
- New coding standard or pattern is established
|
|
418
|
+
- New component library component is mandated for existing patterns
|
|
419
|
+
|
|
420
|
+
### Mandatory Workflow
|
|
421
|
+
|
|
422
|
+
| Step | Action | Deliverable |
|
|
423
|
+
| ---- | ------------------------- | ----------------------------------------------- |
|
|
424
|
+
| 1 | **Create audit plan** | `plans/<RULE_NAME>_COMPLIANCE_PLAN.md` |
|
|
425
|
+
| 2 | **Full codebase scan** | List ALL files/locations violating the new rule |
|
|
426
|
+
| 3 | **Prioritize violations** | Critical → High → Medium → Low |
|
|
427
|
+
| 4 | **Remediate violations** | Fix all with tests, commit incrementally |
|
|
428
|
+
| 5 | **Verify compliance** | All checks pass, no violations remain |
|
|
429
|
+
| 6 | **Document completion** | Move plan to `plans/completed/` |
|
|
430
|
+
|
|
431
|
+
### Priority Levels
|
|
432
|
+
|
|
433
|
+
| Priority | Definition | Timeline |
|
|
434
|
+
| ------------ | ---------------------------------------------- | ------------------------- |
|
|
435
|
+
| **Critical** | Breaks functionality, security issue | Fix immediately |
|
|
436
|
+
| **High** | Affects user experience, inconsistent behavior | Fix before next release |
|
|
437
|
+
| **Medium** | Code quality, maintainability | Fix within current sprint |
|
|
438
|
+
| **Low** | Nice-to-have, cosmetic | Fix when touching file |
|
|
439
|
+
|
|
440
|
+
### Blocking Rule
|
|
441
|
+
|
|
442
|
+
**No new feature work may begin until:**
|
|
443
|
+
|
|
444
|
+
1. All Critical violations are fixed
|
|
445
|
+
2. All High violations are fixed OR have approved timeline
|
|
446
|
+
3. Audit plan is created and tracked
|
|
447
|
+
|
|
448
|
+
### Audit Plan Template
|
|
449
|
+
|
|
450
|
+
Create `plans/<RULE_NAME>_COMPLIANCE_PLAN.md`:
|
|
451
|
+
|
|
452
|
+
```markdown
|
|
453
|
+
# [Rule Name] Compliance Audit
|
|
454
|
+
|
|
455
|
+
## Rule Summary
|
|
456
|
+
|
|
457
|
+
Brief description of the new rule/standard.
|
|
458
|
+
|
|
459
|
+
## Audit Date
|
|
460
|
+
|
|
461
|
+
YYYY-MM-DD
|
|
462
|
+
|
|
463
|
+
## Violations Found
|
|
464
|
+
|
|
465
|
+
### Critical (Must fix immediately)
|
|
466
|
+
|
|
467
|
+
- [ ] `path/to/file.tsx:L123` - Description of violation
|
|
468
|
+
|
|
469
|
+
### High (Fix before next release)
|
|
470
|
+
|
|
471
|
+
- [ ] `path/to/file.tsx:L456` - Description of violation
|
|
472
|
+
|
|
473
|
+
### Medium (Fix within sprint)
|
|
474
|
+
|
|
475
|
+
- [ ] `path/to/file.tsx:L789` - Description of violation
|
|
476
|
+
|
|
477
|
+
### Low (Fix when touching file)
|
|
478
|
+
|
|
479
|
+
- [ ] `path/to/file.tsx:L012` - Description of violation
|
|
480
|
+
|
|
481
|
+
## Remediation Progress
|
|
482
|
+
|
|
483
|
+
- [ ] All critical violations fixed
|
|
484
|
+
- [ ] All high violations fixed
|
|
485
|
+
- [ ] All medium violations fixed
|
|
486
|
+
- [ ] Tests passing
|
|
487
|
+
- [ ] Build passing
|
|
488
|
+
|
|
489
|
+
## Completion Date
|
|
490
|
+
|
|
491
|
+
YYYY-MM-DD (filled when complete)
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
## Coding Standards
|
|
497
|
+
|
|
498
|
+
### Import Ordering
|
|
499
|
+
|
|
500
|
+
Imports MUST follow this exact order, with blank lines between groups:
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
// 1. Directive (MUST be first line if present)
|
|
504
|
+
'use server';
|
|
505
|
+
// OR
|
|
506
|
+
'use client';
|
|
507
|
+
|
|
508
|
+
// 2. React imports
|
|
509
|
+
import React, { useState, useEffect, useCallback } from 'react';
|
|
510
|
+
|
|
511
|
+
// 3. External library imports (alphabetical)
|
|
512
|
+
import { useDrag } from 'react-dnd';
|
|
513
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
514
|
+
import { z } from 'zod';
|
|
515
|
+
|
|
516
|
+
// 4. Internal absolute imports with @/ prefix (alphabetical by path)
|
|
517
|
+
import { createServerClient } from '@/lib/supabase/server';
|
|
518
|
+
import { verifyBoardAccess } from '@/utils/authorization.server';
|
|
519
|
+
import type { Task, Sprint } from '@/types';
|
|
520
|
+
import { useAuth } from '@/app/providers';
|
|
521
|
+
|
|
522
|
+
// 5. Relative imports (parent directories first, then siblings)
|
|
523
|
+
import { Button } from '../ui/button';
|
|
524
|
+
import { TaskCard } from './TaskCard';
|
|
525
|
+
import type { LocalType } from './types';
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Naming Conventions
|
|
529
|
+
|
|
530
|
+
| Type | Convention | Example |
|
|
531
|
+
| ------------------- | ------------------------ | ------------------------------------ |
|
|
532
|
+
| Component files | PascalCase.tsx | `TaskCard.tsx` |
|
|
533
|
+
| Server action files | camelCase.ts | `tasks.ts`, `organizations.ts` |
|
|
534
|
+
| Hook files | usePascalCase.tsx | `useAuthorization.tsx` |
|
|
535
|
+
| Test files | Original.test.tsx | `TaskCard.test.tsx` |
|
|
536
|
+
| Schema files | entity.schema.ts | `task.schema.ts` |
|
|
537
|
+
| Migration files | YYYYMMDD_description.sql | `20240115_add_teams.sql` |
|
|
538
|
+
| Functions | camelCase | `getOrganizations`, `handleSubmit` |
|
|
539
|
+
| Types/Interfaces | PascalCase | `Task`, `OrganizationMember` |
|
|
540
|
+
| Constants | SCREAMING_SNAKE_CASE | `ROLE_HIERARCHY`, `AUTH_STORAGE_KEY` |
|
|
541
|
+
| Database columns | snake_case | `created_at`, `organization_id` |
|
|
542
|
+
| Frontend props | camelCase | `taskId`, `onUpdate`, `isLoading` |
|
|
543
|
+
| Zod schemas | PascalCaseSchema | `TaskSchema`, `CreateTaskSchema` |
|
|
544
|
+
|
|
545
|
+
### Error Handling Pattern
|
|
546
|
+
|
|
547
|
+
**Server Actions** - Always return `{ data, error }` or `{ success, error }`:
|
|
548
|
+
|
|
549
|
+
```typescript
|
|
550
|
+
export async function getEntity(
|
|
551
|
+
id: string
|
|
552
|
+
): Promise<{ data: Entity | null; error: string | null }> {
|
|
553
|
+
try {
|
|
554
|
+
// 1. Verify access FIRST
|
|
555
|
+
const access = await verifyEntityAccess(id);
|
|
556
|
+
if (!access.hasAccess) {
|
|
557
|
+
return { data: null, error: access.error || 'Access denied' };
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
const supabase = await createServerClient();
|
|
561
|
+
const { data, error } = await supabase.from('entities').select('*').eq('id', id).single();
|
|
562
|
+
|
|
563
|
+
if (error) {
|
|
564
|
+
console.error('Error fetching entity:', error);
|
|
565
|
+
return { data: null, error: error.message };
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
return { data: transformEntity(data), error: null };
|
|
569
|
+
} catch (err) {
|
|
570
|
+
console.error('Unexpected error:', err);
|
|
571
|
+
return { data: null, error: 'An unexpected error occurred' };
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
**Components** - Use toast for user feedback:
|
|
577
|
+
|
|
578
|
+
```typescript
|
|
579
|
+
const handleSubmit = async () => {
|
|
580
|
+
try {
|
|
581
|
+
const { data, error } = await createEntity(formData);
|
|
582
|
+
if (error) {
|
|
583
|
+
toast.error(error);
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
toast.success('Created successfully');
|
|
587
|
+
onSuccess?.(data);
|
|
588
|
+
} catch (err) {
|
|
589
|
+
toast.error('An unexpected error occurred');
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
### TypeScript Strictness
|
|
595
|
+
|
|
596
|
+
- ❌ **NO `any` type** - Use proper typing or `unknown` with type guards
|
|
597
|
+
- ✅ **Explicit return types** on all exported functions
|
|
598
|
+
- ✅ **Interface over type** for object shapes (unless union type needed)
|
|
599
|
+
- ✅ **Use `as const`** for readonly arrays: `["admin", "member"] as const`
|
|
600
|
+
- ✅ **Prefer type inference** for local variables when obvious
|
|
601
|
+
|
|
602
|
+
---
|
|
603
|
+
|
|
604
|
+
## Architecture Rules
|
|
605
|
+
|
|
606
|
+
### Server Actions
|
|
607
|
+
|
|
608
|
+
1. **`'use server'` MUST be the first line** of every server action file
|
|
609
|
+
2. **Authorization check MUST come first** before any data access
|
|
610
|
+
3. **Transform database snake_case to camelCase** for frontend consumption
|
|
611
|
+
4. **Use `revalidatePath()`** after mutations to update cached data
|
|
612
|
+
5. **Never expose sensitive data** - filter fields before returning
|
|
613
|
+
|
|
614
|
+
```typescript
|
|
615
|
+
'use server';
|
|
616
|
+
|
|
617
|
+
import { createServerClient } from '@/lib/supabase/server';
|
|
618
|
+
import { verifyBoardAccess } from '@/utils/authorization.server';
|
|
619
|
+
import { revalidatePath } from 'next/cache';
|
|
620
|
+
import type { Task } from '@/types';
|
|
621
|
+
|
|
622
|
+
interface TaskRow {
|
|
623
|
+
id: string;
|
|
624
|
+
ticket_id: string;
|
|
625
|
+
board_id: string;
|
|
626
|
+
created_at: string;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function transformTask(row: TaskRow): Task {
|
|
630
|
+
return {
|
|
631
|
+
id: row.id,
|
|
632
|
+
ticketId: row.ticket_id,
|
|
633
|
+
boardId: row.board_id,
|
|
634
|
+
createdAt: row.created_at,
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
export async function getTasks(
|
|
639
|
+
boardId: string
|
|
640
|
+
): Promise<{ data: Task[] | null; error: string | null }> {
|
|
641
|
+
// 1. Authorization FIRST
|
|
642
|
+
const access = await verifyBoardAccess(boardId);
|
|
643
|
+
if (!access.hasAccess) {
|
|
644
|
+
return { data: null, error: access.error || 'Access denied' };
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// 2. Fetch data
|
|
648
|
+
const supabase = await createServerClient();
|
|
649
|
+
const { data, error } = await supabase.from('tasks').select('*').eq('board_id', boardId);
|
|
650
|
+
|
|
651
|
+
if (error) {
|
|
652
|
+
return { data: null, error: error.message };
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// 3. Transform and return
|
|
656
|
+
return { data: data.map(transformTask), error: null };
|
|
657
|
+
}
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
### Component Patterns
|
|
661
|
+
|
|
662
|
+
1. **`'use client'` for interactive components** - Any component with state, effects, or event handlers
|
|
663
|
+
2. **Hooks at the top** - All hooks must be called before any conditional returns
|
|
664
|
+
3. **Destructure props with defaults** - `({ optional = defaultValue }: Props)`
|
|
665
|
+
4. **Add `data-testid` for testable elements** - Required for E2E test targets
|
|
666
|
+
|
|
667
|
+
```typescript
|
|
668
|
+
"use client";
|
|
669
|
+
|
|
670
|
+
import React, { useState, useEffect } from "react";
|
|
671
|
+
import { useAuth } from "@/app/providers";
|
|
672
|
+
import { Button } from "@/components/ui/button";
|
|
673
|
+
|
|
674
|
+
interface TaskCardProps {
|
|
675
|
+
task: Task;
|
|
676
|
+
onEdit?: (task: Task) => void;
|
|
677
|
+
readOnly?: boolean;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
export function TaskCard({ task, onEdit, readOnly = false }: TaskCardProps) {
|
|
681
|
+
// 1. Hooks first
|
|
682
|
+
const { user } = useAuth();
|
|
683
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
684
|
+
|
|
685
|
+
// 2. Effects
|
|
686
|
+
useEffect(() => {
|
|
687
|
+
// ...
|
|
688
|
+
}, [task.id]);
|
|
689
|
+
|
|
690
|
+
// 3. Handlers
|
|
691
|
+
const handleEdit = () => {
|
|
692
|
+
if (!readOnly) {
|
|
693
|
+
setIsEditing(true);
|
|
694
|
+
onEdit?.(task);
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
// 4. Render
|
|
699
|
+
return (
|
|
700
|
+
<div data-testid={`task-card-${task.id}`}>
|
|
701
|
+
<h3>{task.title}</h3>
|
|
702
|
+
{!readOnly && (
|
|
703
|
+
<Button data-testid="edit-task-btn" onClick={handleEdit}>
|
|
704
|
+
Edit
|
|
705
|
+
</Button>
|
|
706
|
+
)}
|
|
707
|
+
</div>
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### Authorization Flow
|
|
713
|
+
|
|
714
|
+
1. **Server-side**: Use `verify*Access()` functions from `@/utils/authorization.server`
|
|
715
|
+
2. **Client-side**: Use `useAuthorization()` hook for permission checks
|
|
716
|
+
3. **Never trust client-side checks alone** - Always verify on server
|
|
717
|
+
|
|
718
|
+
```typescript
|
|
719
|
+
// Server action
|
|
720
|
+
import { verifyBoardAccess, requireContributorAccess } from '@/utils/authorization.server';
|
|
721
|
+
|
|
722
|
+
export async function createTask(boardId: string, data: CreateTaskData) {
|
|
723
|
+
const boardAccess = await verifyBoardAccess(boardId);
|
|
724
|
+
if (!boardAccess.hasAccess) {
|
|
725
|
+
return { data: null, error: 'Access denied' };
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// For write operations, also check role
|
|
729
|
+
if (boardAccess.workspaceId) {
|
|
730
|
+
try {
|
|
731
|
+
await requireContributorAccess(boardAccess.workspaceId);
|
|
732
|
+
} catch (err) {
|
|
733
|
+
return { data: null, error: (err as Error).message };
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// ... proceed with creation
|
|
738
|
+
}
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
```typescript
|
|
742
|
+
// Client component
|
|
743
|
+
import { useAuthorization } from "@/hooks/useAuthorization";
|
|
744
|
+
|
|
745
|
+
function TaskActions({ task }: { task: Task }) {
|
|
746
|
+
const { can } = useAuthorization();
|
|
747
|
+
|
|
748
|
+
return (
|
|
749
|
+
<>
|
|
750
|
+
{can.editTask() && <Button onClick={handleEdit}>Edit</Button>}
|
|
751
|
+
{can.deleteTask() && <Button onClick={handleDelete}>Delete</Button>}
|
|
752
|
+
</>
|
|
753
|
+
);
|
|
754
|
+
}
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
---
|
|
758
|
+
|
|
759
|
+
## Library Usage Policy
|
|
760
|
+
|
|
761
|
+
### Rule 1: Use Existing Libraries First
|
|
762
|
+
|
|
763
|
+
Before suggesting any solution, check [LIBRARY_INVENTORY.md](LIBRARY_INVENTORY.md). Common solutions already available:
|
|
764
|
+
|
|
765
|
+
| Need | Use This | NOT This |
|
|
766
|
+
| ------------- | -------------------------------------- | ---------------------------------- |
|
|
767
|
+
| UI Components | `@radix-ui/*` + `components/ui/*` | Installing new UI library |
|
|
768
|
+
| Icons | `lucide-react` | Other icon libraries |
|
|
769
|
+
| Drag & Drop | `react-dnd` | @dnd-kit, react-beautiful-dnd |
|
|
770
|
+
| Data Fetching | `@tanstack/react-query` | SWR, custom fetch hooks |
|
|
771
|
+
| Validation | `zod` | yup, joi, other validators |
|
|
772
|
+
| Date Handling | `date-fns` | moment, dayjs |
|
|
773
|
+
| Styling | Tailwind CSS + `clsx`/`tailwind-merge` | styled-components, emotion |
|
|
774
|
+
| Forms | `react-hook-form` | formik, other form libraries |
|
|
775
|
+
| Rich Text | `@tiptap/*` | Draft.js, Slate, Quill |
|
|
776
|
+
| Toasts | `sonner` | react-toastify, other toast libs |
|
|
777
|
+
| Animations | `motion` (framer-motion) | react-spring, other animation libs |
|
|
778
|
+
|
|
779
|
+
### Rule 2: Ask Before Adding New Libraries
|
|
780
|
+
|
|
781
|
+
If a task seems to require a new library:
|
|
782
|
+
|
|
783
|
+
1. **STOP** - Do not install or add to `package.json`
|
|
784
|
+
2. **ASK** - "This would require adding `[library]`. Should I proceed, or would you prefer an alternative approach using existing tools?"
|
|
785
|
+
3. **JUSTIFY** - Explain why existing libraries cannot solve the problem
|
|
786
|
+
4. **WAIT** - Only proceed after explicit user approval
|
|
787
|
+
|
|
788
|
+
### Rule 3: Document Approved Libraries
|
|
789
|
+
|
|
790
|
+
When a new library is approved and added:
|
|
791
|
+
|
|
792
|
+
1. Add entry to [LIBRARY_INVENTORY.md](LIBRARY_INVENTORY.md)
|
|
793
|
+
2. Include: Package name, version, purpose, usage location, approved patterns
|
|
794
|
+
3. Update this document if it replaces an existing recommendation
|
|
795
|
+
|
|
796
|
+
---
|
|
797
|
+
|
|
798
|
+
## Testing Requirements
|
|
799
|
+
|
|
800
|
+
### When Tests Are Required
|
|
801
|
+
|
|
802
|
+
| Change Type | Unit Test Required | Storybook Story Required | E2E Test Required |
|
|
803
|
+
| ------------------------------------------- | ------------------ | ------------------------ | ----------------------- |
|
|
804
|
+
| New UI component (`components/ui/`) | ✅ Yes | ✅ **Yes (mandatory)** | ❌ No |
|
|
805
|
+
| New form component (`components/ui/forms/`) | ✅ Yes | ✅ **Yes (mandatory)** | ❌ No |
|
|
806
|
+
| New hook with logic | ✅ Yes | ❌ No | ❌ No |
|
|
807
|
+
| Complex feature component | ✅ Yes | ⚠️ Recommended | ⚠️ If critical path |
|
|
808
|
+
| Server action | ⚠️ Recommended | ❌ No | ❌ No |
|
|
809
|
+
| Utility function | ✅ Yes | ❌ No | ❌ No |
|
|
810
|
+
| New feature | ✅ Yes | ⚠️ If has UI | ✅ Yes (critical paths) |
|
|
811
|
+
| Bug fix | ✅ Regression test | ❌ No | ⚠️ If E2E exists |
|
|
812
|
+
|
|
813
|
+
### Test File Conventions
|
|
814
|
+
|
|
815
|
+
- Place test files alongside source: `Component.tsx` → `Component.test.tsx`
|
|
816
|
+
- Use fixtures from `test/fixtures.tsx`
|
|
817
|
+
- Mock Supabase using MSW handlers in `lib/test-utils/`
|
|
818
|
+
|
|
819
|
+
### Required `data-testid` Attributes
|
|
820
|
+
|
|
821
|
+
Add `data-testid` to elements that E2E tests need to interact with:
|
|
822
|
+
|
|
823
|
+
```typescript
|
|
824
|
+
// Good - specific, predictable IDs
|
|
825
|
+
<button data-testid="create-task-btn">Create</button>
|
|
826
|
+
<div data-testid={`task-card-${task.id}`}>...</div>
|
|
827
|
+
<input data-testid="task-title-input" />
|
|
828
|
+
|
|
829
|
+
// Bad - generic or missing
|
|
830
|
+
<button>Create</button>
|
|
831
|
+
<div className="task-card">...</div>
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
---
|
|
835
|
+
|
|
836
|
+
## PR Workflow
|
|
837
|
+
|
|
838
|
+
### Using Agent to Fill PR Descriptions
|
|
839
|
+
|
|
840
|
+
When creating a PR, use Agent to automatically fill out the PR description:
|
|
841
|
+
|
|
842
|
+
1. Stage your changes: `git add .`
|
|
843
|
+
2. Ask Agent: "Fill out the PR description for my staged changes using the PR template"
|
|
844
|
+
3. Agent will analyze the diff and populate:
|
|
845
|
+
- Summary of changes
|
|
846
|
+
- Type of change (feature/bugfix/refactor/etc.)
|
|
847
|
+
- Scope from the fixed list
|
|
848
|
+
- Files changed with checklist verification
|
|
849
|
+
- Testing performed
|
|
850
|
+
- Breaking changes assessment
|
|
851
|
+
|
|
852
|
+
### Pre-PR Checklist
|
|
853
|
+
|
|
854
|
+
Before creating a PR, Agent must verify:
|
|
855
|
+
|
|
856
|
+
- [ ] All required files for the change type have been touched
|
|
857
|
+
- [ ] No `any` types introduced
|
|
858
|
+
- [ ] Authorization added for new data access
|
|
859
|
+
- [ ] Types updated in `types/index.ts`
|
|
860
|
+
- [ ] Unit tests added/updated and passing (`pnpm test`)
|
|
861
|
+
- [ ] E2E tests pass for affected flows (`pnpm test:e2e`)
|
|
862
|
+
- [ ] No unapproved new libraries added
|
|
863
|
+
- [ ] Import order follows the standard
|
|
864
|
+
- [ ] `data-testid` attributes added for testable elements
|
|
865
|
+
|
|
866
|
+
---
|
|
867
|
+
|
|
868
|
+
## Quick Reference: Path Aliases
|
|
869
|
+
|
|
870
|
+
| Alias | Path | Example |
|
|
871
|
+
| ---------------- | ---------------- | -------------------------- |
|
|
872
|
+
| `@/*` | Root | `@/utils/authorization` |
|
|
873
|
+
| `@/components/*` | `./components/*` | `@/components/ui/button` |
|
|
874
|
+
| `@/lib/*` | `./lib/*` | `@/lib/supabase/server` |
|
|
875
|
+
| `@/hooks/*` | `./hooks/*` | `@/hooks/useAuthorization` |
|
|
876
|
+
| `@/types/*` | `./types/*` | `@/types/index` |
|
|
877
|
+
| `@test/*` | `./test/*` | `@test/fixtures` |
|
|
878
|
+
| `@app/types` | `./types/index` | `@app/types` |
|
|
879
|
+
|
|
880
|
+
---
|
|
881
|
+
|
|
882
|
+
## Related Documents
|
|
883
|
+
|
|
884
|
+
- [SINGLE_SOURCE_OF_TRUTH.md](SINGLE_SOURCE_OF_TRUTH.md) - Canonical file locations
|
|
885
|
+
- [LIBRARY_INVENTORY.md](LIBRARY_INVENTORY.md) - Approved dependencies
|
|
886
|
+
- [TESTING_STRATEGY.md](TESTING_STRATEGY.md) - Testing patterns
|
|
887
|
+
- [BRANCHING_STRATEGY.md](BRANCHING_STRATEGY.md) - Git workflow
|