-
Notifications
You must be signed in to change notification settings - Fork 0
04_Developer Playbook
Last updated: 2026-05-07
Use this when changing Princeps. Keep the app user-scoped, localized, tier-aware, and easy to reason about.
npm install
docker compose up -d
npx prisma migrate dev
npm run db:seed
npm run devThe dev command runs a database healthcheck before starting Next.js.
Quality checks:
npm run lint
npm run typecheck
npm run buildCheck:
- Which authenticated
userIdowns the data? - Which existing feature is the closest reference?
- Does the change need Prisma, API routes, UI, i18n, tools, context, tiers, settings, notifications, integrations, or docs?
- What must remain server-only?
- Which tests or build checks match the risk?
Typical CRUD feature shape:
prisma/schema.prisma
types/api.ts
lib/<feature>/schemas.ts
lib/<feature>/shared.logic.ts
lib/<feature>/create.logic.ts
lib/<feature>/list.logic.ts
lib/<feature>/update.logic.ts
lib/<feature>/delete.logic.ts
lib/<feature>/index.ts
app/api/<feature>/route.ts
app/api/<feature>/[id]/route.ts
app/(app)/<feature>/page.tsx
components/<feature>/
messages/de.json
messages/en.json
Rules:
- Add
userIdand useful indexes to stored user data. - Keep API routes thin: auth, parse, gate, delegate, respond.
- Keep business logic in
lib/<feature>/. - Keep client mutation logic in
components/<feature>/logic/. - Return client-safe types with ISO date strings.
- Localize all user-facing copy.
Good references:
- Tasks for clean CRUD.
- Contacts for relationship data.
- Meetings for side effects, participants, AI prep packs, and integrations.
Add tools only when the assistant should act, not just talk.
Tool checklist:
- Add registry entries in
lib/tools/registry/<feature>.registry.ts. - Set
minTierandgroup. - Add a handler in
lib/tools/handlers/<feature>.handler.ts. - Validate all args with Zod or a feature schema.
- Resolve names to IDs in the handler, not the registry.
- Enforce the same tier limits as the API route.
- Return compact
ActionResultdata. - Spread registry and handlers into the orchestration files.
Context checklist:
- Add
lib/context/<feature>.slot.tswhen the assistant should always know about the data. - Fetch only user-scoped, compact, relevant data.
- Keep context human-readable and bounded.
- Update prompt/tool availability if tier or disabled-tool settings affect the feature.
Plan limits live in types/billing.ts. Enforcement lives in lib/tiers/enforce.ts.
Use the right limit style:
- At-rest caps for stored records.
- Daily counters for burst guards.
- Monthly counters for LLM and expensive actions.
- Lifetime counters for anti-bypass behavior, such as knowledge characters.
-
0means disabled for that tier. -
-1means unlimited.
Enforce before writes or expensive calls. If an action exists in both UI/API and LLM tools, both paths need equivalent gates.
Most user preferences save through:
PATCH /api/settings
When adding a setting:
- Parse it in
lib/settings/user-preferences.logic.ts. - Accept it in
app/api/settings/route.ts. - Load it in
app/(app)/settings/page.tsx. - Pass it into the owning settings tab.
- Add localized strings.
- Wire it into the real consumer.
Keep usage, subscription, and integration state out of User.preferences unless it is truly a preference.
Current live examples:
- Google Calendar for OAuth, sync, and two-way meeting side effects.
- Google Drive for OAuth, file listing, and Knowledge import.
New provider checklist:
- Pick a stable provider string, for example
gmailormicrosoft_outlook. - Add
lib/integrations/<provider>/client.ts. - Add provider actions such as
sync.ts,events.ts, orimport.ts. - Add routes under
app/api/integrations/<route-slug>/. - Use a provider-specific OAuth state cookie.
- Store tokens with
upsertIntegration(). - Read tokens with
getValidToken(). - Add Settings UI metadata and i18n.
- Add source/dedupe fields to the owning feature if needed.
- Apply tier and usage gates before importing records.
Request minimal scopes. Never expose provider tokens to the client.
Use notifications for meaningful assistant/system events, not every CRUD action.
Rules:
- Notifications belong to one user.
- Soft-delete with
dismissed. - Use
metadata.datefor once-per-day categories. - Respect
notificationsEnabled. - Respect tier and automation toggles for proactive nudges.
Weather uses Open-Meteo without a key. FORCE_GREETING=true bypasses the daily greeting dedupe in development.
Stripe files live in lib/stripe/ and app/api/stripe/.
Local test setup:
npx tsx scripts/stripe-seed.ts
stripe listen --forward-to localhost:3000/api/stripe/webhookSet:
STRIPE_SECRET_KEY
STRIPE_PRICE_PRO_MONTHLY
STRIPE_PRICE_PRO_ANNUAL
STRIPE_PRICE_PREMIUM_MONTHLY
STRIPE_PRICE_PREMIUM_ANNUAL
STRIPE_WEBHOOK_SECRET
Webhook events:
checkout.session.completedcustomer.subscription.updatedcustomer.subscription.deleted
Known product gap: subscription management currently goes through the Stripe Customer Portal; invoice history and richer in-app downgrade/cancel flows are not first-class app screens.
Password reset currently logs links server-side and stores recent links for the dev-only endpoint:
GET /api/dev/reset-links
This endpoint returns 404 outside development.
For production, wire a real provider in lib/auth/auth.ts, for example Resend or SMTP/Nodemailer, and set a verified RESET_PASSWORD_FROM_EMAIL.
LLM tracing is already wired and production-only.
Set:
LANGFUSE_PUBLIC_KEY
LANGFUSE_SECRET_KEY
LANGFUSE_HOST # optional
Tracing records chat calls, streaming chat calls, single embeddings, token counts, tool calls, latency, and errors. It is a no-op without production keys.
Before serious multi-user production:
- Encrypt integration access and refresh tokens at rest.
- Configure a real email provider and email verification if required.
- Use Upstash Redis or another distributed rate limiter.
- Verify Stripe live keys, price IDs, and webhook endpoint.
- Decide backup and migration process for Postgres.
- Review all external scopes and privacy copy.
- Run lint, typecheck, and build.
A change is done when:
- It follows existing layer boundaries.
- User ownership is enforced.
- User-facing copy is localized.
- Tier and usage gates match the feature.
- LLM tools/context are updated when relevant.
- Settings, notifications, integrations, and billing are considered.
- Docs are updated when behavior or architecture changes.
Princeps Wiki: USER_GUIDE.md | ARCHITECTURE.md | FEATURES_REFERENCE.md | DEVELOPER_PLAYBOOK.md
For implementation-level agent context, read CONTEXT/. For exact behavior, verify the current code.
<@coldbydefault>
© 2026 PRINCEPS All rights reserved.
Made by AnotherProject™ - ColdByDefault