Files
parking_solution/wiki/sources/parksql2017-legacy-schema.md
T
julian 58d8f06ba0 docs(wiki): tariff research — legacy ParkSQL2017 schema, time-tiers & validation/sponsorship design
Ingest the predecessor SQL Server schema (raw + source summary) and file design
pages for time-of-day/seasonal tariff tiers and merchant validation/postpaid
sponsorship. Cross-link tariff.md and validation-discounts.md. No code.
2026-06-18 10:59:21 +02:00

5.5 KiB
Raw Blame History

type, tags, sources, updated
type tags sources updated
source
parking
legacy
pricing
schema
fiscalization
parksql2017-legacy-schema
2026-06-17

ParkSQL2017 — Legacy Parking System Schema (source summary)

A SQL Server 2017 schema dump (raw/parksql2017-legacy-schema.sql, scripted 2024-10-07) of an existing/predecessor parking system in the same Albanian market this project targets. It is the single most concrete reference we have for how the prior generation modelled tariffs, discounts, memberships, sessions, shifts, and fiscalization — a real, deployed data model rather than vendor marketing. Treat it as evidence of what worked and what to improve, not as a spec to copy (it has clear anti-patterns, e.g. money as float).

Albanian-context tells: BA_TicketFisc.nivf (NIVF fiscalization code), the Cupons spelling, LostPrice1..4 tiers. BA_ = business-app table prefix; SYS_ = system/auth tables.

Table map (24 tables)

Pricing / tariff

  • BA_TicketPrice — the rate-card header. Key fields: Code, Name, TicketCategoryID, ParkID, ValidFrom/ValidTo (date window), ValidFromHour/ValidToHour (time-of-day window), FixedPrice (flat option), IntervalType (2-char unit, e.g. MI/HR/DY), Interval (increment size), LostPenalty, IsDefault, IsActive. → A rate card is scoped by (category × date-range × hour-range). This is the happy-hour / time-of-day mechanism.
  • BA_TicketPriceHours — the stepped ladder (child of TicketPrice): rows of HourFrom, HourTo, Price. → equivalent to this project's tariff blocks[].
  • BA_TicketCategory — vehicle/customer category (Code, Name, IsDefault, IntervalChange). → a pricing axis by category the current model lacks.
  • BA_TicketFisc — TicketID → nivf (Albanian fiscalization code per ticket).

Discounts / validation

  • BA_Cupons — CODE, DiscMinutes (discount as free minutes), IsUsed, LastUsed, IsPrinted. → validation = a single-use coupon code worth N free minutes; reconciled by counting used codes (prepaid model, no merchant account/ledger).

Sessions

  • BA_ParkRecords — the transient parking session (ticket cars). Carries lifecycle (InTime/OutTime/ExitTime, In/Out Mode/Addr/OperatorID, In/Out ShiftID), money (OrgCharge, Charge, Discount, FreeMin, IsPaid), discount detail (DiscMinutes, DiscType smallint, DisTicketSerial), entry/exit plate+image columns, and ManualOpenReason / ExpiredTime/DateApproval audit fields.
  • BA_MembersCheckINOUT — per-event check-in/out log for members (cards), separate from ticket sessions.
  • BA_ManualCheckINOUT — every manual barrier open, with Reason + OperatorID + image.

Memberships (≈ this project's permits)

  • BA_Members — the member (card+plate identity, contact, isVIP).
  • BA_Memberships — an issued subscription: PlanID, StartDate/EndDate, Price, CalculatedPrice, Paid, AllowedDays.
  • BA_MembershipPlans — plan template: Type, Duration, Price, ActiveDays.
  • BA_MembershipPlansTime — StartTime/EndTime windows per plan → memberships valid only in specific hours (commuter/day-shift permits).

Site / ops / auth

  • BA_Park — a lot: capacity (ParkingPlaces/FreePlaces), LED sign addr, default ticket/lost category codes, FreeMinutes, DiscMinutesTicket, DiscMinutesApp, LostPrice1..4.
  • BA_Shifts — cashier shift / Z-report: open/close, Charged, TicketCharges, CardCharges, entry/exit + manual counts, Reconciled, UserID, MachineID.
  • BA_CashRegister, SYS_Configs (company/fiscal/ticket header+footer, AllowTimeExeed, ImageDays), SYS_User/SYS_Role/SYS_Rights/SYS_UserRights, SYS_Controls, SYS_Language (DB-driven i18n).

What it confirms for our design

  1. Stepped ladder — BA_TicketPriceHours (HourFrom/HourTo/Price) ≈ our blocks[]. Good signal.
  2. Per-rate lost penalty + site-level lost tiers (LostPrice1..4) ≈ our lostTicketMinor (+ the admin-override idea).
  3. Typed discount on the session record (DiscType) ≈ the research's "typed validation modifier."
  4. Manual-open + reason logging at the schema level ≈ our threat-model audit need.

What it adds (genuinely new vs. our current model)

  1. Time-of-day + date windows on the rate card (ValidFromHour/ValidToHour, ValidFrom/ValidTo) — the shipped way to do happy hour / seasonal. See tariff-time-tiers.
  2. Vehicle/customer category as a pricing axis (BA_TicketCategory). See tariff-time-tiers.
  3. Time-/day-restricted memberships (MembershipPlansTime, ActiveDays) — a permit gap.

Anti-patterns to NOT copy

  • Money as float everywhere (Charge, Price, LostPenalty) — drifts across a revenue ledger. Our integer-minor-units rule is the deliberate fix. (rejected alternative)
  • Mutable rate rows (Updated/UpdatedBy in place) — a past session can't reliably reprice against the rate then in force. Our immutable effective-dated tariff versions fix this.
  • No merchant/sponsor account or postpaid ledger — only prepaid printed coupons. The B2B postpaid case is net-new; see validation-sponsorship.
  • Images stored as image BLOBs in-row — we keep snapshot bytes out of the event row and store a reference instead (append-only-event-chain).