diff --git a/.planning/phases/16-grzybyfunkcjonalne-pl-on-reusable-blog-views/16-VALIDATION.md b/.planning/phases/16-grzybyfunkcjonalne-pl-on-reusable-blog-views/16-VALIDATION.md new file mode 100644 index 0000000..2be1f21 --- /dev/null +++ b/.planning/phases/16-grzybyfunkcjonalne-pl-on-reusable-blog-views/16-VALIDATION.md @@ -0,0 +1,91 @@ +--- +phase: "16" +slug: "grzybyfunkcjonalne-pl-on-reusable-blog-views" +# status lifecycle: draft (seeded by plan-phase) → validated (set by validate-phase §6) +# audit-milestone §5.5 distinguishes NOT-VALIDATED (draft) from PARTIAL (validated + nyquist_compliant: false) (#2117) +status: draft +nyquist_compliant: false +wave_0_complete: false +created: "2026-10-09" +--- + +# Phase 16 — Validation Strategy + +> Per-phase validation contract for feedback sampling during execution. + +--- + +## Test Infrastructure + +| Property | Value | +|----------|-------| +| **Framework** | `node --test` on `.ts` (Node ≥22.18 type stripping) for `vue-journal-layer` and `vue-grzybyfunkcjonalne-app`; `go test` (stdlib) for `sm-grzybyfunkcjonalne-app` | +| **Config file** | none — `package.json` `"test": "node --test --test-reporter=tap tests/*.test.ts"` (Wave 0 adds it to both JS repos); Go none | +| **Quick run command** | `pnpm test` (in the touched JS repo); `go vet ./... && go test ./...` (host) | +| **Full suite command** | `pnpm -C vue-journal-layer test && pnpm -C vue-grzybyfunkcjonalne-app build && pnpm -C vue-grzybyfunkcjonalne-app test && go vet ./... && go test ./...` | +| **Smoke** | `scripts/smoke.sh ` over `scripts/urls.txt` (expected status per URL) | +| **Estimated runtime** | ~90 seconds (dominated by `nuxt build`) | + +Testable logic lives in pure TS under `app/utils/` (no `.vue` imports), because `node --test` cannot load SFCs. Rendering is checked through the built SSR server (`.output/server/index.mjs`) started against a fixture API. No Vitest / `@nuxt/test-utils` dependency. + +--- + +## Sampling Rate + +- **After every task commit:** Run `pnpm test` in the touched JS repo; `go vet ./... && go test ./...` in the host +- **After every plan wave:** Run the full suite command, with the site app's `nuxt build` against the layer **installed from the git tag** +- **Before `/msd-verify-work`:** Full suite must be green and `scripts/smoke.sh` must pass against staging +- **Max feedback latency:** 90 seconds + +--- + +## Per-Task Verification Map + +Seeded from RESEARCH.md § Validation Architecture; the planner binds task IDs. + +| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status | +|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------| +| TBD | TBD | TBD | SC-2 | — | route config: defaults, overrides, `false` disables, invalid path rejected | unit | `node --test tests/routes.test.ts` (layer) | ❌ W0 | ⬜ pending | +| TBD | TBD | TBD | SC-2 | — | client builds query (`page`, `per_page` clamp ≤30, `category`, `include_empty`), parses envelope | unit | `node --test tests/client.test.ts` (layer) | ❌ W0 | ⬜ pending | +| TBD | TBD | TBD | SC-2 | — | pagination: page validity, prev/next, 404 on out-of-range | unit | `node --test tests/pagination.test.ts` (layer) | ❌ W0 | ⬜ pending | +| TBD | TBD | TBD | SC-2 | stored XSS | HTML gate rejects the same 3 patterns as Go `FormatHTML` | unit | `node --test tests/htmlGate.test.ts` (layer) | ❌ W0 | ⬜ pending | +| TBD | TBD | TBD | SC-3 | — | sitemap entries from posts + categories use route config | unit | `node --test tests/sitemap.test.ts` (layer) | ❌ W0 | ⬜ pending | +| TBD | TBD | TBD | SC-1 | admin exposure | host boots with `backend.uri: /gfadmin`; `/backend` 404 | unit/boot | `go test ./... -run TestBoot` (host) | ✅ extend `boot_test.go` | ⬜ pending | +| TBD | TBD | TBD | SC-1 | — | featured-image migration: map parse, blob key, row fields, idempotent skip | unit | `go test ./... -run FeaturedImages` (host) | ❌ W0 | ⬜ pending | +| TBD | TBD | TBD | SC-1 | uploaded-file XSS | deploy configs: `nginx -t`, supervisor parse, storage extension allowlist | config check | `scripts/check-deploy.sh` (host) | ❌ adapt | ⬜ pending | +| TBD | TBD | TBD | SC-1 | — | built Nuxt server renders `/`, `/blog`, a post, a category against fixture API | integration | `node --test tests/ssr.test.ts` (app) | ❌ W0 | ⬜ pending | +| TBD | TBD | TBD | SC-3 | — | every old URL → expected status; canonical keeps `?page=N`; `/rss.xml` is RSS | smoke | `scripts/smoke.sh https://` (host) | ❌ W0 | ⬜ pending | + +*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky* + +--- + +## Wave 0 Requirements + +- [ ] Spike: pnpm git dependency from Gitea + `extends` + `nuxt build` (RESEARCH A1, Pitfall 10) +- [ ] `vue-journal-layer/tests/` and `package.json` test script +- [ ] `vue-grzybyfunkcjonalne-app/tests/` + a fixture API (small Node `http` server serving recorded JSON) for SSR tests +- [ ] `sm-grzybyfunkcjonalne-app/scripts/urls.txt`, generated from the live sitemap (71 URLs) + static/negative cases + +--- + +## Manual-Only Verifications + +| Behavior | Requirement | Why Manual | Test Instructions | +|----------|-------------|------------|-------------------| +| Staging deploy on the PHP site's server (Go + Nuxt + imported posts) | SC-1, D-18 | Needs server access, DNS/TLS for the staging host | Deploy per `deploy/` README, then run `scripts/smoke.sh https://` | +| Refreshed visual design matches intent | D-01, D-03 | Subjective visual review | Open staging `/`, `/blog`, a post, a category; compare with the live site | +| Creating the Gitea repos `vue-journal-layer`, `vue-grzybyfunkcjonalne-app` | D-02, D-08 | External service account action | Create public repos on git.golem15.com | + +--- + +## Validation Sign-Off + +- [ ] All tasks have `` verify or Wave 0 dependencies +- [ ] Sampling continuity: no 3 consecutive tasks without automated verify +- [ ] Wave 0 covers all MISSING references +- [ ] No watch-mode flags +- [ ] Feedback latency < 90s +- [ ] `nyquist_compliant: true` set in frontmatter + +**Approval:** pending