92 lines
5.5 KiB
Markdown
92 lines
5.5 KiB
Markdown
---
|
|
phase: 10
|
|
slug: ausschreibungs-radar-foundation-d-e-ingestion
|
|
status: draft
|
|
nyquist_compliant: true
|
|
wave_0_complete: false
|
|
created: 2026-07-21
|
|
---
|
|
|
|
# Phase 10 — Validation Strategy
|
|
|
|
> Per-phase validation contract for feedback sampling during execution.
|
|
|
|
---
|
|
|
|
## Test Infrastructure
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Framework** | Vitest 3.x (existing, `apps/api/vitest.config.ts`) |
|
|
| **Config file** | `apps/api/vitest.config.ts` (existing — not modified by this phase) |
|
|
| **Quick run command** | `pnpm --filter @tessera/api test -- tenders` |
|
|
| **Full suite command** | `pnpm --filter @tessera/api test` |
|
|
| **Estimated runtime** | ~10 seconds (scoped) |
|
|
|
|
---
|
|
|
|
## Sampling Rate
|
|
|
|
- **After every task commit:** Run `pnpm --filter @tessera/api test -- tenders`
|
|
- **After every plan wave:** Run `pnpm --filter @tessera/api test`
|
|
- **Before `/gsd-verify-work`:** Full suite must be green
|
|
- **Max feedback latency:** ~10 seconds (scoped run)
|
|
|
|
---
|
|
|
|
## Per-Task Verification Map
|
|
|
|
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|
|
|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------|
|
|
| 10-01-01 | 01 | 1 | SCHEMA-01 | T-10-SC | adm-zip verified before install (supply chain) | manual-gate | checkpoint:human-verify (blocking-human) | n/a | ⬜ pending |
|
|
| 10-01-02 | 01 | 1 | SCHEMA-01 | T-10-01 | Tender has no tenantId (global data) | build | `grep -c "model Tender" schema.prisma`; `tsc --noEmit` | ❌ W0 | ⬜ pending |
|
|
| 10-01-03 | 01 | 1 | SCHEMA-01 | T-10-01 | [BLOCKING] migration applied to DB | integration | `pnpm --filter @tessera/api exec prisma migrate status` | ❌ W0 | ⬜ pending |
|
|
| 10-02-01 | 02 | 2 | CONFIG-01 | T-10-05 | idempotent registry seed + singleton config | build | `tsc --noEmit`; `grep -c "TendersModule" app.module.ts` | ❌ W0 | ⬜ pending |
|
|
| 10-02-02 | 02 | 2 | CONFIG-01 | T-10-03 | whitelisted slug only | build | `grep -c "tender-radar" module-loader.ts`; web `tsc --noEmit` | ❌ W0 | ⬜ pending |
|
|
| 10-02-03 | 02 | 2 | CONFIG-01 | T-10-04 | seed asserts slug + isSystem | unit | `pnpm --filter @tessera/api test -- tenders.seed` | ❌ W0 | ⬜ pending |
|
|
| 10-03-01 | 03 | 3 | INGEST-01/SCHEMA-01 | T-10-06/07 | real fixtures + failing specs (RED) | unit | `pnpm --filter @tessera/api test -- doe-opendata.adapter tender-normalizer` | ❌ W0 | ⬜ pending |
|
|
| 10-03-02 | 03 | 3 | INGEST-01 | T-10-06/07 | fixed host fetch + zip-bomb ceiling + D-02 filter | unit | `pnpm --filter @tessera/api test -- doe-opendata.adapter` | ❌ W0 | ⬜ pending |
|
|
| 10-03-03 | 03 | 3 | SCHEMA-01 | T-10-08 | eForms-primary deadline, nullable value, dedupKey/hash | unit | `pnpm --filter @tessera/api test -- tender-normalizer` | ❌ W0 | ⬜ pending |
|
|
| 10-04-01 | 04 | 4 | SCHEMA-02 | T-10-09/11 | day-cursor no-op; update-not-duplicate; D-05 prune skips null | integration | `pnpm --filter @tessera/api test -- tender-ingestion` | ❌ W0 | ⬜ pending |
|
|
| 10-04-02 | 04 | 4 | INGEST-06 | T-10-10 | single global cron, no activeTenantId | build | `tsc --noEmit`; `grep -c "activeTenantId" tender-scheduler.service.ts` == 0 | ❌ W0 | ⬜ pending |
|
|
| 10-04-03 | 04 | 4 | INGEST-06 | T-10-10 | 2nd-tenant activation → 0 extra calls/jobs/rows | integration | `pnpm --filter @tessera/api test -- tender-scheduler` | ❌ W0 | ⬜ pending |
|
|
| 10-05-01 | 05 | 5 | INGEST-06 | T-10-15 | DTO bounds (interval floor, limit cap) | build | `tsc --noEmit` | ❌ W0 | ⬜ pending |
|
|
| 10-05-02 | 05 | 5 | INGEST-06 | T-10-13/14 | ModuleGuard read (not tenant-scoped) + admin Roles | build | `tsc --noEmit`; `grep -c "UseModule" tenders.controller.ts` | ❌ W0 | ⬜ pending |
|
|
| 10-05-03 | 05 | 5 | INGEST-06 | T-10-14 | read where has no tenantId; save drives scheduler | unit | `pnpm --filter @tessera/api test -- tenders.controller` | ❌ W0 | ⬜ pending |
|
|
|
|
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
|
|
|
|
---
|
|
|
|
## Wave 0 Requirements
|
|
|
|
- [ ] `apps/api/src/tenders/__fixtures__/doe-eforms-sample.zip` + `doe-ocds-sample.zip` — real captured, trimmed fixtures (Plan 03 Task 1)
|
|
- [ ] `apps/api/src/tenders/tenders.seed.spec.ts` (Plan 02 Task 3)
|
|
- [ ] `apps/api/src/tenders/adapters/doe-opendata.adapter.spec.ts`, `tender-normalizer.service.spec.ts` (Plan 03 Task 1 — RED first)
|
|
- [ ] `apps/api/src/tenders/tender-ingestion.service.spec.ts`, `tender-scheduler.service.spec.ts` (Plan 04)
|
|
- [ ] `apps/api/src/tenders/tenders.controller.spec.ts` (Plan 05 Task 3)
|
|
|
|
Vitest framework already exists — no framework install needed.
|
|
|
|
---
|
|
|
|
## Manual-Only Verifications
|
|
|
|
| Behavior | Requirement | Why Manual | Test Instructions |
|
|
|----------|-------------|------------|-------------------|
|
|
| adm-zip package legitimacy | (supply chain / T-10-SC) | Human judgment on package provenance ([ASSUMED]) | Plan 01 Task 1 checkpoint: verify on npmjs.com + github.com/cthackers/adm-zip |
|
|
| Marketplace activation opens module page | CONFIG-01 | Full portal round-trip (marketplace → activate → page render) is a browser flow | Activate Ausschreibungs-Radar for a tenant, open `/modules/tender-radar`, confirm no 404 |
|
|
|
|
---
|
|
|
|
## Validation Sign-Off
|
|
|
|
- [x] All tasks have `<automated>` verify or a documented Wave 0 / manual-gate dependency
|
|
- [x] Sampling continuity: no 3 consecutive tasks without automated verify
|
|
- [x] Wave 0 covers all MISSING references (fixtures + spec scaffolds)
|
|
- [x] No watch-mode flags (all use `vitest run` via `pnpm test`)
|
|
- [x] Feedback latency < 10s (scoped runs)
|
|
- [x] `nyquist_compliant: true` set in frontmatter
|
|
|
|
**Approval:** approved 2026-07-21
|