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

131 lines
2.8 KiB
Markdown

# 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