What I Built
BriefCraft lets creative leads generate structured project briefs by answering a guided set of inputs. The Claude API runs structured prompt chains to produce each section of the brief consistently: objective, audience, tone, deliverables, constraints, timeline. The output is a formatted, multi-section document that can be shared with clients or exported to PDF.
The platform is multi-tenant: each lead operates in their own isolated organisation. Clients join via a token-based invite link and land inside the lead's workspace. Briefs generated by the lead appear on the client's dashboard; the client cannot see anything from other organisations.
Architecture
Prisma ORM handles schema migrations and type-safe queries against MySQL. Every database query goes through a tenant middleware layer that appends an org_id filter — no query can return rows belonging to a different organisation.
Core Features
Structured Prompt Chains
Each section of a brief is generated by a dedicated prompt with specific context injection. Sections are generated sequentially so later sections can reference earlier ones. Consistent output structure regardless of input variation.
Per-Section Regeneration
Users can re-roll any individual section with additional guidance while keeping the rest of the brief intact. Type "make the tone less formal" or "add a budget constraint" and only that section regenerates.
Token-Based Client Invites
The lead generates an invite link containing a signed token. The client clicks it, registers an account, and lands inside the lead's organisation. Briefs appear on the client's dashboard immediately. No manual user assignment.
Full Tenant Isolation
Each organisation is a separate tenant. Users can only see briefs, team members, and data belonging to their own org. The isolation is enforced at the query layer, not just the UI.
PDF Export
Briefs export to styled PDF via headless Chromium. The PDF mirrors the in-app layout: branded header, section headings, formatted body text. Ready to send to a client without reformatting.
Team Dashboard
Leads see all briefs generated within their organisation. Clients see only the briefs shared with them. Role-based views from a single dashboard component with conditional rendering based on JWT claims.
The Platform
Generated Brief with Internal Notes
Login Page
Team Dashboard — Invite Members
Client View — Brief Sent to Team
Debugging in Production
DEBUGGING STORY
After the initial deployment, new user registrations were creating independent organisations instead of joining the intended team. Tracing the invite flow revealed a flaw in the tenant resolution logic: the registration handler was reading the user's email domain to assign an org rather than reading the invite token.
During the same session: the team_invites table didn't exist in production (missed migration), the database credentials in the production environment file had a character encoding error, and brief generation was truncating at 2,000 tokens — half the content of longer briefs.
All three issues diagnosed and resolved in one session: migration re-run, credentials corrected, and the Claude API call updated to set max_tokens: 4096 explicitly rather than relying on the default.