diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1b3c20b..4d1cdaf 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,7 +12,7 @@ jobs: - name: bun uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 with: - bun-version: 1.3.8 + bun-version: 1.3.9 - name: install run: bun install - name: trunk diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 61fe7ca..dfd614d 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -25,13 +25,13 @@ lint: - trunk-toolbox@0.5.4 - oxipng@10.1.0 - actionlint@1.7.10 - - checkov@3.2.500 + - checkov@3.2.501 - eslint@10.0.0 - git-diff-check - markdownlint@0.47.0 - prettier@3.8.1 - taplo@0.10.0 - - trufflehog@3.93.1 + - trufflehog@3.93.3 - yamllint@1.38.0 ignore: - linters: diff --git a/AGENTS.md b/AGENTS.md index b1e9a2c..a7339f3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,6 +10,7 @@ This document outlines the development workflow, commands, and patterns for work - **Package Manager**: Bun - **Styling**: Tailwind CSS v4 + DaisyUI - **Tooling**: Trunk (lint/format), Vitest (testing), Playwright (e2e) +- **Deployment**: Cloudflare Workers Builds (CI/CD triggered on push) ## Essential Commands @@ -24,8 +25,8 @@ This document outlines the development workflow, commands, and patterns for work - **Generate Migrations**: `bun run db:generate` (Run after changing `server/database/schema.ts`) - **Migrate Local**: `bun run db:migrate` (Applies migrations to local D1 instance) -- **Migrate Staging**: `bun run db:migrate:staging` (Applies to `affirm-staging` DB) -- **Migrate Production**: `bun run db:migrate:prod` (Applies to `affirm` DB) +- **Migrate Staging**: `bun run db:migrate:staging` (Applies to `affirm-staging` DB via `wrangler.staging.jsonc`) +- **Migrate Production**: `bun run db:migrate:prod` (Applies to `affirm` DB via `wrangler.jsonc`) - **Drizzle Studio**: - Staging: `bun run db:studio:staging` - Production: `bun run db:studio:prod` @@ -39,8 +40,16 @@ This document outlines the development workflow, commands, and patterns for work ### Deployment -- **Deploy to Production**: `bun run deploy` -- **Deploy to Staging**: `bun run deploy:nonprod` (Uploads versions without immediate promotion) +Deployment is handled by **Cloudflare Workers Builds** — there is no GitHub Actions deploy workflow. + +- Pushing to `staging` triggers a build+deploy of the `affirm-staging` Worker. +- Pushing to `production` triggers a build+deploy of the `affirm` Worker. +- PRs targeting `staging` get preview versions uploaded to `affirm-staging`. + +For manual/local deploys (rarely needed): + +- **Deploy to Production**: `bun run deploy` (builds + `wrangler deploy -c wrangler.jsonc`) +- **Deploy to Staging**: `bun run deploy:staging` (builds + `wrangler versions upload -c wrangler.staging.jsonc`) ## Code Structure @@ -82,13 +91,17 @@ export default defineEventHandler(async (event) => { ## Configuration -- **`nuxt.config.ts`**: Main Nuxt configuration. -- **`wrangler.jsonc`**: Cloudflare Workers configuration. Defines `DB` bindings for `prod` and `staging` environments. -- **`drizzle.config.ts`**: Drizzle Kit configuration. +- **`wrangler.jsonc`**: Production Cloudflare Workers config. Includes the production D1 binding (`affirm`). +- **`wrangler.staging.jsonc`**: Staging Cloudflare Workers config. Includes the staging D1 binding (`affirm-staging`). +- **`wrangler.dev.jsonc`**: Local dev Cloudflare Workers config. Used by `bun run dev` and local migrations. +- **`nuxt.config.ts`**: Main Nuxt configuration. Uses `$env` to inject the correct D1 binding at build time. +- **`drizzle.config.ts`**: Drizzle Kit configuration (for `db:push` and `db:studio` commands). ## Gotchas & Guidelines -1. **Environment Variables**: Managed via `wrangler.jsonc` bindings for runtime. For local dev, `.dev.vars` is used. -2. **Migrations**: Always run `bun run db:generate` after modifying schema. Do not modify SQL files manually. +1. **Environment Variables**: Managed via wrangler config bindings for runtime. For local dev, `.dev.vars` is used. +2. **Migrations**: Always run `bun run db:generate` after modifying schema. Do not modify SQL files manually. Remote migrations use the D1 binding from the appropriate wrangler config file. 3. **Bindings**: The application relies on Cloudflare bindings (`DB`, `ASSETS`). Ensure `bun run dev` is used to properly proxy these during development. 4. **Imports**: Use `~` alias for project root (e.g., `~/server/utils/db`). +5. **Wrangler Configs**: Each environment has its own wrangler config. Migration and deploy scripts use `-c ` to target the right D1 database. Never pass `--database-id` to wrangler — it's not a valid flag for `d1 migrations apply`. +6. **Workers Builds**: Deployment is handled by Cloudflare Workers Builds, not GitHub Actions. The `ci.yaml` workflow only runs lint/typecheck/build checks. diff --git a/README.md b/README.md index 5cf6207..284817e 100644 --- a/README.md +++ b/README.md @@ -2,49 +2,73 @@ ![CI status](https://github.com/tecapps/affirm/actions/workflows/ci.yaml/badge.svg) ![DevSkim status](https://github.com/tecapps/affirm/actions/workflows/devskim.yaml/badge.svg) -Your first port of call should be the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. +Your first port of call should be the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn +more. > [!IMPORTANT] > Opinions ahead! The following are recommendations. Feel free to ignore them if you have better ideas. -All Nuxt modules except [NuxtUI](https://ui.nuxt.com) are installed and enabled. Notably, this includes [Nuxt Content](https://content.nuxtjs.org/), which will make our lives easier for copywriting by letting them write Markdown instead of HTML/Vue. +All Nuxt modules except [NuxtUI](https://ui.nuxt.com) are installed and enabled. Notably, this +includes [Nuxt Content](https://content.nuxtjs.org/), which will make our lives easier for copywriting by letting them +write Markdown instead of HTML/Vue. -But what are we going to use if not [NuxtUI](https://ui.nuxt.com)? Simple. [Tailwind](https://tailwindcss.com/) with [DaisyUI](https://daisyui.com/). This gives us a lot of flexibility while still providing a component library to speed up development. +But what are we going to use if not [NuxtUI](https://ui.nuxt.com)? Simple. [Tailwind](https://tailwindcss.com/) +with [DaisyUI](https://daisyui.com/). This gives us a lot of flexibility while still providing a component library to +speed up development. -The benefit of [DaisyUI](https://daisyui.com/) is that they don't dick about by having a "pro" version. The open-source version of DaisyUI is it. +The benefit of [DaisyUI](https://daisyui.com/) is that they don't dick about by having a "pro" version. The open-source +version of DaisyUI is the full package. -I'm not a frontend developer but I'd encourage use of the [Catppuccin](https://github.com/catppuccin) palette. There are dedicated packages for [the palette](https://github.com/catppuccin/palette), [DaisyUI](https://github.com/catppuccin/daisyui), and [Tailwind](https://github.com/catppuccin/tailwindcss). +I'm not a frontend developer but I'd encourage use of the [Catppuccin](https://github.com/catppuccin) palette. There are +dedicated packages +for [the palette](https://github.com/catppuccin/palette), [DaisyUI](https://github.com/catppuccin/daisyui), +and [Tailwind](https://github.com/catppuccin/tailwindcss). -Recommended VS Code extensions are configured for this workspace. Check the extensions view's _Recommended_ section. Feel free to add any you find useful. +Recommended VS Code extensions are configured for this workspace. Check the extensions view's _Recommended_ section. +Feel free to add any you find useful. > [!IMPORTANT] > Opinions end here. It's objectivity from here on. Mostly. ## Branch protections -The `main` branch is the production deployment. It's protected; changes to it can only come from a pull request, and that means a separate branch. +The `staging` branch is the integration branch. The `production` branch is the live deployment. Both are protected; +changes can only come from pull requests. Do your work in a branch named `username/purpose`; eg `daveio/fix-header`. -When it's ready to merge, submit a pull request. Two approvals are required on each PR. I ([@daveio](https://github.com/daveio)) will try to review all PRs and you can function as the other approver if you like. If I'm unavailable to review a PR, ask another team member to review it for you. Anyone can. +When it's ready to merge, submit a pull request targeting `staging`. Two approvals are required on each PR. +I ([@daveio](https://github.com/daveio)) will try to review all PRs and you can function as the other approver if you +like. If I'm unavailable to review a PR, ask another team member to review it for you. Anyone can. -The purpose of this isn't to be a pain in the arse, it's to minimise the possibility of broken code reaching production. Your pushes to branches generate a `workers.dev` URL, so you can validate things before submitting a PR and save everyone a bunch of time. +The purpose of this isn't to be a pain in the arse, it's to minimise the possibility of broken code reaching production. +Your pushes to branches generate preview versions on the `affirm-staging` Worker, so you can validate things before +submitting a PR and save everyone a bunch of time. > [!TIP] -> Please **sign your commits**. It's a major security win and it's not enormous hassle. You don't need a GnuPG key any more; Git supports signing with SSH keys now, and you probably use one of those to push anyway. See [the documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) for more information. +> Please **sign your commits**. It's a major security win and it's not enormous hassle. You don't need a GnuPG key any +> more; Git supports signing with SSH keys now, and you probably use one of those to push anyway. +> See [the documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) +> for more information. ## Setup -Install [`bun`](https://bun.sh) if you haven't already. I suggest using [`mise`](https://github.com/jdx/mise), which you can also use to manage Node versions and a bunch of other stuff too. +Install [`bun`](https://bun.sh) if you haven't already. I suggest using [`mise`](https://github.com/jdx/mise), which you +can also use to manage Node versions and a bunch of other stuff too. There is a `mise.toml` file included in this repo. It will install everything you need. -The only exception is `trunk` which is a _massive_ pain in the arse to manage using `mise`. It'll be installed as a dev dependency and can be invoked through `bun run trunk`, or read the [installation documentation](https://docs.trunk.io/code-quality/overview/initialize-trunk) to install it globally if you prefer. +The only exception is `trunk` which is a _massive_ pain in the arse to manage using `mise`. It'll be installed as a dev +dependency and can be invoked through `bun run trunk`, or read +the [installation documentation](https://docs.trunk.io/code-quality/overview/initialize-trunk) to install it globally if +you prefer. > [!NOTE] -> It will also install a few extras; the CLIs for the major coding agents, and `rust` in case we decide to use `wasm` in the future. Feel free to edit it if you need to, just be aware you'll be changing it for everyone else too. +> It will also install a few extras; the CLIs for the major coding agents, and `rust` in case we decide to use `wasm` in +> the future. Feel free to edit it if you need to, just be aware you'll be changing it for everyone else too. > -> There are also `.tool-versions` and `.node-version` files, but they're more for Workers Builds. `mise` should be treated as the source of truth. +> There are also `.tool-versions` and `.node-version` files, but they're more for Workers Builds. `mise` should be +> treated as the source of truth. If you are using `mise`, simply run: @@ -73,16 +97,27 @@ bun dev ## Development -This repository hosts a **Nuxt 4** web application deployed to **Cloudflare Workers**. It uses **Bun** as the package manager and runtime for development scripts. +This repository hosts a **Nuxt 4** web application deployed to **Cloudflare Workers**. It uses **Bun** as the package +manager and runtime for development scripts. -### ⚡️ Essential Commands +### Essential Commands Run these commands with `bun`. - **Install dependencies**: `bun install` (or `bun run postinstall` to setup Trunk) -- **Development Server**: `bun run dev` (starts Nuxt dev server) -- **Build**: `bun run build` (builds for Cloudflare) -- **Deploy**: `bun run deploy` (deploys to Cloudflare via Wrangler) +- **Development Server**: `bun run dev` (starts Nuxt dev server with local D1) +- **Build**: + - `bun run build` (builds for production — uses `--envName=production`) + - `bun run build:staging` (builds for staging — uses `--envName=staging`) +- **Deploy** (prefer Workers Builds — see [Deployment](#deployment)): + - `bun run deploy` (build + deploy to production via `wrangler.jsonc`) + - `bun run deploy:staging` (build staging + upload version via `wrangler.staging.jsonc`) +- **Database**: + - `bun run db:generate` (generate migrations after schema changes) + - `bun run db:migrate` (apply migrations to local D1) + - `bun run db:migrate:staging` (apply migrations to staging D1 via `wrangler.staging.jsonc`) + - `bun run db:migrate:prod` (apply migrations to production D1 via `wrangler.jsonc`) + - `bun run db:studio:staging` / `bun run db:studio:prod` (Drizzle Studio) - **Lint & Format**: - `bun run lint:fix` (Run all linters and fix issues) - `bun run format` (Format code with Prettier and Trunk) @@ -90,7 +125,7 @@ Run these commands with `bun`. - `bun run test` (Unit tests via Vitest) - `bun run test:e2e` (E2E tests via Playwright) -### 📂 Project Structure +### Project Structure This project follows the **Nuxt 4** directory structure (source in `app/`). @@ -108,12 +143,13 @@ This project follows the **Nuxt 4** directory structure (source in `app/`). - **`shared/`**: Code shared between client and server. - **`public/`**: Static files served at root (favicon, robots.txt). -### 🧩 Development Patterns +### Development Patterns #### Vue & TypeScript - Use **Composition API** with `