tenantpilot/specs/001-global-policy-search/quickstart.md
2025-12-05 22:06:22 +01:00

2.8 KiB

Quickstart: Global Policy Search

Feature: 001-global-policy-search
Time Estimate: ~4 hours


Prerequisites

  • Node.js 20+
  • PostgreSQL running (Docker: tenantpilot-db)
  • Azure AD app registration configured
  • POLICY_API_SECRET environment variable set

Step 1: Add Environment Variable

Add to .env:

# API Secret for n8n ingestion (generate a strong random string)
POLICY_API_SECRET=your-secure-random-secret-here

Generate a secure secret:

openssl rand -base64 32

Step 2: Create Database Schema

Create the policy settings schema file:

# File: lib/db/schema/policySettings.ts

Then push to database:

npm run db:push

Step 3: Extend NextAuth Session

Update lib/auth/utils.ts to include tenantId in session from Azure AD tid claim.


Step 4: Create Server Actions

Create lib/actions/policySettings.ts with:

  • searchPolicySettings(searchTerm)
  • getPolicySettingById(id)
  • getRecentPolicySettings(limit)

Step 5: Create Ingestion API Route

Create app/api/policy-settings/route.ts:

  • POST handler with X-API-SECRET validation
  • Bulk upsert logic with onConflictDoUpdate

Step 6: Create Search UI

  1. Create search page: app/(app)/search/page.tsx
  2. Create search input component with Shadcn UI
  3. Create results table component

Step 7: Add Navigation

Update config/nav.ts to include search page in sidebar.


Testing the Ingestion API

curl -X POST http://localhost:3000/api/policy-settings \
  -H "Content-Type: application/json" \
  -H "X-API-SECRET: your-secret-here" \
  -d '{
    "settings": [
      {
        "tenantId": "your-azure-tenant-id",
        "policyName": "Test Policy",
        "policyType": "deviceConfiguration",
        "settingName": "TestSetting",
        "settingValue": "enabled",
        "graphPolicyId": "test-graph-id"
      }
    ]
  }'

File Checklist

File Purpose Status
lib/db/schema/policySettings.ts Drizzle schema
lib/validators/policySettings.ts Zod validation
lib/actions/policySettings.ts Server Actions
app/api/policy-settings/route.ts Ingestion API
app/(app)/search/page.tsx Search page
components/search/SearchInput.tsx Search input
components/search/ResultsTable.tsx Results display
lib/auth/utils.ts Session with tenantId
config/nav.ts Navigation update
.env POLICY_API_SECRET

Verify Setup

  1. Database: npm run db:push succeeds
  2. Auth: Login shows tenantId in session
  3. API: POST to /api/policy-settings with secret returns 200
  4. Search: Search page shows results after ingestion