Skip to content

Commit de3e048

Browse files
authored
πŸ”€ merge pull request #364 from onRuntime/antoinekm/claude
πŸ“ add claude.md
2 parents d834e53 + 4f28b62 commit de3e048

7 files changed

Lines changed: 117 additions & 47 deletions

File tree

β€ŽCLAUDE.mdβ€Ž

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Commands
6+
7+
```bash
8+
# Development
9+
pnpm dev # Start dev server with Turbopack
10+
pnpm build # Build all packages
11+
pnpm type-check # Run TypeScript checks
12+
13+
# Run commands for specific app
14+
pnpm --filter @onruntime/web dev
15+
pnpm --filter @onruntime/web build
16+
```
17+
18+
## Architecture
19+
20+
### Monorepo Structure (Turborepo + pnpm workspaces)
21+
22+
```
23+
/
24+
β”œβ”€β”€ apps/
25+
β”‚ └── web/ # Next.js 16 website (@onruntime/web)
26+
β”œβ”€β”€ packages/ # Shared packages (future)
27+
β”œβ”€β”€ turbo.json # Turborepo configuration
28+
└── pnpm-workspace.yaml # pnpm workspace config
29+
```
30+
31+
### Web App Structure (`apps/web/src/`)
32+
33+
- **app/**: Next.js App Router pages and API routes
34+
- **components/**: React components (ui/, layout/, marketing/)
35+
- **services/**: External API clients with lazy initialization
36+
- **constants/**: Static data (projects, agencies, services, team members)
37+
- **content/**: MDX content (glossary, legal pages)
38+
- **lib/**: Utilities and helpers
39+
- **types/**: TypeScript type definitions
40+
41+
### Key Patterns
42+
43+
**Services**: Use lazy initialization for external API clients to avoid build failures when env vars are missing in CI:
44+
```typescript
45+
// services/email.ts - Proxy pattern for lazy init
46+
export const resend = new Proxy({} as Resend, {
47+
get(_, prop) {
48+
if (!instance) {
49+
instance = new Resend(env.RESEND_API_KEY);
50+
}
51+
return instance[prop as keyof Resend];
52+
},
53+
});
54+
55+
// services/join.ts - Client pattern
56+
export const joinClient = {
57+
async jobs() { ... },
58+
async job(id) { ... },
59+
};
60+
```
61+
62+
**Environment Variables**: Managed via `@t3-oss/env-nextjs` in `env.ts`. Validation is skipped in CI (`skipValidation: !!process.env.CI`).
63+
64+
**API Routes**: Use `unstable_cache` from Next.js for caching external API responses.
65+
66+
## Environment Variables
67+
68+
Required for runtime (optional for build):
69+
- `RESEND_API_KEY`: Email sending via Resend
70+
- `JOIN_API_KEY`: Job listings from join.com API
File renamed without changes.

β€Žapps/web/next.config.mjsβ€Ž

Lines changed: 0 additions & 44 deletions
This file was deleted.

β€Žapps/web/next.config.tsβ€Ž

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import createMDX from "@next/mdx";
2+
import type { NextConfig } from "next";
3+
import "./env";
4+
5+
const nextConfig: NextConfig = {
6+
pageExtensions: ["ts", "tsx", "js", "jsx", "md", "mdx"],
7+
reactStrictMode: process.env.NODE_ENV === "development",
8+
transpilePackages: ["next-seo"],
9+
env: {
10+
NEXT_PUBLIC_NODE_ENV: process.env.NODE_ENV,
11+
},
12+
webpack(config) {
13+
config.module.rules.push({
14+
test: /\.svg$/i,
15+
use: ["@svgr/webpack"],
16+
});
17+
return config;
18+
},
19+
async redirects() {
20+
return [
21+
{
22+
source: "/projects/instagram-dark/welcome",
23+
destination: "/projects/dark-theme-instagram",
24+
permanent: true,
25+
},
26+
{
27+
source: "/projects/instagram-dark",
28+
destination: "/projects/dark-theme-instagram",
29+
permanent: true,
30+
},
31+
{
32+
source: "/about",
33+
destination: "/npo",
34+
permanent: false,
35+
},
36+
];
37+
},
38+
};
39+
40+
const withMDX = createMDX({
41+
extension: /\.mdx?$/,
42+
});
43+
44+
export default withMDX(nextConfig);

β€Žapps/web/src/app/careers/[id]/page.tsxβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { constructMetadata } from "@/lib/utils/metadata";
33
import JobDetailPage from "@/screens/marketing/careers/job-details";
44
import { JobPosting } from "@/types/job";
55
import { Metadata } from "next";
6-
import { env } from "env.mjs";
6+
import { env } from "env";
77

88
async function getJobById(id: string): Promise<JobPosting | null> {
99
try {

β€Žapps/web/src/services/email.tsβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { env } from "env.mjs";
1+
import { env } from "env";
22
import { Resend } from "resend";
33

44
let instance: Resend | null = null;

β€Žapps/web/src/services/join.tsβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { z } from "zod";
2-
import { env } from "env.mjs";
2+
import { env } from "env";
33

44
const JOIN_API_BASE_URL = "https://api.join.com/v2";
55

0 commit comments

Comments
Β (0)