Add comprehensive implementation guide for creating PlanAction claims via hydratePlan() function pattern, following established hydrateGive() and hydrateOffer() patterns. Changes: - Add hydrate-plan-implementation-guide.md with complete implementation details, usage examples, and testing recommendations - Link implementation guide from getting-valid-plan-ids.md Method 6 - Link implementation guide from localhost-testing-guide.md Option B The guide provides: - Complete hydratePlan() function implementation - PlanActionClaim interface structure - Helper functions (createAndSubmitPlan, editAndSubmitPlan) - Usage examples and edge cases - Testing recommendations and security considerations This complements plan creation documentation by showing how to programmatically construct valid PlanAction JWTs for POST /api/v2/claim.
219 lines
6.0 KiB
Markdown
219 lines
6.0 KiB
Markdown
# Getting Valid Plan Handle IDs for Testing
|
|
|
|
**Author**: Matthew Raymer
|
|
**Version**: 1.0.0
|
|
**Status**: Testing Setup Guide
|
|
|
|
## Overview
|
|
|
|
Plan handle IDs must match the format used by your TimeSafari database. The placeholder IDs (`test_project_1`, etc.) are not valid. This guide explains how to obtain real plan handle IDs for testing.
|
|
|
|
## Methods to Get Valid Plan Handle IDs
|
|
|
|
### Method 1: Create Projects in TimeSafari App (Recommended)
|
|
|
|
1. **Start TimeSafari app** (development or test app)
|
|
2. **Create a project** via the UI
|
|
3. **Get the plan handle ID**:
|
|
- Open browser DevTools (F12)
|
|
- Check Network tab for API responses when creating/loading projects
|
|
- Look for the `handleId` field in API responses
|
|
- Note: Plans are created via **POST `/api/v2/claim`** with a PlanAction JWT (see Method 6)
|
|
- Or check localStorage/database for the plan record
|
|
|
|
### Method 2: Query Your Local Database
|
|
|
|
If you have access to your local TimeSafari database:
|
|
|
|
```sql
|
|
-- SQLite example
|
|
SELECT handleId FROM plans LIMIT 5;
|
|
|
|
-- Or check what format handleIds use
|
|
SELECT handleId, name FROM plans WHERE name IS NOT NULL LIMIT 10;
|
|
```
|
|
|
|
### Method 3: Use Starred Projects from Account Settings
|
|
|
|
1. **Open TimeSafari app**
|
|
2. **Star some projects** in the UI
|
|
3. **Check account settings**:
|
|
```javascript
|
|
// In browser console or app
|
|
const settings = await $accountSettings();
|
|
console.log(settings.starredPlanHandleIds);
|
|
```
|
|
|
|
### Method 4: Check API Responses
|
|
|
|
1. **Query your localhost API**:
|
|
```bash
|
|
curl http://localhost:3000/api/v2/report/plans?planHandleIds=[]
|
|
```
|
|
2. **Look for existing projects** in the response
|
|
|
|
### Method 5: Extract from Crowd-Master Database
|
|
|
|
If you're using crowd-master for testing:
|
|
|
|
```bash
|
|
cd /home/matthew/projects/timesafari/crowd-master
|
|
# Check your local database or API for actual plan handle IDs
|
|
```
|
|
|
|
### Method 6: Create Plans via PlanAction JWT Import
|
|
|
|
Plans are created by importing JWT claims containing a `PlanAction`:
|
|
|
|
**Route: POST `/api/v2/claim`**
|
|
|
|
```json
|
|
{
|
|
"jwtEncoded": "<signed JWT with PlanAction claim>"
|
|
}
|
|
```
|
|
|
|
**Requirements**:
|
|
- JWT claim payload must include `@type: "PlanAction"`
|
|
- JWT must be signed with a valid DID key
|
|
- Response includes `handleId` and `planId` if creation succeeds
|
|
|
|
**Implementation Guide**: See [`docs/hydrate-plan-implementation-guide.md`](./hydrate-plan-implementation-guide.md) for complete implementation details, including:
|
|
- `hydratePlan()` function pattern
|
|
- PlanActionClaim interface structure
|
|
- Helper functions for create/edit operations
|
|
- Usage examples and testing recommendations
|
|
|
|
**Note**: This method requires generating signed JWTs with DID keys, which is complex. **Method 1 (TimeSafari App UI) is recommended** for creating test plans.
|
|
|
|
## Plan Handle ID Format
|
|
|
|
Plan handle IDs **must be valid URIs** (RFC 3986 format).
|
|
|
|
### Default Format (System-Generated)
|
|
|
|
**`https://endorser.ch/entity/{ULID}`**
|
|
|
|
- **ULID**: 26-character string, Crockford base32 encoded
|
|
- **Example**: `https://endorser.ch/entity/01GQBE7Q0RQQAGJMEEW6RSGKTF`
|
|
|
|
### Custom Global URIs
|
|
|
|
Any valid URI with a scheme is accepted:
|
|
- `https://endorser.ch/entity/01GQBE7Q0RQQAGJMEEW6RSGKTF` (default)
|
|
- `http://example.com/project/123` (custom)
|
|
- `did:ethr:0x1234...` (DID format)
|
|
- Any URI matching: `^[A-Za-z][A-Za-z0-9+.-]+:`
|
|
|
|
**Validation**: The format must match RFC 3986 URI specification.
|
|
|
|
### ULID Format Details
|
|
|
|
- **Length**: Exactly 26 characters
|
|
- **Encoding**: Crockford base32 (0-9, A-Z excluding I, L, O, U)
|
|
- **Structure**: Timestamp + random component
|
|
- **Purpose**: Globally unique, lexicographically sortable identifiers
|
|
|
|
## Updating Test Configuration
|
|
|
|
Once you have valid plan handle IDs:
|
|
|
|
### Update Test Config
|
|
|
|
Edit `test-apps/daily-notification-test/src/config/test-user-zero.ts`:
|
|
|
|
```typescript
|
|
starredProjects: {
|
|
planIds: [
|
|
"your-real-plan-id-1", // Replace with actual IDs
|
|
"your-real-plan-id-2",
|
|
"your-real-plan-id-3"
|
|
],
|
|
// ...
|
|
}
|
|
```
|
|
|
|
### Update Seed Script Defaults
|
|
|
|
Edit `scripts/seed-test-projects.js`:
|
|
|
|
```javascript
|
|
const DEFAULT_TEST_PROJECT_IDS = [
|
|
"your-real-plan-id-1", // Replace with actual IDs
|
|
"your-real-plan-id-2",
|
|
"your-real-plan-id-3"
|
|
];
|
|
```
|
|
|
|
### Pass IDs via Command Line
|
|
|
|
You can also provide IDs when starting the test server:
|
|
|
|
```bash
|
|
# Start test server with your real plan IDs
|
|
node scripts/test-api-server-with-seed.js 3000 "id1,id2,id3"
|
|
|
|
# Or when seeding
|
|
node scripts/seed-test-projects.js seed http://localhost:3000 "id1,id2,id3"
|
|
```
|
|
|
|
## Quick Setup Workflow
|
|
|
|
1. **Start your local TimeSafari API** (if you have one)
|
|
2. **Create 3-5 test projects** via the UI or API
|
|
3. **Note the plan handle IDs** from the responses
|
|
4. **Update test-user-zero.ts** with those IDs
|
|
5. **Restart test server** with real IDs
|
|
|
|
## Using Placeholder IDs (Limited)
|
|
|
|
The placeholder IDs (`PLACEHOLDER_ID_1`, etc.) will work for testing the **structure and flow** of the prefetch system, but:
|
|
|
|
- ❌ Won't match real projects in your database
|
|
- ❌ API responses will be empty or fail validation
|
|
- ❌ Can't test actual starred projects querying
|
|
|
|
For full testing, you **must** use real plan handle IDs.
|
|
|
|
## Troubleshooting
|
|
|
|
### "Invalid plan handle ID" errors
|
|
|
|
- Check the format matches your database
|
|
- Verify IDs exist in your TimeSafari database
|
|
- Check API logs for validation errors
|
|
|
|
### Empty API responses
|
|
|
|
- Plan IDs don't exist in database
|
|
- IDs are in wrong format
|
|
- Database query is failing
|
|
|
|
### Cannot find plan IDs
|
|
|
|
- Check Network tab in DevTools when creating projects
|
|
- Query database directly
|
|
- Check localStorage/IndexedDB for plan records
|
|
- Look at API response when loading projects list
|
|
|
|
## Example: Finding IDs via Browser DevTools
|
|
|
|
1. Open TimeSafari app in browser
|
|
2. Open DevTools → Network tab
|
|
3. Create a new project
|
|
4. Look for POST/GET requests to `/api/v2/plans` or similar
|
|
5. Check response JSON for `handleId` field
|
|
6. Copy the `handleId` value
|
|
|
|
Example response might look like:
|
|
```json
|
|
{
|
|
"handleId": "abc123def456789",
|
|
"name": "My Test Project",
|
|
...
|
|
}
|
|
```
|
|
|
|
Use that `handleId` in your test configuration.
|
|
|