Skip to main content

Fullcourt Training

  • Next.js
  • TypeScript
  • Expo
  • React Native
  • Supabase
  • RevenueCat
  • Stripe
  • Tailwind CSS
  • Playwright
  • Jest
Table of contents

Fullcourt Training is a cross-platform basketball product that combines animated drills and plays, user accounts, saved content, subscriptions, and club access in one system. I own the product and have been responsible for its research, product direction, visual identity, content production, development, integrations, testing, SEO, and deployment.

The platform includes a live Next.js website and a production-ready Expo app built around the same Supabase backend. Its central technical challenge is not simply displaying sports content, but keeping identity and premium access consistent across web, iOS, Android, and multi-user club subscriptions.

Project overview

Fullcourt Training helps basketball coaches and players understand drills and plays through clear animations rather than static diagrams or long written explanations. Users can browse a structured playbook, create an account, save content, and unlock premium material. Clubs can purchase access for several people and manage how their licences are distributed.

The project began through a collaboration with Onside – Training. The purpose was to explore a subscription-based product without forcing Onside to replace or restructure its existing solution. I used that context as the starting point for an independent product that I now own and continue to develop.

The website is live, while the mobile app is technically ready for publication. I have delayed the public app release because the content library still needs more product videos before the mobile experience is strong enough to launch properly.

Context and my responsibility

I handled the complete product lifecycle. This included stakeholder interviews, requirements, product strategy, UX, visual design, branding, animation and video production, data modelling, frontend and backend development, payment integrations, automated testing, deployment, SEO, and ongoing maintenance.

Working across that entire scope required me to switch continuously between product, technical, and communication responsibilities. When speaking with non-technical stakeholders, I focused on business rules and user outcomes rather than frameworks. I then translated those conversations into concrete data structures, access rules, interface states, and testable workflows.

I also developed the native app in a separate public repository: Fullcourt Training app.

The problem

Basketball knowledge is often communicated through whiteboard sketches, static court diagrams, or lengthy explanations. These formats make it difficult to understand movement, timing, spacing, and player responsibilities at a glance. Coaches also need material that can be found quickly while planning or running a practice.

The business problem was equally important. The product needed a realistic way to monetise premium content across several platforms. A user who purchased access on the web should receive the same access in the app, while iOS and Android purchases should also be reflected on the website. Clubs needed another model entirely: they needed to buy several licences and distribute them without sharing one account.

This meant that content, authentication, payments, and access control could not be treated as unrelated features. They had to be designed as one product system.

Requirements and constraints

I gathered requirements through informal semi-structured interviews with the Onside – Training team and a pilot basketball coach. The stakeholder conversations clarified the commercial requirements, while the coach provided practical insight into how drills and plays are searched for and used.

The platform therefore needed to:

  • Work as a coherent product across web and mobile.
  • Support public, personal premium, and club-based access.
  • Make drills and plays easy to browse, filter, understand, and save.
  • Keep payment logic separate from the interface that consumes premium status.
  • Remain understandable to non-technical administrators and customers.
  • Preserve parts of the Onside design language while establishing a distinct basketball identity.
  • Provide a foundation that could support more content and additional sports concepts later.

A further constraint was that app-store billing, web billing, and club billing follow different rules. The architecture therefore needed a shared entitlement model rather than several platform-specific definitions of what “premium” meant.

Product and UX decisions

I structured drills and plays as domain-specific content rather than generic posts. Content can be organised through attributes such as category, type, player count, and access level. This gives coaches useful filters while keeping the browsing experience simple.

Public content provides immediate value and lets visitors evaluate the product. Premium content creates a reason to subscribe without making the entire platform feel closed. The interface clearly communicates which material is available, while the backend enforces the same access rules independently of the client.

Accounts support saved drills and plays, making the platform more useful as a working playbook rather than a one-time content catalogue. A user can build a relevant collection and access it from different devices.

For clubs, I deliberately avoided shared accounts. A club purchases a code and receives a management dashboard where it can follow code usage. Individual users redeem the code from their own accounts, preserving personal identity, saved content, and access history.

Technical implementation

The web application is built with Next.js and TypeScript, while the mobile client uses Expo and React Native. Both use Supabase for authentication, application data, and the stored premium state.

RevenueCat acts as the subscription and entitlement layer. Webhooks update the user’s premium status in Supabase, which allows both clients to consume a consistent access state without embedding payment-provider logic throughout the application. Stripe supports web and business purchases, while the iOS and Android purchase flows are configured and working through RevenueCat even though the app is not yet publicly released.

The most significant architectural correction happened when I introduced club subscriptions. My original model assumed that premium access belonged to one paying user. It was not designed for an organisation purchasing access for several independent accounts. Trying to force team billing into that structure would have made access rules and renewal behaviour difficult to maintain.

After researching alternative models, I implemented code-based distribution. A club purchase creates a redeemable access path and a management interface. When a user redeems a valid code, the system grants a promotional entitlement in RevenueCat. RevenueCat then sends the entitlement change through the existing webhook flow, and Supabase stores the resulting premium state. This allowed team access to reuse the same entitlement architecture as individual purchases rather than creating a second, incompatible definition of premium.

I use Playwright and Jest to test important user and application flows. Testing is especially valuable around authentication, redemption, and access control, where a small inconsistency can result in either blocked customers or unintended premium access.

Communication and collaboration

A central part of the project was communicating with people who cared about the product but not the implementation details. Instead of asking stakeholders to make technical choices, I presented consequences: how a subscription would behave across devices, what a club administrator would control, and what information a coach needed when finding a drill.

I translated these discussions into requirements and then into technical research questions. That process helped me avoid selecting technologies before I understood the actual business rules. It also made it easier to explain later architectural changes, including why team access needed a separate purchasing workflow but a shared entitlement model.

The pilot coach provided a practical reference point for navigation and content structure. Although the project has not undergone a larger formal usability study, these conversations grounded the core product decisions in real coaching needs.

Results and current status

The web product is live with accounts, public and premium content, personal subscriptions, business purchases, club dashboards, code redemption, and cross-platform entitlement handling. The mobile app is ready for publication from a technical perspective, including functioning iOS and Android payment flows, but is being held until the content library is stronger.

Fullcourt Training has also developed an audience beyond the product itself. Its social channels have passed 10,000 followers and are approaching 1.5 million combined views. That reach supports the product by validating interest in animated basketball education and by creating a direct distribution channel for new content.

The project continues to evolve through new drills, plays, articles, and commercial features. Because I own both the product and implementation, I can connect audience feedback directly to product decisions and releases.

Lessons and retrospective

The largest lesson was that billing models must be treated as domain architecture, not as checkout details. My initial implementation solved individual subscriptions well, but it did not leave enough room for club-based access. Correcting that required me to separate the purchaser, the account receiving access, and the entitlement itself.

I also learned the value of designing around stable product concepts. The website and app have different interfaces and payment constraints, but they share users, content, bookmarks, and entitlements. Treating those entities as the centre of the architecture made it possible to extend the product without duplicating its core logic.

If I were starting again, I would include organisational access in the initial domain model and define the relationships between purchasers, groups, users, and entitlements earlier. The later code-based solution works well, but reaching it required restructuring assumptions that had been embedded in the original system.

What this project demonstrates

Fullcourt Training demonstrates my ability to own a product from research and stakeholder communication through UX, architecture, implementation, testing, content, and deployment. It also shows that I can work across web and mobile, integrate complex payment systems, and revise an existing architecture when new business requirements expose its limitations.