Stack overview
- App: Next.js 15 (App Router)
- Database: Supabase (PostgreSQL)
- Auth: Clerk for users; API keys for programmatic access
- Validation: Zod on request bodies and query params
Tables (reference)
Example integration
const API_KEY = process.env.MPJ_API_KEY;
const BASE_URL = 'https://app.mypropjournal.com/api/v1';
async function fetchTrades(startDate, endDate) {
const response = await fetch(
`${BASE_URL}/trades?start_date=${startDate}&end_date=${endDate}`,
{
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
}
);
return response.json();
}
async function createTrade(tradeData) {
const response = await fetch(`${BASE_URL}/trades`, {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(tradeData),
});
return response.json();
}
Rate limiting
Rate limits are not enforced yet. When added, expect 429 responses with Retry-After headers for client backoff.
Versioning
- Current stable prefix:
/api/v1 - Breaking changes will ship under
/api/v2 - v1 will remain backward compatible while deprecated paths are supported
- Deprecations will be announced with at least six months notice
Testing checklist
Authentication
- Valid key → 200/201 as expected
- Invalid key → 401
- Missing header → 401
- Free-tier user key → 403
- Revoked key → 401
Isolation
- Create two paid users with separate keys
- Create trades for user A
- Call user A’s ids with user B’s key → 404 or empty lists
CRUD smoke tests
For each resource: create → list (pagination) → get → update → delete.
Edge cases
limitabove 100 should cap at 100- Bad date strings → 400
- Missing required POST fields → 400
- Malformed UUIDs → 400 or 404