chore: update .gitignore and improve coding standards documentation

- Added .cursor/sessions/* to .gitignore to prevent session files from being tracked.
- Enhanced coding standards in SKILL.md by adding semicolons to TypeScript examples for consistency.
- Improved formatting in continuous learning, detail layout, and other SKILL.md files for better readability.

These changes aim to streamline development processes and maintain code quality across the project.
This commit is contained in:
shancheas
2026-08-25 17:50:17 +07:00
parent ff6814d038
commit f2f0be111a
48 changed files with 962 additions and 742 deletions
+10 -10
View File
@@ -37,8 +37,8 @@ Standards for this TypeScript/React frontend. Not a NestJS API.
### Naming
```typescript
const searchQuery = 'widget'
const isAuthenticated = true
const searchQuery = 'widget';
const isAuthenticated = true;
async function fetchVehicleType(id: string) {}
function isValidCode(code: string): boolean {}
@@ -47,8 +47,8 @@ function isValidCode(code: string): boolean {}
### Immutability (CRITICAL)
```typescript
const updated = { ...row, name: 'New' }
const nextItems = [...items, newItem]
const updated = { ...row, name: 'New' };
const nextItems = [...items, newItem];
```
Never mutate: no `push`, `splice`, or in-place property assignment on shared state.
@@ -71,12 +71,12 @@ No `any`. Prefer entity types in `domain/entities` and DTOs next to transformers
## Imports (this repo)
```ts
import { Button, Text } from '@repo/ui/components'
import { FieldTextInput } from '@repo/ui/form'
import { EnterpriseModuleProvider } from '@repo/ui/foundations'
import { compose, required } from '@repo/ui/validators'
import { createHttpClient } from '@repo/core-api/http-client'
import { CommonRemoteDataServices } from '@repo/core-api/data-services'
import { Button, Text } from '@repo/ui/components';
import { FieldTextInput } from '@repo/ui/form';
import { EnterpriseModuleProvider } from '@repo/ui/foundations';
import { compose, required } from '@repo/ui/validators';
import { createHttpClient } from '@repo/core-api/http-client';
import { CommonRemoteDataServices } from '@repo/core-api/data-services';
```
Do not import `@mantine/core` or axios in `apps/web` feature code.
+8 -12
View File
@@ -32,23 +32,19 @@ Edit `config.json` to customize:
"debugging_techniques",
"project_specific"
],
"ignore_patterns": [
"simple_typos",
"one_time_fixes",
"external_api_issues"
]
"ignore_patterns": ["simple_typos", "one_time_fixes", "external_api_issues"]
}
```
## Pattern Types
| Pattern | Description |
|---------|-------------|
| `error_resolution` | How specific errors were resolved |
| `user_corrections` | Patterns from user corrections |
| `workarounds` | Solutions to framework/library quirks |
| `debugging_techniques` | Effective debugging approaches |
| `project_specific` | Project-specific conventions |
| Pattern | Description |
| ---------------------- | ------------------------------------- |
| `error_resolution` | How specific errors were resolved |
| `user_corrections` | Patterns from user corrections |
| `workarounds` | Solutions to framework/library quirks |
| `debugging_techniques` | Effective debugging approaches |
| `project_specific` | Project-specific conventions |
## Hook Setup
+20 -20
View File
@@ -32,11 +32,11 @@ Optional **identity / hero** (§3) is an extra content block when the entity ben
Look at **how many distinct data categories** the entity has — that decides stacked vs tabbed body:
| Detail type | Body mode |
| --- | --- |
| Few categories (≤34 section cards; e.g. Branch, User, simple master data) | **Stacked sections** — vertical stack of section cards under the header |
| Detail type | Body mode |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| Few categories (≤34 section cards; e.g. Branch, User, simple master data) | **Stacked sections** — vertical stack of section cards under the header |
| Many categories (>34 distinct groups) **or** the user explicitly asks for tabs | **Tabbed body** — keep a slim always-visible top (identity / summary / stepper), then a horizontal tab bar; each tab owns one category's content |
| Narrow / mobile viewport | Same mode as desktop; only the **internal** key-value and status layouts collapse (§13) |
| Narrow / mobile viewport | Same mode as desktop; only the **internal** key-value and status layouts collapse (§13) |
Once a page picks stacked vs tabbed, stay consistent — don't mix an ad-hoc tab region with an ad-hoc long scroll of the same categories.
@@ -67,8 +67,8 @@ Use when the entity has a meaningful visual (device photo, avatar, logo). Skip f
Single horizontal row inside one section surface:
| Left | Middle (flex grow) | Right |
| --- | --- | --- |
| Left | Middle (flex grow) | Right |
| ----------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
| Leading media (fixed square/circle) | Title stack: primary name (+ id if not already in chrome), then one short subtitle/category line | Primary content action if it belongs to this block (usually omit — Edit lives in module chrome) |
- Media left-aligned; title stack left-aligned next to media; any block-level action right-aligned on the same row.
@@ -203,25 +203,25 @@ Horizontal gaps inside grids match the medium rhythm. Don't invent a fourth gap
## 13. Responsive collapse
| Wide layout | Narrow collapse |
| --- | --- |
| Identity hero row (media \| title \| action) | Centered vertical stack (media → title → subtitle → full-width action) |
| Key-value label-above grid (§5A) | Label-left / value-right rows (§5B) |
| Status metric horizontal row (§6) | Stacked metric sub-blocks; badge beside value |
| Summary 23 columns (§7) | Stacked column groups, same order |
| Tab list | Horizontally scrollable tab list; panels still one-at-a-time |
| Table | Horizontal scroll inside the section **or** stacked label/value per row — pick one strategy per table type and keep it project-wide |
| Wide layout | Narrow collapse |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Identity hero row (media \| title \| action) | Centered vertical stack (media → title → subtitle → full-width action) |
| Key-value label-above grid (§5A) | Label-left / value-right rows (§5B) |
| Status metric horizontal row (§6) | Stacked metric sub-blocks; badge beside value |
| Summary 23 columns (§7) | Stacked column groups, same order |
| Tab list | Horizontally scrollable tab list; panels still one-at-a-time |
| Table | Horizontal scroll inside the section **or** stacked label/value per row — pick one strategy per table type and keep it project-wide |
Never re-pair fields into different logical groups on collapse — only column count / orientation changes.
## 14. Action placement (position only)
| Action scope | Position |
| --- | --- |
| Global entity actions (Edit, Delete, Activate, …) | Module header actions via `EnterpriseDetailPageProvider` — top-right of chrome |
| Section-scoped action (Upload, Add record) | Right side of that section's header band (§4 / §11) |
| Section filters | Right side of the table/section header, before or beside the section primary action |
| Row action | Trailing column of that row only |
| Action scope | Position |
| ------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Global entity actions (Edit, Delete, Activate, …) | Module header actions via `EnterpriseDetailPageProvider` — top-right of chrome |
| Section-scoped action (Upload, Add record) | Right side of that section's header band (§4 / §11) |
| Section filters | Right side of the table/section header, before or beside the section primary action |
| Row action | Trailing column of that row only |
Do not duplicate Edit in the body if the provider already exposes it, unless a mobile identity block needs a full-width local affordance (§3 narrow).
+59 -22
View File
@@ -5,6 +5,7 @@ A formal evaluation framework for Claude Code sessions, implementing eval-driven
## Philosophy
Eval-Driven Development treats evals as the "unit tests of AI development":
- Define expected behavior BEFORE implementation
- Run evals continuously during development
- Track regressions with each change
@@ -13,33 +14,41 @@ Eval-Driven Development treats evals as the "unit tests of AI development":
## Eval Types
### Capability Evals
Test if Claude can do something it couldn't before:
```markdown
[CAPABILITY EVAL: feature-name]
Task: Description of what Claude should accomplish
Success Criteria:
- [ ] Criterion 1
- [ ] Criterion 2
- [ ] Criterion 3
Expected Output: Description of expected result
- [ ] Criterion 1
- [ ] Criterion 2
- [ ] Criterion 3
Expected Output: Description of expected result
```
### Regression Evals
Ensure changes don't break existing functionality:
```markdown
[REGRESSION EVAL: feature-name]
Baseline: SHA or checkpoint name
Tests:
- existing-test-1: PASS/FAIL
- existing-test-2: PASS/FAIL
- existing-test-3: PASS/FAIL
Result: X/Y passed (previously Y/Y)
- existing-test-1: PASS/FAIL
- existing-test-2: PASS/FAIL
- existing-test-3: PASS/FAIL
Result: X/Y passed (previously Y/Y)
```
## Grader Types
### 1. Code-Based Grader
Deterministic checks using code:
```bash
# Check if file contains expected pattern
grep -q "export function handleAuth" src/auth.ts && echo "PASS" || echo "FAIL"
@@ -52,10 +61,13 @@ npm run build && echo "PASS" || echo "FAIL"
```
### 2. Model-Based Grader
Use Claude to evaluate open-ended outputs:
```markdown
[MODEL GRADER PROMPT]
Evaluate the following code change:
1. Does it solve the stated problem?
2. Is it well-structured?
3. Are edge cases handled?
@@ -66,7 +78,9 @@ Reasoning: [explanation]
```
### 3. Human Grader
Flag for manual review:
```markdown
[HUMAN REVIEW REQUIRED]
Change: Description of what changed
@@ -77,13 +91,17 @@ Risk Level: LOW/MEDIUM/HIGH
## Metrics
### pass@k
"At least one success in k attempts"
- pass@1: First attempt success rate
- pass@3: Success within 3 attempts
- Typical target: pass@3 > 90%
### pass^k
"All k trials succeed"
- Higher bar for reliability
- pass^3: 3 consecutive successes
- Use for critical paths
@@ -91,28 +109,34 @@ Risk Level: LOW/MEDIUM/HIGH
## Eval Workflow
### 1. Define (Before Coding)
```markdown
## EVAL DEFINITION: feature-xyz
### Capability Evals
1. Can create new user account
2. Can validate email format
3. Can hash password securely
### Regression Evals
1. Existing login still works
2. Session management unchanged
3. Logout flow intact
### Success Metrics
- pass@3 > 90% for capability evals
- pass^3 = 100% for regression evals
```
### 2. Implement
Write code to pass the defined evals.
### 3. Evaluate
```bash
# Run capability evals
[Run each capability eval, record PASS/FAIL]
@@ -124,25 +148,25 @@ npm test -- --testPathPattern="existing"
```
### 4. Report
```markdown
EVAL REPORT: feature-xyz
========================
# EVAL REPORT: feature-xyz
Capability Evals:
create-user: PASS (pass@1)
validate-email: PASS (pass@2)
hash-password: PASS (pass@1)
Overall: 3/3 passed
create-user: PASS (pass@1)
validate-email: PASS (pass@2)
hash-password: PASS (pass@1)
Overall: 3/3 passed
Regression Evals:
login-flow: PASS
session-mgmt: PASS
logout-flow: PASS
Overall: 3/3 passed
login-flow: PASS
session-mgmt: PASS
logout-flow: PASS
Overall: 3/3 passed
Metrics:
pass@1: 67% (2/3)
pass@3: 100% (3/3)
pass@1: 67% (2/3)
pass@3: 100% (3/3)
Status: READY FOR REVIEW
```
@@ -150,26 +174,33 @@ Status: READY FOR REVIEW
## Integration Patterns
### Pre-Implementation
```
/eval define feature-name
```
Creates eval definition file at `.cursor/evals/feature-name.md`
### During Implementation
```
/eval check feature-name
```
Runs current evals and reports status
### Post-Implementation
```
/eval report feature-name
```
Generates full eval report
## Eval Storage
Store evals in project:
```
.cursor/
evals/
@@ -194,7 +225,9 @@ Store evals in project:
## EVAL: add-authentication
### Phase 1: Define (10 min)
Capability Evals:
- [ ] User can register with email/password
- [ ] User can login with valid credentials
- [ ] Invalid credentials rejected with proper error
@@ -202,19 +235,23 @@ Capability Evals:
- [ ] Logout clears session
Regression Evals:
- [ ] Public routes still accessible
- [ ] API responses unchanged
- [ ] Database schema compatible
### Phase 2: Implement (varies)
[Write code]
### Phase 3: Evaluate
Run: /eval check add-authentication
### Phase 4: Report
EVAL REPORT: add-authentication
==============================
# EVAL REPORT: add-authentication
Capability: 5/5 passed (pass@3: 100%)
Regression: 3/3 passed (pass^3: 100%)
Status: SHIP IT
@@ -82,7 +82,7 @@ Auth lives under `src/apps/auth/`. Shared-across-modules code lives in `src/core
### Module config + factory
```typescript
import { ModuleConfigEntity } from '@repo/ui/foundations'
import { ModuleConfigEntity } from '@repo/ui/foundations';
export const fullPageModuleConfig: ModuleConfigEntity = {
moduleKey: 'EXAMPLE_FULL_PAGE',
@@ -91,28 +91,28 @@ export const fullPageModuleConfig: ModuleConfigEntity = {
webUrl: '/app/example/full-page',
moduleCategory: 'FULL_PAGE',
moduleType: 'MASTER_DATA',
}
};
```
```tsx
import { EnterpriseModuleProvider } from '@repo/ui/foundations'
import { registerModuleNamespace } from '@repo/core-i18n'
import { apiClient } from '../../../../../../../core/lib/api-client'
import { EnterpriseModuleProvider } from '@repo/ui/foundations';
import { registerModuleNamespace } from '@repo/core-i18n';
import { apiClient } from '../../../../../../../core/lib/api-client';
registerModuleNamespace(fullPageModuleConfig.translationNamespace, { id, en })
registerModuleNamespace(fullPageModuleConfig.translationNamespace, { id, en });
```
### Validators (Zod)
```typescript
import { z } from 'zod'
import { compose, required, rangeLength } from '@repo/ui/validators'
import { z } from 'zod';
import { compose, required, rangeLength } from '@repo/ui/validators';
export const createFullPageSchema = (t: (key: string) => string) =>
z.object({
code: compose(z.string(), required(t('common:fields.code'))),
name: compose(z.string(), required(t('common:fields.name')), rangeLength(3, 50, t('common:fields.name'))),
})
});
```
### Forms and HTTP
+3 -3
View File
@@ -21,11 +21,11 @@ Client-side security for this React/Electron frontend. There is no NestJS API or
```typescript
// NEVER
const apiKey = "sk-proj-xxxxx"
const apiKey = 'sk-proj-xxxxx';
// ALWAYS
import { ENV } from '../environment'
if (!ENV.API_BASE_URL) throw new Error('VITE_API_BASE_URL is not configured')
import { ENV } from '../environment';
if (!ENV.API_BASE_URL) throw new Error('VITE_API_BASE_URL is not configured');
```
- [ ] No hardcoded secrets
+4 -1
View File
@@ -10,11 +10,13 @@ Suggests manual `/compact` at strategic points in your workflow rather than rely
## Why Strategic Compaction?
Auto-compaction triggers at arbitrary points:
- Often mid-task, losing important context
- No awareness of logical task boundaries
- Can interrupt complex multi-step operations
Strategic compaction at logical boundaries:
- **After exploration, before execution** - Compact research context, keep implementation plan
- **After completing a milestone** - Fresh start for next phase
- **Before major context shifts** - Clear exploration context before different task
@@ -47,6 +49,7 @@ Already wired in `.cursor/hooks.json` as an `afterFileEdit` command:
## Configuration
Environment variables:
- `COMPACT_THRESHOLD` - Tool calls before first suggestion (default: 50)
## Best Practices
@@ -54,7 +57,7 @@ Environment variables:
1. **Compact after planning** - Once plan is finalized, compact to start fresh
2. **Compact after debugging** - Clear error-resolution context before continuing
3. **Don't compact mid-implementation** - Preserve context for related changes
4. **Read the suggestion** - The hook tells you *when*, you decide *if*
4. **Read the suggestion** - The hook tells you _when_, you decide _if_
## Related
+15 -15
View File
@@ -38,31 +38,31 @@ TDD for this frontend monorepo (Vitest, not NestJS/Supertest).
## Unit example
```typescript
import { describe, it, expect } from 'vitest'
import { createFullPageSchema } from './full-page.validator'
import { describe, it, expect } from 'vitest';
import { createFullPageSchema } from './full-page.validator';
describe('createFullPageSchema', () => {
const t = (key: string) => key
const t = (key: string) => key;
it('rejects an empty code', () => {
const result = createFullPageSchema(t).safeParse({ code: '', name: 'Widget' })
expect(result.success).toBe(false)
})
})
const result = createFullPageSchema(t).safeParse({ code: '', name: 'Widget' });
expect(result.success).toBe(false);
});
});
```
## Component example
```tsx
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
it('calls onClick', async () => {
const onClick = vi.fn()
render(<Button onClick={onClick}>Save</Button>)
await userEvent.click(screen.getByRole('button', { name: 'Save' }))
expect(onClick).toHaveBeenCalledTimes(1)
})
const onClick = vi.fn();
render(<Button onClick={onClick}>Save</Button>);
await userEvent.click(screen.getByRole('button', { name: 'Save' }));
expect(onClick).toHaveBeenCalledTimes(1);
});
```
## Mocking
@@ -72,7 +72,7 @@ Mock `@repo/core-api` and `apiClient`, not a database.
```ts
vi.mock('@repo/core-api/http-client', () => ({
createHttpClient: () => ({ get: vi.fn(), post: vi.fn(), put: vi.fn(), delete: vi.fn() }),
}))
}));
```
## File organization
+10
View File
@@ -5,6 +5,7 @@ A comprehensive verification system for Claude Code sessions.
## When to Use
Invoke this skill:
- After completing a feature or significant code change
- Before creating a PR
- When you want to ensure quality gates pass
@@ -13,6 +14,7 @@ Invoke this skill:
## Verification Phases
### Phase 1: Build Verification
```bash
# Check if project builds
npm run build 2>&1 | tail -20
@@ -23,6 +25,7 @@ pnpm build 2>&1 | tail -20
If build fails, STOP and fix before continuing.
### Phase 2: Type Check
```bash
# TypeScript projects
npx tsc --noEmit 2>&1 | head -30
@@ -34,6 +37,7 @@ pyright . 2>&1 | head -30
Report all type errors. Fix critical ones before continuing.
### Phase 3: Lint Check
```bash
# JavaScript/TypeScript
npm run lint 2>&1 | head -30
@@ -43,6 +47,7 @@ ruff check . 2>&1 | head -30
```
### Phase 4: Test Suite
```bash
# Run tests with coverage
npm run test -- --coverage 2>&1 | tail -50
@@ -52,12 +57,14 @@ npm run test -- --coverage 2>&1 | tail -50
```
Report:
- Total tests: X
- Passed: X
- Failed: X
- Coverage: X%
### Phase 5: Security Scan
```bash
# Check for secrets
grep -rn "sk-" --include="*.ts" --include="*.js" . 2>/dev/null | head -10
@@ -68,6 +75,7 @@ grep -rn "console.log" --include="*.ts" --include="*.tsx" src/ 2>/dev/null | hea
```
### Phase 6: Diff Review
```bash
# Show what changed
git diff --stat
@@ -75,6 +83,7 @@ git diff HEAD~1 --name-only
```
Review each changed file for:
- Unintended changes
- Missing error handling
- Potential edge cases
@@ -107,6 +116,7 @@ For long sessions, run verification every 15 minutes or after major changes:
```markdown
Set a mental checkpoint:
- After completing each function
- After finishing a component
- Before moving to next task