Business Data Dictionary
What every Symfony entity means to the business, how the records connect, and which states must stay consistent.
The database is the shared memory of the platform. It must answer who used which boat, when, under which company/account, what happened during the trip, what was charged, and what communication or follow-up occurred.
How the main records connect
erDiagram
CUSTOMER ||--o{ BOOKING : makes
CUSTOMER ||--o{ BOOKING_REQUEST : asks_for
BOAT ||--o{ BOOKING : is_assigned_to
BOAT_MODEL ||--o{ BOAT : describes
LOCATION ||--o{ BOAT : holds
REGION ||--o{ LOCATION : contains
BOOKING ||--o{ BOOKING_HISTORY : records_changes
BOAT ||--o{ BOAT_ISSUE : has
BOOKING ||--o{ BOAT_ISSUE : may_report
CUSTOMER ||--o{ INVOICE : receives
COMPANY ||--o{ VAT : configuresThis diagram shows business relationships. Many links are saved as IDs inside JSON rather than enforced database foreign keys, so application rules are still responsible for keeping them valid.
Identity, access, and organization
| Entity (table) | What it represents and why it exists |
|---|---|
Account (accounts) | One tenant/domain using the platform. It separates configuration and data ownership. |
Company (comps) | A legal or operating company. It chooses financial and tax context for work performed under that company. |
User (users) | A staff account with role and region/location scope. |
ServiceUser (services) | A restricted account for service work rather than general administration. |
Customer (customers) | A member account: identity, sign-in, company/region access, preferences, balances, Stripe IDs, and membership-related data. |
TemporaryLink (temporary_links) | A time-limited recovery/verification link so a password can change without exposing the old password. |
ExternalIntegration (external_integrations) | An approved external caller and its account-scoped authentication information. |
Fleet, places, and service content
| Entity (table) | What it represents and why it exists |
|---|---|
Boat (resources) | One physical boat and the information needed to identify, locate, book, monitor, and service it. |
BoatModel (resource_types) | Reusable model/type information shared by similar boats. |
ResourceCategory (resource_categories) | A broad category for bookable resources; current boat records use the boat category. |
Region (regions) | A geographic operating area with currency and regional settings. |
Location (locations) | A marina or collection place used by boats, bookings, maps, and member instructions. |
Facility (facilities) | A facility or item that can be shown or recorded around a place or trip. |
ChecklistItem (checklist_items) | A reusable inspection/safety step used in check-in, check-out, or service data. |
ExtraService (extra_services) | An optional service that can be offered with a booking. |
Phone (phones) | A support or operational contact shown to approved clients. |
Video (videos) | Tutorial or boat-related video information. |
File (files) | An uploaded photo, document, receipt, or other media item linked from business records. |
Booking and trip history
| Entity (table) | What it represents and why it exists |
|---|---|
Booking (bookings) | A confirmed or blocked period for a boat, including member, place, dates, state, price-related data, and trip handover answers. |
BookingRequest (booking_requests) | Member demand that still needs a boat or staff decision. It must stay separate from a confirmed promise. |
BookingHistory (booking_history) | Who changed a booking, when, and what changed, so later support and audits can reconstruct the story. |
ServiceCheckin (service_checkin) | A time-bounded inspection or service visit for a boat. |
Frog (frogs) | A reusable category for a kind of boat issue. |
BoatIssue (resource_issues) | One real issue reported for a boat, including source, text, evidence, approval/rejection, and fixed information. |
MemberRating (member_rating) | Aggregated/detail rating information used to understand member/trip experience. |
Prices and payments
| Entity (table) | What it represents and why it exists |
|---|---|
Price (price_category) | A configured pricing record used when a booking or category needs a price. |
Vat (vats) | Company/region tax configuration, including default, fuel, and other rates and their Stripe IDs. |
Invoice (invoices) | A local financial record for booking, fuel, or other invoice work, preserving amount, currency, tax, provider reference, and processing times. |
Subscriptions are currently kept as part of member/payment data and Stripe metadata rather than as a separate Symfony entity file.
Messages and delivery history
| Entity (table) | What it represents and why it exists |
|---|---|
Notification (notifications) | Reusable notification text/configuration for supported events. |
NotificationLogs (notification_logs) | Evidence that a notification action was recorded for a recipient/event. |
Newsletter (newsletters) | A staff-created broadcast and its pending/in-progress/complete processing state. |
SuccessSms (successsms) | SMS provider work recorded as successful. |
FailedSms (failedsms) | SMS work that needs investigation or retry. |
PushToken (push_tokens) | A device address linked to a member for push delivery. |
PushLog / PushReport (push_logs) | The sent push audience, message, provider errors, and success/failure counts. Both entity views map to the same table. |
Client compatibility
| Entity (table) | What it represents and why it exists |
|---|---|
AppVersions (app_versions) | Current and required iOS/Android version thresholds returned to clients. |
BaseEntity is the common storage shape used by many of the records above. It
is not a business record or a separate table.
Important states
Booking
| State | Meaning |
|---|---|
payment_pending | A booking flow exists but payment is not yet confirmed. |
booked | The boat and time are confirmed. |
blocked | The period is intentionally unavailable rather than assigned to a normal member trip. |
checked in | The trip has started and custody was handed to the member. |
checked out | The trip ended and return information was recorded. |
cancelled | The booking will not take place or was ended through cancellation. |
expired | The booking is no longer current because its allowed time passed. |
Booked, blocked, checked-in, and payment-pending records take part in overlap protection. Reports and member views can intentionally use different subsets.
Booking request
Requests can be pending, reserved, solved, unsolved, rejected, or
cancelled. Pending and reserved requests are considered active. Solving creates
or confirms the operational outcome; it is not merely another name for reserved.
Invoice and subscription
Local invoice state is not_paid, paid, or canceled. Subscription state is
unpaid, paid, or canceled. These local values must be reconciled with the
correct company's Stripe object.
Flexible JSON storage
Many entities have:
id— stable local identity;account_id— tenant ownership;data— feature-specific values;meta— state and change information such as active/created details.
This made it possible for old and new services to share records. The trade-off is that field names and nested shapes must be changed carefully. Before changing a JSON field, search both repositories, existing data migrations, API responses, reports, and tests.
Never repair a business inconsistency by directly deleting or rewriting JSON in production without an approved migration or recovery procedure.