@withmata/blueprints 0.2.0
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/.claude/commands/audit.md +179 -0
- package/.claude/commands/discover.md +92 -0
- package/.claude/commands/new-blueprint.md +265 -0
- package/.claude/commands/new-project.md +230 -0
- package/.claude/commands/scaffold-auth.md +310 -0
- package/.claude/commands/scaffold-db.md +270 -0
- package/.claude/commands/scaffold-foundation.md +158 -0
- package/.cursor/commands/audit.md +179 -0
- package/.cursor/commands/discover.md +92 -0
- package/.cursor/commands/new-blueprint.md +265 -0
- package/.cursor/commands/new-project.md +230 -0
- package/.cursor/commands/scaffold-auth.md +310 -0
- package/.cursor/commands/scaffold-db.md +270 -0
- package/.cursor/commands/scaffold-foundation.md +158 -0
- package/.opencode/commands/audit.md +183 -0
- package/.opencode/commands/discover.md +96 -0
- package/.opencode/commands/new-blueprint.md +269 -0
- package/.opencode/commands/new-project.md +234 -0
- package/.opencode/commands/scaffold-auth.md +314 -0
- package/.opencode/commands/scaffold-db.md +274 -0
- package/.opencode/commands/scaffold-foundation.md +162 -0
- package/ENGINEERING.md +47 -0
- package/blueprints/discovery/product-discovery/BLUEPRINT.md +361 -0
- package/blueprints/discovery/product-discovery/templates/archetype-template.md +143 -0
- package/blueprints/discovery/product-discovery/templates/product-brief.md +65 -0
- package/blueprints/discovery/product-discovery/templates/product-thesis.md +64 -0
- package/blueprints/discovery/product-discovery/templates/research-summary.md +43 -0
- package/blueprints/features/auth-better-auth/BLUEPRINT.md +794 -0
- package/blueprints/features/auth-better-auth/files/client/auth-client.ts +31 -0
- package/blueprints/features/auth-better-auth/files/client/context/organization.ts +236 -0
- package/blueprints/features/auth-better-auth/files/client/hooks/use-create-organization.ts +45 -0
- package/blueprints/features/auth-better-auth/files/client/hooks/use-has-permission.ts +26 -0
- package/blueprints/features/auth-better-auth/files/client/hooks/use-organization.ts +64 -0
- package/blueprints/features/auth-better-auth/files/client/schema/auth.ts +21 -0
- package/blueprints/features/auth-better-auth/files/client/schema/organization.ts +51 -0
- package/blueprints/features/auth-better-auth/files/client/types/organization.ts +20 -0
- package/blueprints/features/auth-better-auth/files/db/auth-schema.ts +184 -0
- package/blueprints/features/auth-better-auth/files/db/drizzle.config.ts +21 -0
- package/blueprints/features/auth-better-auth/files/middleware/route-protection.ts +84 -0
- package/blueprints/features/auth-better-auth/files/server/auth-db.ts +18 -0
- package/blueprints/features/auth-better-auth/files/server/auth.ts +159 -0
- package/blueprints/features/auth-better-auth/files/server/env.ts +44 -0
- package/blueprints/features/auth-better-auth/files/server/middleware.ts +144 -0
- package/blueprints/features/db-drizzle-postgres/BLUEPRINT.md +596 -0
- package/blueprints/features/db-drizzle-postgres/files/db/drizzle.config.ts +18 -0
- package/blueprints/features/db-drizzle-postgres/files/db/env.example +3 -0
- package/blueprints/features/db-drizzle-postgres/files/db/package.json +33 -0
- package/blueprints/features/db-drizzle-postgres/files/db/src/client.ts +34 -0
- package/blueprints/features/db-drizzle-postgres/files/db/src/example-entity.ts +73 -0
- package/blueprints/features/db-drizzle-postgres/files/db/src/index.ts +8 -0
- package/blueprints/features/db-drizzle-postgres/files/db/src/scripts/seed.ts +50 -0
- package/blueprints/features/db-drizzle-postgres/files/db/tsconfig.json +13 -0
- package/blueprints/features/tailwind-v4/BLUEPRINT.md +29 -0
- package/blueprints/features/ui-shared-components/BLUEPRINT.md +35 -0
- package/blueprints/foundation/monorepo-turbo/BLUEPRINT.md +378 -0
- package/blueprints/foundation/monorepo-turbo/files/apps/web/app/globals.css +2 -0
- package/blueprints/foundation/monorepo-turbo/files/apps/web/app/layout.tsx +23 -0
- package/blueprints/foundation/monorepo-turbo/files/apps/web/app/page.tsx +7 -0
- package/blueprints/foundation/monorepo-turbo/files/apps/web/env.ts +13 -0
- package/blueprints/foundation/monorepo-turbo/files/apps/web/next.config.ts +12 -0
- package/blueprints/foundation/monorepo-turbo/files/apps/web/package.json +28 -0
- package/blueprints/foundation/monorepo-turbo/files/apps/web/postcss.config.mjs +5 -0
- package/blueprints/foundation/monorepo-turbo/files/apps/web/tsconfig.json +18 -0
- package/blueprints/foundation/monorepo-turbo/files/config/tailwind-config/package.json +14 -0
- package/blueprints/foundation/monorepo-turbo/files/config/tailwind-config/postcss.config.mjs +5 -0
- package/blueprints/foundation/monorepo-turbo/files/config/tailwind-config/shared-styles.css +88 -0
- package/blueprints/foundation/monorepo-turbo/files/config/typescript-config/base.json +19 -0
- package/blueprints/foundation/monorepo-turbo/files/config/typescript-config/nextjs.json +12 -0
- package/blueprints/foundation/monorepo-turbo/files/config/typescript-config/package.json +5 -0
- package/blueprints/foundation/monorepo-turbo/files/config/typescript-config/react-library.json +7 -0
- package/blueprints/foundation/monorepo-turbo/files/root/biome.json +46 -0
- package/blueprints/foundation/monorepo-turbo/files/root/gitignore +35 -0
- package/blueprints/foundation/monorepo-turbo/files/root/package.json +25 -0
- package/blueprints/foundation/monorepo-turbo/files/root/pnpm-workspace.yaml +5 -0
- package/blueprints/foundation/monorepo-turbo/files/root/turbo.json +30 -0
- package/dist/index.js +453 -0
- package/package.json +53 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Example Entity — Replace with your domain entity
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// This file demonstrates the Drizzle schema patterns used in this project.
|
|
5
|
+
// Copy this file for each new domain entity, then:
|
|
6
|
+
// 1. Define your enums (if any)
|
|
7
|
+
// 2. Define your table with columns and indexes
|
|
8
|
+
// 3. Export $inferSelect / $inferInsert types
|
|
9
|
+
// 4. Add the file path to drizzle/{{GROUP}}/drizzle.config.ts schema array
|
|
10
|
+
// 5. Add the re-export to this group's index.ts
|
|
11
|
+
// 6. Run `pnpm {{GROUP}}:generate` then `pnpm {{GROUP}}:migrate`
|
|
12
|
+
// =============================================================================
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
index,
|
|
16
|
+
pgEnum,
|
|
17
|
+
pgTable,
|
|
18
|
+
text,
|
|
19
|
+
timestamp,
|
|
20
|
+
uuid,
|
|
21
|
+
varchar,
|
|
22
|
+
} from "drizzle-orm/pg-core";
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Enums (optional — use pgEnum for PostgreSQL native enums)
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
export const exampleStatusEnum = pgEnum("example_status", [
|
|
29
|
+
"active",
|
|
30
|
+
"archived",
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// Table
|
|
35
|
+
// ============================================================================
|
|
36
|
+
|
|
37
|
+
export const example = pgTable(
|
|
38
|
+
"example",
|
|
39
|
+
{
|
|
40
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
41
|
+
|
|
42
|
+
// CONFIGURE: Uncomment these if using the auth blueprint for user/org scoping
|
|
43
|
+
// userId: text("user_id").notNull(),
|
|
44
|
+
// organizationId: text("organization_id").notNull(),
|
|
45
|
+
|
|
46
|
+
name: varchar("name", { length: 200 }).notNull(),
|
|
47
|
+
description: text("description"),
|
|
48
|
+
status: exampleStatusEnum("status").default("active").notNull(),
|
|
49
|
+
|
|
50
|
+
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
51
|
+
updatedAt: timestamp("updated_at")
|
|
52
|
+
.defaultNow()
|
|
53
|
+
.$onUpdate(() => new Date())
|
|
54
|
+
.notNull(),
|
|
55
|
+
},
|
|
56
|
+
(table) => [
|
|
57
|
+
index("example_name_idx").on(table.name),
|
|
58
|
+
index("example_status_idx").on(table.status),
|
|
59
|
+
// CONFIGURE: Add indexes for foreign key columns
|
|
60
|
+
// index("example_user_id_idx").on(table.userId),
|
|
61
|
+
// index("example_org_id_idx").on(table.organizationId),
|
|
62
|
+
],
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// Type Exports
|
|
67
|
+
// ============================================================================
|
|
68
|
+
|
|
69
|
+
/** Type for a row read from the database (all columns). */
|
|
70
|
+
export type Example = typeof example.$inferSelect;
|
|
71
|
+
|
|
72
|
+
/** Type for inserting a new row (required columns only, optionals omitted). */
|
|
73
|
+
export type NewExample = typeof example.$inferInsert;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// {{GROUP}} database schemas — barrel export
|
|
2
|
+
// Each domain entity has its own file, re-exported here.
|
|
3
|
+
//
|
|
4
|
+
// CONFIGURE: Add re-exports for each new entity file you create.
|
|
5
|
+
// After adding a new export here, also add the file to
|
|
6
|
+
// drizzle/{{GROUP}}/drizzle.config.ts schema array.
|
|
7
|
+
|
|
8
|
+
export * from "./example.js";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Seed Script — Development Data
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Populates the {{GROUP}} database with sample data for development.
|
|
5
|
+
//
|
|
6
|
+
// Usage: pnpm seed
|
|
7
|
+
// (runs via tsx, configured in packages/db/package.json)
|
|
8
|
+
//
|
|
9
|
+
// CONFIGURE: Replace the example inserts with your actual domain entities.
|
|
10
|
+
// =============================================================================
|
|
11
|
+
|
|
12
|
+
import { config } from "dotenv";
|
|
13
|
+
import { drizzle } from "drizzle-orm/node-postgres";
|
|
14
|
+
import pg from "pg";
|
|
15
|
+
import { example } from "../{{GROUP}}/index.js";
|
|
16
|
+
|
|
17
|
+
config({ path: "./.env" });
|
|
18
|
+
|
|
19
|
+
const DATABASE_URL = process.env.{{GROUP_UPPER}}_DATABASE_URL;
|
|
20
|
+
if (!DATABASE_URL) {
|
|
21
|
+
console.error("Missing {{GROUP_UPPER}}_DATABASE_URL in packages/db/.env");
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function seed() {
|
|
26
|
+
const pool = new pg.Pool({ connectionString: DATABASE_URL });
|
|
27
|
+
const db = drizzle(pool);
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
console.log("Seeding {{GROUP}} database...\n");
|
|
31
|
+
|
|
32
|
+
const [record] = await db
|
|
33
|
+
.insert(example)
|
|
34
|
+
.values({
|
|
35
|
+
name: "Example Record",
|
|
36
|
+
description: "Created by seed script",
|
|
37
|
+
})
|
|
38
|
+
.returning();
|
|
39
|
+
|
|
40
|
+
console.log(` Created example: "${record!.name}" (${record!.id})`);
|
|
41
|
+
console.log("\nDone!");
|
|
42
|
+
} finally {
|
|
43
|
+
await pool.end();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
seed().catch((err) => {
|
|
48
|
+
console.error("Seed failed:", err);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "{{SCOPE}}/typescript-config/base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "dist",
|
|
5
|
+
"rootDir": "src",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"module": "NodeNext",
|
|
9
|
+
"moduleResolution": "NodeNext"
|
|
10
|
+
},
|
|
11
|
+
"include": ["src/**/*.ts"],
|
|
12
|
+
"exclude": ["node_modules", "dist", "drizzle"]
|
|
13
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Tailwind v4 Blueprint — Full Design System Setup
|
|
2
|
+
|
|
3
|
+
## Tier
|
|
4
|
+
|
|
5
|
+
Feature
|
|
6
|
+
|
|
7
|
+
## Status
|
|
8
|
+
|
|
9
|
+
Planned.
|
|
10
|
+
|
|
11
|
+
## Problem
|
|
12
|
+
|
|
13
|
+
The foundation blueprint creates a minimal `config/tailwind-config/` package with basic theme tokens. Production apps need a complete design system: extended color palettes, dark mode strategy, animation utilities, typography scale, font loading, and component-friendly CSS custom properties. This blueprint extends the foundation's base into a full design system.
|
|
14
|
+
|
|
15
|
+
## Intended Scope
|
|
16
|
+
|
|
17
|
+
- Extended CSS custom properties and design tokens in `config/tailwind-config/`
|
|
18
|
+
- Dark mode setup (class-based or media-query)
|
|
19
|
+
- Animation utilities and keyframes
|
|
20
|
+
- Typography scale and font loading (local + variable fonts)
|
|
21
|
+
- Color palette generation using OKLCH color space
|
|
22
|
+
- shadcn/ui-compatible token structure
|
|
23
|
+
- Documentation of available tokens and usage patterns
|
|
24
|
+
|
|
25
|
+
## Blueprint Dependencies
|
|
26
|
+
|
|
27
|
+
| Blueprint | Type | Why |
|
|
28
|
+
|-----------|------|-----|
|
|
29
|
+
| `foundation/monorepo-turbo` | recommended | Provides the base `config/tailwind-config/` package with minimal theme tokens. Without it, this blueprint creates the config structure from scratch. Works in both monorepo and single-repo projects. |
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# UI Shared Components Blueprint — shadcn/ui + Monorepo
|
|
2
|
+
|
|
3
|
+
## Tier
|
|
4
|
+
|
|
5
|
+
Feature
|
|
6
|
+
|
|
7
|
+
## Status
|
|
8
|
+
|
|
9
|
+
Planned.
|
|
10
|
+
|
|
11
|
+
## Problem
|
|
12
|
+
|
|
13
|
+
Sharing UI components across multiple apps in a Turborepo monorepo requires careful package structure, export patterns, and styling integration. Without a standard setup, teams duplicate components, diverge on patterns, and fight build tooling issues.
|
|
14
|
+
|
|
15
|
+
## Intended Scope
|
|
16
|
+
|
|
17
|
+
- `packages/ui/` workspace package with shadcn/ui setup
|
|
18
|
+
- Component export pattern via barrel `index.ts`
|
|
19
|
+
- Consuming shared components from `apps/web/` and other apps
|
|
20
|
+
- Integration with the shared Tailwind config from `config/tailwind-config/`
|
|
21
|
+
- Component generation workflow (shadcn CLI adapted for monorepo)
|
|
22
|
+
- Storybook setup (optional)
|
|
23
|
+
|
|
24
|
+
## Blueprint Dependencies
|
|
25
|
+
|
|
26
|
+
| Blueprint | Type | Why |
|
|
27
|
+
|-----------|------|-----|
|
|
28
|
+
| `features/tailwind-v4` | required | UI components depend on design tokens and theme setup from the Tailwind blueprint. Without it, components lack consistent styling. |
|
|
29
|
+
| `foundation/monorepo-turbo` | recommended | Provides workspace structure, TypeScript config, and package conventions. Without it, the shared UI package is created as a local directory. |
|
|
30
|
+
|
|
31
|
+
### If `tailwind-v4` is not installed
|
|
32
|
+
|
|
33
|
+
The scaffold command should ask: "UI components need the Tailwind design system. Install tailwind-v4 first? (Y/n)"
|
|
34
|
+
|
|
35
|
+
If declined, scaffold with basic Tailwind defaults and warn about missing design tokens.
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
# Monorepo Foundation Blueprint — Turborepo + pnpm
|
|
2
|
+
|
|
3
|
+
## Tier
|
|
4
|
+
|
|
5
|
+
Foundation — produces the project skeleton: monorepo structure, tooling configuration, shared config packages, and a minimal Next.js application shell.
|
|
6
|
+
|
|
7
|
+
## Problem
|
|
8
|
+
|
|
9
|
+
Setting up a production-ready Turborepo monorepo from scratch involves dozens of interconnected configuration decisions — workspace layout, TypeScript config hierarchy, linting/formatting, CSS tooling, environment variable validation, package exports, and dev tooling. Getting any of these wrong creates friction that compounds over the life of the project. This blueprint produces a working skeleton that feature blueprints can build on.
|
|
10
|
+
|
|
11
|
+
## Status
|
|
12
|
+
|
|
13
|
+
Complete.
|
|
14
|
+
|
|
15
|
+
## Blueprint Dependencies
|
|
16
|
+
|
|
17
|
+
None. Reads from discovery context if available, but does not require it.
|
|
18
|
+
|
|
19
|
+
**Note:** This blueprint sets up a Turborepo monorepo. For single-repo applications (standalone Next.js, Node, or Bun apps), skip this blueprint and go directly to feature blueprints — they adapt to single-repo projects automatically.
|
|
20
|
+
|
|
21
|
+
## Output
|
|
22
|
+
|
|
23
|
+
This blueprint generates the project skeleton:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
<project-root>/
|
|
27
|
+
├── apps/
|
|
28
|
+
│ └── web/ # Next.js app (App Router)
|
|
29
|
+
│ ├── app/
|
|
30
|
+
│ │ ├── globals.css
|
|
31
|
+
│ │ ├── layout.tsx
|
|
32
|
+
│ │ └── page.tsx
|
|
33
|
+
│ ├── env.ts # t3-env validation
|
|
34
|
+
│ ├── next.config.ts
|
|
35
|
+
│ ├── package.json
|
|
36
|
+
│ ├── postcss.config.mjs
|
|
37
|
+
│ └── tsconfig.json
|
|
38
|
+
├── apis/ # Empty — backend blueprint adds server here
|
|
39
|
+
├── config/
|
|
40
|
+
│ ├── tailwind-config/ # Shared Tailwind v4 styles
|
|
41
|
+
│ │ ├── package.json
|
|
42
|
+
│ │ ├── postcss.config.mjs
|
|
43
|
+
│ │ └── shared-styles.css
|
|
44
|
+
│ └── typescript-config/ # Shared TypeScript base configs
|
|
45
|
+
│ ├── base.json
|
|
46
|
+
│ ├── nextjs.json
|
|
47
|
+
│ ├── package.json
|
|
48
|
+
│ └── react-library.json
|
|
49
|
+
├── packages/ # Empty — feature blueprints add packages here
|
|
50
|
+
├── .gitignore
|
|
51
|
+
├── biome.json # Linting + formatting
|
|
52
|
+
├── package.json # Root workspace scripts
|
|
53
|
+
├── pnpm-workspace.yaml # Workspace patterns
|
|
54
|
+
└── turbo.json # Task orchestration
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**What's NOT created** (handled by feature blueprints):
|
|
58
|
+
- `apis/server/` — backend/server feature blueprint
|
|
59
|
+
- `packages/db/` — database feature blueprint
|
|
60
|
+
- `packages/ui/` — UI component feature blueprint
|
|
61
|
+
- `packages/api-client/` — backend feature blueprint
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Architecture
|
|
66
|
+
|
|
67
|
+
### Monorepo Tool: Turborepo + pnpm
|
|
68
|
+
|
|
69
|
+
- **pnpm workspaces** — Fast, disk-efficient, strict dependency isolation. Hoists shared deps while preventing phantom dependencies.
|
|
70
|
+
- **Turborepo** — Task orchestration with dependency-aware caching. `dev` runs all workspaces in parallel. `build` respects dependency order via `^build`.
|
|
71
|
+
- **Workspace protocol** — Internal deps use `workspace:*` for automatic linking. No manual version tracking between packages.
|
|
72
|
+
|
|
73
|
+
### Linting & Formatting: Biome
|
|
74
|
+
|
|
75
|
+
Single tool replacing both ESLint and Prettier. Faster, simpler configuration, fewer dependencies.
|
|
76
|
+
|
|
77
|
+
- Formatter: 2-space indent, 80-char line width, double quotes, LF line endings
|
|
78
|
+
- Linter: recommended rules with a11y warnings
|
|
79
|
+
- Organizes imports automatically
|
|
80
|
+
- Single `biome.json` at root covers the entire monorepo
|
|
81
|
+
|
|
82
|
+
### TypeScript: Shared Config Package
|
|
83
|
+
|
|
84
|
+
TypeScript configs live in `config/typescript-config/` as a workspace package. Every other package extends from it.
|
|
85
|
+
|
|
86
|
+
- **`base.json`** — The foundation: strict mode, `noUncheckedIndexedAccess`, `NodeNext` modules, `ES2022` target
|
|
87
|
+
- **`nextjs.json`** — Extends base for Next.js apps: `ESNext` modules, `Bundler` resolution, `jsx: preserve`, `noEmit`
|
|
88
|
+
- **`react-library.json`** — Extends base for React packages: `jsx: react-jsx`
|
|
89
|
+
|
|
90
|
+
### Tailwind CSS v4: Shared Config Package
|
|
91
|
+
|
|
92
|
+
Tailwind v4 uses CSS-based configuration (no more `tailwind.config.js`). Shared styles live in `config/tailwind-config/` as a workspace package.
|
|
93
|
+
|
|
94
|
+
- **`shared-styles.css`** — `@import "tailwindcss"`, `@theme inline` with CSS custom properties, light/dark theme tokens using OKLCH color space
|
|
95
|
+
- Design tokens are set up for shadcn/ui compatibility (the UI feature blueprint extends this)
|
|
96
|
+
- Each consuming app imports: `@import "{{SCOPE}}/tailwind-config"`
|
|
97
|
+
|
|
98
|
+
### Module Resolution: Node.js Subpath Imports
|
|
99
|
+
|
|
100
|
+
Uses the `#` prefix pattern via `package.json` `imports` field instead of `@/` tsconfig path aliases.
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"imports": {
|
|
105
|
+
"#auth/*": "./auth/*",
|
|
106
|
+
"#components/*": "./components/*"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This is a Node.js native feature — works without bundler magic and is forward-compatible with all runtimes.
|
|
112
|
+
|
|
113
|
+
### Environment Variables: t3-env + Zod
|
|
114
|
+
|
|
115
|
+
Environment variables are validated at startup using `@t3-oss/env-nextjs` (client) or `@t3-oss/env-core` (server). Failed validation crashes immediately rather than failing at runtime.
|
|
116
|
+
|
|
117
|
+
- `env.ts` is imported at app entry point (imported in `next.config.ts` for the web app)
|
|
118
|
+
- Client vars prefixed with `NEXT_PUBLIC_`
|
|
119
|
+
- Feature blueprints merge their env vars into the existing `env.ts`
|
|
120
|
+
|
|
121
|
+
### Source-Based Packages
|
|
122
|
+
|
|
123
|
+
Workspace packages that are consumed by Next.js can export TypeScript source directly (no build step for dev). Next.js transpiles them via `transpilePackages`. Packages deployed standalone (like an API server) still build to `dist/`.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Naming Conventions
|
|
128
|
+
|
|
129
|
+
| What | Convention | Example |
|
|
130
|
+
|------|-----------|---------|
|
|
131
|
+
| Files and directories | kebab-case | `use-organization.ts`, `brand-voices/` |
|
|
132
|
+
| React components | PascalCase | `OrganizationProvider`, `MemberList` |
|
|
133
|
+
| Functions and variables | camelCase | `createAuthClient`, `useHasPermission` |
|
|
134
|
+
| TypeScript types/interfaces | PascalCase | `SessionUser`, `Organization` |
|
|
135
|
+
| Environment variables | SCREAMING_SNAKE_CASE | `BETTER_AUTH_SECRET`, `NEXT_PUBLIC_API_URL` |
|
|
136
|
+
| npm packages | `{{SCOPE}}/kebab-case` | `@myapp/db`, `@myapp/typescript-config` |
|
|
137
|
+
| CSS custom properties | kebab-case | `--color-primary`, `--radius-lg` |
|
|
138
|
+
| Database tables | snake_case | `user`, `organization`, `pipeline_runs` |
|
|
139
|
+
| Database enums | snake_case | `company_size`, `industry` |
|
|
140
|
+
|
|
141
|
+
### File Organization
|
|
142
|
+
|
|
143
|
+
- **Prefer named exports** over default exports
|
|
144
|
+
- **Co-locate related files** — tests, types, and schemas live next to their source
|
|
145
|
+
- **Feature-based structure** — organize by feature/domain, not by file type
|
|
146
|
+
- **Barrel exports** — each package exposes a clean public API via `index.ts`
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Folder Conventions
|
|
151
|
+
|
|
152
|
+
### Workspace Layout
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
apps/ # Deployable applications (web frontends, marketing sites)
|
|
156
|
+
apis/ # API servers (Hono, Express — added by backend feature blueprint)
|
|
157
|
+
packages/ # Shared libraries (db, ui, api-client — added by feature blueprints)
|
|
158
|
+
config/ # Shared configuration packages (typescript-config, tailwind-config)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### How Feature Blueprints Extend This
|
|
162
|
+
|
|
163
|
+
| Feature Blueprint | Creates |
|
|
164
|
+
|-------------------|---------|
|
|
165
|
+
| Backend/Server | `apis/server/` with Hono setup, adds `transpilePackages` to Next.js |
|
|
166
|
+
| Database | `packages/db/` with Drizzle config, schemas, connection helpers |
|
|
167
|
+
| UI Components | `packages/ui/` with shadcn setup, extends tailwind-config |
|
|
168
|
+
| Auth | Files across `apis/server/src/auth/`, `apps/web/auth/`, `packages/db/src/auth/` |
|
|
169
|
+
|
|
170
|
+
### Inside apps/web/
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
apps/web/
|
|
174
|
+
├── app/ # Next.js App Router
|
|
175
|
+
│ ├── (protected)/ # Route groups for auth-gated pages
|
|
176
|
+
│ ├── auth/ # Auth flow pages (added by auth blueprint)
|
|
177
|
+
│ ├── globals.css # CSS entry point
|
|
178
|
+
│ ├── layout.tsx # Root layout
|
|
179
|
+
│ └── page.tsx # Home page
|
|
180
|
+
├── auth/ # Auth client code (added by auth blueprint)
|
|
181
|
+
├── components/ # App-specific components
|
|
182
|
+
├── hooks/ # App-specific hooks
|
|
183
|
+
├── types/ # App-specific types
|
|
184
|
+
├── env.ts # Environment validation
|
|
185
|
+
├── next.config.ts
|
|
186
|
+
├── package.json
|
|
187
|
+
├── postcss.config.mjs
|
|
188
|
+
└── tsconfig.json
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## What's Configurable
|
|
194
|
+
|
|
195
|
+
| Choice | Default | Alternatives |
|
|
196
|
+
|--------|---------|-------------|
|
|
197
|
+
| npm scope | Derived from product name | Any valid npm scope |
|
|
198
|
+
| Package manager | pnpm | bun (documented alternative) |
|
|
199
|
+
| Node.js version | `>=22` | Any LTS version |
|
|
200
|
+
|
|
201
|
+
**Note on bun:** If using bun instead of pnpm, replace `pnpm-workspace.yaml` with a `workspaces` field in root `package.json`, and update the `packageManager` field. The workspace protocol (`workspace:*`) works the same way.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## What's Opinionated
|
|
206
|
+
|
|
207
|
+
These are locked-down decisions. The blueprint doesn't offer alternatives for these:
|
|
208
|
+
|
|
209
|
+
- **pnpm** as package manager (bun documented as alternative, but npm and yarn are not supported)
|
|
210
|
+
- **Turborepo** for monorepo task orchestration (not Nx, Lerna, or Rush)
|
|
211
|
+
- **Biome** for linting + formatting (not ESLint + Prettier)
|
|
212
|
+
- **Strict TypeScript** — `strict: true` and `noUncheckedIndexedAccess: true` in every package
|
|
213
|
+
- **Next.js App Router** (not Pages Router)
|
|
214
|
+
- **Tailwind CSS v4** with CSS-based configuration (not v3 with JS config)
|
|
215
|
+
- **Node.js subpath imports** (`#prefix`) for internal module resolution (not `@/` tsconfig paths)
|
|
216
|
+
- **`config/` as top-level dir** — shared configs are separate from `packages/`
|
|
217
|
+
- **`workspace:*` protocol** for all internal dependencies
|
|
218
|
+
- **t3-env + Zod** for environment variable validation
|
|
219
|
+
- **Named exports** preferred over default exports
|
|
220
|
+
- **Double quotes** for strings (configured in Biome)
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Expects from Discovery
|
|
225
|
+
|
|
226
|
+
If product discovery was run first (`.claude/project-context.md` exists with a `## Product Discovery` section), the foundation blueprint reads:
|
|
227
|
+
|
|
228
|
+
- **Product name** — used to derive the npm scope (e.g., "Acme Dashboard" → `@acme`)
|
|
229
|
+
- **Technical constraints** — may influence Node.js version target or workspace complexity
|
|
230
|
+
|
|
231
|
+
If no discovery was run, the foundation asks these questions directly.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Dependencies
|
|
236
|
+
|
|
237
|
+
### Root devDependencies
|
|
238
|
+
|
|
239
|
+
| Package | Version | Purpose |
|
|
240
|
+
|---------|---------|---------|
|
|
241
|
+
| `turbo` | `^2` | Monorepo task orchestration |
|
|
242
|
+
| `@biomejs/biome` | `^2` | Linting + formatting |
|
|
243
|
+
| `typescript` | `^5.9` | TypeScript compiler |
|
|
244
|
+
| `tsx` | `^4` | TypeScript execution for scripts |
|
|
245
|
+
| `@types/node` | `^22` | Node.js type definitions |
|
|
246
|
+
|
|
247
|
+
### apps/web dependencies
|
|
248
|
+
|
|
249
|
+
| Package | Version | Purpose |
|
|
250
|
+
|---------|---------|---------|
|
|
251
|
+
| `next` | `^15` | React framework |
|
|
252
|
+
| `react` | `^19` | UI library |
|
|
253
|
+
| `react-dom` | `^19` | React DOM renderer |
|
|
254
|
+
| `@t3-oss/env-nextjs` | `^0.13` | Environment variable validation |
|
|
255
|
+
| `zod` | `^3` | Schema validation (used by t3-env) |
|
|
256
|
+
|
|
257
|
+
### apps/web devDependencies
|
|
258
|
+
|
|
259
|
+
| Package | Version | Purpose |
|
|
260
|
+
|---------|---------|---------|
|
|
261
|
+
| `tailwindcss` | `^4` | CSS framework |
|
|
262
|
+
| `@tailwindcss/postcss` | `^4` | PostCSS plugin for Tailwind |
|
|
263
|
+
| `typescript` | `^5.9` | TypeScript compiler |
|
|
264
|
+
| `@types/react` | `^19` | React type definitions |
|
|
265
|
+
| `@types/react-dom` | `^19` | React DOM type definitions |
|
|
266
|
+
|
|
267
|
+
### config/tailwind-config dependencies
|
|
268
|
+
|
|
269
|
+
| Package | Version | Purpose |
|
|
270
|
+
|---------|---------|---------|
|
|
271
|
+
| `tailwindcss` | `^4` | Tailwind CSS v4 |
|
|
272
|
+
| `@tailwindcss/postcss` | `^4` | PostCSS integration |
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## File Manifest
|
|
277
|
+
|
|
278
|
+
| Blueprint File | Target Location | Description |
|
|
279
|
+
|----------------|-----------------|-------------|
|
|
280
|
+
| `files/root/package.json` | `package.json` | Root monorepo package.json with workspace scripts |
|
|
281
|
+
| `files/root/turbo.json` | `turbo.json` | Turborepo task configuration |
|
|
282
|
+
| `files/root/pnpm-workspace.yaml` | `pnpm-workspace.yaml` | Workspace patterns |
|
|
283
|
+
| `files/root/biome.json` | `biome.json` | Biome linter + formatter config |
|
|
284
|
+
| `files/root/gitignore` | `.gitignore` | Git ignore patterns |
|
|
285
|
+
| `files/config/typescript-config/package.json` | `config/typescript-config/package.json` | TypeScript config package |
|
|
286
|
+
| `files/config/typescript-config/base.json` | `config/typescript-config/base.json` | Base TypeScript config (strict) |
|
|
287
|
+
| `files/config/typescript-config/nextjs.json` | `config/typescript-config/nextjs.json` | Next.js TypeScript config |
|
|
288
|
+
| `files/config/typescript-config/react-library.json` | `config/typescript-config/react-library.json` | React library TypeScript config |
|
|
289
|
+
| `files/config/tailwind-config/package.json` | `config/tailwind-config/package.json` | Tailwind config package |
|
|
290
|
+
| `files/config/tailwind-config/shared-styles.css` | `config/tailwind-config/shared-styles.css` | Shared Tailwind v4 styles + theme |
|
|
291
|
+
| `files/config/tailwind-config/postcss.config.mjs` | `config/tailwind-config/postcss.config.mjs` | PostCSS config for Tailwind |
|
|
292
|
+
| `files/apps/web/package.json` | `apps/web/package.json` | Next.js app package.json |
|
|
293
|
+
| `files/apps/web/tsconfig.json` | `apps/web/tsconfig.json` | Next.js TypeScript config |
|
|
294
|
+
| `files/apps/web/next.config.ts` | `apps/web/next.config.ts` | Next.js configuration |
|
|
295
|
+
| `files/apps/web/env.ts` | `apps/web/env.ts` | Environment variable validation |
|
|
296
|
+
| `files/apps/web/postcss.config.mjs` | `apps/web/postcss.config.mjs` | PostCSS config for web app |
|
|
297
|
+
| `files/apps/web/app/layout.tsx` | `apps/web/app/layout.tsx` | Root layout with font + metadata |
|
|
298
|
+
| `files/apps/web/app/page.tsx` | `apps/web/app/page.tsx` | Home page placeholder |
|
|
299
|
+
| `files/apps/web/app/globals.css` | `apps/web/app/globals.css` | CSS entry point |
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Integration Points
|
|
304
|
+
|
|
305
|
+
- **npm scope** — Used by every feature blueprint for package names and imports (e.g., `{{SCOPE}}/db`, `{{SCOPE}}/typescript-config`)
|
|
306
|
+
- **TypeScript configs** — Feature blueprints extend `{{SCOPE}}/typescript-config/base.json` (or `nextjs.json` / `react-library.json`)
|
|
307
|
+
- **Tailwind config** — UI feature blueprint extends `{{SCOPE}}/tailwind-config` with additional component styles
|
|
308
|
+
- **Workspace dirs** — Feature blueprints create new packages in `apis/`, `packages/` — foundation creates the empty dirs and workspace patterns
|
|
309
|
+
- **Root scripts** — Feature blueprints add scripts to root `package.json` (e.g., `auth:generate`, `db:migrate`)
|
|
310
|
+
- **Turbo tasks** — Feature blueprints add tasks to `turbo.json` (e.g., `auth:generate: { cache: false }`)
|
|
311
|
+
- **Environment variables** — Feature blueprints merge their vars into `apps/web/env.ts` and add server-side env files
|
|
312
|
+
- **project-context.md** — Feature blueprints read the Foundation section to determine npm scope, workspace layout
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Maintenance Hooks
|
|
317
|
+
|
|
318
|
+
### Git Hooks (lefthook)
|
|
319
|
+
|
|
320
|
+
The foundation blueprint includes a lefthook configuration for mechanical code quality enforcement. These run automatically on git actions — no AI involvement needed.
|
|
321
|
+
|
|
322
|
+
**Pre-commit:**
|
|
323
|
+
- Format staged files with Biome
|
|
324
|
+
- Auto-fix and re-stage
|
|
325
|
+
|
|
326
|
+
**Pre-push:**
|
|
327
|
+
- Run typecheck across all workspaces
|
|
328
|
+
|
|
329
|
+
The lefthook config is minimal by design. Feature blueprints may add their own checks (e.g., auth:generate verification).
|
|
330
|
+
|
|
331
|
+
### Structural Hooks (for CLAUDE.md)
|
|
332
|
+
|
|
333
|
+
| When you... | Then run... | Why |
|
|
334
|
+
|---|---|---|
|
|
335
|
+
| Add a new workspace package to `apps/`, `apis/`, `packages/`, or `config/` | Verify `pnpm-workspace.yaml` patterns cover it, then run `pnpm install` | New workspaces need to be discovered by pnpm |
|
|
336
|
+
| Change a shared config package (`config/typescript-config/` or `config/tailwind-config/`) | Run `pnpm dev` and verify all consuming packages still build | Shared config changes cascade to all consumers |
|
|
337
|
+
| Add a workspace dependency (e.g., `"@scope/ui": "workspace:*"`) | Run `pnpm install` then verify imports resolve | Workspace links need pnpm to wire them up |
|
|
338
|
+
| Modify `turbo.json` task definitions | Verify `pnpm turbo run <task>` executes in the expected order | Task dependency changes affect build orchestration |
|
|
339
|
+
| Change the TypeScript `base.json` config | Run typecheck across all workspaces: `pnpm turbo typecheck` | Base config changes affect every package |
|
|
340
|
+
|
|
341
|
+
### Condensed Rules for CLAUDE.md
|
|
342
|
+
```markdown
|
|
343
|
+
### Monorepo maintenance
|
|
344
|
+
- After every code change: format with Biome (`pnpm biome check --write .`) before considering work complete
|
|
345
|
+
- After adding new workspace packages: verify `pnpm-workspace.yaml` patterns match, run `pnpm install`
|
|
346
|
+
- After modifying shared configs (`config/typescript-config/`, `config/tailwind-config/`): verify all consumers still build
|
|
347
|
+
- After changing `turbo.json`: verify task ordering with `pnpm turbo run <task> --dry`
|
|
348
|
+
- After adding workspace dependencies: run `pnpm install` to create workspace links
|
|
349
|
+
- Keep `turbo.json` tasks with `cache: false` for any task with side effects (migrations, code generation)
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Project Context Output
|
|
355
|
+
|
|
356
|
+
After completion, appends to `.claude/project-context.md`:
|
|
357
|
+
|
|
358
|
+
```yaml
|
|
359
|
+
## Foundation
|
|
360
|
+
monorepo_tool: turborepo
|
|
361
|
+
package_manager: pnpm
|
|
362
|
+
npm_scope: "{{SCOPE}}"
|
|
363
|
+
node_version: ">=22"
|
|
364
|
+
workspaces:
|
|
365
|
+
apps: ["web"]
|
|
366
|
+
apis: []
|
|
367
|
+
packages: []
|
|
368
|
+
config: ["typescript-config", "tailwind-config"]
|
|
369
|
+
framework: next.js (app router)
|
|
370
|
+
typescript: strict
|
|
371
|
+
linter: biome
|
|
372
|
+
styling: tailwind-v4
|
|
373
|
+
env_validation: t3-env + zod
|
|
374
|
+
module_resolution: node subpath imports (#prefix)
|
|
375
|
+
foundation_completed: <date>
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { Inter } from "next/font/google";
|
|
3
|
+
import "./globals.css";
|
|
4
|
+
|
|
5
|
+
// CONFIGURE: Replace with your preferred font
|
|
6
|
+
const inter = Inter({ subsets: ["latin"] });
|
|
7
|
+
|
|
8
|
+
export const metadata: Metadata = {
|
|
9
|
+
title: "{{APP_NAME}}",
|
|
10
|
+
description: "",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default function RootLayout({
|
|
14
|
+
children,
|
|
15
|
+
}: Readonly<{
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
}>) {
|
|
18
|
+
return (
|
|
19
|
+
<html lang="en">
|
|
20
|
+
<body className={inter.className}>{children}</body>
|
|
21
|
+
</html>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createEnv } from "@t3-oss/env-nextjs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const env = createEnv({
|
|
5
|
+
client: {
|
|
6
|
+
NEXT_PUBLIC_FRONTEND_URL: z.string().url(),
|
|
7
|
+
// CONFIGURE: Feature blueprints add their env vars here
|
|
8
|
+
// e.g., NEXT_PUBLIC_API_URL for backend blueprint
|
|
9
|
+
},
|
|
10
|
+
runtimeEnv: {
|
|
11
|
+
NEXT_PUBLIC_FRONTEND_URL: process.env.NEXT_PUBLIC_FRONTEND_URL,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { NextConfig } from "next";
|
|
2
|
+
|
|
3
|
+
// CONFIGURE: Import env.ts to validate environment variables at build time
|
|
4
|
+
import "./env";
|
|
5
|
+
|
|
6
|
+
const nextConfig: NextConfig = {
|
|
7
|
+
// CONFIGURE: Feature blueprints may add:
|
|
8
|
+
// - transpilePackages: ["{{SCOPE}}/api-client"] for source-based workspace packages
|
|
9
|
+
// - rewrites() for API proxy in production (cross-domain cookie support)
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default nextConfig;
|