A VB.NET WinForms desktop app for a fictional cinema ("Palace Kino Cinema"): staff log in or register an account, browse what's currently showing, pick a showtime and ticket types, choose seats on a 64-seat hall map (A1–H8), and confirm payment. Built as the CSC301 Visual Basic course project (UiTM, 2022) on .NET Framework 4.7.2. The forms carry a cosmetic dark-cinema restyle (near-black surfaces, gold/red accents, Segoe UI, flat buttons), and the originally documented functional gaps have since been fixed (working payment confirmation + receipt, real data handoff between forms, seat deselect with a quantity cap, register validation, password masking, friendly first run, clean process exit — see Functional fixes below).
New developer? Start with
.docs/tldr.md— every doc summarised on one page. The full guide lives in.docs/.
Captured from a live run (just run, demo account registered in-app):
Login![]() |
Register![]() |
Start Up![]() |
Movie Information![]() |
Booking![]() |
Payment![]() |
Seat — the 64-label hall map (A1–H8); click a seat to select it (red), click again to deselect (here D4, D5, E4, E5; selection is capped at the booking quantity):
Receipt — after CONFIRM PAYMENT, the RECEIPT button prints the full booking:
Screen by screen:
| Screen | What happens there |
|---|---|
| Login (entry form) | Reads UsernameAndPassword.txt line-pairs and matches the typed username/password (masked input); success opens Start Up. First run: friendly "no accounts yet" message and the file is created |
| Register | Validates all fields are filled and the username is not already taken, then appends the pair to UsernameAndPassword.txt and returns to Login |
| Start Up | Hub menu — More Information, Book, or Exit (exits the whole app cleanly) |
| Movie Information | Static movie fact sheet: title, director, cast, genre, subtitle, synopsis, rating, length |
| Booking | Showtime picker: date, time, ticket types (Adult RM20 / Children RM15 / Disabled RM10 / Senior), quantity — all handed to the shared BookingContext on NEXT |
| Seat | 64-label seat map (rows A–H, seats 1–8); click to select (red) / click again to deselect; selection capped at the booking quantity; Confirm carries the seats to Payment |
| Payment | Live booking summary (movie, date, time, type, seats, quantity, RM total) + payment-method radio group; CONFIRM PAYMENT validates a method and confirms; RECEIPT shows the full receipt |
Every transition is a Form.Show() + Me.Hide() pair — one process, eight forms — with the
booking flowing through a shared BookingContext module.
| Tool | Version | Installed by |
|---|---|---|
| PowerShell + winget | Windows 10/11 stock | — (the only true prerequisites) |
| MSBuild | Framework MSBuild (ships with Windows); VS Build Tools 2022 preferred if present | — (detected by setup.ps1, never auto-installed) |
| .NET Framework 4.7.2 runtime | in Windows 10/11 stock | — |
| Node.js | LTS (only for the Claude CLI) | setup.ps1 |
| uv + Python | latest (only for .claude tooling) |
setup.ps1 |
| just | any recent | setup.ps1 |
| Claude Code CLI | latest | setup.ps1 (optional, for AI-assisted dev) |
# 1. One-time machine setup (idempotent — safe to re-run)
pwsh ./setup.ps1
# 2. Close and reopen PowerShell so PATH updates land
# 3. Build and launch the app (the Login window opens)
just runThe app is a GUI — just run builds the solution and launches the exe; close the window or
run just stop. First launch has no accounts: click Register first (clicking LOGIN
without any accounts shows a friendly "no accounts yet" message and creates the store).
Run just with no arguments to list every recipe. The ones you'll use daily:
| Command | What it does |
|---|---|
just build |
Build the solution (Debug) with MSBuild |
just run |
Build, then launch the WinForms app |
just stop |
Kill only THIS repo's app processes (matched by exe path) |
just clean |
Delete MSBuild output (bin\, obj\) |
just test |
Run the test suite — smoke checks + BookingContext unit tests (tests/smoke.ps1) |
just claudex |
Launch Claude Code (Sonnet, all permissions) |
just test runs tests/smoke.ps1 — 48 checks, exit 0 only on a full
pass. Sections 1–4 are smoke/regression checks over the built app; section 5 is a real
headless unit suite over the one piece of logic that is testable without a GUI.
- Build gate —
just buildmust exit 0 and produce the exe. - Launch/lifecycle — the exe is launched (working dir pinned to
bin\Debug, same asjust run); within 10 s it must expose a main window handle titled Login; it must still be alive 3 s after launch (no startup crash); it is then closed viaCloseMainWindow()(WM_CLOSE, withKill()as fallback) and zero processes may be left running from this repo's exe path. - Warning-baseline gate — a rebuild capturing MSBuild output must introduce no warning codes beyond the documented three-warning baseline (the uncoded ToolsVersion 15.0→4.0 notice, MSB3644, MSB3270 — see Troubleshooting). A warning-free Build Tools 2022 build passes trivially.
- Regression gates — that the functional fixes stay in place. Two of these read the
built assembly by reflection rather than grepping source: each password box is
instantiated and its real
UseSystemPasswordCharproperty asserted, and every navigational form must carry a*_FormClosedhandler that survived into IL. A tightened source check then requires all six navigational forms to guard the call (If e.CloseReason <> CloseReason.ApplicationExitCall Then Application.Exit()), not merely mentionApplication.Exitsomewhere. - BookingContext value assertions —
tests/bookingcontext.tests.ps1, dot-sourced so its results fold into the same summary.BookingContext.vbis a plainPublic Modulewith no WinForms dependency, sovbc.execompiles it standalone into a throwaway DLL (using the same switches the.vbprojuses) which PowerShell then drives directly. That standalone compile is itself the assertion that the module stays WinForms-free. The 34 checks pinTicketCount(typed quantity, and the fallback toSelectedSeats.Countwhen it is 0),TotalPrice(=TicketCount× RM20, on both paths),SeatList()(join order, deselection, the"-"empty case), and a full Booking → Seat → Payment round-trip: the fieldsBooking.btnNext_Clickwrites and the seatsSeat.ToggleSeatadds, asserted as the exact stringsPayment.RefreshSummaryrenders ("A5, A6","2","RM40") plus the receipt gate. Run it alone withpowershell -NoProfile -File tests\bookingcontext.tests.ps1.
What is still not covered, and why. Everything except BookingContext is WinForms
code-behind: Seat.ToggleSeat's quantity cap and colour toggle, Login/Register
validation, and the MessageBox receipt text only run in response to real clicks. Asserting
those would need a UI-automation driver (WinAppDriver / FlaUI) that this repo does not
carry, or an MVP-style extraction far larger than the targeted fixes here. Rather than ship
hollow tests that pretend otherwise, the suite asserts what can be asserted honestly — and
where a check is necessarily static (the CloseReason guard, the .vbproj wiring) it is
labelled as such in tests/smoke.ps1.
The coursework originally shipped with a set of documented functional gaps. They have all
been fixed (the history of what each gap was lives in
.docs/01-overview/architecture.md):
| Was | Now | Where |
|---|---|---|
CONFIRM PAYMENT and RECEIPT buttons had no Click handlers (dead UI) |
Confirm validates a payment method and shows the booking-summary confirmation; Receipt shows the full receipt (customer + booking + seats + total) | Payment.vb |
| No data flowed between forms | BookingContext shared module carries customer, date/time, ticket type, quantity, and seats from Booking → Seat → Payment |
BookingContext.vb |
| Seats could not be deselected and nothing was passed on | Click toggles select/deselect; selection is capped at the booking quantity (gentle warning); selected seats reach Payment | Seat.vb (+ on-screen hint) |
| Register appended blindly — duplicates and empty fields accepted | All fields required; duplicate usernames rejected (file is read before append) | Register.vb |
| Passwords visible as typed | UseSystemPasswordChar masking on both password boxes |
Login.Designer.vb, Register.Designer.vb |
| First-run login crashed into "Error : Reading UnSuccessful !" | Missing credentials file is created and a friendly "no accounts yet — Register first" message shown; typed exception handling | Login.vb |
| Closing Start Up (or any later form) left a windowless zombie process | Application.Exit wired on Exit button and on real form closes across the flow |
StartUp.vb + all non-main forms |
Remaining known limitations (documented, deliberate scope):
| Limitation | Where |
|---|---|
| Passwords stored in plaintext line pairs in a flat text file (no hashing) | UsernameAndPassword.txt (git-ignored) |
The movie title is a fixed house value (Palace Kino Feature) — the Booking form never captured one; totals use the RM20 adult rate × quantity (no per-category counts) |
BookingContext.vb |
frmIndex is an empty leftover form that still compiles |
frmIndex.vb |
The credential store path is relative to the process working directory (the justfile pins it to bin\Debug) |
Login.vb, Register.vb |
Expected with the Framework MSBuild that ships with Windows — all three are benign and the
exe works. Installing VS Build Tools 2022 (manual, elevated) makes them disappear; the
justfile auto-prefers it once present. See
.docs/06-troubleshooting/common-issues.md.
There are no committed credentials. Click Register to create an account first, then log
in with it. (UsernameAndPassword.txt lives next to the exe and is git-ignored; clicking
LOGIN on a fresh machine creates it empty and points you at Register.)
Run pwsh ./setup.ps1 — it verifies at least the Framework MSBuild exists at
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe (present on every stock
Windows 10/11).
Check the build output above the Start-Process line — if MSBuild failed, run stops at the
build step. Also confirm nothing killed it: Get-Process | Where-Object { $_.Path -like "*cinema-ticket-booking*" }.
More in .docs/06-troubleshooting/common-issues.md.
cinema-ticket-booking/
Cinema Ticketing Booking System.sln # VS solution (open in Visual Studio if you have it)
Cinema Ticketing Booking System/ # the single VB.NET WinForms project
Login.vb / Register.vb # flat-file auth (validated; passwords masked)
BookingContext.vb # shared booking state (Booking -> Seat -> Payment)
StartUp.vb # hub menu (Exit ends the process cleanly)
MovieInformation.vb # static movie fact sheet
Booking.vb # showtime + ticket-type form (fills BookingContext)
Seat.vb # 64-label seat map (toggle select, quantity cap)
Payment.vb # summary + confirm payment + receipt
frmIndex.vb # empty leftover form
*.Designer.vb / *.resx # designer-generated UI per form
My Project/ # AssemblyInfo, app startup config (MainForm=Login)
App.config # targets .NET Framework 4.7.2
bin/, obj/ # build output (git-ignored)
docs/images/ # README screenshots (captured from a live run)
tests/smoke.ps1 # build + launch/lifecycle + regression gates (`just test`)
tests/bookingcontext.tests.ps1 # headless BookingContext unit suite (dot-sourced by smoke.ps1)
justfile # day-2 commands (`just` to list)
setup.ps1 # one-time machine bootstrap
.docs/ # numbered documentation set — start at .docs/tldr.md
.claude/ # Claude Code skills, hooks, settings







