kmcom-nuxt-layers 2.6.2 → 2.7.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/docs/ARCHITECTURE.md +21 -17
- package/docs/FEEDS.md +42 -34
- package/docs/IMPROVE-AUDIT-README.md +9 -10
- package/docs/IMPROVE-AUDIT-RESULTS.md +16 -17
- package/docs/IMPROVE-DEEP-AUDIT-RESULTS.md +29 -29
- package/docs/LAYERS-FIXES.md +1 -0
- package/docs/LAYOUT.md +91 -86
- package/docs/MIGRATION.md +93 -60
- package/docs/UPAGE-GRID-INTEGRATION.md +12 -10
- package/docs/USAGE.md +29 -38
- package/layers/animations/app/utils/pointerMotion.ts +1 -4
- package/layers/baseline/app/components/BaselineStatus.vue +13 -13
- package/layers/baseline/app/plugins/baseline-status.client.ts +4 -1
- package/layers/canvas/app/composables/useRendererCapabilities.ts +2 -2
- package/layers/content/app/components/Blog/Card.vue +1 -0
- package/layers/content/app/components/Gallery/Card.vue +1 -1
- package/layers/content/app/components/Gallery/Detail.vue +8 -1
- package/layers/content/app/components/Portfolio/Card.vue +1 -0
- package/layers/content/app/components/Portfolio/ColorPalette.vue +8 -1
- package/layers/content/app/components/Portfolio/Typography.vue +12 -2
- package/layers/content/app/composables/useGalleryItems.ts +3 -2
- package/layers/content/app/composables/usePortfolioItems.ts +3 -2
- package/layers/core/app/components/DiagnosticsPage.vue +15 -3
- package/layers/core/app/utils/featureClasses.test.ts +1 -3
- package/layers/core/app/utils/featureClasses.ts +1 -3
- package/layers/core/app/utils/helpers.test.ts +6 -2
- package/layers/core/nuxt.config.ts +2 -0
- package/layers/feeds/app/assets/css/feeds.css +3 -2
- package/layers/feeds/app/components/Feeds/Index.vue +36 -6
- package/layers/feeds/app/components/Feeds/RouteCard.vue +1 -3
- package/layers/feeds/app/plugins/feed-head.ts +2 -2
- package/layers/feeds/package.json +1 -1
- package/layers/feeds/public/feed/style.css +9 -9
- package/layers/feeds/server/utils/content-adapter.test.ts +3 -4
- package/layers/feeds/server/utils/content-adapter.ts +1 -1
- package/layers/feeds/server/utils/feed-author.test.ts +3 -3
- package/layers/feeds/server/utils/feed-config.test.ts +28 -6
- package/layers/feeds/server/utils/feed-config.ts +1 -4
- package/layers/feeds/server/utils/feed-service.ts +1 -1
- package/layers/feeds/server/utils/formats/rss.ts +1 -1
- package/layers/feeds/server/utils/formats.test.ts +1 -1
- package/layers/forms/app/utils/fieldProps.ts +1 -2
- package/layers/forms/server/api/contact.post.ts +4 -1
- package/layers/layout/app/assets/css/layout/grids.css +12 -3
- package/layers/layout/app/assets/css/layout/modes/fluid.css +9 -0
- package/layers/layout/app/components/Layout/Section/Sidebar.vue +11 -4
- package/layers/layout/app/utils/gridPlacementStyle.test.ts +3 -9
- package/layers/layout/app/utils/gridPlacementStyle.ts +10 -7
- package/layers/mailer/server/utils/email.ts +4 -3
- package/layers/mailer/server/utils/hooks.ts +1 -1
- package/layers/metadata/app/composables/useMetadataItem.ts +6 -2
- package/layers/metadata/app/composables/useMetadataSearch.ts +6 -2
- package/layers/metadata/providers/comicvine/server/utils/metadata-comicvine/client.ts +5 -5
- package/layers/metadata/providers/comicvine/server/utils/metadata-comicvine/provider.ts +11 -3
- package/layers/metadata/providers/google-books/server/utils/metadata-google-books/client.ts +9 -6
- package/layers/metadata/providers/google-books/server/utils/metadata-google-books/provider.ts +6 -3
- package/layers/metadata/providers/openlibrary/server/utils/metadata-openlibrary/normalise.test.ts +3 -1
- package/layers/metadata/providers/openlibrary/server/utils/metadata-openlibrary/provider.ts +4 -2
- package/layers/metadata/providers/themoviedb/server/utils/metadata-tmdb/client.test.ts +1 -3
- package/layers/metadata/providers/themoviedb/server/utils/metadata-tmdb/provider.ts +3 -1
- package/layers/metadata/server/api/metadata/status.get.ts +13 -18
- package/layers/metadata/server/utils/metadata/provider-registry.test.ts +1 -1
- package/layers/metadata/server/utils/metadata/search.test.ts +18 -18
- package/layers/metadata/server/utils/metadata/search.ts +16 -8
- package/layers/navigation/app/utils/site.test.ts +1 -3
- package/layers/scroll/app/components/Motion/PinnedSection.vue +11 -1
- package/layers/scroll/app/composables/useSectionProgress.ts +1 -1
- package/layers/scroll/app/plugins/locomotive-scroll.client.ts +6 -0
- package/layers/scroll/app/utils/scroll.ts +5 -1
- package/layers/seo/app/utils/seoConfig.test.ts +1 -1
- package/layers/shader/app/assets/css/shader.css +1 -1
- package/layers/shader/app/components/Material/AmbientAurora.client.vue +16 -4
- package/layers/shader/app/components/Material/AmbientFlow.client.vue +21 -5
- package/layers/shader/app/components/Material/AmbientGradientMesh.client.vue +21 -5
- package/layers/shader/app/components/Material/AmbientNebula.client.vue +21 -5
- package/layers/shader/app/components/Material/AmbientOcean.client.vue +16 -4
- package/layers/shader/app/components/Material/Gradient.client.vue +1 -1
- package/layers/shader/app/components/Material/Image.client.vue +1 -1
- package/layers/shader/app/components/Material/Noise.client.vue +11 -3
- package/layers/shader/app/composables/useAmbientMaterials.ts +0 -1
- package/layers/shader/app/shaders/common/blend.ts +5 -1
- package/layers/shader/app/shaders/common/grain.ts +5 -1
- package/layers/shader/app/shaders/common/lighting.ts +1 -6
- package/layers/shader/app/shaders/common/noise.ts +3 -1
- package/layers/shader/app/shaders/common/patterns.ts +1 -1
- package/layers/shader/app/shaders/common/shapes.ts +5 -1
- package/layers/shader/app/shaders/common/uv.ts +19 -2
- package/layers/shader/app/shaders/createMaterial.ts +11 -6
- package/layers/shader/app/shaders/layers/shaderGradient.ts +2 -12
- package/layers/shader/app/shaders/types.ts +1 -1
- package/layers/shader/app/types/uniforms.ts +1 -0
- package/layers/shader/app/utils/tsl/animation.ts +34 -36
- package/layers/starter/app/components/StarterDesignSystem.vue +120 -120
- package/layers/starter/app/components/StarterHome.vue +233 -208
- package/layers/theme/app/assets/css/theme.css +1 -1
- package/layers/theme/server/utils/accent-css.test.ts +17 -2
- package/layers/theme/server/utils/fouc-config.test.ts +7 -3
- package/layers/theme/server/utils/fouc-config.ts +24 -12
- package/layers/transitions/app/assets/css/transitions.css +6 -0
- package/layers/typography/app/assets/css/typography.css +313 -0
- package/layers/typography/app/components/Typography/Headline.vue +23 -14
- package/layers/typography/app/components/Typography/HeadlineScreen.vue +5 -12
- package/layers/typography/app/components/Typography/index.vue +4 -0
- package/layers/typography/app/composables/typography.ts +45 -5
- package/layers/typography/app/types/typography.ts +36 -7
- package/layers/typography/nuxt.config.ts +2 -0
- package/layers/visual/app/app.config.ts +1 -1
- package/layers/visual/app/assets/css/visual.css +1 -1
- package/layers/visual/app/composables/accent.ts +1 -2
- package/layers/visual/app/composables/tint.ts +1 -2
- package/layers/visual/app/types/media.ts +2 -2
- package/layers/visual/app/utils/gradientStyle.test.ts +1 -2
- package/layers/visual/app/utils/responsiveSizes.ts +0 -1
- package/package.json +36 -16
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -94,6 +94,7 @@ pnpm dev
|
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
The `resolveExtendedLayers()` function:
|
|
97
|
+
|
|
97
98
|
1. Parses `PLAYGROUND_LAYERS` as a comma-separated list
|
|
98
99
|
2. Auto-includes each layer's dependencies (defined in `LAYER_DEPENDENCIES`)
|
|
99
100
|
3. Returns paths in correct order (dependencies first, following `AVAILABLE_LAYERS` order)
|
|
@@ -117,11 +118,13 @@ Nuxt auto-discovers components from all extended layers' `app/components/` direc
|
|
|
117
118
|
The shader layer uses explicit component registration with `global: true` for its WebGPU components:
|
|
118
119
|
|
|
119
120
|
```ts
|
|
120
|
-
components: [
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
components: [
|
|
122
|
+
{
|
|
123
|
+
path: './app/components',
|
|
124
|
+
pathPrefix: false,
|
|
125
|
+
global: true,
|
|
126
|
+
},
|
|
127
|
+
]
|
|
125
128
|
```
|
|
126
129
|
|
|
127
130
|
## app.config.ts
|
|
@@ -129,6 +132,7 @@ components: [{
|
|
|
129
132
|
Each layer provides typed runtime configuration via `app.config.ts` with sensible defaults. Consumers can override any value in their own `app.config.ts`.
|
|
130
133
|
|
|
131
134
|
Key config namespaces:
|
|
135
|
+
|
|
132
136
|
- `coreLayer` — loading screen, error handling, scroll guard, 404 page
|
|
133
137
|
- `motion` — Lenis smooth scroll, GSAP ScrollTrigger integration
|
|
134
138
|
- `themeLayer` — accent colors, default accent
|
|
@@ -186,15 +190,15 @@ Some layers (ui, content) support standalone mode via environment variables (`UI
|
|
|
186
190
|
|
|
187
191
|
## Layer Details
|
|
188
192
|
|
|
189
|
-
| Layer
|
|
190
|
-
|
|
191
|
-
| **core**
|
|
192
|
-
| **ui**
|
|
193
|
-
| **layout**
|
|
194
|
-
| **motion**
|
|
195
|
-
| **shader**
|
|
196
|
-
| **forms**
|
|
197
|
-
| **database** | Database infrastructure. Drizzle ORM + Neon Postgres via HTTP driver. Exposes `useSql()` and `useDrizzle(schema)` server utilities. App-owned schema and migrations; env: `NUXT_DATABASE_LAYER_URL`.
|
|
198
|
-
| **auth**
|
|
199
|
-
| **theme**
|
|
200
|
-
| **content**
|
|
193
|
+
| Layer | Description |
|
|
194
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
195
|
+
| **core** | Foundation layer. Nuxt UI, VueUse, device detection, Pinia, loading screen, error handler, scroll guard, feature detection, PWA support (production only). |
|
|
196
|
+
| **ui** | Design system primitives. Typography components (Headline, CodeBlock, QuoteBlock), color system, media/picture component, site branding, breakpoint types. |
|
|
197
|
+
| **layout** | Page structure. Grid systems, containers, spacing, layout compositions with breakpoint-based responsiveness. |
|
|
198
|
+
| **motion** | Animation layer. GSAP with ScrollTrigger, Locomotive Scroll (Lenis) smooth scrolling, motion composables. Transpiles GSAP for SSR. |
|
|
199
|
+
| **shader** | WebGPU/WebGL layer. Three.js + TresJS integration, TSL shader support, post-processing. Includes custom shader utilities and auto-imported shader modules. |
|
|
200
|
+
| **forms** | Form validation layer. Zod schema-based validation, form composables, typed form components. |
|
|
201
|
+
| **database** | Database infrastructure. Drizzle ORM + Neon Postgres via HTTP driver. Exposes `useSql()` and `useDrizzle(schema)` server utilities. App-owned schema and migrations; env: `NUXT_DATABASE_LAYER_URL`. |
|
|
202
|
+
| **auth** | Authentication layer. nuxt-auth-utils + GitHub OAuth handler, sealed-cookie sessions. Opt-in `auth` route middleware; no user table (app's responsibility). Env: `NUXT_SESSION_PASSWORD`, `NUXT_OAUTH_GITHUB_CLIENT_ID/SECRET`. |
|
|
203
|
+
| **theme** | Theming layer. Color mode switching, accent color palette, theme plugin, CSS custom properties for dynamic theming. |
|
|
204
|
+
| **content** | Content management layer. @nuxt/content integration, better-sqlite3 for local content DB, optional Nuxt Studio support. |
|
package/docs/FEEDS.md
CHANGED
|
@@ -42,7 +42,7 @@ export default defineNuxtConfig({
|
|
|
42
42
|
**Resolver-style (like the playground):**
|
|
43
43
|
|
|
44
44
|
```ts
|
|
45
|
-
const AVAILABLE_LAYERS = [/* ...existing...
|
|
45
|
+
const AVAILABLE_LAYERS = [, /* ...existing... */ 'content', 'feeds'] as const
|
|
46
46
|
|
|
47
47
|
const LAYER_PATHS = {
|
|
48
48
|
/* ... */
|
|
@@ -69,24 +69,24 @@ export default defineAppConfig({
|
|
|
69
69
|
site: {
|
|
70
70
|
title: 'My Site',
|
|
71
71
|
description: 'What the site is about',
|
|
72
|
-
url: 'https://example.com',
|
|
72
|
+
url: 'https://example.com', // canonical origin, no trailing slash
|
|
73
73
|
author: { name: 'Jane', email: 'jane@example.com' },
|
|
74
74
|
},
|
|
75
75
|
feedsLayer: {
|
|
76
76
|
feed: {
|
|
77
|
-
limit: 30,
|
|
77
|
+
limit: 30, // max items per feed
|
|
78
78
|
collections: ['blog', 'portfolio'], // every collection to expose
|
|
79
|
-
defaultCollection: 'blog',
|
|
79
|
+
defaultCollection: 'blog', // backs the /feed/rss shorthand routes
|
|
80
80
|
},
|
|
81
81
|
},
|
|
82
82
|
})
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
| Option
|
|
86
|
-
|
|
87
|
-
| `limit`
|
|
88
|
-
| `collections`
|
|
89
|
-
| `defaultCollection` | `'blog'`
|
|
85
|
+
| Option | Default | Meaning |
|
|
86
|
+
| ------------------- | ---------- | ----------------------------------------------------- |
|
|
87
|
+
| `limit` | `30` | Max items included in each feed |
|
|
88
|
+
| `collections` | `['blog']` | Collection names to expose as feeds |
|
|
89
|
+
| `defaultCollection` | `'blog'` | Collection served by the shorthand `/feed/rss` routes |
|
|
90
90
|
|
|
91
91
|
---
|
|
92
92
|
|
|
@@ -94,19 +94,19 @@ export default defineAppConfig({
|
|
|
94
94
|
|
|
95
95
|
Every configured collection serves:
|
|
96
96
|
|
|
97
|
-
| URL
|
|
98
|
-
|
|
99
|
-
| `/feed/:collection/rss`
|
|
100
|
-
| `/feed/:collection/atom` | Atom 1.0
|
|
97
|
+
| URL | Format |
|
|
98
|
+
| ------------------------ | ------------- |
|
|
99
|
+
| `/feed/:collection/rss` | RSS 2.0 |
|
|
100
|
+
| `/feed/:collection/atom` | Atom 1.0 |
|
|
101
101
|
| `/feed/:collection/json` | JSON Feed 1.1 |
|
|
102
102
|
|
|
103
103
|
Plus site-wide shorthand and index routes:
|
|
104
104
|
|
|
105
|
-
| URL
|
|
106
|
-
|
|
107
|
-
| `/feed/rss`, `/feed/atom`, `/feed/json` | Shorthand → serves `defaultCollection`
|
|
108
|
-
| `/feed`
|
|
109
|
-
| `/feed/style.xsl`
|
|
105
|
+
| URL | Purpose |
|
|
106
|
+
| --------------------------------------- | ------------------------------------------ |
|
|
107
|
+
| `/feed/rss`, `/feed/atom`, `/feed/json` | Shorthand → serves `defaultCollection` |
|
|
108
|
+
| `/feed` | JSON index of all configured feeds |
|
|
109
|
+
| `/feed/style.xsl` | Browser stylesheet (applied automatically) |
|
|
110
110
|
|
|
111
111
|
Opening any feed URL in a browser shows a styled page thanks to the XSLT stylesheet — no app work required.
|
|
112
112
|
|
|
@@ -146,11 +146,11 @@ The `feed-head.ts` plugin injects `<link rel="alternate">` tags so RSS readers a
|
|
|
146
146
|
- **Every page** gets the 3 main site feeds (shorthand routes → `defaultCollection`).
|
|
147
147
|
- A page whose first path segment matches a **non-default** collection (e.g. `/portfolio/...`) **also** gets that collection's 3 specific feeds.
|
|
148
148
|
|
|
149
|
-
| Page
|
|
150
|
-
|
|
151
|
-
| `/`, `/about`, any non-collection page
|
|
152
|
-
| `/blog`, `/blog/hello` (when `blog` is the default)
|
|
153
|
-
| `/portfolio`, `/portfolio/project` (non-default collection) | 3 main + 3 portfolio feeds
|
|
149
|
+
| Page | Links injected |
|
|
150
|
+
| ----------------------------------------------------------- | ----------------------------------------- |
|
|
151
|
+
| `/`, `/about`, any non-collection page | 3 main site feeds |
|
|
152
|
+
| `/blog`, `/blog/hello` (when `blog` is the default) | 3 main site feeds (already point to blog) |
|
|
153
|
+
| `/portfolio`, `/portfolio/project` (non-default collection) | 3 main + 3 portfolio feeds |
|
|
154
154
|
|
|
155
155
|
**Do nothing.** Don't hand-add `<link rel="alternate">` tags — you'll duplicate them.
|
|
156
156
|
|
|
@@ -162,10 +162,18 @@ If you've aliased a collection (e.g. reused the portfolio schema as `works` via
|
|
|
162
162
|
|
|
163
163
|
```ts
|
|
164
164
|
// app.config.ts
|
|
165
|
-
feedsLayer: {
|
|
165
|
+
feedsLayer: {
|
|
166
|
+
feed: {
|
|
167
|
+
collections: ['blog', 'works']
|
|
168
|
+
}
|
|
169
|
+
}
|
|
166
170
|
|
|
167
171
|
// nuxt.config.ts
|
|
168
|
-
nitro: {
|
|
172
|
+
nitro: {
|
|
173
|
+
prerender: {
|
|
174
|
+
routes: ['/feed/works/rss', '/feed/works/atom', '/feed/works/json']
|
|
175
|
+
}
|
|
176
|
+
}
|
|
169
177
|
```
|
|
170
178
|
|
|
171
179
|
See `MIGRATION.md` → "Collection Aliases" for how to define the alias itself.
|
|
@@ -185,12 +193,12 @@ See `MIGRATION.md` → "Collection Aliases" for how to define the alias itself.
|
|
|
185
193
|
|
|
186
194
|
## Quick reference
|
|
187
195
|
|
|
188
|
-
| Goal
|
|
189
|
-
|
|
190
|
-
| Turn on feeds
|
|
191
|
-
| Expose a collection
|
|
192
|
-
| Set the shorthand target
|
|
193
|
-
| Cap items per feed
|
|
194
|
-
| Static hosting
|
|
195
|
-
| Autodiscovery in `<head>` | Automatic — nothing to do
|
|
196
|
-
| Feed channel metadata
|
|
196
|
+
| Goal | Action |
|
|
197
|
+
| ------------------------- | -------------------------------------------------------------------- |
|
|
198
|
+
| Turn on feeds | Register `core` + `content` + `feeds` layers |
|
|
199
|
+
| Expose a collection | Add its name to `feedsLayer.feed.collections` |
|
|
200
|
+
| Set the shorthand target | `feedsLayer.feed.defaultCollection` |
|
|
201
|
+
| Cap items per feed | `feedsLayer.feed.limit` |
|
|
202
|
+
| Static hosting | Add `/feed/<collection>/{rss,atom,json}` to `nitro.prerender.routes` |
|
|
203
|
+
| Autodiscovery in `<head>` | Automatic — nothing to do |
|
|
204
|
+
| Feed channel metadata | Top-level `site` config in `app.config.ts` |
|
|
@@ -4,8 +4,8 @@ Audit written against commit `a2805da`.
|
|
|
4
4
|
|
|
5
5
|
## Files
|
|
6
6
|
|
|
7
|
-
| File
|
|
8
|
-
|
|
|
7
|
+
| File | Purpose |
|
|
8
|
+
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
|
|
9
9
|
| [IMPROVE-AUDIT-RESULTS.md](./IMPROVE-AUDIT-RESULTS.md) | Vetted improve audit findings, direction options, verification results, and recommended planning order. |
|
|
10
10
|
|
|
11
11
|
## Recommended Next Work
|
|
@@ -20,11 +20,10 @@ Recommended first implementation set:
|
|
|
20
20
|
|
|
21
21
|
## Dependency Order
|
|
22
22
|
|
|
23
|
-
| Order | Finding
|
|
24
|
-
|
|
|
25
|
-
| 1
|
|
26
|
-
| 2
|
|
27
|
-
| 3
|
|
28
|
-
| 4
|
|
29
|
-
| 5
|
|
30
|
-
|
|
23
|
+
| Order | Finding | Depends On | Status |
|
|
24
|
+
| ----- | -------------------------------------------------- | ------------------------------------------------- | ------ |
|
|
25
|
+
| 1 | Current feeds lint failure | None | TODO |
|
|
26
|
+
| 2 | Server route typecheck coverage | Feeds lint fix recommended first | TODO |
|
|
27
|
+
| 3 | Public forms status endpoint leaks email addresses | Server route typecheck coverage recommended first | TODO |
|
|
28
|
+
| 4 | Wrong mailer env var docs in forms demo | None | TODO |
|
|
29
|
+
| 5 | Missing behavior tests | Typecheck/lint baseline | TODO |
|
|
@@ -10,25 +10,25 @@ This pass did not audit ignored generated folders, local `.env`, or every Vue de
|
|
|
10
10
|
|
|
11
11
|
## Verification
|
|
12
12
|
|
|
13
|
-
| Command
|
|
14
|
-
|
|
|
15
|
-
| `pnpm typecheck`
|
|
16
|
-
| `pnpm lint`
|
|
17
|
-
| `pnpm -F kmcom-layer-feeds typecheck`
|
|
18
|
-
| `pnpm audit --audit-level high --prod` | FAIL
|
|
13
|
+
| Command | Result | Notes |
|
|
14
|
+
| -------------------------------------- | ------ | ---------------------------------------------------------------------------------- |
|
|
15
|
+
| `pnpm typecheck` | PASS | Uses `vue-tsc --noEmit -p tsconfig.typecheck.json`. |
|
|
16
|
+
| `pnpm lint` | FAIL | Fails in `kmcom-layer-feeds` on `layers/feeds/server/utils/content-adapter.ts:25`. |
|
|
17
|
+
| `pnpm -F kmcom-layer-feeds typecheck` | PASS | Passes even though feeds server files are outside the root typecheck include. |
|
|
18
|
+
| `pnpm audit --audit-level high --prod` | FAIL | Reports high advisories for `esbuild` and `ws`. |
|
|
19
19
|
|
|
20
20
|
## Findings
|
|
21
21
|
|
|
22
|
-
| #
|
|
23
|
-
| --- |
|
|
24
|
-
| 1
|
|
25
|
-
| 2
|
|
26
|
-
| 3
|
|
27
|
-
| 4
|
|
28
|
-
| 5
|
|
29
|
-
| 6
|
|
30
|
-
| 7
|
|
31
|
-
| 8
|
|
22
|
+
| # | Finding | Category | Impact | Effort | Risk | Confidence | Evidence |
|
|
23
|
+
| --- | ---------------------------------------------------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------ | ---- | ---------- | ------------------------------------------------------------------------------------------------- |
|
|
24
|
+
| 1 | `pnpm lint` currently fails on feeds server code | DX / Tooling | The main local quality gate is red, so CI cannot safely adopt it yet. | S | LOW | HIGH | `layers/feeds/server/utils/content-adapter.ts:25` |
|
|
25
|
+
| 2 | Published server routes are excluded from root typecheck and type-aware lint | Correctness / DX | Feed/form/mailer server code ships in npm but can pass `pnpm typecheck` with type errors hiding there. | M | MED | HIGH | `tsconfig.typecheck.json:25`, `eslint.config.mjs:387`, `package.json:37` |
|
|
26
|
+
| 3 | Public forms status endpoint exposes configured email addresses | Security | Any visitor can read `emailFrom` and `emailTo`, leaking operational inboxes and increasing spam targeting. | S | LOW | HIGH | `layers/forms/server/api/forms/status.get.ts:4`, `layers/forms/server/api/forms/status.get.ts:7` |
|
|
27
|
+
| 4 | Forms demo documents the wrong mailer env var namespace | Correctness / Docs | Users following the UI instructions set `NUXT_FORMS_LAYER_*`, but runtime config reads `NUXT_MAILER_LAYER_*`, leaving email unconfigured. | S | LOW | HIGH | `apps/playground/app/pages/forms.vue:732`, `layers/mailer/nuxt.config.ts:16` |
|
|
28
|
+
| 5 | Contact email endpoint has no server-side abuse controls | Security | The public POST path can be used to burn Resend quota or spam the configured recipient. | M | MED | HIGH | `layers/forms/server/api/contact.post.ts:11`, `layers/mailer/server/utils/email.ts:17` |
|
|
29
|
+
| 6 | Lockfile still contains high-advisory `esbuild` and `ws` versions | Security / Dependencies | Build/tooling and Nuxt Content dependency paths remain vulnerable per `pnpm audit --prod`. | S/M | MED | HIGH | `pnpm-lock.yaml:6770`, `pnpm-lock.yaml:12275` |
|
|
30
|
+
| 7 | No automated behavior tests exist for the published layers | Test Coverage | Feed serialization, contact email, routing governance, and content composables have no regression harness. | M/L | LOW | HIGH | `package.json:41`, `package.json:246` |
|
|
31
|
+
| 8 | Feed generation fetches whole collections before filtering/limiting | Performance | Large content collections make each feed request do avoidable in-memory filtering, sorting, and slicing. | M | MED | HIGH | `layers/feeds/server/utils/content-adapter.ts:61`, `layers/feeds/server/utils/feed-service.ts:16` |
|
|
32
32
|
|
|
33
33
|
## Direction Options
|
|
34
34
|
|
|
@@ -49,4 +49,3 @@ This pass did not audit ignored generated folders, local `.env`, or every Vue de
|
|
|
49
49
|
3. Fix findings 3 and 4 while the server route coverage is fresh.
|
|
50
50
|
4. Add focused tests for the same paths before larger refactors.
|
|
51
51
|
5. Address dependency advisories and feed query performance after the baseline is stable.
|
|
52
|
-
|
|
@@ -10,38 +10,38 @@ This pass stayed read-only for source code. It did not read `.env` files. It did
|
|
|
10
10
|
|
|
11
11
|
## Verification Summary
|
|
12
12
|
|
|
13
|
-
| Command
|
|
14
|
-
|
|
|
15
|
-
| `pnpm typecheck`
|
|
16
|
-
| `pnpm -r --if-present --workspace-concurrency=1 --no-bail typecheck`
|
|
17
|
-
| `pnpm -r --if-present --workspace-concurrency=1 --no-bail lint`
|
|
18
|
-
| `pnpm format:check`
|
|
19
|
-
| `git ls-files '*.css' \| xargs pnpm exec stylelint --allow-empty-input`
|
|
20
|
-
| `pnpm audit --audit-level high --prod --json`
|
|
21
|
-
| `fallow health --hotspots --targets --format json --quiet`
|
|
22
|
-
| `fallow dupes --top 20 --format json --quiet`
|
|
23
|
-
| `fallow dead-code --unused-deps --unused-files --unused-exports --format json --quiet` | COMPLETE | 260 cleanup candidates: 43 files, 190 exports, 27 dependencies. Treat as trace-required leads.
|
|
24
|
-
| `fallow flags --format json --quiet`
|
|
25
|
-
| `fallow security --surface --format json --quiet`
|
|
13
|
+
| Command | Result | Notes |
|
|
14
|
+
| -------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------- |
|
|
15
|
+
| `pnpm typecheck` | PASS | Root `vue-tsc --noEmit -p tsconfig.typecheck.json` passed. |
|
|
16
|
+
| `pnpm -r --if-present --workspace-concurrency=1 --no-bail typecheck` | PASS | Recursive package typecheck completed successfully across workspace packages. |
|
|
17
|
+
| `pnpm -r --if-present --workspace-concurrency=1 --no-bail lint` | FAIL | 23 packages passed, `kmcom-layer-feeds` failed on one ESLint error. The run also reported 63 warnings. |
|
|
18
|
+
| `pnpm format:check` | FAIL | Reports unknown `ignorePath` config option and 309 formatting failures, including local `.agents` content. |
|
|
19
|
+
| `git ls-files '*.css' \| xargs pnpm exec stylelint --allow-empty-input` | FAIL | Tracked CSS only: 96 problems, 84 errors and 12 warnings. |
|
|
20
|
+
| `pnpm audit --audit-level high --prod --json` | FAIL | 2 high advisories: `esbuild` and `ws`. Metadata also reports 1 low and 1 moderate advisory. |
|
|
21
|
+
| `fallow health --hotspots --targets --format json --quiet` | COMPLETE | 651 files, 2825 functions, 147 functions above Fallow thresholds. |
|
|
22
|
+
| `fallow dupes --top 20 --format json --quiet` | COMPLETE | 467 files, 147 with clones, 5593 duplicated lines in the top clone set, 9.18% duplication. |
|
|
23
|
+
| `fallow dead-code --unused-deps --unused-files --unused-exports --format json --quiet` | COMPLETE | 260 cleanup candidates: 43 files, 190 exports, 27 dependencies. Treat as trace-required leads. |
|
|
24
|
+
| `fallow flags --format json --quiet` | COMPLETE | No feature flags detected by Fallow, despite routing runtime flags being hand-implemented. |
|
|
25
|
+
| `fallow security --surface --format json --quiet` | COMPLETE | One low-severity weak-hash candidate in feed ETag generation. |
|
|
26
26
|
|
|
27
27
|
## Confirmed Findings
|
|
28
28
|
|
|
29
|
-
| Priority | Finding
|
|
30
|
-
|
|
|
31
|
-
| P0
|
|
32
|
-
| P0
|
|
33
|
-
| P0
|
|
34
|
-
| P1
|
|
35
|
-
| P1
|
|
36
|
-
| P1
|
|
37
|
-
| P1
|
|
38
|
-
| P1
|
|
39
|
-
| P2
|
|
40
|
-
| P2
|
|
41
|
-
| P2
|
|
42
|
-
| P2
|
|
43
|
-
| P2
|
|
44
|
-
| P3
|
|
29
|
+
| Priority | Finding | Impact | Effort | Confidence | Evidence |
|
|
30
|
+
| -------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
31
|
+
| P0 | Public forms status endpoint exposes configured email addresses. | Any visitor can read operational sender and recipient addresses, increasing spam and metadata exposure. | S | HIGH | `layers/forms/server/api/forms/status.get.ts:4`, `layers/forms/server/api/forms/status.get.ts:7`, `apps/playground/app/pages/forms.vue:662`, `apps/playground/app/pages/forms.vue:675` |
|
|
32
|
+
| P0 | Contact email endpoint has no server-side abuse controls. | The public POST path can burn Resend quota, spam the configured recipient, and create noisy hooks. | M | HIGH | `layers/forms/server/api/contact.post.ts:11`, `layers/forms/server/api/contact.post.ts:22`, `layers/mailer/server/utils/email.ts:17` |
|
|
33
|
+
| P0 | Production dependency audit has high advisories. | `pnpm audit` reports high-severity `esbuild` and `ws` paths in production dependency graphs. | S/M | HIGH | `pnpm-lock.yaml:6770`, `pnpm-lock.yaml:6775`, `pnpm-lock.yaml:12275`, `package.json:106`, `package.json:112`, `package.json:115` |
|
|
34
|
+
| P1 | Content list composables reuse cache keys while accepting different query options. | Calls with different `tags`, `limit`, `featured`, or `excludeDrafts` can share or cancel the wrong `useAsyncData` payload. | S/M | HIGH | `layers/content/app/composables/useContentData.ts:1`, `layers/content/app/composables/useBlogPosts.ts:3`, `layers/content/app/composables/useBlogPosts.ts:6`, `layers/content/app/composables/useGalleryItems.ts:3`, `layers/content/app/composables/usePortfolioItems.ts:3`, `layers/content/app/composables/createPortfolioComposables.ts:20` |
|
|
35
|
+
| P1 | Published server files are outside root typecheck and type-aware lint. | `layers/*/server/**` ships in the package but is excluded from root typechecking and has type-aware ESLint disabled. | M | HIGH | `package.json:37`, `tsconfig.typecheck.json:25`, `eslint.config.mjs:387`, `eslint.config.mjs:390` |
|
|
36
|
+
| P1 | Main lint baseline is red. | Recursive lint has one hard error, so CI or pre-commit adoption cannot rely on lint yet. | S | HIGH | `layers/feeds/server/utils/content-adapter.ts:25`, recursive lint summary: 1 fail, 23 pass |
|
|
37
|
+
| P1 | Format baseline is noisy and includes local agent assets. | `pnpm format:check` fails on 309 files and warns that `ignorePath` is not a valid config option. The ignore file does not exclude `.agents/` or `.claude/`. | S | HIGH | `prettier.config.cjs:46`, `.prettierignore:1`, `.prettierignore:85` |
|
|
38
|
+
| P1 | No tracked behavior tests exist. | Feed serialization, forms/mailer, routing governance, content composables, and shader utilities rely on manual checks plus lint/typecheck. | M/L | HIGH | `package.json:41`, `package.json:246`; `git ls-files` found no `*.test.*`, `*.spec.*`, `tests`, or `__tests__` paths. |
|
|
39
|
+
| P2 | Feed dynamic collection routes accept arbitrary collection names. | `/feed/:collection/:format` passes unvalidated path segments into `queryCollection(event, collection)`, so invalid collections become uncontrolled content-query failures instead of 404s. | S | HIGH | `layers/feeds/server/routes/feed/[collection]/rss.get.ts:2`, `layers/feeds/server/utils/content-adapter.ts:28`, `layers/feeds/app/app.config.ts:5`, `layers/feeds/server/routes/feed/discovery.get.ts:20` |
|
|
40
|
+
| P2 | Feed generation fetches whole collections before filtering and limiting. | Large collections make every feed request filter, sort, and slice in memory instead of pushing draft/date/limit work into the Nuxt Content query. | M | HIGH | `layers/feeds/server/utils/content-adapter.ts:61`, `layers/feeds/server/utils/content-adapter.ts:63`, `layers/feeds/server/utils/feed-service.ts:16` |
|
|
41
|
+
| P2 | Feed date handling can turn bad frontmatter into runtime feed failures. | `new Date(...)` is not validated before `toISOString()`. Invalid dates can crash JSON or Atom serialization. | S | MED | `layers/feeds/server/utils/content-adapter.ts:50`, `layers/feeds/server/utils/formats/json.ts:16`, `layers/feeds/server/utils/formats/atom.ts:13`, `layers/feeds/server/utils/formats/atom.ts:22` |
|
|
42
|
+
| P2 | CSS lint rules are configured but tracked CSS fails them. | Stylelint reports 84 errors and 12 warnings against tracked CSS only, mostly token fallback hex colors, import ordering, keyframe casing, and deprecated properties. | M | HIGH | `stylelint.config.mjs:48`, `stylelint.config.mjs:123`, `layers/core/app/assets/css/core.css:6`, `layers/feeds/public/feed/style.css:15`, `layers/feeds/app/assets/css/feeds.css:20` |
|
|
43
|
+
| P2 | Routing runtime flags have a client fetch contract but no shipped endpoint. | Product and enterprise presets enable `runtimeFlags`, and the client fetches `/api/feature-flags`; the layer does not provide that server route. Consumers need an explicit contract or optional route. | S/M | HIGH | `layers/routing/app/plugins/feature-flags.client.ts:8`, `layers/routing/app/plugins/feature-flags.client.ts:12`, `layers/routing/app/types/routing.ts:47`, `layers/routing/app/types/routing.ts:56` |
|
|
44
|
+
| P3 | Feed ETag generation uses MD5. | This is not password/signature crypto, but modern cache fingerprints should use SHA-256 to avoid weak-crypto findings. | S | HIGH | `layers/feeds/server/utils/cache.ts:5` |
|
|
45
45
|
|
|
46
46
|
## Structural Findings
|
|
47
47
|
|