Waitlist Party Size Bug: Max Limit Not Enforced
Hey guys! đź‘‹ Let's dive into a frustrating little bug I found while working on the waitlist feature. It turns out, when you're adding a guest, the app isn't properly enforcing the waitlist's specific maximum party size. Instead, it's using a global hard cap. This means the waitlist's custom settings are being ignored, which is, well, not ideal. We're going to break down the issue, where the problem lies, and how we can fix it. So, buckle up!
Summary of the Issue: Party Size Problems
The core issue is simple: when adding a guest to a waitlist, the application isn't respecting the waitlist-specific "max party size" setting. Think of it like this: You set a limit for how many people can join a waitlist, but the app isn't paying attention to that limit. It's using a global setting that's, frankly, too generous. The waitlist-level max party size isn’t even being pulled from the database, so it's effectively always null within the app’s state. This causes some real problems with functionality. In addition, the current implementation has multiple code issues to be improved. So, we're going to see how the software works and try to improve it.
Observed Behavior: What's Actually Happening?
Here’s what you might see when this bug is in play. The app allows you to:
- Increase a guest’s party size up to the global limit (currently set to 20), regardless of the waitlist’s configured max. It's as if the custom settings are there, but the app is not using them.
- Any “max party size” entered when creating a waitlist is not reflected later. It is dropped before persistence and is not present in the database schema. Therefore, the custom settings you have made are not being used.
Expected Behavior: What Should Be Happening?
If the waitlist has a "maxPartySize" set to a specific number (like 5, 10, etc.), the following should happen:
- When adding a guest, the app should prevent adding one with a party size exceeding that number. It must show a clear error or prevent the addition entirely. This protects the integrity of the waitlist. Imagine a scenario where a waitlist has a maximum party size of 4, but someone tries to add a group of 6. The app should block that.
- The waitlist’s maxPartySize setting should be correctly stored, retrieved from the database, and reflected throughout the app's user interface. This is crucial for making the feature usable. Imagine setting the max party size and the setting disappears! That won’t work.
Root-Cause Findings: Code and Database Deep Dive
Let's get our hands dirty and figure out why this is happening. The problem comes down to several issues in the code and database configuration. Let’s dive in!
1) Add-Guest Form: Global Max, No Waitlist Check
The add-guest form does have a maxPartySize setting, but it's hardcoded to use a global limit (the BusinessRules.MAX_PARTY_SIZE). This means the form is always using the global value, which defeats the purpose of the waitlist-specific setting. So, you can change the party size, but only up to the global limit.
- Code Location:
composeApp/src/commonMain/kotlin/dev/endian/shokken/presentation/screen/home/components/AddGuestForm.kt:120andcomposeApp/src/commonMain/kotlin/dev/endian/shokken/presentation/screen/home/components/AddGuestForm.kt:303 - The party size increment/decrement buttons could enforce the per-waitlist setting, but they're not currently wired up to do so. They use
coerceAtMost(maxPartySize)andcoerceAtLeast(minPartySize), butmaxPartySizeis not taking the waitlist setting into consideration. This is a missed opportunity!
2) Add-Guest Flow: Ignoring Waitlist Max
Even if the add-guest form knew the waitlist's max party size, the HomeScreenModel.addGuest() function in the view model doesn't check it. It simply passes the party size straight to the use cases. This is a critical omission. This is where the actual logic for adding guests is handled. The current code is at:
- Code Location:
composeApp/src/commonMain/kotlin/dev/endian/shokken/presentation/viewmodel/home/HomeScreenModel.kt:1447
3) Waitlist Max Party Size in Domain, But Not in Persistence
The domain entity (Waitlist) does have a maxPartySize: Int? field, which is good. The problem is that it’s never being populated from the database. It is not loaded when a waitlist is read from the database, and it is not saved when a new waitlist is created.
- The
WaitlistDto(Data Transfer Object) is missing amax_party_sizefield, which means the data isn’t being properly mapped and saved to the database. - The mapper, which converts data between the domain and data layers, explicitly sets
maxPartySize = null. This means no matter what the user sets, it will always benull.
4) Supabase Schema: Missing Max Party Size and No Upper Bound
Let’s look at the database schema. This is where we see some serious issues.
- The
public.waitliststable in Supabase is missing amax_party_sizecolumn, so there's no way to store the waitlist's maximum party size. It simply does not exist. - The
public.guests.party_sizecolumn only has aCHECK (party_size > 0)constraint, meaning it only checks that the party size is positive and does not have an upper bound. This is a problem because we need to restrict the party size to themax_party_sizevalue.
5) Inconsistent Max Party Size Constants
There’s no single source of truth for the maximum party size. The limits are different across layers, which makes it easier for errors to creep in and makes maintenance a nightmare.
- The UI/business rules (
BusinessRules.MAX_PARTY_SIZE = 20) - The domain (
Guestentity allows up to 50) - The database has no max at all (besides > 0)
Suggested Solution and Directions
So, how do we fix this, guys? Here's a suggested direction to tackle the issue, aiming for the most effective and least disruptive solution:
- Add
max_party_sizetopublic.waitlists: This is the most crucial step. Add themax_party_sizecolumn to thepublic.waitliststable in the database schema. Then, ensure that the field is included in theWaitlistDtoand the mapping. This creates a place to store the setting. - Integrate
maxPartySizeinto the Add-Guest Form: Ensure that the add-guest form controller and validation take the selected waitlist’smaxPartySizeinto account. The UI should display the waitlist’s maximum party size and prevent the user from entering a party size that exceeds that limit. Think UI/UX first! - Enforce
guest.party_size <= waitlist.max_party_sizeat the Database Level: The database should always be the final source of truth. Implement a check or constraint at the database level to ensure that the party size of a guest never exceeds the waitlist’s maximum party size. This can be done via a trigger or a check constraint. - Align Max Party Size Limits: Establish a single source of truth for the maximum party size across the UI, domain, and database. This will help to prevent inconsistencies.
Verification and Testing
- Local Test: The local tests should pass after these changes. However, there are no existing tests to cover waitlist-specific max party size enforcement. So, we'll need to write some new tests to make sure this is working correctly. This is important to ensure the changes are working as expected and do not break any existing functionality.
By following these steps, we can ensure that the waitlist's maximum party size is properly enforced, creating a better user experience and preventing any issues that could come from exceeding the limit. This will require updates to the database schema, data transfer objects, the waitlist mapper, and the add guest form. By adding more test coverage, we will make sure the changes don’t create any issues with existing functionality.
And that's it, folks! Now, let's get to work and fix this bug! đź’Ş