# Operations dashboard: saved-card warning and import validation

2026-09-19. Both defects reproduced while executing the actual local learner course, using only own `cf_dash_20260919` records in the newly created learner organization. Browser evidence is in [operations-dashboard-local-20260919](../learner-review-records/assets/operations-dashboard-local-20260919/progress.md).

## Changes

- `websitemint/packages/ui/src/components/data-viz/layout/layout-card.tsx`: show the unconfigured-card warning only when **all** supported configuration sources are empty (`items`, `queryRef`, legacy table/chart refs). The previous condition ignored the saved query that had already rendered. Browser screenshot 21 reproduces the warning under the correct chart; 32/33 show the same persisted dashboard without it, including after reload.
- `appengine/src/util/validatorData.ts`: normalize Studio field-level boolean `required` metadata into parent required arrays, preserving standard rules, nested/array schemas, optional fields and hidden-field behavior. Accept presentation annotations and register standard AJV formats. Compilation errors now return an explicit schema validation error instead of silently treating every row as valid. Malformed standard required rules remain errors. Schema normalization does not mutate the saved schema; defaults retain their established behavior.
- `websitemint/packages/ui/src/components/data-import/step-report.tsx`: validation-only failures say nothing was written, identify failed validation rows and direct correction before retrying; actual import wording is preserved. [Five actual component render checks](assets/dashboard-validation/report-verification.txt) cover failed, partial and successful dry runs plus live-import wording.
- `appengine/package.json` and the workspace dependency entry in `yarn.lock`: declare the already installed/resolved `ajv-formats` 2.1.1 dependency. No installation, network fetch or unrelated dependency edits were performed by this task.

The supplied course schema has both standard `required:['title']` and Studio `properties.title.required:true`. Before repair AJV rejected that field metadata (`required must be array`), and validateData swallowed the compilation failure. Browser dry run therefore reported 3 read / 0 created / 3 skipped / 0 failed. The patch corrects the validator; it does not weaken the supplied schema or remove its required/minLength rule.

## Verification

```sh
node tutorials-plan/application-fixes/assets/dashboard-validation/verify.cjs
```

[18 passing validator/import checks](assets/dashboard-validation/verification.txt) execute the real validator and actual bulk importRow/map/coercion methods with synthetic data and forbidden persistence. Valid rows pass; blank/missing title, negative budgets, invalid enum/date/email and malformed schemas fail. Legacy field flags, nesting, arrays, hidden fields, defaults, non-mutation and dry-run 2 skipped / 1 failed are covered. Full AppEngine `tsc --noEmit --incremental false --pretty false` passed; changed source `git diff --check` passed.

Both fixes passed the actual browser recheck. After the coordinated local API rebuild, the same CSV/collection in Validate only returned Rows read 3, Created 0, Skipped 2, Failed 1, with row 2 rejected for its missing title (capture 35). The report component now labels this **Validation found errors — nothing was written** and asks the learner to correct errors instead of suggesting an immediate write (capture 36). Data Explorer still contained exactly the original five projects, with zero imported samples (capture 37). No production, external provider, message-send or real-customer action occurred.
