Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 209 additions & 0 deletions .claude/org-rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# OrrisTech Organization Rules

These rules apply to ALL repositories in the OrrisTech GitHub organization.
Claude Code automatically loads this file from `.claude/org-rules.md`.

---

## Pre-Change Verification

Before ANY commit, the following checks MUST pass. Do not commit code that breaks
existing functionality.

1. **Lint** -- Run lint and fix all errors. Warnings are acceptable only if pre-existing.
2. **Type check** -- Run `tsc --noEmit` (or the repo's `typecheck` script). Zero errors.
3. **Tests** -- Run the full test suite. All tests must pass.
4. **Build** -- Run a production build. It must complete without errors.

If any of these steps fail, fix the issue before committing. Never use `--no-verify`
to skip pre-commit hooks.

---

## Testing Requirements

- All new features MUST have unit tests (prefer Vitest; Jest is acceptable).
- All user-facing features MUST have BDD-style tests that describe behavior from the
user's perspective (Given/When/Then or describe/it patterns).
- All existing tests MUST continue to pass after your changes.
- Coverage: maintain or improve the current coverage percentage. Never merge a PR that
reduces coverage without explicit approval.
- Place all test files in a `__tests__/` directory co-located with the source, or in a
top-level `tests/` directory -- follow the convention already established in the repo.

---

## React Best Practices

### Server Components (RSC) -- Next.js App Router
- Default to Server Components. Only add `"use client"` when the component genuinely
needs interactivity, React hooks, or browser-only APIs.
- Data fetching belongs in Server Components or Server Actions -- not in client-side
`useEffect`.

### React 19 Patterns
- Use `useActionState` for form state management (replaces `useFormState`).
- Use `useOptimistic` for optimistic UI updates.
- Use Server Actions for mutations (`"use server"` functions).
- Use the `use()` hook for reading promises and context in render.

### Performance
- No premature optimization. Profile first with React DevTools or Lighthouse, then
optimize the identified bottleneck.
- Use `React.memo`, `useMemo`, and `useCallback` only when profiling shows a real
performance problem -- not preemptively.
- Use `<Suspense>` boundaries around async data to show meaningful loading states.
- Prefer streaming and partial rendering over blocking the entire page.

---

## Documentation Requirements

- Update `/docs` when changing architecture, adding features, or modifying APIs.
- Keep `README.md` current with accurate setup instructions and prerequisites.
- Delete stale documentation when removing features -- do not leave orphan docs.
- PRD (Product Requirements Document) must be updated for feature changes.
- Inline comments: add them only where the logic is non-obvious. Do not add comments
that merely restate the code.

---

## UI / Design Standards

### Component Library & Styling
- Use **shadcn/ui** components as the base component library.
- Use **Tailwind CSS v4** for all styling. No inline styles, no CSS modules, no
styled-components unless the repo already uses them.
- SVG icons only. No icon fonts (Font Awesome, Material Icons CDN), no PNG/JPG icons.

### Design Principles
- Clarity over cleverness. Every UI element should have an obvious purpose.
- Consistent spacing using Tailwind's spacing scale.
- Strong visual hierarchy: size, weight, and color should guide the user's eye.

### Animations
Follow Emil Kowalski's animation principles:
- Every animation must have a **purpose** (feedback, orientation, delight).
- Duration: **< 300ms** for UI transitions. Longer only for page-level choreography.
- Easing: **ease-out** for elements entering, **ease-in** for elements exiting.
- Prefer CSS transitions over JS animation libraries when possible.
- No animation is better than bad animation.

### Responsive & Accessibility
- Mobile-first responsive design. Start with the smallest breakpoint and scale up.
- Dark mode support where applicable (use Tailwind's `dark:` variant).
- Keyboard navigable: all interactive elements must be reachable via Tab.
- Screen reader friendly: use semantic HTML, ARIA labels where needed, alt text on
images.

---

## SEO Requirements

- Every page MUST have unique metadata: `title`, `description`, and `og:image`.
- Use structured data (JSON-LD) where applicable (articles, products, FAQ, breadcrumbs).
- Proper heading hierarchy: one `<h1>` per page, logical `<h2>` through `<h6>` nesting.
- Internal linking: related pages should link to each other.
- Alt text on ALL images. Decorative images use `alt=""`.
- No orphan pages -- every page must be reachable from at least one other page.
- Use `<link rel="canonical">` to prevent duplicate content issues.

---

## Blog Content Standards

Follow Google's helpful content guidelines:

- **Length**: 1000-2500+ words for substantive posts. Short posts are acceptable for
changelogs or announcements.
- **Structure**: Include categories, tags, author, publication date, and a table of
contents for posts over 1500 words.
- **CTA**: Every post needs a clear call-to-action or takeaway for the reader.
- **Quality**: Write for humans first. Provide unique insight, real examples, or
original research.

### Banned AI Writing Patterns
Never use these words/phrases that signal low-quality AI-generated content:
- "delve", "landscape", "tapestry", "in conclusion", "it's worth noting"
- "navigate the complexities", "in today's fast-paced", "game-changer"
- "dive deep", "unlock the power", "revolutionary"
- Excessive hedging ("it's important to note that...")
- Lists of generic advice with no specific examples

---

## Terminology & Style

- Maintain a `STYLE_GUIDE.md` in each repo for project-specific terminology.
- Use **American English** spelling (color, not colour; optimize, not optimise).
- Technical terms must be consistent across all content within a repo. Pick one term
and stick with it (e.g., "sign in" vs "log in" -- choose one).
- Brand names: use the official casing (GitHub, TypeScript, Next.js, Tailwind CSS).

---

## Package Manager

- **New projects**: Use **Bun** as the default package manager. Initialize with `bun init` and
commit a `bun.lock` file.
- **Existing repos**: Respect the package manager already in use. CI auto-detects based on lock
files:
- `pnpm-lock.yaml` → **pnpm**
- `package-lock.json` → **npm**
- No recognized lock file → **Bun** (default)
- Do NOT mix package managers within a single repo. If migrating, remove the old lock file and
regenerate with the new package manager in a dedicated PR.
- Use `--frozen-lockfile` (pnpm/bun) or `npm ci` (npm) in CI to ensure reproducible installs.

---

## Environment Variables

- Every repo MUST have a `.env.example` at the root listing ALL required environment
variables with placeholder values. This file is used by CI to provide dummy env vars
during builds.
- If a `.env.sample` file exists, **rename it to `.env.example`** and use that instead.
Do not keep both files.
- When adding, removing, or renaming an env var in code, **update `.env.example`** in
the same commit. Do not leave `.env.example` out of sync with the actual code.
- Format: one `KEY=placeholder_value` per line. Use comments to group related vars:
```
# Supabase
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

# Stripe
STRIPE_SECRET_KEY=sk_test_xxx
```
- Never put real secret values in `.env.example` — only descriptive placeholders.
- `.env.example` MUST be committed to git. `.env`, `.env.local`, and `.env.production`
MUST be in `.gitignore` and never committed.

---

## Security Requirements

- **No new vulnerabilities**: `npm audit` / `pnpm audit` must not introduce new
high or critical severity vulnerabilities.
- **No committed secrets**: Never commit API keys, tokens, passwords, or credentials.
Use environment variables and `.env.local` (which must be in `.gitignore`).
- **Input validation**: All user-facing forms must validate input on both client and
server side. Use Zod schemas for type-safe validation.
- **XSS prevention**: Sanitize all user-generated content before rendering. Never
render unsanitized HTML from user input. Use a sanitizer library like DOMPurify
when rendering dynamic HTML is unavoidable.
- **CSRF protection**: All mutations (POST, PUT, DELETE) must use CSRF tokens or
Server Actions (which handle CSRF automatically).
- **Dependencies**: Keep dependencies up to date. Review changelogs before major
version bumps.

---

## Dead Link Prevention

- Check all internal links before merging PRs that add or modify content.
- When deleting a page, update or remove all links that pointed to it.
- Use relative links for internal navigation (e.g., `/blog/my-post` not
`https://example.com/blog/my-post`).
- Redirects: when moving a page to a new URL, add a redirect from the old URL.
58 changes: 58 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
## Description
<!-- Brief description of changes -->

## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Refactoring

## Checklist

### Code Quality
- [ ] Lint passes (`pnpm lint` / `npm run lint`)
- [ ] TypeScript compiles (`pnpm typecheck` / `npm run typecheck`)
- [ ] Build succeeds (`pnpm build` / `npm run build`)
- [ ] No debug code (`console.log`, `debugger`, leftover `TODO`)
- [ ] No AI slop (unnecessary abstractions, over-engineering)

### Testing
- [ ] Unit tests added for new functionality
- [ ] BDD tests added for user-facing features
- [ ] All existing tests pass
- [ ] Edge cases covered

### Security
- [ ] No new npm audit vulnerabilities (high/critical)
- [ ] No committed secrets or API keys
- [ ] Input validation on user-facing forms
- [ ] XSS prevention (sanitized user content)

### Documentation
- [ ] `/docs` updated (if architecture changed)
- [ ] README updated (if setup changed)
- [ ] No stale documentation left behind
- [ ] Inline comments for complex logic only

### UI / Design (if applicable)
- [ ] Follows design system (shadcn/ui + Tailwind CSS v4)
- [ ] SVG icons only (no icon fonts, no PNGs)
- [ ] Animations < 300ms, purposeful
- [ ] Mobile responsive
- [ ] Accessible (keyboard nav, screen reader, alt text)

### SEO (if applicable)
- [ ] Metadata set (title, description, og:image)
- [ ] Structured data (JSON-LD) where applicable
- [ ] Heading hierarchy correct (single h1)
- [ ] Alt text on all images
- [ ] No broken internal links

### Blog Content (if applicable)
- [ ] 1000+ words for substantive posts
- [ ] Categories, tags, and author set
- [ ] Table of contents included
- [ ] No banned AI writing patterns
- [ ] Clear takeaway / CTA for the reader
49 changes: 49 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# CI Pipeline -- Thin caller workflow
# Calls reusable workflows from the OrrisTech/.github org repo.
# Synced to all repos via files-to-sync.yml.
name: CI

on:
pull_request:
push:
branches: [main, master]

# Permissions needed by reusable workflows:
# - contents:read — checkout code
# - pull-requests:write — react-doctor posts PR comments
permissions:
contents: read
pull-requests: write

# Cancel in-progress runs for the same branch/PR to save runner minutes
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
lint-typecheck:
name: Lint & Type Check
uses: OrrisTech/.github/.github/workflows/ci-lint-typecheck.yml@main
secrets: inherit

test:
name: Test
uses: OrrisTech/.github/.github/workflows/ci-test.yml@main
secrets: inherit

build:
name: Build
needs: [lint-typecheck]
uses: OrrisTech/.github/.github/workflows/ci-build.yml@main
secrets: inherit

security:
name: Security Audit
uses: OrrisTech/.github/.github/workflows/ci-security.yml@main
secrets: inherit

react-doctor:
name: React Doctor
if: github.event_name == 'pull_request'
uses: OrrisTech/.github/.github/workflows/ci-react-doctor.yml@main
Comment on lines +26 to +48
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These reusable workflows are referenced with @main. To avoid unexpected CI behavior changes (and reduce supply-chain risk), pin the uses: references to an immutable tag or commit SHA (or a dedicated release branch) and update intentionally when needed.

Suggested change
uses: OrrisTech/.github/.github/workflows/ci-lint-typecheck.yml@main
secrets: inherit
test:
name: Test
uses: OrrisTech/.github/.github/workflows/ci-test.yml@main
secrets: inherit
build:
name: Build
needs: [lint-typecheck]
uses: OrrisTech/.github/.github/workflows/ci-build.yml@main
secrets: inherit
security:
name: Security Audit
uses: OrrisTech/.github/.github/workflows/ci-security.yml@main
secrets: inherit
react-doctor:
name: React Doctor
if: github.event_name == 'pull_request'
uses: OrrisTech/.github/.github/workflows/ci-react-doctor.yml@main
uses: OrrisTech/.github/.github/workflows/ci-lint-typecheck.yml@ci-v1
secrets: inherit
test:
name: Test
uses: OrrisTech/.github/.github/workflows/ci-test.yml@ci-v1
secrets: inherit
build:
name: Build
needs: [lint-typecheck]
uses: OrrisTech/.github/.github/workflows/ci-build.yml@ci-v1
secrets: inherit
security:
name: Security Audit
uses: OrrisTech/.github/.github/workflows/ci-security.yml@ci-v1
secrets: inherit
react-doctor:
name: React Doctor
if: github.event_name == 'pull_request'
uses: OrrisTech/.github/.github/workflows/ci-react-doctor.yml@ci-v1

Copilot uses AI. Check for mistakes.
secrets: inherit
Loading
Loading