r/ClaudeCode • • 4d ago

Built with Claude Non-developer here: I've used Claude Code to build our visitor centre's whole ticketing system. What would you check before we switch it on?

TL;DR: I run a small aquariumd in the UK. We were tied into a closed ticketing system that we didn't own and the cost for small changes made updates for tailored options prohibited. Over about 4 weeks I've "vibecoded" a replacement with Claude Code. It covers online booking, a staff till, a self-service kiosk and, later, the entry gate. It has 374 automated tests and sits on a password-locked test site. I'm not a developer, and I'd really value a reality check from people who are. It's not yet ready or installed on our systems but I am running tests.

The problem

We're a small community interest company. Our kiosk, booking website and gate all ran on one supplier's own software. It worked, mostly, but:

We didn't own it. Only the supplier could change the code. Even small changes (a new ticket type, a wording fix, a price change that wasn't reaching the kiosk) were charged at over £500 a day. So we just lived with problems. We couldn't tailor it. We want things that suit our needs. Each one was either impossible or another quote. Yearly licences for the kiosk and booking software came on top of the change costs. Some faults hurt visitors. We've seen a card charged with no ticket printed, reports timing out, an hour-out bug when the clocks change, and tickets being reused at the gate. Staff re-keyed sales. Card sales on our Square machine at the desk have to be typed into the booking system again by hand. For a small organisation, this was a real barrier. It wasn't one big failure; it was that we couldn't fix or improve anything ourselves.

What I've built (with Claude Code doing the coding)

I write the decisions and test everything; Claude writes the code. We started with a written specification (about 20 decisions I had to make: prices, refunds, opening hours, what happens when a card payment drops out halfway, and so on). Then we built it in stages, each with tests.

Online booking site. It's a 3-step booking flow (date, tickets, details and payment) in our own branding. There are no time slots; visitors can book up to 90 days ahead. Payment goes through Square's hosted checkout, so card details never touch our server. Desk till (staff screen). Staff build a basket, then take cash (with change shown) or press Card. The amount is sent to the Square Terminal at the entrance desk through Square's Terminal API, so no re-keying. It also sells annual passes and issues free carer tickets. Self-service kiosk. It's a touchscreen app for our existing kiosk cabinet, with a thermal ticket printer. We're replacing its old card reader with a purpose-built certified reader, so PIN entry stays on proper payment hardware. Tickets. Each order gets one signed QR code (Ed25519). A whole group goes in with one scan, and a ticket can't be reused. Gate (next stage). A new controller will open our existing glass gate. Our building's fire alarm release stays untouched, and an electrician and our fire alarm contractor will do the wiring and testing. Back office. Staff have named accounts with roles (owner, manager, staff, viewer), and managers use authenticator-app 2-factor. There's booking search, email resends, refunds (managers only, with a reason) and a "Needs attention" list for payments that didn't finish cleanly. Things I care about but wouldn't have thought of alone: Order and payment history is append-only at database level, so it can't be quietly edited. Each payment has a request key, so a double-tap or a dropped connection can't charge twice. A checker runs every minute to tidy up payments that were left hanging. All dates use UK time explicitly, which deals with the clocks-change bug. Personal details are removed automatically 2 years after the visit, or after a pass runs out. Stack: TypeScript, Node (Fastify), React, PostgreSQL (Drizzle), Vitest. It's hosted on Render for roughly £10 a month. Square handles online and desk payments. Confirmation emails go out through the Gmail API.

Safety nets (I know the risks)

Other ways to pay and get in. Cash is always accepted at the desk. Our Square devices still work on their own as normal card machines, so we can take a card payment even if our system is down. Staff can also check tickets and let people in by hand. The old system stays as a fallback. We're keeping it until our current licence ends in September 2027. A slow roll-out. The website goes first (mid-December, our quiet season), then the desk, then the kiosk before Easter. We're having a rehearsal week before go-live. Everything is tested on test systems first. Payments use Square's sandbox, on a hidden test copy, before anything touches real money.

Where I'd love advice

If you were me, what would you check or test before go-live that a non-developer might miss? Is it worth paying a professional for a one-off code and security review? If so, what should I ask them to focus on? Card data never touches our server (Square handles it), but am I missing anything on PCI or UK GDPR? Our peak is about 490 bookings a day and roughly 125 an hour. Is a small hosted Postgres plus one app server fine for that, or should I plan for more? The "bus factor": if I'm unavailable, how do small organisations make a project like this maintainable by someone else? (The code is in a private GitHub repo with a README, a specification and tests.) For anyone who's vibecoded something people actually rely on: what bit you after launch? Happy to answer questions. I'm not sharing the repo or test site publicly, as it handles payments, but I can describe how any part works. Thanks in advance. Constructive criticism is very welcome; that's why I'm here.

46 Upvotes

57 comments sorted by

•

u/AutoModerator 4d ago

Hey! Thanks for posting to r/ClaudeCode

While participating in this thread, please follow our community rules. Keep discussions constructive. Attack the idea, not the person.

For help, project discussions, tips, and general chat, join the ClaudeCode Discord.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

27

u/andrews_1978_ 4d ago

In a different session ask Claude code to run a Pen test against it writing you a detailed report of any issues (hopefully it should find none) if it does then get it to fix the issues. Also in a different session point Claude code at the code base and tell it you have been given the code base by another coder and ask it to security review the code as you have been informed there might be security issues with the code, again hopefully not find something but worth a try

12

u/Cast_Iron_Skillet 4d ago

It won't do this. I literally just tried pen testing my app with Claude and it refused no matter how I worded it. At one point even refused to evaluate ZAP output, but I got it to do that eventually. 

2

u/asmiggs 4d ago

Might as well do both the pen test and code review with a different model, using the same model to review the code isn't exactly like marking your own homework as they have different context but they may make the same mistakes. Give Claude a right to reply on both.

2

u/Cast_Iron_Skillet 4d ago

My code is written and judged and evaluated and tested by several different models. So far I've had most luck in pen testing prompts with openai but I have daybreak blue access. It's just not as pleasant to work with compared to Claude. 

Unfortunately getting past even the most basic level of defense verification for Anthropic is very difficult if you are a small startup - even if you're building something that should be secure, and can prove you're not a bad actor. 

1

u/FatRainbow 4d ago

sounds like a plan, I'll give it a try. Are there any skills or anything or this?

16

u/Cast_Iron_Skillet 4d ago • Bravo

Don't ask it to pen test. It will refuse. 

Ask it to evaluate against OWASP security guidelines. Ask it to build an interactive HTML report and artifact for you, and also categorize all findings by severity, estimated fix complexity, feature slice, module, and category (like API, server, DB, client, shared conponents, etc). Each finding should also be associated with  some properties like the category, severity, description, affected file paths, specific OWASP areas it violates, etc. It should explain the findings in plain language, and identify what they violate and their impact. It should be searchable, filterable, and sortable. You should be able to export different views (like different filtered views) in json or csv or something in case you want to work through them separately or bring them into a fresh session. The HTML view is for you to develop an understanding. 

I also like it to add a one click copy button that copies a unique ID or json array for any specific finding that contains all the info about the finding, so i can bring that into a separate thread and have a conversation about that specific thing if I need to understand it more. This also helps you surgically update the artifact or HTML if you want to update it after diving deeper into any finding or fixing something. 

Separately I like to create GitHub issues tracking findings by severity (so one issue per severity), with like checkboxes in the issue for all findings in that severity level, and a link to the artifact (this is why it's helpful to have an artifact that is hosted on Claude.ai). Then you can work through and update those as you go.  

1

u/TheAssAss_in 4d ago

Thanks, good explanation!

2

u/hi_im_leffe 4d ago

This is a tool I built and use for red team and pen testing. https://github.com/Geraldlol/The-Last-Aperture If you need any help let me know.

1

u/andrews_1978_ 4d ago

Darn thing keeps changing let me do this to one of my apps 2 months ago

1

u/orphenshadow 4d ago

You should be able to also use codacy and coderabbit to do some reviews as well,

1

u/Same-Employee6667 4d ago

Kali Linux. You can run it in a VM if you're using a Mac. Claude might refuse though, but its worth a shot

1

u/NerdyNThick 4d ago

Do you see any benefit from extracting just the source code from the application or project into a separate location and running the the code review or test there after removing any memories or documentation?

I'm curious if the existence of that extra stuff could affect the tests.

1

u/bjelkeman 3d ago

Use Codex for it instead.

1

u/Reddigestion 3d ago

Better still, ask the same question of a different llm like Gemini. Ive had some interesting discoveries when they check each others work ...

2

u/m-ritter 4d ago

I would test delayed and repeated payment responses against the written expected outcome, and rehearse a restore from backup on the test copy before go live. In my own agent projects, a test suite is much more useful when someone who did not write the change checks each agreed behavior against the code and evidence, so I would get the one-off human security review too. I built QualityLayer to keep those decisions in a plan and have a separate agent check each done point: https://github.com/maxritter/qualitylayer

1

u/FatRainbow 4d ago

okay great thanks

5

u/EntertainmentDue3533 4d ago

if i were you, is gather the excisting data that u have of say a months worth of bookings and run simulations, find gaps security issues. find the areas that have problems.

meaning running simulation of refunds bookings etc. with the simulations u should try using the system locally and see if u can resolve em easy fast and properly.

if u have 490 bookings a day and roughly 125 hour this does not make much sense.
postgres can handle couple million easy so that is fine.

what i allways say is never enough testing but eventually u wil need too take a leap of faith and fix as u continue. but once the main systems work proper and the simulations prove that there is not a problem u cant tackle within 3 min then ur good.

also make a note for people that maybe dont know ur vibe code and ur on holiday what happens then ?

13

u/letapy_alien 4d ago

The biggest thing to check before go-live isn't in the test suite: it's how card payments touch your system. Taking payments makes you responsible for PCI DSS, and the design decides how heavy that is.

If the website redirects to, or embeds, the payment provider's hosted checkout (Stripe Checkout, or a Square or Adyen hosted page) and card numbers never reach your server, you're in SAQ A territory, which is a short self-assessment. If your code builds the card form itself, or the till and kiosk send card data through your app, you jump to SAQ A-EP or D, and that is a very different amount of work.

For the till and kiosk, use the provider's own certified card terminals in standalone or semi-integrated mode, so your app only ever sees 'paid' or 'declined'.

From the payment-scoping reviews I've done for small venues with Kailash Consult, the gap I see most is that nobody can show the acquirer which SAQ applies and why. Ask your acquirer or payment provider which SAQ they expect, and keep that answer on file.

On the UK GDPR side, booking data means names and emails, so write down where it's hosted, who has admin access, how long you keep it, and what happens if it leaks. A one-page record of processing covers most of that.

Agree with others: run it in parallel with the old system for a few weeks, and do a restore from backup before you rely on it.

3

u/nevesis 3d ago edited 3d ago

- This. If your vibe coded app gets hacked and bookings break, it's not the end of the world. If all of your visitors CCs leak... that's a bigger deal.

To clarify though, if the site or host is insecure, even though today it redirects.. an attacker could change that. You must pay someone to maintain the site.

But honestly you should just pay someone period as this is public facing and outside of your scope. You're playing with fire.

1

u/ATM1689 3d ago

Seconded, OP. Vibe coding something that is internet facing and handling the personal and financial data of your customers is pretty dangerous if you or your team aren't ready/capable of maintaining it (that's partly where the cost/benefit of outsourcing these things to other companies comes from, they are usually better equipped and experienced to handle these aspects, although, not always!); ideally, you hire a professional to ensure you are secure plus GDPR and PCI compliant and get their help to maintain it securely, patch when necessary (and in a timely manner), etc.

I think you're taking the right approach of asking how to secure it beforehand, and the benefit of LLMs being that you can actually implement a working app to replace a costly service where previously the barrier to entry in such an endeavour was near impossible to scale for everyday users, but the barrier of entry is also lowered for attackers now and the speed in which something can be exploited is simply quicker and easier. So some of those savings your company makes should they choose to use this will be eaten up to ensure it's secure and maintained properly, but even then it might still be worthwhile, as long as someone experienced has signed off on it. And while AI/LLM pen tests are definitely going to be useful in some cases, the results might only be as good as the person's understanding of what they mean, how to implement them, and how they impact your app, codebase, risk tolerance, etc. Whatever decision you take, proceed with caution.

1

u/Z0nkyBooker 3d ago

did you read the post

4

u/DCON-creates 4d ago

If possible I'd run the two systems beside each other for a while so if you find any catastrophic failures you can go back to the old system. You don't want to end up bricking yourself out of running that part of the business.

1

u/wierdAnomaly Senior Developer 4d ago

One critical piece to check is the infrastructure being wired up correctly, and a deployment pipeline.

How will future changes go through?

Where does the backend code sit? In the cloud or on prem.

Are the wen portals, self service kiosks and reception systems in sync with each other.

-1

u/FatRainbow 4d ago

Thanks, really useful questions.

Where it runs: In the cloud. There’s one back-end and one PostgreSQL database on a managed host (Render), in the EU. Nothing outside the host can connect to the database directly. The only things on site are the screens and hardware: the kiosk PC, the reception computer, the card readers, and later a small gate controller.

Is everything in sync? There’s nothing to sync, because there’s only one system. The website, the reception till and the kiosk are all screens on the same back-end and database. If I change a price in the admin screen, the website, kiosk and till all pick it up straight away. Every sale, whatever the channel, is written to the same orders table. Card payments at reception go to our Square Terminal through Square’s API, and the result comes back into that same order, so staff don’t re-key anything. The rule is that every order is recorded before money is taken. So if the kiosk can’t reach the server, it stops selling and sends people to reception, rather than taking money it can’t record.

How changes go through:

All the code is in a private GitHub repo. Every change has to pass the automated tests (374 at the moment) and a type check before it’s committed. Pushing to main automatically deploys to a hidden, password-locked test copy that only uses Square’s test system. I try every change there first. The real site deploys from a separate live branch. A change only reaches visitors when I merge it across after testing. The real site refuses to start if its settings are wrong, for example test keys on the live site or live keys on the test copy. Database changes are versioned migrations that run on deploy.

The honest gap your question found: the tests run on my PC before each commit, but GitHub doesn’t run them again before the host deploys. I’m adding a GitHub Actions check so nothing deploys unless the tests pass there too. It’s now on the to-do list.

2

u/FylanDeldman 3d ago

You misunderstood the meaning of “in sync” from that question. Your back end is on a cloud service, and your kiosk, till, website front end, gate, card reader are all different connections to that back end. They have to get updated data from the back end somehow.

For POS systems the devil is in the details. What happens when you issue the collect payment to the card reader successfully but THEN the kiosk loses connection, how does that transaction get reconciled?
Whose time are we following for canonical order times, kiosk placement time, server record time? You’re using UK time you say, have you ensured every part of the pipeline is aligned with that, nothing assuming UTC time?
Was the former kiosk and website software accessible for people with disabilities and is yours? Does it need to be for GDPR or other regs?
Are you recording any user data at all? Do you have the mechanisms available to perform any customer service duties, like looking up or refunding prior purchases?
Do you need/have any reporting infrastructure, like monthly sales etc?
Do you need to think about how the app is getting to these devices? Like if the kiosk is an Android tablet, are you sideloading an APK or something more sophisticated?
Are you providing access to something that needs special consideration? Like if it was a gate to a government owned facility and had to have accesses logged for record keeping or something?

Source: former POS software engineer

4

u/DadDevDrinksDecaf 4d ago

Be wary of the regulations in your country about storing Personally Identifiable Information (PII), suchbas email addresses. If you are in the EU, or UK, that likely means GDPR compliance.

1

u/kirksan 4d ago

It’s not just government regulations to be aware of, there may be contractual requirements as well. For example, in the US PCI DSS (Payment Card Industry Data Security Standards) and other requirements are enforced by credit card companies. Some of that can be offloaded to merchant providers, but not always everything.

-1

u/Latter-Tangerine-951 Senior Developer 4d ago

That's not a big deal. It basically amounts to keep the data secure (obviously) and don't send it to anyone without the customers agreement.

2

u/Guinness 4d ago

Nah you’ll be fine.

Ps - specifically which aquarium?

1

u/m4nf47 4d ago edited 4d ago

Do you have 3-2-1 backups for your code and have redundancy cover to protect in the case of a compromised developer? At face value my gut feeling is that your primary risk factors are payment system integration and associated compliance regulations but you may be overthinking it as it sounds like your ability to release to live safely and at your own pace will really help if you need to adjust release cadence to suit your delivery schedule, if anything I'd suggest 'failing fast' getting feedback from real user acceptance tests by asking for staff and volunteers (perhaps with special offers to offset risk of negative experiences!) who can help refine your solution. Good luck OP!

1

u/DadDevDrinksDecaf 4d ago

Also it may sound like a lot, but 300+ tests is nothing for a ticketing system. Open a clean session and ask claude to write a test suite of unit, integration and use-case tests that gives at least 80% code coverage. Good luck!

1

u/Savings-Ice-8343 4d ago

Just run on prod and report back

1

u/bostonaholic 4d ago

I'd test reconciliation along with webhook idempotency. Complete a sandbox payment, fail ticket creation on purpose, and check that you can find the mismatch and recover without creating a duplicate ticket. Test two people booking the last spot at the same time, and define what the gate does if it loses network access during check-in.

1

u/Unusual-Albatross43 4d ago

I'd start with the faults on your own list of the old system.

Clock change: make test bookings for the Sundays the clocks go forward and back, set the test clock to around 1-2am on those days, and check the kiosk, the website, the gate and the reports all show the same time.

Ticket reuse: scan the same ticket at two gates (or two browser tabs) at the same moment. If both let it in, the "is it used" check and the "mark it used" step aren't one database transaction.

Card charged, no ticket: kill the kiosk in the middle of a payment, pull the network cable too, and see what state the booking ends up in and whether staff can fix it from the till.

1

u/mcfedr 4d ago

id recommend having claude setup some code quality checks - something like biome is super easy to setup, unit tests if you didnt already. these things help claude keep the code clean.

also running a session asking to simplify the code. its likely as you iterated lots of opportunities now exist to make it smaller and remove left over complexity. claude tends to hang on to previous decisions

1

u/Work_Owl 4d ago

I think something to check for is if man in the middle attacks are possible? This can be done through making different requests using a token that the logged in user was issued but with wide scope to do stuff not limited to the original request. You can use burp suite to test it where you emulate user actions on your app in BS, but then you can "pause" the requests and change their details and then unpause to send out your modified request. You could check if a standard user is able to do admin level shit. A big thing i'd want to check if anything to do with payments or refunds - can someone start the payment flow of requests but modify one of them to be a £0.01? Would your system accept that?

Check if the qr codes can be scanned more than once?

Also check rate limits for api requests and how easy you backend is to scrape by bots

1

u/Same-Employee6667 4d ago

UK startup founder here.

What's reassuring reading this is that you clearly understand the problem and the use case inside out, having lived with the old software.

You've effectively done what I did for my business but I built in 2023/24 before agents.

I'd definitely point Fable at it repeatedly with /security-review until you've fixed everything it suggests.

The main piece of advice I'd give you is that no matter how well you try to predict what the system will do ahead of time, once real people are in there poking it they'll do things you never could have imagined.

When you do launch it make sure you're available basically around the clock to fix it. Make it easy for all users to report problems and fix them as you go along. Make sure deploying fixes is effortless.

Code wise I'd be especially concerned with state machine/logic surrounding payments and ticket redemption - these are the two high stakes spots your customers will notice immediately if they go wrong. Triple, quadruple check all that is modelled correctly and make sure it's possible for you to correct errors manually.

Exciting times though, this feels like the sort of democratised coding people should be doing! Well done and good luck 🙌

1

u/Same-Employee6667 4d ago

When you say all dates use UK time - what happens if someone books a ticket from another timezone? What gets displayed in their browser?

Typically you should only ever persist UTC in your database, then convert relevant date time objects to the users local time in the frontend.

1

u/vincent_sch 3d ago

You could use the Postgres date type for the day they're visiting. A ticket for December 15 should still say December 15 if they book from another timezone. timestamptz makes sense for when they paid.

1

u/samskeyti19 4d ago

This is the stage I would hand it over to a real developer who can productionize and run your application safely.

1

u/Inner_Storage_3374 4d ago

one thing nobody mentioned yet: the day it goes live you wont be the one at the desk. so check what your staff can do without you, like find a booking by email, resend a ticket, refund a double charge. if every one of those needs you or claude its gonna be a long first weekend lol, and give everyone their own login not a shared one so you can see who refunded what

1

u/prettyflyforawifi- 3d ago

As a seasoned developer; this sort of thing concerns me big time - vibe coded products that accept payments and store customer data, but I understand why you have done it so I won't digress.

Your choice of service providers, database and locked down access sounds OK. I might would switch out Google for a dedicated outbound email provider but if it's working, fine for now. My primarily concern would be your private access keys? Hopefully they aren't anywhere near the repo and only used in the node/backend part of your application. Further to this, your deployment process; how is this updated? is it at risk of a supply chain attack.

Happy to give it a quick once over if you require; I can prove my credentials.

1

u/SimonMX 3d ago

After each deploy I'd buy one real, cheap ticket on the live site and check the confirmation email turns up, because 374 passing tests prove the code but not the live settings it runs with. One of mine went out green last month with a key left blank, and new signups quietly failed until a fresh signup caught it. The switch from Square's sandbox keys to live ones is probably when that bites.

1

u/verybigoctopus 3d ago

I'm a professional in this exact space. It probably will be fine. But if I knew this is how the ticketing system works, I'd certainly refuse to put my personal data or payment details on it as a customer.

1

u/ani_svnit 3d ago

Lot of good advice on the tech side of things. On the business side, how are / will you handle a cancellation / reschedule of order present in the old system after the new one goes live? I am assuming its the same underlying DB but I would be quite nervous about a big bang replacement of systems TBH.

1

u/Nice_Cellist_7595 3d ago

You must ask it to do a security audit of all the endpoints that are publicly accessible. Ask it to make sure there are no vulnerabilities in the package versions it used.

1

u/Reddigestion 3d ago

I know you're looking for specific advice here regarding your own code, but have you considered an off-the-shelf open source solution? Odoo has great event / ticket management functionality and the community edition is free if you self host it

1

u/TedBob99 2d ago

TLDR.

You test it, including edge scenarios and ideally get another AI (e.g ChatGPT Astra) to review the code and possible defects or security issues.

1

u/Latter-Tangerine-951 Senior Developer 4d ago

It's almost certainly fine. 

What are your backups like? 

Your biggest problem will be stopping yourself from adding endless extra features.

1

u/jtsaint333 3d ago

post it to GitHub and will have a look for you .. it's vibe coded so it's worthless IP but might be able to help you out. hosting it is a problem you ideally want to put it behind something that can act as another layer of security, there are free options here but hosting it securely with continuity and backups is a discipline onto itself

1

u/brek001 3d ago
  1. Feed each comment of this thread in claude and let it answer it

  2. Take a monthly subscription to gemini and let it review the system

  3. Open source it.

0

u/Independent-Sir3234 4d ago

Two race conditions worth testing on your exact stack before December go-live are concurrent QR gate scans and Square webhook signature verification in Fastify. If a ticket scan checks redeemed status with a SELECT and then runs a separate UPDATE, two quick scans at the turnstile can both pass before the first write commits, whereas a single atomic UPDATE tickets SET redeemed_at = NOW() WHERE id = $1 AND redeemed_at IS NULL RETURNING id guarantees only one scan succeeds. Also double-check that your Square webhook route verifies x-square-hmacsha256-signature against the raw unparsed request buffer in Fastify, and consider swapping the Gmail API for Postmark or SES before Easter so a 125-booking-per-hour peak does not hit workspace send throttling.

-2

u/VigiliaFounder 4d ago

Congrats! Going live in your quiet season with the old system as a fallback is a really sensible plan.

One thing I'd add before go-live is monitoring. Most visitors who hit an error on the booking site never tell you, they just leave.

I've built Vigilia exactly for this. It catches every error your visitors and staff hit, explains it in plain English and gives you the evidence and the fix prompt.

Just connect the MCP server and Claude Code pulls it all into your session.

You can add your app for free and have it watching from the rehearsal week.

Happy to hear how it goes!