Inspiration

I'm Zoe Martinez, and I've trained and competed in karate for more than 15 years. As a student and competitor, I kept seeing the same thing at every dojo: teachers buried in paper. Attendance on notebooks, payments tracked in chat threads, tournament sign-ups on loose sheets, and dozens of parents messaging about fees, exams and schedules. Payment messages got lost, records went missing, and teachers spent their evenings chasing information instead of teaching.

I convinced my teammates that we could fix this for them. When we saw the chance to build on PayPal's tools, we knew it was our way in: if the hardest part of running a dojo is collecting money and keeping track of who paid, then reliable online payments were the place to start.

What it does

DojoManager is a management app for martial arts schools, built around the people who actually use it:

  • Administrators manage students, teachers, classes, monthly fees, events and the dojo's settings.
  • Teachers take attendance, track belt promotions, manage their groups and send announcements to families.
  • Parents and guardians see their children's attendance and progress, sign them up for tournaments and exams, and pay monthly fees, event registrations and equipment with PayPal from their phone.
  • ki-AI, our assistant powered by Claude, helps staff with the repetitive writing and analysis: it drafts payment reminders, summarizes a student's progress, reviews a group's attendance, recommends equipment and turns a rough idea into a clear announcement. It replies in each user's preferred language (Spanish or English).

Families join through an invitation link or QR code, so nobody has to type a long sign-up form.

How we built it

  • Frontend: React + Vite + Tailwind CSS, with light and dark themes, adjustable font size and full Spanish/English translations.
  • Backend: Node.js + Express with Prisma 7 on PostgreSQL.
  • Payments: the PayPal Orders API (create, then capture) with the PayPal JS SDK buttons, plus a signed webhook as a backup.
  • AI: the Anthropic Claude API for ki-AI, always fed with the dojo's real data and never allowed to invent amounts.
  • Automation: Zapier workflows for scheduled payment reminders and monthly reports.

Each dojo's data is isolated: one platform can host many dojos, and a Prisma extension automatically scopes every query to the dojo of the logged-in user.

Payments we can trust

The browser never decides how much to charge. It only says which fee it wants to pay. The backend reads the amount from the database, creates the PayPal order and, after approval, captures it on the server. A payment is only marked as paid if what PayPal captured matches exactly what was owed:

$$ \text{paid} \iff \text{status} = \texttt{COMPLETED} \;\land\; \text{captured} = \text{owed} \;\land\; \text{currency} = \text{expected} $$

We also made sure a family can never be charged twice:

  • every capture is sent with a PayPal-Request-Id, so retries and double clicks are idempotent;
  • the button and the webhook can arrive in any order, but a conditional update means only the first one changes the record;
  • each order is stored on its fee before approval, so an abandoned older order can't settle it later.

Challenges we ran into

  • Race conditions in payments. The capture from the button and the PayPal webhook can arrive at the same moment. Designing the flow so that exactly one of them settles the fee took several iterations.
  • Multi-tenant data safety. Isolating each dojo's data without remembering to add a filter in hundreds of queries pushed us to centralize the scoping in a Prisma extension, with an explicit, rarely used escape hatch for platform-level tasks.
  • Making AI useful, not decorative. Early drafts from the assistant sounded generic or got numbers wrong. We gave ki-AI strict instructions to use only the figures in the data we send, to answer in the user's language, and to fail gracefully: if the AI is unavailable, the rest of the app keeps working.
  • Real-world testing. Testing on phones over the local network revealed problems we never saw on localhost, such as the browser blocking the clipboard on non-HTTPS pages. We also built realistic demo data (months of attendance, fees paid on time, late and unpaid) to test the reminder and recovery flows properly.
  • Working as a team of five. Coordinating branches, pull requests, database migrations and shared test data across five people taught us as much as the code did.

What we learned

  • How to integrate payments safely: server-side amounts, server-side capture, idempotency and webhook signature verification.
  • That the hard part of a payment flow isn't the happy path. It's declined cards, double clicks, closed windows and late webhooks.
  • How to design AI features around a real task, with guardrails, rather than adding a chatbot for its own sake.
  • That accessibility, translations and dark mode matter from day one when your users range from teenagers to grandparents.

What's next

  • Deploy to production and onboard our first real dojos.
  • A mobile app version (starting as an installable PWA).
  • Recurring payments for monthly fees with PayPal subscriptions.
  • Scheduled ki-AI collection reminders running directly in the backend.

Built With

Share this project:

Updates

Submission history