create-atsdc-stack 1.1.0 → 1.2.1

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.
Files changed (48) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/CLAUDE.md +236 -215
  3. package/CONTRIBUTING.md +342 -342
  4. package/INSTALLATION.md +359 -359
  5. package/LICENSE +201 -201
  6. package/README.md +405 -405
  7. package/app/.env.example +17 -17
  8. package/app/.github/labeler.yml +61 -0
  9. package/app/.github/workflows/browser-tests.yml +101 -0
  10. package/app/.github/workflows/check.yml +24 -0
  11. package/app/.github/workflows/greetings.yml +16 -0
  12. package/app/.github/workflows/label.yml +22 -0
  13. package/app/.github/workflows/stale.yml +27 -0
  14. package/app/.github/workflows/summary.yml +34 -0
  15. package/app/.stylelintrc.json +8 -0
  16. package/app/README.md +251 -251
  17. package/app/astro.config.mjs +83 -83
  18. package/app/drizzle.config.ts +16 -16
  19. package/app/package.json +66 -52
  20. package/app/playwright.config.ts +27 -0
  21. package/app/public/manifest.webmanifest +36 -36
  22. package/app/pwa-assets.config.ts +8 -0
  23. package/app/src/components/Card.astro +36 -36
  24. package/app/src/db/initialize.ts +107 -107
  25. package/app/src/db/schema.ts +72 -72
  26. package/app/src/db/validations.ts +158 -158
  27. package/app/src/layouts/Layout.astro +63 -63
  28. package/app/src/lib/config.ts +36 -36
  29. package/app/src/lib/content-converter.ts +141 -141
  30. package/app/src/lib/dom-utils.ts +230 -230
  31. package/app/src/lib/exa-search.ts +269 -269
  32. package/app/src/pages/api/chat.ts +91 -91
  33. package/app/src/pages/api/posts.ts +350 -350
  34. package/app/src/pages/index.astro +87 -87
  35. package/app/src/styles/components/button.scss +152 -152
  36. package/app/src/styles/components/card.scss +180 -180
  37. package/app/src/styles/components/form.scss +240 -240
  38. package/app/src/styles/global.scss +141 -141
  39. package/app/src/styles/pages/index.scss +80 -80
  40. package/app/src/styles/reset.scss +83 -83
  41. package/app/src/styles/variables/globals.scss +96 -96
  42. package/app/src/styles/variables/mixins.scss +238 -238
  43. package/app/tests/browser.test.nopause.ts +10 -0
  44. package/app/tests/browser.test.ts +13 -0
  45. package/bin/cli.js +1151 -1151
  46. package/package.json +8 -6
  47. package/app/.astro/settings.json +0 -5
  48. package/app/.astro/types.d.ts +0 -1
@@ -3,7 +3,9 @@
3
3
  "allow": [
4
4
  "Bash(node -e:*)",
5
5
  "Bash(git mv:*)",
6
- "Bash(git add:*)"
6
+ "Bash(git add:*)",
7
+ "Bash(test:*)",
8
+ "Bash(npm install:*)"
7
9
  ]
8
10
  }
9
11
  }
package/CLAUDE.md CHANGED
@@ -1,215 +1,236 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Project Overview
6
-
7
- The ATSDC Stack is a full-stack web application framework built with Astro, TypeScript, SCSS, Drizzle ORM, and Clerk. It's designed as both a production-ready template and a CLI tool for scaffolding new projects.
8
-
9
- This is a monorepo with two main parts:
10
- - **Root**: CLI tool for scaffolding new projects (`create-atsdc-stack`)
11
- - **app/**: The actual Astro application template
12
-
13
- ## Development Commands
14
-
15
- Run these commands from the **root directory** (they delegate to the app workspace):
16
-
17
- ```bash
18
- # Development
19
- npm run dev # Start dev server at http://localhost:4321
20
-
21
- # Build & Preview
22
- npm run build # Type-check and build for production
23
- npm run preview # Preview production build locally
24
-
25
- # Database Operations
26
- npm run db:push # Push schema changes to database (no migrations)
27
- npm run db:generate # Generate migration files from schema
28
- npm run db:migrate # Apply pending migrations
29
- npm run db:studio # Open Drizzle Studio GUI for database
30
- ```
31
-
32
- ## Architecture Overview
33
-
34
- ### Database Layer (Drizzle ORM)
35
-
36
- **Key files:**
37
- - `app/src/db/schema.ts` - Table definitions using Drizzle ORM
38
- - `app/src/db/validations.ts` - Zod schemas for runtime validation
39
- - `app/src/db/initialize.ts` - Database client initialization and utilities
40
- - `app/drizzle.config.ts` - Drizzle Kit configuration
41
-
42
- **Important patterns:**
43
- - Uses **NanoID** (21 chars) for all primary keys, not UUIDs or auto-increment
44
- - All IDs are `varchar(21)` with `.$defaultFn(() => nanoid())`
45
- - TypeScript types are inferred: `typeof posts.$inferSelect` and `typeof posts.$inferInsert`
46
- - Zod validation schemas mirror database schemas but add runtime validation
47
- - Use `@vercel/postgres` for connection pooling, wrapped by Drizzle
48
-
49
- ### API Routes
50
-
51
- **Location:** `app/src/pages/api/`
52
-
53
- **Pattern:** Each file exports HTTP methods as named exports:
54
- ```typescript
55
- export const GET: APIRoute = async ({ request, url }) => { ... }
56
- export const POST: APIRoute = async ({ request }) => { ... }
57
- export const PUT: APIRoute = async ({ request }) => { ... }
58
- export const DELETE: APIRoute = async ({ request, url }) => { ... }
59
- ```
60
-
61
- **Key conventions:**
62
- 1. Always validate inputs with Zod schemas from `validations.ts`
63
- 2. Return JSON responses with proper status codes (200, 201, 400, 404, 500)
64
- 3. Handle `ZodError` separately from generic errors
65
- 4. Use Drizzle query builder, not raw SQL
66
- 5. For query params, use `url.searchParams.get()` and validate with Zod
67
-
68
- **Example:** See `app/src/pages/api/posts.ts` for complete CRUD implementation
69
-
70
- ### AI Integration (Vercel AI SDK v5+)
71
-
72
- **Location:** `app/src/pages/api/chat.ts`
73
-
74
- **Key pattern:** Uses AI Gateway - no provider-specific packages needed!
75
- ```typescript
76
- import { streamText } from 'ai';
77
-
78
- const result = streamText({
79
- model: 'openai/gpt-4o', // or 'anthropic/claude-3-5-sonnet-20241022'
80
- messages: validatedData.messages,
81
- apiKey: process.env.OPENAI_API_KEY, // Pass the appropriate API key
82
- });
83
-
84
- return result.toDataStreamResponse();
85
- ```
86
-
87
- **Supported formats:** `openai/`, `anthropic/`, `google/`, etc.
88
-
89
- ### SCSS Architecture
90
-
91
- **Critical rules:**
92
- 1. **NO inline `<style>` tags** in `.astro` files (except truly standalone components)
93
- 2. **NO utility classes** - use semantic class names (`.btn`, `.card`, not `.px-4`)
94
- 3. All styles in external `.scss` files under `app/src/styles/`
95
- 4. Component styles: `app/src/styles/components/`
96
- 5. Page styles: `app/src/styles/pages/`
97
- 6. Global variables auto-imported via Vite config: `@use "@/styles/variables/globals.scss" as *;`
98
-
99
- **Import pattern in .astro files:**
100
- ```astro
101
- ---
102
- import '@/styles/components/button.scss';
103
- import '@/styles/pages/example.scss';
104
- ---
105
- ```
106
-
107
- **Styling modifiers (in order of preference):**
108
- 1. Data attributes: `<button class="btn" data-variant="primary" data-size="lg">`
109
- 2. Class chaining: `<button class="btn primary lg">`
110
-
111
- **SCSS organization:**
112
- - `variables/globals.scss` - Colors, spacing, typography
113
- - `variables/mixins.scss` - Reusable mixins like `@include flex-center`
114
- - `reset.scss` - CSS reset
115
- - `global.scss` - Global base styles
116
-
117
- ### TypeScript Path Aliases
118
-
119
- Configured in `app/tsconfig.json`:
120
- ```json
121
- {
122
- "@/*": ["src/*"],
123
- "@db/*": ["src/db/*"],
124
- "@styles/*": ["src/styles/*"],
125
- "@components/*": ["src/components/*"]
126
- }
127
- ```
128
-
129
- **Usage:**
130
- ```typescript
131
- import { db } from '@/db/initialize';
132
- import { posts } from '@/db/schema';
133
- import '@/styles/components/card.scss';
134
- ```
135
-
136
- ### Authentication (Clerk)
137
-
138
- - Pre-configured in `app/astro.config.mjs`
139
- - Middleware: Create `app/src/middleware.ts` with `clerkMiddleware()` to protect routes
140
- - User IDs stored as `authorId` in database (varchar 255)
141
- - React components available via `@clerk/clerk-react`
142
-
143
- ### Progressive Web App (PWA)
144
-
145
- - Configured via `vite-plugin-pwa` in `astro.config.mjs`
146
- - Auto-updates enabled (`registerType: 'autoUpdate'`)
147
- - Manifest and service worker auto-generated
148
- - Assets should be in `app/public/` (pwa-192x192.png, pwa-512x512.png)
149
-
150
- ## Environment Variables
151
-
152
- **Required:**
153
- - `DATABASE_URL` - PostgreSQL connection string
154
- - `PUBLIC_CLERK_PUBLISHABLE_KEY` - Clerk publishable key
155
- - `CLERK_SECRET_KEY` - Clerk secret key
156
- - `OPENAI_API_KEY` - OpenAI API key (for AI features)
157
-
158
- **Setup:** Copy `.env.example` to `.env` and fill in values
159
-
160
- ## Key Design Decisions
161
-
162
- 1. **NanoID over UUID/auto-increment:** URL-safe, shorter, equally collision-resistant
163
- 2. **Vercel Postgres over node-postgres:** Better connection pooling for serverless
164
- 3. **Drizzle over Prisma:** Closer to SQL, better TypeScript inference, lighter weight
165
- 4. **Zod validation separate from schema:** Allows different validation rules for create/update operations
166
- 5. **SCSS over Tailwind:** Enforces semantic naming, better for large teams and maintainability
167
- 6. **Astro server mode:** Enables API routes and dynamic rendering with Vercel adapter
168
-
169
- ## Common Patterns
170
-
171
- ### Creating a new database table
172
-
173
- 1. Define schema in `app/src/db/schema.ts` using NanoID for primary key
174
- 2. Create Zod schemas in `app/src/db/validations.ts` for create/update operations
175
- 3. Export TypeScript types: `export type MyModel = typeof myTable.$inferSelect`
176
- 4. Push to database: `npm run db:push` (dev) or `npm run db:generate && npm run db:migrate` (prod)
177
-
178
- ### Creating a new API route
179
-
180
- 1. Create file in `app/src/pages/api/[name].ts`
181
- 2. Export named HTTP method handlers: `GET`, `POST`, `PUT`, `DELETE`
182
- 3. Validate inputs with Zod schemas
183
- 4. Use Drizzle ORM for database operations
184
- 5. Return JSON responses with proper error handling
185
-
186
- ### Adding new styles
187
-
188
- 1. Create `.scss` file in appropriate location (`components/` or `pages/`)
189
- 2. Import in `.astro` component: `import '@/styles/components/mycomponent.scss'`
190
- 3. Use semantic class names with data attributes for modifiers
191
- 4. Access global variables/mixins automatically (via Vite config)
192
-
193
- ## Testing Database Connection
194
-
195
- ```typescript
196
- import { getDatabaseHealth } from '@/db/initialize';
197
-
198
- const health = await getDatabaseHealth();
199
- // Returns: { connected: boolean, tablesExist: boolean, timestamp: Date }
200
- ```
201
-
202
- ## Deployment
203
-
204
- Configured for **Vercel** deployment with:
205
- - Adapter: `@astrojs/vercel` (serverless mode)
206
- - Build command: `npm run build`
207
- - Output directory: `app/dist/`
208
- - Environment variables must be set in Vercel project settings
209
-
210
- ## Workspace Structure
211
-
212
- This is an npm workspace:
213
- - Root `package.json` contains CLI tooling and workspace configuration
214
- - `app/package.json` contains the Astro application dependencies
215
- - Commands run from root are proxied to the app workspace via `--workspace=app`
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ The ATSDC Stack is a full-stack web application framework built with Astro, TypeScript, SCSS, Drizzle ORM, and Clerk. It's designed as both a production-ready template and a CLI tool for scaffolding new projects.
8
+
9
+ This is a monorepo with two main parts:
10
+
11
+ - **Root**: CLI tool for scaffolding new projects (`create-atsdc-stack`)
12
+ - **app/**: The actual Astro application template
13
+
14
+ ## Development Commands
15
+
16
+ ### Root Directory Commands
17
+
18
+ These commands can be run from the root directory (they delegate to the app workspace):
19
+
20
+ ```bash
21
+ npm run dev # Start dev server at http://localhost:4321
22
+ npm run build # Type-check and build for production
23
+ npm run preview # Preview production build locally
24
+ ```
25
+
26
+ ### App Directory Commands
27
+
28
+ Database commands should be run from the `app/` directory:
29
+
30
+ ```bash
31
+ cd app
32
+
33
+ npx drizzle-kit push # Push schema changes to database (no migrations)
34
+ npx drizzle-kit generate # Generate migration files from schema
35
+ npx drizzle-kit migrate # Apply pending migrations
36
+ npx drizzle-kit studio # Open Drizzle Studio GUI for database
37
+ ```
38
+
39
+ ## Architecture Overview
40
+
41
+ ### Database Layer (Drizzle ORM)
42
+
43
+ **Key files:**
44
+
45
+ - `app/src/db/schema.ts` - Table definitions using Drizzle ORM
46
+ - `app/src/db/validations.ts` - Zod schemas for runtime validation
47
+ - `app/src/db/initialize.ts` - Database client initialization and utilities
48
+ - `app/drizzle.config.ts` - Drizzle Kit configuration
49
+
50
+ **Important patterns:**
51
+
52
+ - Uses **NanoID** (21 chars) for all primary keys, not UUIDs or auto-increment
53
+ - All IDs are `varchar(21)` with `.$defaultFn(() => nanoid())`
54
+ - TypeScript types are inferred: `typeof posts.$inferSelect` and `typeof posts.$inferInsert`
55
+ - Zod validation schemas mirror database schemas but add runtime validation
56
+ - Use `@vercel/postgres` for connection pooling, wrapped by Drizzle
57
+
58
+ ### API Routes
59
+
60
+ **Location:** `app/src/pages/api/`
61
+
62
+ **Pattern:** Each file exports HTTP methods as named exports:
63
+
64
+ ```typescript
65
+ export const GET: APIRoute = async ({ request, url }) => { ... }
66
+ export const POST: APIRoute = async ({ request }) => { ... }
67
+ export const PUT: APIRoute = async ({ request }) => { ... }
68
+ export const DELETE: APIRoute = async ({ request, url }) => { ... }
69
+ ```
70
+
71
+ **Key conventions:**
72
+
73
+ 1. Always validate inputs with Zod schemas from `validations.ts`
74
+ 2. Return JSON responses with proper status codes (200, 201, 400, 404, 500)
75
+ 3. Handle `ZodError` separately from generic errors
76
+ 4. Use Drizzle query builder, not raw SQL
77
+ 5. For query params, use `url.searchParams.get()` and validate with Zod
78
+
79
+ **Example:** See `app/src/pages/api/posts.ts` for complete CRUD implementation
80
+
81
+ ### AI Integration (Vercel AI SDK v5+)
82
+
83
+ **Location:** `app/src/pages/api/chat.ts`
84
+
85
+ **Key pattern:** Uses AI Gateway - no provider-specific packages needed!
86
+
87
+ ```typescript
88
+ import { streamText } from 'ai';
89
+
90
+ const result = streamText({
91
+ model: 'openai/gpt-4o', // or 'anthropic/claude-3-5-sonnet-20241022'
92
+ messages: validatedData.messages,
93
+ apiKey: process.env.OPENAI_API_KEY, // Pass the appropriate API key
94
+ });
95
+
96
+ return result.toDataStreamResponse();
97
+ ```
98
+
99
+ **Supported formats:** `openai/`, `anthropic/`, `google/`, etc.
100
+
101
+ ### SCSS Architecture
102
+
103
+ **Critical rules:**
104
+
105
+ 1. **NO inline `<style>` tags** in `.astro` files (except truly standalone components)
106
+ 2. **NO utility classes** - use semantic class names (`.btn`, `.card`, not `.px-4`)
107
+ 3. All styles in external `.scss` files under `app/src/styles/`
108
+ 4. Component styles: `app/src/styles/components/`
109
+ 5. Page styles: `app/src/styles/pages/`
110
+ 6. Global variables auto-imported via Vite config: `@use "@/styles/variables/globals.scss" as *;`
111
+
112
+ **Import pattern in .astro files:**
113
+
114
+ ```astro
115
+ ---
116
+ import '@/styles/components/button.scss';
117
+ import '@/styles/pages/example.scss';
118
+ ---
119
+ ```
120
+
121
+ **Styling modifiers (in order of preference):**
122
+
123
+ 1. Data attributes: `<button class="btn" data-variant="primary" data-size="lg">`
124
+ 2. Class chaining: `<button class="btn primary lg">`
125
+
126
+ **SCSS organization:**
127
+
128
+ - `variables/globals.scss` - Colors, spacing, typography
129
+ - `variables/mixins.scss` - Reusable mixins like `@include flex-center`
130
+ - `reset.scss` - CSS reset
131
+ - `global.scss` - Global base styles
132
+
133
+ ### TypeScript Path Aliases
134
+
135
+ Configured in `app/tsconfig.json`:
136
+
137
+ ```json
138
+ {
139
+ "@/*": ["src/*"],
140
+ "@db/*": ["src/db/*"],
141
+ "@styles/*": ["src/styles/*"],
142
+ "@components/*": ["src/components/*"]
143
+ }
144
+ ```
145
+
146
+ **Usage:**
147
+
148
+ ```typescript
149
+ import { db } from '@/db/initialize';
150
+ import { posts } from '@/db/schema';
151
+ import '@/styles/components/card.scss';
152
+ ```
153
+
154
+ ### Authentication (Clerk)
155
+
156
+ - Pre-configured in `app/astro.config.mjs`
157
+ - Middleware: Create `app/src/middleware.ts` with `clerkMiddleware()` to protect routes
158
+ - User IDs stored as `authorId` in database (varchar 255)
159
+ - React components available via `@clerk/clerk-react`
160
+
161
+ ### Progressive Web App (PWA)
162
+
163
+ - Configured via `vite-plugin-pwa` in `astro.config.mjs`
164
+ - Auto-updates enabled (`registerType: 'autoUpdate'`)
165
+ - Manifest and service worker auto-generated
166
+ - Assets should be in `app/public/` (pwa-192x192.png, pwa-512x512.png)
167
+
168
+ ## Environment Variables
169
+
170
+ **Required:**
171
+
172
+ - `DATABASE_URL` - PostgreSQL connection string
173
+ - `PUBLIC_CLERK_PUBLISHABLE_KEY` - Clerk publishable key
174
+ - `CLERK_SECRET_KEY` - Clerk secret key
175
+ - `OPENAI_API_KEY` - OpenAI API key (for AI features)
176
+
177
+ **Setup:** Copy `.env.example` to `.env` and fill in values
178
+
179
+ ## Key Design Decisions
180
+
181
+ 1. **NanoID over UUID/auto-increment:** URL-safe, shorter, equally collision-resistant
182
+ 2. **Vercel Postgres over node-postgres:** Better connection pooling for serverless
183
+ 3. **Drizzle over Prisma:** Closer to SQL, better TypeScript inference, lighter weight
184
+ 4. **Zod validation separate from schema:** Allows different validation rules for create/update operations
185
+ 5. **SCSS over Tailwind:** Enforces semantic naming, better for large teams and maintainability
186
+ 6. **Astro server mode:** Enables API routes and dynamic rendering with Vercel adapter
187
+
188
+ ## Common Patterns
189
+
190
+ ### Creating a new database table
191
+
192
+ 1. Define schema in `app/src/db/schema.ts` using NanoID for primary key
193
+ 2. Create Zod schemas in `app/src/db/validations.ts` for create/update operations
194
+ 3. Export TypeScript types: `export type MyModel = typeof myTable.$inferSelect`
195
+ 4. Push to database: `npm run db:push` (dev) or `npm run db:generate && npm run db:migrate` (prod)
196
+
197
+ ### Creating a new API route
198
+
199
+ 1. Create file in `app/src/pages/api/[name].ts`
200
+ 2. Export named HTTP method handlers: `GET`, `POST`, `PUT`, `DELETE`
201
+ 3. Validate inputs with Zod schemas
202
+ 4. Use Drizzle ORM for database operations
203
+ 5. Return JSON responses with proper error handling
204
+
205
+ ### Adding new styles
206
+
207
+ 1. Create `.scss` file in appropriate location (`components/` or `pages/`)
208
+ 2. Import in `.astro` component: `import '@/styles/components/mycomponent.scss'`
209
+ 3. Use semantic class names with data attributes for modifiers
210
+ 4. Access global variables/mixins automatically (via Vite config)
211
+
212
+ ## Testing Database Connection
213
+
214
+ ```typescript
215
+ import { getDatabaseHealth } from '@/db/initialize';
216
+
217
+ const health = await getDatabaseHealth();
218
+ // Returns: { connected: boolean, tablesExist: boolean, timestamp: Date }
219
+ ```
220
+
221
+ ## Deployment
222
+
223
+ Configured for **Vercel** deployment with:
224
+
225
+ - Adapter: `@astrojs/vercel` (serverless mode)
226
+ - Build command: `npm run build`
227
+ - Output directory: `app/dist/`
228
+ - Environment variables must be set in Vercel project settings
229
+
230
+ ## Workspace Structure
231
+
232
+ This is an npm workspace:
233
+
234
+ - Root `package.json` contains CLI tooling and workspace configuration
235
+ - `app/package.json` contains the Astro application dependencies
236
+ - Commands run from root are proxied to the app workspace via `--workspace=app`