clean and refine product docs structure
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Domain 3 — Services & Pricing — Balinyaar docs</title>
|
||||
<link rel="stylesheet" href="../assets/doc.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layout">
|
||||
<aside class="sidebar">
|
||||
<a class="brand" href="../index.html"><span class="dot"></span> Balinyaar docs</a>
|
||||
<p class="tagline">Trust-first home-nursing marketplace · Iran</p>
|
||||
<nav><div class="group"><div class="label">Start here</div><ul><li><a href="../index.html">Docs home</a></li><li><a href="../overview/platform-summary.html">Platform summary & ground truths</a></li></ul></div><div class="group"><div class="label">Business requirements</div><ul><li><a href="../business/index.html">Overview & MVP scope</a></li><li><a href="../business/01-actors-and-onboarding.html">1. Actors & onboarding</a></li><li><a href="../business/02-nurse-verification.html">2. Nurse verification</a></li><li><a href="../business/03-service-catalog-and-pricing.html">3. Service catalog & pricing</a></li><li><a href="../business/04-search-and-matching.html">4. Search & matching</a></li><li><a href="../business/05-booking-and-scheduling.html">5. Booking & scheduling</a></li><li><a href="../business/06-evv-and-service-delivery.html">6. EVV / service delivery</a></li><li><a href="../business/07-cancellation-and-refunds.html">7. Cancellation & refunds</a></li><li><a href="../business/08-payments-and-escrow.html">8. Payments & escrow</a></li><li><a href="../business/09-installments-bnpl.html">9. Installments / BNPL</a></li><li><a href="../business/10-payouts.html">10. Payouts to nurses</a></li><li><a href="../business/11-reviews-trust-and-safety.html">11. Reviews, trust & safety</a></li><li><a href="../business/12-messaging-and-emergencies.html">12. Messaging & emergencies</a></li><li><a href="../business/13-tax-invoicing-and-legal.html">13. Tax, invoicing & legal</a></li><li><a href="../business/14-notifications-and-admin.html">14. Notifications & admin</a></li></ul></div><div class="group"><div class="label">Database model</div><ul><li><a href="index.html">Overview & decisions</a></li><li><a href="diagrams.html">Diagrams</a></li><li><a href="01-identity-and-access.html">1. Identity & access</a></li><li><a href="02-geography.html">2. Geography</a></li><li><a class="active" href="03-services-and-pricing.html">3. Services & pricing</a></li><li><a href="04-verification-and-credentials.html">4. Verification & credentials</a></li><li><a href="05-booking-and-scheduling.html">5. Booking & scheduling</a></li><li><a href="06-payments-ledger-and-refunds.html">6. Payments, ledger & refunds</a></li><li><a href="07-payouts.html">7. Payouts</a></li><li><a href="08-bnpl.html">8. BNPL / installments</a></li><li><a href="09-messaging.html">9. Messaging</a></li><li><a href="10-reviews-and-records.html">10. Reviews & records</a></li><li><a href="11-notifications.html">11. Notifications</a></li><li><a href="12-audit-config-and-reference.html">12. Audit, config & reference</a></li><li><a href="13-partner-centers-and-future.html">13. Partner centers & future</a></li></ul></div><div class="group"><div class="label">Payments deep-dive</div><ul><li><a href="../payments/index.html">Overview & exec summary</a></li><li><a href="../payments/iranian-payment-reality.html">Iranian payment reality</a></li><li><a href="../payments/escrow-ledger.html">Escrow as a ledger</a></li><li><a href="../payments/bnpl-landscape.html">BNPL landscape & finding</a></li><li><a href="../payments/cancellation-and-payout.html">Cancellation & nurse payout</a></li><li><a href="../payments/integration-notes.html">Integration & schema touchpoints</a></li><li><a href="../payments/sources.html">Recommendations & sources</a></li></ul></div><div class="group"><div class="label">Research & strategy</div><ul><li><a href="../research/index.html">Overview & exec summary</a></li><li><a href="../research/market-and-competitors.html">Market & competitors</a></li><li><a href="../research/problems-and-risks.html">Problems & risks</a></li><li><a href="../research/verification.html">Verification (research)</a></li><li><a href="../research/legal-landscape.html">Legal landscape</a></li><li><a href="../research/go-to-market.html">Go-to-market & sources</a></li></ul></div><div class="group"><div class="label">Notes & more</div><ul><li><a href="../notes/open-questions.html">Open questions</a></li><li><a href="../notes/future-ideas.html">Future ideas</a></li><li><a href="../wireframes/index.html">Wireframes</a></li><li><a href="../fa/index.html">Farsi documents</a></li></ul></div></nav>
|
||||
</aside>
|
||||
<main class="main"><div class="content">
|
||||
<div class="topbar"><button class="theme-toggle" type="button" onclick="__t()">theme</button></div>
|
||||
<h1 id="domain-3-services-pricing">Domain 3 — Services & Pricing</h1>
|
||||
<p><a href="index.html">← Database Model</a></p>
|
||||
<p>The service model keeps the original three admin layers (category → option group → option value) and two nurse layers (variant → variant option). This <strong>EAV-style configurability is deliberately kept</strong> — it lets admins add a new pricing dimension (e.g. "شبانهروزی / live-in", "number of patients") without a migration, and lets each nurse price every combination independently. The only addition is a denormalized read model for search.</p>
|
||||
<h3 id="service_categories-core"><code>service_categories</code> [CORE] <a class="anchor" href="#service_categories-core" aria-hidden="true">#</a></h3>
|
||||
<p><strong>Role:</strong> Admin-managed top-level care types (Elderly, Post-Surgery, Infant, Chronic, Companionship). The primary search dimension. <strong>Why admin-managed rows:</strong> the catalog is a business lever, not a code constant. Fields unchanged. <strong>Relations:</strong> 1:N → <code>service_option_groups</code>, <code>nurse_service_variants</code>.</p>
|
||||
<h3 id="service_option_groups-core-service_option_values-core"><code>service_option_groups</code> [CORE] / <code>service_option_values</code> [CORE] <a class="anchor" href="#service_option_groups-core-service_option_values-core" aria-hidden="true">#</a></h3>
|
||||
<p><strong>Role:</strong> The configurable dimensions (group, e.g. "نوع شیفت") and their concrete choices (value, e.g. "شبانهروزی"). A NULL <code>service_category_id</code> on a group = cross-category (e.g. shift type applies everywhere). <strong>Why two tables:</strong> separating dimension from choice lets a dimension be <code>is_required</code> and reused across categories. Fields unchanged. <strong>Relations:</strong> <code>service_categories</code> 1:N <code>service_option_groups</code> 1:N <code>service_option_values</code>.</p>
|
||||
<h3 id="nurse_service_variants-core"><code>nurse_service_variants</code> [CORE] <a class="anchor" href="#nurse_service_variants-core" aria-hidden="true">#</a></h3>
|
||||
<p><strong>Role:</strong> The atomic <strong>bookable unit</strong> — a specific nurse offering a category with a chosen option combination at a price. <strong>Why this is the bookable unit (not the nurse):</strong> a nurse offers many priced combinations; search and booking operate on the exact thing the customer pays for. The <code>price_unit</code> (<code>per_hour</code>/<code>per_session</code>/<code>per_half_day</code>/<code>per_day</code>/<code>per_24h</code>) determines display and, with <code>session_count</code>, the engagement total. Fields unchanged. <strong>Consider</strong> a uniqueness strategy on <code>(nurse_id, category, option-set)</code> to prevent duplicate identical listings. <strong>Relations:</strong> N:1 → <code>nurse_profiles</code>, <code>service_categories</code>; 1:N → <code>nurse_service_variant_options</code>, <code>booking_requests</code>.</p>
|
||||
<h3 id="nurse_service_variant_options-core"><code>nurse_service_variant_options</code> [CORE] <a class="anchor" href="#nurse_service_variant_options-core" aria-hidden="true">#</a></h3>
|
||||
<p><strong>Role:</strong> The option values that define a variant's configuration. <strong>Why:</strong> one row per dimension makes the variant's meaning explicit and queryable. <code>UNIQUE(variant_id, option_group_id)</code> — one value per dimension. <strong>Relations:</strong> N:1 → <code>nurse_service_variants</code>, <code>service_option_groups</code>, <code>service_option_values</code>.</p>
|
||||
<h3 id="nurse_search_index-core-new"><code>nurse_search_index</code> [CORE] — <strong>NEW</strong> <a class="anchor" href="#nurse_search_index-core-new" aria-hidden="true">#</a></h3>
|
||||
<p><strong>Role:</strong> A denormalized, one-row-per-bookable-variant read model holding every search-relevant field flat: nurse (verified + accepting), variant (category, price, unit), areas (city/district), gender, rating, partner center. <strong>Why:</strong> nurse search otherwise needs 4+ joins (<code>nurse_profiles → variants → variant_options → service_areas</code>) plus a rating sort from day one — slow at modest scale. A maintained-on-write flat table is far cheaper than adding Elasticsearch at MVP stage.</p>
|
||||
<div class="table-wrap"><table><thead><tr><th>Field</th><th>Type</th><th>Notes</th></tr></thead><tbody>
|
||||
<tr><td><code>id</code></td><td>BIGINT PK</td><td></td></tr>
|
||||
<tr><td><code>variant_id</code></td><td>BIGINT FK → nurse_service_variants</td><td></td></tr>
|
||||
<tr><td><code>nurse_id</code></td><td>BIGINT FK → nurse_profiles</td><td></td></tr>
|
||||
<tr><td><code>service_category_id</code></td><td>BIGINT FK</td><td></td></tr>
|
||||
<tr><td><code>price</code>, <code>price_unit</code></td><td>…</td><td>Copied from variant</td></tr>
|
||||
<tr><td><code>city_id</code>, <code>district_id</code></td><td>BIGINT</td><td>One row per covered area (fan-out)</td></tr>
|
||||
<tr><td><code>nurse_gender</code></td><td>NVARCHAR(10)</td><td>For same-gender filtering</td></tr>
|
||||
<tr><td><code>average_rating</code>, <code>total_reviews</code>, <code>total_completed_bookings</code></td><td>…</td><td>Copied from profile</td></tr>
|
||||
<tr><td><code>is_searchable</code></td><td>BIT</td><td>True <strong>only</strong> when nurse <code>is_verified=1</code>, not suspended, accepting, and variant <code>is_active=1</code></td></tr>
|
||||
<tr><td><code>updated_at</code></td><td>DATETIME2</td><td></td></tr>
|
||||
</tbody></table></div>
|
||||
<p><strong>Relations (read-only projection):</strong> maintained on writes to <code>nurse_profiles</code>, <code>nurse_service_variants</code>, <code>nurse_service_areas</code>, <code>reviews</code>. <strong>Invariant:</strong> a row is <code>is_searchable=1</code> only when its source nurse/variant are bookable.</p>
|
||||
<h3 id="nurse_availability_slots-mvp-nurse_availability_exceptions-mvp"><code>nurse_availability_slots</code> [MVP] / <code>nurse_availability_exceptions</code> [MVP] <a class="anchor" href="#nurse_availability_slots-mvp-nurse_availability_exceptions-mvp" aria-hidden="true">#</a></h3>
|
||||
<p><strong>Role:</strong> Recurring weekly windows + date overrides. <strong>Why soft-constraint:</strong> these are <strong>guidance only</strong> — the nurse still accepts/rejects each request; they inform search but never block a request. <code>day_of_week</code> uses the Shamsi week (0=Saturday … 6=Friday). Fields unchanged, with CHECK <code>end_time > start_time</code>. <strong>Relations:</strong> N:1 → <code>nurse_profiles</code>.</p>
|
||||
<a class="back-to-top" href="#">↑ Back to top</a>
|
||||
</div></main>
|
||||
</div>
|
||||
<script>
|
||||
(function(){var k='balinyaar-docs-theme';var s=localStorage.getItem(k);
|
||||
if(s)document.documentElement.setAttribute('data-theme',s);
|
||||
else if(matchMedia('(prefers-color-scheme: dark)').matches)document.documentElement.setAttribute('data-theme','dark');})();
|
||||
function __t(){var d=document.documentElement;var n=d.getAttribute('data-theme')==='dark'?'light':'dark';
|
||||
d.setAttribute('data-theme',n);localStorage.setItem('balinyaar-docs-theme',n);}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user