Baseleg Docs

v1 spine — conceptual ER

The three primary entities of the v1 product spine and their relationships. This is a conceptual diagram — it shows domain relationships, not exact database schema column names.

<!-- Member entity -->
<div style="border:2px solid var(--docs-secondary);border-radius:10px;overflow:hidden">
  <div style="background:var(--docs-secondary);padding:8px 14px">
    <div style="font-weight:700;color:#ffffff;font-size:0.9rem">Member</div>
    <div style="color:color-mix(in srgb,#ffffff 75%,transparent);font-size:0.7rem">People context</div>
  </div>
  <div style="padding:10px 14px;background:color-mix(in srgb,var(--docs-secondary) 8%,#ffffff)">
    <div style="display:flex;flex-direction:column;gap:4px">
      <div style="display:flex;gap:8px;align-items:baseline">
        <span style="font-size:0.65rem;font-weight:700;color:var(--docs-secondary);min-width:18px">PK</span>
        <span style="font-size:0.78rem;color:var(--docs-primary);font-family:monospace">id</span>
      </div>
      <div style="height:1px;background:var(--docs-border);margin:2px 0"></div>
      <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">name</div>
      <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">email</div>
      <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">phone?</div>
      <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">roles[ ]</div>
      <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">status</div>
    </div>
  </div>
</div>

<!-- Booking entity (centre) -->
<div style="margin:0 -2px;position:relative;z-index:1">
  <div style="border:2px solid #f97316;border-radius:10px;overflow:hidden;box-shadow:0 2px 12px color-mix(in srgb,#f97316 20%,transparent)">
    <div style="background:#f97316;padding:8px 14px">
      <div style="font-weight:700;color:#ffffff;font-size:0.9rem">Booking</div>
      <div style="color:color-mix(in srgb,#ffffff 75%,transparent);font-size:0.7rem">Scheduling context</div>
    </div>
    <div style="padding:10px 14px;background:color-mix(in srgb,#f97316 6%,#ffffff)">
      <div style="display:flex;flex-direction:column;gap:4px">
        <div style="display:flex;gap:8px;align-items:baseline">
          <span style="font-size:0.65rem;font-weight:700;color:#f97316;min-width:18px">PK</span>
          <span style="font-size:0.78rem;color:var(--docs-primary);font-family:monospace">id</span>
        </div>
        <div style="height:1px;background:var(--docs-border);margin:2px 0"></div>
        <div style="display:flex;gap:8px;align-items:baseline">
          <span style="font-size:0.65rem;font-weight:700;color:var(--docs-secondary);min-width:18px">FK</span>
          <span style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">memberId</span>
        </div>
        <div style="display:flex;gap:8px;align-items:baseline">
          <span style="font-size:0.65rem;font-weight:700;color:var(--docs-secondary);min-width:18px">FK</span>
          <span style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">aircraftId</span>
        </div>
        <div style="display:flex;gap:8px;align-items:baseline">
          <span style="font-size:0.65rem;font-weight:700;color:color-mix(in srgb,var(--docs-secondary) 60%,#ffffff);min-width:18px">FK?</span>
          <span style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 55%,transparent);font-family:monospace">instructorId</span>
        </div>
        <div style="height:1px;background:var(--docs-border);margin:2px 0"></div>
        <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">startAt</div>
        <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">endAt</div>
        <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">status</div>
        <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 55%,transparent);font-family:monospace">cancelledAt?</div>
      </div>
    </div>
  </div>
</div>

<!-- Aircraft entity -->
<div style="border:2px solid #22c55e;border-radius:10px;overflow:hidden">
  <div style="background:#22c55e;padding:8px 14px">
    <div style="font-weight:700;color:#ffffff;font-size:0.9rem">Aircraft</div>
    <div style="color:color-mix(in srgb,#ffffff 75%,transparent);font-size:0.7rem">Aircraft context</div>
  </div>
  <div style="padding:10px 14px;background:color-mix(in srgb,#22c55e 6%,#ffffff)">
    <div style="display:flex;flex-direction:column;gap:4px">
      <div style="display:flex;gap:8px;align-items:baseline">
        <span style="font-size:0.65rem;font-weight:700;color:#22c55e;min-width:18px">PK</span>
        <span style="font-size:0.78rem;color:var(--docs-primary);font-family:monospace">id</span>
      </div>
      <div style="height:1px;background:var(--docs-border);margin:2px 0"></div>
      <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">registration</div>
      <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">type</div>
      <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 70%,transparent);font-family:monospace">status</div>
      <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 55%,transparent);font-family:monospace">groundedReason?</div>
      <div style="font-size:0.75rem;color:color-mix(in srgb,var(--docs-primary) 55%,transparent);font-family:monospace">groundedAt?</div>
    </div>
  </div>
</div>
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;padding-top:2px">
  <div style="width:1px;height:20px;background:var(--docs-border)"></div>
  <div style="font-size:0.65rem;color:color-mix(in srgb,var(--docs-primary) 50%,transparent);text-align:center">1 Member<br>has many Bookings</div>
  <div style="display:flex;align-items:center;gap:4px;width:100%">
    <div style="flex:1;height:1px;background:var(--docs-border)"></div>
    <div style="font-size:0.65rem;padding:2px 6px;border:1px solid var(--docs-border);border-radius:4px;color:color-mix(in srgb,var(--docs-primary) 45%,transparent);background:var(--docs-surface-2);white-space:nowrap">1 : N</div>
    <div style="flex:1;height:1px;background:var(--docs-border)"></div>
  </div>
</div>

<div style="display:flex;flex-direction:column;align-items:center;gap:4px;padding-top:2px">
</div>

<div style="display:flex;flex-direction:column;align-items:center;gap:4px;padding-top:2px">
  <div style="width:1px;height:20px;background:var(--docs-border)"></div>
  <div style="font-size:0.65rem;color:color-mix(in srgb,var(--docs-primary) 50%,transparent);text-align:center">1 Aircraft<br>has many Bookings</div>
  <div style="display:flex;align-items:center;gap:4px;width:100%">
    <div style="flex:1;height:1px;background:var(--docs-border)"></div>
    <div style="font-size:0.65rem;padding:2px 6px;border:1px solid var(--docs-border);border-radius:4px;color:color-mix(in srgb,var(--docs-primary) 45%,transparent);background:var(--docs-surface-2);white-space:nowrap">1 : N</div>
    <div style="flex:1;height:1px;background:var(--docs-border)"></div>
  </div>
</div>

Domain rules enforced at booking time

🚫 Rejected
  • Aircraft is grounded
  • Aircraft already booked in overlapping time range
  • Instructor already booked in overlapping time range
  • Member is inactive
✓ Accepted when
  • Aircraft status is available
  • No confirmed bookings overlap the time range
  • Instructor (if assigned) is free in the time range
  • Booking owner is an active Member

See Scheduling bounded context for the full domain rules.