Skip to content

User stories

Customer-facing language is English, therefore all user stories are maintained in English only. Every story maps to a use case in docs/02-use-cases.md (repository) (UC id in brackets). Status: ✅ = implemented in the MVP prototype · 🔜 = planned (see Roadmap). Format: As a <actor>, I want <capability>, so that <benefit> + acceptance criteria for key stories.

#StoryUCStatus
US-A1As a platform operator, I want to create a new agency tenant with plan, currency and timezone, so that a new customer can start working in an isolated workspace within minutes.A1🔜
US-A2As a platform operator, I want to change or cancel a tenant’s plan with pro-rata billing, so that upgrades and churn are handled without manual invoicing.A2🔜
US-A3As an agency admin, I want to connect my own domain to my public website, so that guests book on my brand, not on a generic platform URL.A3🔜
US-A4As a platform operator, I want per-plan feature flags and unit limits, so that pricing tiers are enforced automatically.A4🔜
US-A5As a platform operator, I want audited, time-limited impersonation of a tenant, so that I can reproduce support issues without permanent access.A5🔜
#StoryUCStatus
US-B1As an agency admin, I want to invite staff by e-mail with a role, so that new team members onboard themselves securely.B1🔜
US-B2As an agency admin, I want to change a member’s role and unit scope, so that responsibilities stay accurate as the team changes.B2🔜
US-B3As an agency admin, I want to create portal access for a landlord, so that owners see their own units without e-mailing us.B3✅ (seeded owner login)
US-B4As an agency admin, I want to enforce 2FA for admin roles, so that a stolen password alone cannot compromise the agency.B4🔜
US-B5As an agency admin, I want to deactivate a user instantly, so that leavers lose access the moment they leave.B5🔜

US-B7 · Hardened authentication (key story) — ✅

Section titled “US-B7 · Hardened authentication (key story) — ✅”

As the SaaS operator, I want every portal endpoint protected by verified JWTs with revocable sessions, so that no data can leak even if a token or a laptop goes astray.

  • Given any /v1 portal endpoint, then it accepts only a validly signed JWT (HS256, issuer/audience/expiry checked); tampered tokens are rejected with 401.
  • Given an expired access token and a valid refresh session, then a new JWT is minted transparently; given a logout, then the session is revoked server-side and refresh fails immediately (a stolen access token dies within ≤15 minutes).
  • Given both tokens live in httpOnly cookies, then JavaScript can never read them (XSS-safe); unknown origins receive no CORS allow header; login and public forms are rate-limited; security headers (HSTS, nosniff, frame-deny) are set on every response.
  • Given the dev seed, then landlord identities are anonymized at fetch time — real owner PII never reaches the repository or database.

As a staff member or landlord, I want to sign in with e-mail and password, so that I see exactly the data my role allows.

  • Given valid credentials, when I sign in, then I get a session and land on my dashboard.
  • Given an owner account, when I open any list or calendar, then only my own units are present.
  • Given invalid credentials, then I see a generic error (no user enumeration).
#StoryUCStatus
US-C1As a backoffice agent, I want to create a unit with structured master data (building, area, bedrooms, permit no., check-in/out times), so that listings are complete and DET-compliant.C1✅ (seeded; create-form 🔜)
US-C2As a backoffice agent, I want to manage a photo gallery with cover image, so that the website and portal look professional.C2✅ (view; upload 🔜)
US-C3As a backoffice agent, I want structured multilingual descriptions and amenity tags, so that guests get consistent information on every channel.C3✅ (EN)
US-C4As an agency admin, I want to link one or more owners with share % and commission %, so that statements calculate automatically later.C4✅ (view)
US-C5As an agency admin, I want to assign a cleaning team and a manager per unit, so that operational responsibility is always clear.C5🔜
US-C6As an agency admin, I want per-unit pricing (base rate, cleaning fee, deposit, min-stay, discounts), so that quotes need no manual math.C6✅
US-C7As an agency admin, I want a publish checklist, so that incomplete listings never reach the public website.C7🔜 (status toggle ✅)
US-C8As an agency admin, I want to archive a unit while keeping its history, so that ended contracts don’t pollute daily views but stay auditable.C8✅ (status)
US-C9As a manager, I want all units on a map with filters, so that I can plan field work geographically.C9🔜

US-C10 · Browse real units (key story) — ✅

Section titled “US-C10 · Browse real units (key story) — ✅”

As a backoffice agent, I want to browse all apartments as visual cards with photo, key facts and 30-day occupancy, so that I can find and open any unit in seconds.

  • Given the unit list, when I type in the search box, then cards filter by name/area/building instantly.
  • When I open a unit, then I see gallery, facts, amenities, owners with share & commission, pricing and occupancy.
  • Given the settings tab, when I change price or description and save, then the public website reflects it on next load.

Epic D — Calendar & Bookings (the heart)

Section titled “Epic D — Calendar & Bookings (the heart)”

US-D1 · Create a booking (key story) — ✅

Section titled “US-D1 · Create a booking (key story) — ✅”

As a backoffice agent, I want to click a free day in the calendar and create a booking with guest, source and price in one dialog, so that phone and channel bookings are captured in under a minute.

  • Given the timeline, when I click an empty day, then a dialog opens pre-filled with unit and date.
  • When I pick a source (Airbnb, Booking.com, Website, Direct, Partner), then the bar is colour-coded by source everywhere in the system.
  • Given no price override, then the quote engine calculates nights × rate − discounts + cleaning + Tourism Dirham + VAT automatically.
  • Given the nights are already taken, then I get a clear conflict error and nothing is saved (DB-level guard).

US-D2 · No double bookings ever (key story) — ✅

Section titled “US-D2 · No double bookings ever (key story) — ✅”

As an agency admin, I want the system to make overlapping bookings technically impossible, so that we never walk two guests into one apartment.

  • Given two parallel attempts for the same nights, then exactly one succeeds and the other receives a 409 conflict.
  • Given a cancellation, then the nights are released atomically.
#StoryUCStatus
US-D3As a backoffice agent, I want to see all units × days as a colour-coded timeline with today marker, weekend shading and occupancy %, so that the whole house state is one glance.D8✅
US-D4As a backoffice agent, I want to move or extend a booking, so that guest changes are two clicks, with the same conflict guard.D2/D3✅ (API) / drag 🔜
US-D5As a backoffice agent, I want to cancel with a reason, so that statistics separate real demand from cancellations.D4✅
US-D6As a manager, I want check-in / check-out actions on the booking, so that operational state is live for everyone.D5/D6✅
US-D7As a backoffice agent, I want blocks (maintenance, owner stay, generic), so that unavailable periods are explicit and typed.D7✅
US-D8As a backoffice agent, I want filters (area, source, search) on the calendar, so that large portfolios stay navigable.D8✅
US-D9As a backoffice agent, I want internal notes on bookings, so that shift colleagues see arrival times and special requests.D9✅
US-D10As a backoffice agent, I want an option/hold status with expiry, so that tentative requests can reserve nights without staying forever.D1✅ (expiry job 🔜)
US-D11As a backoffice agent, I want iCal import/export per unit, so that Airbnb and Booking.com calendars stay in sync automatically.P-05🔜
US-D14As an agency admin, I want to configure Airbnb / Booking.com connections per agency so external reservations appear in the calendar automatically. v1 ships the visual preview: connection cards with toggle, account reference, last-sync and an import log; auto-imported bookings carry a ⚡ badge in the calendar.D13✅ (visual preview) / 🔜 (real sync)

US-D15 · Audit-compliant cancellation (key story) — ✅

Section titled “US-D15 · Audit-compliant cancellation (key story) — ✅”

As an agency admin, I want cancellations to stay in the system forever with a structured category, so that “guest reserved but never paid” is provable years later — to auditors and to landlords.

  • Given a cancellation, then the record keeps status, timestamp, acting user, a category (guest cancelled / no payment / channel cancelled / force majeure / agency decision / other) and a free-text reason; only the nights are released.
  • Given a landlord opens their portal, then they see every cancellation on their units — period, source, category, reason and the lost revenue share — without any guest personal data (“why is my anticipated revenue gone?” answers itself).
  • Given the cancel dialog, then the category is mandatory and the audit note is shown before confirming.

US-D12 · Role-scoped calendar (key story) — ✅

Section titled “US-D12 · Role-scoped calendar (key story) — ✅”

As an agency admin, I want every role to see a different calendar cut, so that data protection and focus are guaranteed by design.

  • Given an admin/backoffice login, then all units and full guest details are visible.
  • Given a landlord login, then only owned units appear and guest names are replaced by “Guest” while period, source and amount remain visible.
  • Given a cleaner login (planned), then only task-relevant units around check-out/check-in appear.

Actors: backoffice, admin, manager (assigned) · indirectly landlords (revenue follows the unit!) and housekeeping (turnover changes). Cross-references: overlap guard (US-D2), owner statements (Epic J/P-04 — revenue moves with the unit), housekeeping notifications (Epic T), extension flow (US-N3).

US-N1 · Relocation assistant (key story) — ✅

Section titled “US-N1 · Relocation assistant (key story) — ✅”

As a backoffice agent, I want a ranked list of units a booking can be transferred to, so that a relocation (guest extends, maintenance issue, overbooking) takes seconds and hurts nobody.

  • Given a booking, when I open Transfer unit, then I see all units free for the whole period, ranked by ① same landlord first (the owner keeps the revenue — with ~150 units across ~40 landlords owning 1–40 units each, this is the difference between a happy and an angry owner), ② same area (Marina, Creek Harbour, Business Bay, Downtown …), ③ matching category & capacity, ④ smallest nightly-price difference.
  • Then each candidate shows badges (Same landlord, Same area), the nightly price difference and capacity — and unsuitable units (too small for the pax) are excluded.
  • When I pick a target, then the booking moves atomically (nights re-guarded); on a race conflict I get a clean 409 and the list refreshes.

Conflicts & edge cases: price difference is displayed but never auto-charged — the agent decides (and documents) any price adjustment; transferring between owners moves future statement revenue (flagged in the dialog); same-day turnovers on the target unit are the agent’s call; owner-created blocks are never displaced.

US-N2 · Same-landlord preference (key story) — ✅

Section titled “US-N2 · Same-landlord preference (key story) — ✅”

As a landlord with several units, I want relocations to prefer my own units, so that a guest moving out of one of my apartments doesn’t move my income to another owner.

  • Given the guest’s unit belongs to owner O and O has another free, fitting unit, then that unit ranks above all other candidates.
  • Given no same-owner unit fits, then same-area units follow — the guest stays in their neighbourhood.

As a backoffice agent, I want to change a booking’s dates in place, so that “can we stay three more nights?” is one edit.

  • Given new dates that are free, then the booking updates atomically and the price note reminds me to adjust the total if needed.
  • Given the extension collides, then I get the conflict and a one-click jump into the relocation assistant (US-N1).
  • Then housekeeping is informed automatically (US-T3): extension → “turnover on {old date} cancelled”, shortening → “turnover moved up to {new date}”.
#StoryUCStatus
US-E1As an agency admin, I want base rates and fees per unit, so that every quote starts from correct numbers.E1✅
US-E2As an agency admin, I want named seasons with multipliers, so that winter high season prices itself.E2🔜
US-E3As an agency admin, I want to drag-select days in a price-calendar mode and bulk-set price/min-stay/closed, so that event pricing (NYE, GITEX) takes seconds.E3🔜
US-E4As an agency admin, I want weekly/monthly discounts, so that long stays are competitive without manual quoting.E4✅
US-E5As a backoffice agent, I want a quote preview for any unit and period, so that phone enquiries get instant, correct totals.E5✅ (booking dialog auto-price)

US-F1 · Search & discover (key story) — ✅

Section titled “US-F1 · Search & discover (key story) — ✅”

As a guest, I want to search stays by dates, guests and style and browse rich listing pages, so that I can choose with confidence.

  • Given dates in the search, then only actually available units are listed (live availability).
  • Given a listing page, then I see gallery, amenities, neighbourhood, house rules, DET permit number and a 3-month availability calendar.
  • Given any page, then it renders server-side with correct meta tags (SEO).

US-F2 · Request to book (key story) — ✅

Section titled “US-F2 · Request to book (key story) — ✅”

As a guest, I want to select dates, see the full price breakdown (incl. cleaning, Tourism Dirham, VAT) and send a booking request, so that there are no surprises at payment.

  • Given selected dates, then the quote box shows every line item and the total.
  • Given unavailable dates, then the button is disabled with a clear message.
  • When I submit the form, then the agency sees my request in their inbox and I get a confirmation screen.
#StoryUCStatus
US-F3As a guest, I want instant booking on marked units, so that I can secure a stay immediately.F4🔜 (request flow ✅, badge ✅)
US-F4As a backoffice agent, I want a website-request inbox with one-click convert/reject, so that requests become bookings without retyping.F4✅
US-F5As a guest, I want the site in EN/DE/RU/AR with RTL support, so that I can book in my language.F5🔜 (EN ✅)
US-F6As an agency marketer, I want sitemaps, structured data and fast Core Web Vitals, so that listings rank on Google.F6✅ (basics) / 🔜 (sitemap)
#StoryUCStatus
US-G1As a cleaner, I want a mobile daily list sorted by priority (same-day turnovers first), so that I always know where to go next.G1🔜
US-G2As a cleaner, I want to progress a task (start → done) with required photos, so that quality is documented.G2🔜
US-G3As a cleaner, I want to report damage with a photo, so that maintenance starts before the next guest arrives.G3🔜
US-G4As a team lead, I want a suggested day route across my units (checkout ≥ 11:00, same-day deadline 15:00), so that we drive less and clean more.G4🔜
US-G5As a backoffice agent, I want mid-stay cleanings for long stays, so that monthly guests get weekly service automatically.G5🔜
US-G6As a manager, I want an inspection step before check-in, so that same-day turnovers are verified guest-ready.G6🔜
#StoryUCStatus
US-H1As a cleaner, I want to capture a found item with photo and unit, so that nothing gets lost in a WhatsApp thread.H1🔜
US-H2As a backoffice agent, I want automatic matching to the last checkout, so that the likely owner is one click away.H1/H2🔜
US-H3As a backoffice agent, I want storage location and status tracking through return/disposal, so that we can always answer “where is it now?”.H2–H4🔜

US-I1 · Owner transparency (key story) — ✅ (portal basics)

Section titled “US-I1 · Owner transparency (key story) — ✅ (portal basics)”

As a landlord, I want to log in and see my units, their occupancy and every booking period with source and my revenue, so that I trust the agency and stay out of their inbox.

  • Given my login, then I see only my 3 units — with the same live data the agency sees, minus guest personal data.
  • Given the calendar, then each bar shows period, source colour and amount, labelled “Guest”.
  • Given the dashboard, then I see 30-day occupancy and today’s arrivals/departures for my units.

US-I6 · Revenue by payment state (key story) — ✅

Section titled “US-I6 · Revenue by payment state (key story) — ✅”

As a landlord, I want my revenue per period split by payment state, so that I always know where my money actually is.

  • Given my dashboard, then I see three totals and a stacked monthly chart: Booked (reservation exists, no money flowed yet — gold), Received (guest money at the agency, my transfer pending — blue), Paid out (transferred to my account — emerald).
  • Given a partially paid booking, then the amounts split correctly across the states (paid portion counts as received, the open remainder as booked).
  • Given a cancellation, then the lost share appears separately (US-D15), never silently.
  • Given the agency records a payout on a booking (one click in the finance panel), then my chart moves the amount from received to paid out.
#StoryUCStatus
US-I2As a landlord, I want monthly statements as PDF with per-booking detail, so that my accounting is effortless.I3, J4🔜
US-I3As a landlord, I want yearly performance (occupancy, ADR, revenue vs. last year), so that I can judge my investment.I4🔜
US-I4As a landlord, I want to block periods on my own units directly — as own stay or not rentable — so that reserving my apartment doesn’t need a phone call. The overlap guard protects existing guest bookings.I5✅
US-I4bAs a landlord, I want to remove my own future blocks, so that freed periods become bookable again instantly.I5✅
US-I5As a landlord, I want my contract documents in the portal, so that everything about my unit lives in one place.I6🔜

Actors: accountant, admin, backoffice · guests receive the invoices · landlords are affected downstream (statements). Cross-references: quote engine (Epic E — invoice lines snapshot the same breakdown), daily agenda (Epic T — overdue payments), owner statements (planned), legal editor (company profile feeds the letterhead). Compliance basis (researched): UAE VAT Executive Regulation Art. 59 — full tax invoice (label “Tax Invoice”, supplier name/address/TRN, recipient details incl. TRN when registered, unique sequential number, issue + supply date, per-line net/qty/VAT rate, VAT amount in AED, gross in AED); simplified invoice allowed for non-registered recipients (any amount) or ≤ AED 10,000; 14-day issuance rule; Tourism Dirham is a government fee outside the VAT base and is shown as a separate non-VAT line.

US-J1 · FTA-compliant guest invoice (key story) — ✅

Section titled “US-J1 · FTA-compliant guest invoice (key story) — ✅”

As an accountant, I want to issue a numbered tax invoice for a booking and print it as an A4 document, so that guests and corporate clients get FTA-compliant paperwork.

  • Given a booking, when I create an invoice, then it receives a gapless sequential number per tenant (INV-2026-00001), snapshots the line items (accommodation, discounts, cleaning, Tourism Dirham as non-VAT fee, VAT 5%) and freezes the billing name/address (pre-filled from the guest, editable, optional recipient TRN).
  • Then the A4 print view carries the company letterhead (legal name, address, TRN, license/ORN from the Legal & Company profile), the words TAX INVOICE, and all Art. 59 fields.
  • Given an issued invoice, then it is immutable — corrections are made by voiding and re-issuing.

Conflicts & edge cases: manual price overrides (e.g. OTA gross amounts) are back-calculated into a consistent breakdown (VAT extracted from the VAT-able part, Dirham/cleaning kept at standard) — flagged on the invoice as derived; invoices for cancelled bookings remain (audit) but can be voided.

US-J2 · Manual payment tracking (key story) — ✅

Section titled “US-J2 · Manual payment tracking (key story) — ✅”

As a backoffice agent, I want to record every incoming payment manually (no bank integration, by design), so that anyone can see at a glance whether the money for a stay has arrived.

  • Given a booking, when I record a payment (deposit / balance / security deposit / refund; cash, bank transfer, external card, payment link; date + reference), then the balance updates instantly: unpaid / partially paid / paid — visible in the booking dialog, the bookings list and the daily agenda.
  • Given a security deposit, then it is tracked but never counted towards the stay balance.
  • Given a refund, then it increases the open balance again (negative payment).

US-J7 · Invoice delivery log (key story) — ✅

Section titled “US-J7 · Invoice delivery log (key story) — ✅”

As an accountant, I want to log every copy of an invoice that leaves the house — copy number, date, channel (e-mail / print / post / WhatsApp), recipient address, note — so that “which copy went where, when?” is always answerable.

  • Given an invoice, when I record a delivery, then the log appends copy #, channel, address, date and who sent it; nothing is ever deleted. | US-J8 | As a backoffice agent, I want bookings with open balances and near arrivals to surface as urgent items in the daily agenda, so that no guest arrives unpaid unnoticed. | J8 | ✅ | | US-J3 | As an accountant, I want a monthly statement run per owner (revenue share − commission − costs), so that payout day is hours, not days. | J4 | 🔜 | | US-J4 | As an accountant, I want a Tourism Dirham report per month, so that the DET declaration is copy-paste. | J5 | 🔜 (fee calculated per booking ✅) | | US-J5 | As an agency admin, I want CSV exports of bookings and revenue, so that external accountants get data their way. | J6 | 🔜 |
Section titled “Epic K — Legal & Company Content (per tenant)”

As an agency admin, I want to edit my company profile and the legal pages (Terms, Privacy, Imprint, Disclaimer, Cancellation Policy) with live preview, so that my website is legally correct for my company — every agency behind a tenant is its own legal entity.

  • Given the editor, when I save a page, then it is published on the public website immediately under /legal/<page>.
  • Given the company profile (legal name, license, ORN, TRN, address), then website footer and imprint update automatically.
  • Given Markdown content, then the preview renders exactly like the public page.

Privacy invariant: everything in this epic is agency-only. Landlords never see guest names, contacts or histories — enforced server-side, not just hidden in the UI.

US-M1 · Recognise returning guests (key story) — ✅

Section titled “US-M1 · Recognise returning guests (key story) — ✅”

As a backoffice agent, I want the system to recognise returning guests when I create a booking, so that their history stays connected instead of piling up duplicate guest records.

  • Given the booking dialog, when I search the guest file (typeahead by name/e-mail), then matches show with their stay count and last stay, and selecting one links the existing guest.
  • Given I type an e-mail that already exists for this tenant, then the server links the existing guest automatically (no duplicate).
  • Given a guest with more than one stay, then their calendar bars carry a returning badge (↺ + count) for agency roles.

US-M2 · Guest history in the calendar (key story) — ✅

Section titled “US-M2 · Guest history in the calendar (key story) — ✅”

As an agency admin, I want to see a guest’s previous stays when I open their booking in the calendar, so that context (“was here twice, always Marina”) is one click away.

  • Given a booking detail dialog, then previous stays are listed with period, unit, source and amount.
  • Given a landlord session, then neither history nor names are ever delivered.

US-M3 · Seasonal regular suggestions (key story) — ✅

Section titled “US-M3 · Seasonal regular suggestions (key story) — ✅”

As a backoffice agent, I want the system to propose reservations for yearly regulars in their favourite apartment, so that we secure loyal revenue before the calendar fills up.

  • Given a guest with stays in ≥ 2 different years within a similar seasonal window (arrival day-of-year ± 21 days), then they appear on the dashboard as a seasonal regular with favourite unit, usual window (e.g. “second half of August”) and predicted dates.
  • Given the guest already has a booking around the predicted window, then no suggestion is shown.
  • When I click Prepare option, then the booking dialog opens pre-filled (guest, favourite unit, predicted dates, status option/hold).

US-M4 · Warning when booking over a regular’s window (key story) — ✅

Section titled “US-M4 · Warning when booking over a regular’s window (key story) — ✅”

As a backoffice agent, I want a warning when I book a regular’s favourite apartment inside their usual window for someone else — “Mr X usually arrives in the second half of August and hasn’t booked yet!” — so that we don’t give away a loyal guest’s slot by accident.

  • Given the create dialog with unit + dates overlapping a regular’s predicted window (±7 days), then a non-blocking warning names the guest, their usual window and stay count.
  • Given the regular themselves is being booked (same linked guest / e-mail), then no warning appears.
#StoryUCStatus
US-M5As an agency admin, I want owner-created blocks clearly visible in the team calendar, so that operations always know why a unit is unavailable.M5✅

Epic T — Daily / Weekly Operations Planner

Section titled “Epic T — Daily / Weekly Operations Planner”

Actors: admin, backoffice, manager (assigned units) · housekeeping consumes the notifications (full mobile flow in P5) · landlords never see the planner (internal operations). Cross-references: payments (Epic J — overdue items), bookings (check-ins/outs, hold expiry), extension automation (Epic N), future housekeeping module (Epic G).

US-T1 · “What’s due today?” agenda (key story) — ✅

Section titled “US-T1 · “What’s due today?” agenda (key story) — ✅”

As a backoffice agent, I want one screen showing everything due today and this week, so that the morning huddle needs no spreadsheet.

  • Given the planner, then each day shows grouped items: check-ins (guest, pax, source), check-outs (= turnovers), urgent outstanding payments (open balance, arrival ≤ 3 days → red, ≤ 7 days → listed), expiring option holds, and manual tasks due that day.
  • Given an overdue manual task, then it rolls onto today with an overdue marker instead of disappearing into the past.

As a backoffice agent, I want quick manual tasks with category, priority, due date and an optional unit/booking link, so that things like “guest wants extra coffee capsules” or “coffee machine broken — replace” are tracked, not remembered.

  • Given the add-task dialog, then I choose category (payment / guest request / maintenance / housekeeping / general), priority (urgent / normal / low), due date and can link a unit or booking.
  • When I tick a task, then it completes with timestamp; done tasks stay visible for audit.

US-T3 · Automatic housekeeping notices (key story) — ✅

Section titled “US-T3 · Automatic housekeeping notices (key story) — ✅”

As a team lead, I want the system to create a notice when a guest extends — “turnover on {old date} cancelled — do not go” — so that the cleaning crew never stands in front of an occupied apartment.

  • Given a booking extension (departure moved later), then a housekeeping task is created automatically for the old checkout date’s unit.
  • Given a shortened stay, then the task says the turnover moved up to the new date (urgent when within 48 h).
#StoryUCStatus
US-T4As an agency admin, I want open/in-progress/done states, category filters and an urgent-count badge in the navigation, so that nothing urgent hides.T4✅

Actors: admin, backoffice (full scope) · landlords (same charts scoped to their units). Cross-references: booking sources (Epic D), payments (Epic J), owner portal (Epic I).

US-L4 · Visual dashboard (key story) — ✅

Section titled “US-L4 · Visual dashboard (key story) — ✅”

As an agency admin, I want colourful, animated charts (ApexCharts) wherever numbers matter, so that occupancy, revenue and channel mix are understood in seconds, not read in tables.

  • Given the dashboard, then I see an animated occupancy area chart (next 60 days), a revenue-by-month bar chart (recent + upcoming booked months), a source-mix donut in the channel colours (Airbnb coral, Booking navy, website emerald, direct gold, partner purple) and a payment-status radial (paid / partial / unpaid of upcoming stays).
  • Given a landlord login, then the same charts render scoped to their own units — payment internals stay agency-only.
  • Then charts share one brand palette and animate on load (ApexCharts defaults tuned, no gimmicks).
#StoryUCStatus
US-L1As an agency admin, I want occupancy/ADR/RevPAR by period and unit, so that pricing decisions are data-driven.K1✅ (occupancy, revenue) / 🔜 (ADR, RevPAR)
US-L2As an agency admin, I want the booking-source mix, so that I can steer marketing towards direct bookings.K2✅ (chart)
US-L3As an agency admin, I want simple pacing vs. last year, so that soft months are visible early.K3🔜