2.8 KiB
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_SECRETenvironment 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-SECRETvalidation - Bulk upsert logic with
onConflictDoUpdate
Step 6: Create Search UI
- Create search page:
app/(app)/search/page.tsx - Create search input component with Shadcn UI
- 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
- Database:
npm run db:pushsucceeds - Auth: Login shows tenantId in session
- API: POST to
/api/policy-settingswith secret returns 200 - Search: Search page shows results after ingestion