# Quickstart: Global Policy Search **Feature**: 001-global-policy-search **Time Estimate**: ~4 hours --- ## Prerequisites - [x] Node.js 20+ - [x] PostgreSQL running (Docker: `tenantpilot-db`) - [x] Azure AD app registration configured - [ ] `POLICY_API_SECRET` environment variable set --- ## Step 1: Add Environment Variable Add to `.env`: ```bash # API Secret for n8n ingestion (generate a strong random string) POLICY_API_SECRET=your-secure-random-secret-here ``` Generate a secure secret: ```bash openssl rand -base64 32 ``` --- ## Step 2: Create Database Schema Create the policy settings schema file: ```bash # File: lib/db/schema/policySettings.ts ``` Then push to database: ```bash 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 ```bash 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