From appfolio-pack
Production readiness checklist for AppFolio integrations. Trigger: "appfolio production checklist".
npx claudepluginhub flight505/skill-forge --plugin appfolio-packThis skill is limited to using the following tools:
AppFolio manages properties, tenants, leases, and work orders for real estate operations. A production integration handles sensitive tenant PII, financial transactions, and maintenance workflows. Failures here mean missed rent collections, unprocessed work orders, or tenant data exposure under CCPA. This checklist ensures your AppFolio API integration is resilient, compliant, and observable.
Guides Next.js Cache Components and Partial Prerendering (PPR): 'use cache' directives, cacheLife(), cacheTag(), revalidateTag() for caching, invalidation, static/dynamic optimization. Auto-activates on cacheComponents: true.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Share bugs, ideas, or general feedback.
AppFolio manages properties, tenants, leases, and work orders for real estate operations. A production integration handles sensitive tenant PII, financial transactions, and maintenance workflows. Failures here mean missed rent collections, unprocessed work orders, or tenant data exposure under CCPA. This checklist ensures your AppFolio API integration is resilient, compliant, and observable.
APPFOLIO_API_KEY stored in secrets manager (not environment files)https://api.appfolio.com/v1)async function checkAppFolioReadiness(): Promise<void> {
const checks: { name: string; pass: boolean; detail: string }[] = [];
const baseUrl = process.env.APPFOLIO_BASE_URL || 'https://api.appfolio.com/v1';
// API connectivity
try {
const res = await fetch(`${baseUrl}/properties?limit=1`, {
headers: { Authorization: `Bearer ${process.env.APPFOLIO_API_KEY}` },
});
checks.push({ name: 'API Connectivity', pass: res.ok, detail: res.ok ? 'Connected' : `HTTP ${res.status}` });
} catch (e: any) { checks.push({ name: 'API Connectivity', pass: false, detail: e.message }); }
// Credentials present
checks.push({ name: 'API Key Set', pass: !!process.env.APPFOLIO_API_KEY, detail: process.env.APPFOLIO_API_KEY ? 'Present' : 'MISSING' });
// Work order endpoint
try {
const res = await fetch(`${baseUrl}/work_orders?limit=1`, {
headers: { Authorization: `Bearer ${process.env.APPFOLIO_API_KEY}` },
});
checks.push({ name: 'Work Orders', pass: res.ok, detail: res.ok ? 'Accessible' : `HTTP ${res.status}` });
} catch (e: any) { checks.push({ name: 'Work Orders', pass: false, detail: e.message }); }
for (const c of checks) console.log(`[${c.pass ? 'PASS' : 'FAIL'}] ${c.name}: ${c.detail}`);
}
checkAppFolioReadiness();
| Check | Risk if Skipped | Priority |
|---|---|---|
| API key rotation | Expired keys halt property sync | P1 |
| Payment sync failure | Missed rent collections | P1 |
| Tenant PII exposure | CCPA violation, legal liability | P1 |
| Work order duplication | Duplicate maintenance dispatch | P2 |
| Rate limit handling | 429 errors during bulk property import | P3 |
See appfolio-security-basics for tenant data protection and access control.