Skip to content

"feat(policy): implement import/export with validation and diff previ…#167

Open
BernardOnuh wants to merge 10 commits into
karagozemin:mainfrom
BernardOnuh:feat/policy-import-export-validation
Open

"feat(policy): implement import/export with validation and diff previ…#167
BernardOnuh wants to merge 10 commits into
karagozemin:mainfrom
BernardOnuh:feat/policy-import-export-validation

Conversation

@BernardOnuh

Copy link
Copy Markdown
Contributor

feat(policy): implement import/export with validation and diff preview (#30)

Summary

Adds the ability for operators to export the active policy as JSON and import a new policy through the policy editor, with schema validation and a diff preview shown before anything is saved. Closes #30.

What changed

  • Added a PolicyImportExport component, integrated into policy-editor.tsx, with an Export button that downloads the current policy as JSON and an Import flow that lets a user upload a JSON file.
  • Imported JSON is validated against the existing policyConfigSchema (Zod) before anything happens to the live policy. Invalid imports show field-level error messages and leave the current policy untouched.
  • Valid imports go through a diff step first: changes are computed against the active policy and grouped/displayed by category (domains, tools, caps, thresholds, hours) so the operator can review exactly what will change before confirming the save.
  • Import and save are gated to operators; viewers can still export but cannot import or save, enforced via an isOperator check in the component and handler.
  • Added diff.ts with the comparison/formatting utilities used by the diff preview (numeric, array, and object field comparisons).
  • Added an optional /api/policy/validate endpoint for preview-only validation against policyConfigSchema, returning structured field errors without mutating stored policy state.
  • Added a 10-test suite covering schema validation (valid/invalid caps, empty arrays, missing fields), diff generation (no-change, numeric change, array additions, category grouping), non-mutation on failed import, and JSON export correctness.

Why

Operators currently have no way to back up, version-control, or bulk-edit policies outside the manual form editor. This adds a safe import/export path: validation happens before any state change, and the diff preview gives the operator a clear, reviewable picture of what an import will do before they commit to it.

Testing

npm run lint   # 0 errors, 0 warnings
npm run build  # compiles cleanly, type-checks pass
npm test -- policy-import-export.test.ts   # 10/10 passing

Manually verified:

  • Export downloads valid JSON
  • Re-importing the same file shows no diff
  • Editing fields and re-importing shows the correct diff
  • Malformed/invalid JSON is rejected with field-level errors and does not alter the saved policy
  • Viewer role can export but the import/save controls are disabled

Files changed

  • src/components/policy-editor.tsx — wired up the import handler and rendered the new component
  • src/components/policy-import-export.tsx (new)
  • src/lib/validation/diff.ts (new)
  • src/app/api/policy/validate/route.ts (new, optional preview endpoint)
  • src/components/policy-import-export.test.ts (new)

Acceptance criteria

  • Export current policy as JSON
  • Import JSON with schema validation
  • Diff preview shown before save
  • Invalid JSON/schema errors rejected without mutating current policy
  • Viewers can export but not import/save

@vercel

vercel Bot commented Jun 30, 2026

Copy link
Copy Markdown

@BernardOnuh is attempting to deploy a commit to the karagoz's projects Team on Vercel.

A member of the Team first needs to authorize it.

@karagozemin

Copy link
Copy Markdown
Owner

Thanks for the policy import/export PR. I started the review under the karagozemin account, but the PR is blocked before tests/typecheck because whitespace validation fails:

git diff --check origin/main...HEAD
src/components/policy-editor.tsx:255: trailing whitespace.
src/components/policy-editor.tsx:263: trailing whitespace.
src/components/policy-editor.tsx:265: trailing whitespace.
src/components/policy-editor.tsx:270: trailing whitespace.
src/components/policy-editor.tsx:419: trailing whitespace.

Please remove the trailing whitespace, then rerun:

  • git diff --check origin/main...HEAD
  • npm test -- --run src/components/policy-import-export.test.ts src/lib/policy/diff.test.ts src/app/api/policy/route.test.ts
  • npx tsc --noEmit
  • npm run lint

After diff check is clean I can continue the functional review.

@BernardOnuh

BernardOnuh commented Jun 30, 2026 via email

Copy link
Copy Markdown
Contributor Author

@karagozemin

Copy link
Copy Markdown
Owner

Thanks for following up. I rechecked the current merge ref, but the whitespace issue is still present; there is no new commit after my previous review.

Command run:

git diff --check main...pr-167-merge

Result:

src/components/policy-editor.tsx:255: trailing whitespace.
src/components/policy-editor.tsx:263: trailing whitespace.
src/components/policy-editor.tsx:265: trailing whitespace.
src/components/policy-editor.tsx:270: trailing whitespace.
src/components/policy-editor.tsx:419: trailing whitespace.

Please push a new commit that removes these trailing spaces; after that I can continue with the functional tests/typecheck/lint.

@BernardOnuh

BernardOnuh commented Jun 30, 2026 via email

Copy link
Copy Markdown
Contributor Author

@karagozemin

Copy link
Copy Markdown
Owner

Good progress: the previous whitespace blocker is fixed. I rechecked the current merge ref from the maintainer account.

Passing checks:

git diff --check main...pr-167-merge
npm test -- --run src/components/policy-import-export.test.ts src/lib/policy/diff.test.ts src/app/api/policy/route.test.ts
npx tsc --noEmit
npm run lint

Results: 19 focused tests passed, typecheck passed, lint passed.

One acceptance item from #30 is still missing before I can merge: README policy section documents import/export usage. The current effective PR diff only includes code/test files and does not update README.md. Please add a short README note for operators/viewers explaining policy export, import validation, diff preview, and viewer read-only behavior. After that this should be ready if the same checks stay green.

@BernardOnuh

BernardOnuh commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

✅ PR #30 Complete & Ready to Merge

All acceptance criteria met @karagozemin . All checks passing:

  • ✅ Policy export/import functionality

  • ✅ Schema validation & diff preview

  • ✅ Role-based access control

  • ✅ 19 tests passing

  • ✅ README documentation

    Tests: 19/19 ✓
    TypeScript: ✓
    Lint: ✓
    Ready: Yes �

@karagozemin

Copy link
Copy Markdown
Owner

Thanks for the PR! The build passes locally ✅, but after other PRs landed on main this branch now has merge conflicts and can't be merged as-is. Could you rebase onto the latest main and resolve the conflicts? Once it's mergeable I'll merge right away. 🙏

@BernardOnuh

Copy link
Copy Markdown
Contributor Author

Thanks for the PR! The build passes locally ✅, but after other PRs landed on main this branch now has merge conflicts and can't be merged as-is. Could you rebase onto the latest main and resolve the conflicts? Once it's mergeable I'll merge right away. 🙏 - Done

@karagozemin

karagozemin commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Rechecked: after your latest push CI is still red — the CI job is failing. Could you check the CI logs, fix the errors and push again? Once it goes green I will re-review and merge.

BernardOnuh and others added 5 commits July 8, 2026 00:22
- Propagate blocklist fetch errors through analyzer status (check getBlocklistHealth after fetch)

- Ensure policy store write operations call ensureStore() to handle concurrent access

- Fix test fixture in analyzer test: use string that actually triggers SECRET_TARGETING

- Isolate policy simulate test with unique FORTEXA_STORE_DIR to avoid parallel test conflicts
@BernardOnuh

Copy link
Copy Markdown
Contributor Author

Thanks for the PR! The build passes locally ✅, but after other PRs landed on main this branch now has merge conflicts and can't be merged as-is. Could you rebase onto the latest main and resolve the conflicts? Once it's mergeable I'll merge right away. 🙏 - Done @karagozemin

1 similar comment
@BernardOnuh

Copy link
Copy Markdown
Contributor Author

Thanks for the PR! The build passes locally ✅, but after other PRs landed on main this branch now has merge conflicts and can't be merged as-is. Could you rebase onto the latest main and resolve the conflicts? Once it's mergeable I'll merge right away. 🙏 - Done @karagozemin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Policy import/export with validation and diff preview

2 participants