Historical Project Outcomes at a Glance
- Capacity: Zero double-bookings through the custom capacity system.
- First-year scale: More than 1,400 events managed.
- Financial operations: Installment and invoice automation reduced payment-chasing and administrative work.
- Schedule alignment: Two-way Google Calendar synchronization connected the historical project scheduling workflow.
These outcomes describe the historical project period and were not remeasured for this case study. For a shorter introduction, view the WhiteMarker project overview.
1. The Operational Fracture
Running an event agency requires several kinds of truth to remain consistent. Sales needs to know whether a date is available; operations needs to know who is assigned and what was promised; finance needs to know what is owed, collected and still outstanding. Before WhiteMarker, that context was distributed across calendars, spreadsheets, invoice documents and email threads. Each tool could describe its part of the work, but a coordinator had to reconcile the relationships manually whenever something changed.
An event date is a useful example of the problem. Moving it can affect contractor availability, vendor arrangements, service deadlines and the run-of-show, while the financial agreement remains attached to the engagement. A package change creates a different set of dependencies: delivery scope and the commercial amount may need to change together. The cost of fragmentation is therefore repeated interpretation, as staff work out which records refer to the same event and which version of its commitments should guide the next action.
I engineered WhiteMarker end to end as a connected agency and event-operations platform. Capacity planning provides the broad view of work, and the project workspace gathers the people, services, schedule and money needed to deliver an engagement. The architecture carries that continuity through tenant ownership, explicit resource contracts and auditable financial history. The product's central design choice is to make the project a common operating context while giving each domain its own responsibilities.
2. Capacity Planning Across the Whole Year
The custom capacity matrix responds to a planning problem that an appointment list leaves unresolved. An agency needs to see possible work, committed events, unavailable periods and ongoing delivery phases across a season. WhiteMarker's yearly view places all twelve months beside a selected day and upcoming events, so coordinators can move between long-range load and near-term execution. The monthly view offers another planning scale within that same product model.

The legend distinguishes Inquiry, Booked, Blocked, Canceled, Meeting, Editing and Done in the historical interface. Those labels help explain why capacity extends beyond the day on which an event happens: preparation, follow-through and unavailable time also shape what an agency can accept. The selected-day treatment gives the operator a position within the annual grid, while the upcoming-event panel keeps immediate commitments readable. The full-resolution view is useful here because the matrix is intentionally dense; its value comes from keeping the year's pattern visible together.
The current persistence model separates Projects, pending Inquiries and BlockedDates and combines them in calendar projections. A pending inquiry remains a potential engagement with its own intake lifecycle; a project carries operational metadata; a blocked period reserves unavailable time. That separation preserves meaning when these resources appear in the same calendar window. It also lets the system handle a multi-day block or an inquiry conversion without forcing each into the lifecycle of a generic event record.
This flow describes how planning leads into coordination. The calendar composes work without becoming the owner of every detail, and a project opens the context needed for assignments, delivery and finance. During the historical project period, the custom capacity system achieved zero double-bookings. The architectural lesson is that an availability decision becomes more useful when the application retains the distinction between possible demand, scheduled work and deliberately unavailable capacity.
3. The Project Workspace as a Shared Context
WhiteMarker's event workspace holds date, venue, start/end time and lifecycle status beside a financial summary. Funnel stage, booked plan, lead source and planner/producer context remain visible above tabs for the client, team, services, vendors, bookkeeping and notes. That arrangement supports a coordinator moving between responsibilities without losing the identity of the engagement. It also makes commercial and financial context available while a delivery decision is being made.

The financial summary's proximity to event details matters operationally. A coordinator can see pending payment context while reviewing an assignment, rather than reconstructing it from an invoice document. The planner/producer and lead-source fields provide additional relationship context around the same project. Tabs make the detail manageable, but the design keeps the event's shared context in place as attention moves from the client to delivery scope or bookkeeping.
Complex editing needs a comparable boundary behind the interface. The current workspace implementation uses owned edit sessions, staged changes and explicit save/discard behavior. Requests carry draft revisions and mutation identities; the server checks the workspace revision and relevant contact revisions before accepting changes. Commit operations validate the actor and permissions within serializable transactions, and replay checks distinguish a repeated request from a reused identity carrying different content.
The frontend coordinator then reconciles authoritative committed resources into TanStack Query and invalidates affected project and calendar projections. A stale revision or lost permission stops continued editing instead of allowing an outdated draft to silently overwrite another change. This does not make every tab one undifferentiated record: metadata, assignments, commercial snapshots and finance retain their own boundaries. The workspace supplies a coordinated way to stage related changes while those domain responsibilities remain explicit.
4. People and Relationships Across Projects
An event's people are more than contact information. A client may have partner context, a vendor may have a history of shared events, and a team member has a project-specific role and payment arrangement. The expanded client view brings identity, partner details and the related event into one surface. It gives the operator a path from a relationship to its engagement, which is more useful than finding a phone number and then searching elsewhere for the associated work.

The current model gives tenant-managed CRM identity to Contact, with composable client, team-member and vendor profiles. A business relationship can participate in different kinds of work without requiring a new login identity for each role. Project assignments then express how that contact participates in a specific engagement. Tenant ownership remains part of those relationships, so a reusable identity within one agency does not become an implicit shared identity across unrelated businesses.

Vendor history supports a different operational question from the event workspace: where has this relationship already participated? The year-specific shared-event panel lets a coordinator examine work across projects while retaining venue and schedule context. Inside an event, typed client, team and vendor assignments carry the local responsibilities; planner is a vendor capability and assignment. Archiving an assignment removes participation from that project while preserving the contact for other engagements and historical reference.
The historical product served five permission-gated roles: Super Admin, Admin, Client, Contractor and Vendor. The current architecture uses tenant memberships, roles and permissions to govern operations, allowing access rules to be expressed at the responsibility boundary. Permission-aware controls help users understand available actions, while backend authorization remains the authority for whether a change can be made. This keeps shared workflow context useful without assuming that every participant should have the same operational access.
5. Turning Sold Services into Delivery Commitments
A booking needs to describe what will actually be delivered. WhiteMarker's services view places a package plan, included/excluded services, extras and a delivery deadline within the project workspace. The deadline is expressed relative to the event, which makes the relationship between the scheduled engagement and later delivery visible. A coordinator can therefore inspect the scope of the promise while retaining the event and financial context above it.

Reusable service and package catalogs support defining offerings without making every project a fresh list of unrelated text. The project's commercial snapshot captures the agreed package and line items; confirmed commercial history is immutable, and revisions create a new version. That distinction matters when an offering changes after an engagement has already been agreed. Catalog maintenance should not silently rewrite what an earlier client bought or the commercial context used by its payment plan.
The event-relative deadline also exposes a coordination dependency. If an event moves, staff need to review delivery timing along with participant arrangements and the timetable. Keeping service scope inside the workspace gives them the relevant context for that review. The product does not need to obscure this relationship behind a separate task application: delivery commitments are part of the engagement's operational meaning, and commercial versioning preserves the agreement behind them.
6. Finance as an Auditable Project Lifecycle
The bookkeeping view puts the package amount, discount, tax, processing fee and installment plan beside invoice actions and In/Out tracking. Installments have their own amounts, deadlines and payment states. This gives coordinators a working view of financial progression rather than a single total detached from delivery. Ad-hoc travel and assistant entries also show why a project's incoming payments and delivery costs need to be understood together.

The current finance architecture models auditable resources rather than mutable paid/unpaid flags. Commercial versions define the agreement; versioned payment plans define schedules; installments define obligations; invoices, payments and allocations record progression against them. A payment is recorded once and allocated to obligations, while settlement projections derive the balance from those records. This makes a financial summary explainable: the system retains what was agreed, what was requested, what arrived and where it was applied.
Revisions and reversals require separate treatment. A payment plan can be superseded by another version without rewriting earlier invoice or payment history. Refunds and disputes create reversal records and allocations, preserving the successful receipt and the later change to its financial effect. Team/vendor payouts remain distinct from customer payments and ad-hoc Tracking entries. The architecture can therefore distinguish an expense recorded by an operator from structured settlement of a participant's payment arrangement.
The diagram separates requesting money from recording its receipt, which is why invoice state and installment settlement should not be reduced to the same flag. Decimal monetary values and explicit currency codes carry that discipline into calculation and transport. Summaries remain grouped by currency rather than adding unlike amounts without an exchange-rate contract. For users, the consequence is a financial view that can retain context after a schedule revision, partial payment or reversal; for maintainers, the underlying resources provide a traceable basis for reconciliation.
7. Stripe Connect and Retryable Provider Work
Stripe supplies the payment infrastructure, while WhiteMarker connects that infrastructure to project agreements and financial resources. Each tenant connects its own Stripe Standard account and remains merchant of record. Server-owned OAuth binds the connection to the active tenant and authorized membership, and encrypted credentials remain behind the API boundary. Connected-account context gives invoice and payment activity an explicit business owner rather than placing all agencies behind an undifferentiated payment identity.
Inbound and outbound provider work have different responsibilities. Webhook ingestion verifies the signature against the untouched raw request body and persists the provider event before processing it. Duplicate handling consults processing state, so receiving an event again does not imply that previously attempted work succeeded. Refund and dispute handling feed reversal history, preserving the relationship between the provider event and its effect on local finance resources.
For outbound operations, local intent is stored before the provider call. Persisted operations retain idempotency keys and retry state, allowing a retry to refer to the same action rather than create another invoice because a response was interrupted. The PostgreSQL outbox is the authority for this work; optional BullMQ/Redis workers wake and retry due Stripe operations. This boundary separates a durable business decision from the timing of an external service response and gives failures a record that can be examined and retried.
8. Scheduling Beyond the Application
Event work also happens in calendars used by staff and vendors outside the agency's operations platform. Historical WhiteMarker delivery included two-way Google Calendar synchronization, helping project schedule changes remain aligned with connected calendars. That capability addressed a practical coordination burden: a changed date could otherwise leave the internal booking and the people delivering it working from different schedules. It belongs alongside capacity planning because shared availability has value only when participants can work from aligned event context.
The current Google Calendar integration boundary is server-owned. OAuth authorization is tied to tenant context, the service selects a writable calendar, and refresh credentials are encrypted on the server. Integration state records the selected calendar and connection lifecycle, while project synchronization persistence retains the relationship needed for provider-facing scheduling work. These responsibilities keep access and connection management separate from the local project model; calendar connection status is also separate from a project's delivery or payment state.
The separation also protects the local operating context. The operator's project record should retain its meaning when a provider is disconnected, and a browser should not become the owner of refresh tokens. Integration settings expose connection actions according to permissions, while the backend handles provider credentials and authorization. The architecture diagram below represents this Google Calendar integration boundary without treating it as the same worker path as Stripe's implemented outbox processing.
9. From Project Context to Operational Handoff
The event timeline turns an engagement into a run-of-show. Preparation, ceremony, group photos, reception, speeches and wrap-up have concrete times, with fields for further milestones. Team, vendor and planner/producer selections identify the intended handoff context. These details show the final operational consequence of connecting people and scope around the project: the event can carry a usable working plan instead of leaving execution in an unstructured message thread.

An assignment adds another dimension to that handoff. The team view combines a person's role, payment amount, assignment/payment state and contact information within the same event. A coordinator can see who is expected to perform a responsibility and the associated payment context without treating the person as merely a calendar attendee. The project-sync control sits beside the assignment's role and payment state, reinforcing the connection between scheduling and delivery responsibilities.

The timetable and assignment view answer complementary questions: what happens when, and who is involved in delivering it? Neither requires replacing the project context with another disconnected system. The recurring header preserves the event identity while the working detail changes below it. That continuity helps operations move from agreement to preparation and execution, then return to delivery deadlines and financial follow-through after the event day.
10. Current Architecture by Responsibility
Bun workspaces organize WhiteMarker into frontend and backend applications plus shared packages. The React 18/Vite 6 frontend uses React Router 6 for navigable state, React Hook Form for drafts and local React state for bounded interactions. New and migrated server resources use TanStack Query, with tenant-scoped query keys, resource reconciliation and explicit invalidation. Legacy Redux remains for unmigrated compatibility surfaces, and legacy JavaScript still exists; new modules use TypeScript without requiring every mature screen to change at once.
That ownership split keeps several kinds of state from competing. A selected tab belongs to the interaction, an unsaved value belongs to the form or workspace draft, and a persisted contact or project belongs to the server-resource cache. After a workspace commit, authoritative returned resources update the relevant caches and affected projections refresh. Storybook supplies controlled component states for development, complementing resource and workflow tests without becoming another application state authority.
Shared Zod 4 schemas define migrated HTTP contracts; OpenAPI 3.1 generation produces runtime-free types consumed through the shared API client. Request validation and response serialization belong to the backend, while the frontend receives a contract suited to presentation rather than importing database models. This is especially valuable for finance, where decimal strings and currency codes need to cross the boundary predictably. Separating schemas, generated types and client transport keeps frontend/backend agreement explicit without exposing persistence details to every screen.
NestJS and TypeScript define the backend's domain/module boundaries, and Prisma 7 persists operational and financial resources in PostgreSQL. Better Auth owns sessions and selected tenant context; the API derives active membership from that session and tenant-scoped RBAC checks the requested operation. Tenant-safe resource lookups and relations add ownership checks beneath the UI. A contact or project identifier therefore needs valid tenant context and authorization, while permission-aware presentation communicates available actions to the operator.
11. From Inquiry to Delivery and Financial History
A prospective engagement begins as an Inquiry, allowing intake and pending demand to exist before the operation creates a real Project. The capacity view places that possibility beside scheduled projects and blocked time. When an inquiry converts, an idempotent transaction creates the project and preserves its origin. This gives the agency a traceable transition from demand to operational work while avoiding duplicate projects from repeated conversion requests.
The workspace then brings together metadata, client/team/vendor assignments and commercial commitments. Service scope explains what must be delivered, assignments identify the participants, and the date supplies context for preparation and deadlines. Related edits can be staged against revision-aware workspace state before commit. Persisted changes then flow into project views, contact context and calendar projections, keeping each surface connected to authoritative resources instead of relying on a coordinator to update several independent copies.
Finance continues the same engagement through a versioned payment plan, installment obligations, invoices, receipts and allocations. Provider events contribute to that financial history through tenant-connected Stripe infrastructure, while ad-hoc Tracking and participant payouts retain their separate meanings. The timetable supplies the event-day handoff, and delivery commitments keep the project relevant beyond the ceremony or production date. Later revisions, refunds or disputes extend its history rather than erasing the financial state that preceded them.
WhiteMarker managed 1,400+ events in its first year, with zero double-bookings recorded for its historical capacity system and reduced administrative work around payment chasing. Those outcomes reflect the value of carrying planning, people and money through a shared operational workflow. My end-to-end ownership covered the application architecture, frontend, backend, access model, capacity planning and integrations. The resulting system connects an agency's commitments across planning, delivery and money, giving both operators and maintainers a coherent way to understand the work.
If your event business repeatedly reconciles bookings, participant assignments and installment records by hand, let's discuss how those responsibilities could share one system.
