diff --git a/.env.example b/.env.example
index c308638..541adb4 100644
--- a/.env.example
+++ b/.env.example
@@ -8,3 +8,4 @@ CLOUDFLARE_DATABASE_ID=
CLOUDFLARE_PRODUCTION_DATABASE_ID=
CLOUDFLARE_STAGING_DATABASE_ID=
CLOUDFLARE_D1_TOKEN=
+NUXT_SESSION_PASSWORD=
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index bca95a5..cb786d1 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -8,7 +8,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
+ - name: node
+ uses: actions/setup-node@f4a67bbeca970f103397d3d2b9462cf787cd2980
+ with:
+ node-version: 24
- name: bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
@@ -16,7 +20,7 @@ jobs:
- name: install
run: bun install
- name: trunk
- uses: trunk-io/trunk-action@bf81325059d2534b31df5365182237788c5e0338
+ uses: trunk-io/trunk-action@04ba50e7658c81db7356da96657e6e77f220bfa3
- name: typecheck
run: bun run lint:types
- name: build
diff --git a/.github/workflows/devskim.yaml b/.github/workflows/devskim.yaml
index efd595d..a9f75bc 100644
--- a/.github/workflows/devskim.yaml
+++ b/.github/workflows/devskim.yaml
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
- name: analysis
uses: microsoft/DevSkim-Action@4b5047945a44163b94642a1cecc0d93a3f428cc6
- name: upload
diff --git a/.gitignore b/.gitignore
index 9508ea2..4616f3f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,6 @@ logs
# Gemini
.gemini/
+
+*storybook.log
+storybook-static
diff --git a/.node-version b/.node-version
index 5bf4400..b832e40 100644
--- a/.node-version
+++ b/.node-version
@@ -1 +1 @@
-24.15.0
+24.16.0
diff --git a/.storybook/main.ts b/.storybook/main.ts
new file mode 100644
index 0000000..edc2b15
--- /dev/null
+++ b/.storybook/main.ts
@@ -0,0 +1,8 @@
+import type { StorybookConfig } from "@storybook-vue/nuxt";
+
+const config: StorybookConfig = {
+ stories: ["../app/components/**/__stories__/*.stories.@(js|jsx|ts|tsx|mdx)"],
+ addons: [],
+ framework: "@storybook-vue/nuxt",
+};
+export default config;
diff --git a/.storybook/preview.ts b/.storybook/preview.ts
new file mode 100644
index 0000000..6e92f52
--- /dev/null
+++ b/.storybook/preview.ts
@@ -0,0 +1,14 @@
+import type { Preview } from "@storybook-vue/nuxt";
+
+const preview: Preview = {
+ parameters: {
+ controls: {
+ matchers: {
+ color: /(background|color)$/i,
+ date: /Date$/i,
+ },
+ },
+ },
+};
+
+export default preview;
diff --git a/.tool-versions b/.tool-versions
index 67a6731..bc3d15a 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -1 +1 @@
-nodejs 24.15.0
+nodejs 24.16.0
diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index f247491..de69708 100644
--- a/.trunk/trunk.yaml
+++ b/.trunk/trunk.yaml
@@ -7,31 +7,32 @@ cli:
plugins:
sources:
- id: trunk
- ref: v1.7.6
+ ref: v1.10.0
uri: https://github.com/trunk-io/plugins
# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
runtimes:
enabled:
- go@1.21.0
- node@22.16.0
- - python@3.10.8
+ - python@3.14.4
# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
lint:
disabled:
- osv-scanner
enabled:
+ - grype@0.112.0
- shellcheck@0.11.0
- shfmt@3.6.0
- trunk-toolbox@0.7.0
- oxipng@10.1.1
- actionlint@1.7.12
- - checkov@3.2.525
- - eslint@10.2.1
+ - checkov@3.3.1
+ - eslint@10.5.0
- git-diff-check
- - markdownlint@0.48.0
- - prettier@3.8.3
+ - markdownlint@0.49.0
+ - prettier@3.8.4
- taplo@0.10.0
- - trufflehog@3.95.2
+ - trufflehog@3.95.3
- yamllint@1.38.0
ignore:
- linters:
diff --git a/GETTING-STARTED.md b/GETTING-STARTED.md
index eaa00d4..965b1e2 100644
--- a/GETTING-STARTED.md
+++ b/GETTING-STARTED.md
@@ -301,7 +301,7 @@ affirm/
│ └── pages/ # File-based routing
│
├── server/ # ⚙️ Nitro server backend
-│ ├── api/ # API endpoints (e.g. /api/hello)
+│ ├── api/ # API endpoints (e.g. /api/ping)
│ ├── database/ # Drizzle schema and migrations
│ └── utils/ # Auto-imported server utilities (e.g. useDB)
│
@@ -378,7 +378,7 @@ All Vue components should use the **Composition API** with `
@@ -411,7 +411,7 @@ Refer to the [DaisyUI documentation](https://daisyui.com/) for available compone
Use `useFetch` for all data fetching in pages and components. It handles SSR hydration automatically:
```typescript
-const { data, pending, error } = await useFetch("/api/hello");
+const { data, pending, error } = await useFetch("/api/ping");
```
### Server API Routes
@@ -419,7 +419,7 @@ const { data, pending, error } = await useFetch("/api/hello");
Create API endpoints in `server/api/`. Export a default event handler:
```typescript
-// server/api/hello.ts
+// server/api/ping.ts
export default defineEventHandler((event) => {
return { message: "Hello from the server" };
});
diff --git a/README.md b/README.md
index 284817e..2af057c 100644
--- a/README.md
+++ b/README.md
@@ -137,7 +137,7 @@ This project follows the **Nuxt 4** directory structure (source in `app/`).
- **`middleware/`**: Route middleware.
- **`assets/`**: CSS and static assets (Tailwind entry point).
- **`server/`**: Nitro server backend.
- - **`api/`**: API endpoints (e.g., `/api/hello`).
+ - **`api/`**: API endpoints (e.g., `/api/ping`).
- **`database/`**: Drizzle schema and migrations.
- **`utils/`**: Auto-imported server utilities (e.g., `useDB`).
- **`shared/`**: Code shared between client and server.
@@ -162,7 +162,7 @@ This project follows the **Nuxt 4** directory structure (source in `app/`).
- Use **`useFetch`** for data fetching in pages/components. It handles SSR hydration automatically.
```ts
- const { data } = await useFetch("/api/hello");
+ const { data } = await useFetch("/api/ping");
```
#### Server API
diff --git a/app/components/AppFooter.vue b/app/components/AppFooter.vue
index e03ca46..541a014 100644
--- a/app/components/AppFooter.vue
+++ b/app/components/AppFooter.vue
@@ -1,5 +1,5 @@
-