Sync: expand data model and gitops notes
This commit is contained in:
574
Project/fonrey/DATA_MODEL/diagram/fonrey-er.svg
Normal file
574
Project/fonrey/DATA_MODEL/diagram/fonrey-er.svg
Normal file
@@ -0,0 +1,574 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2560 1980">
|
||||
<defs>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap');
|
||||
text { font-family: 'JetBrains Mono', 'Noto Sans SC', 'PingFang SC', 'SF Mono', monospace; }
|
||||
</style>
|
||||
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
||||
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#1e293b" stroke-width="0.5"/>
|
||||
</pattern>
|
||||
<!-- Arrow markers per color -->
|
||||
<marker id="arrow-cyan" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#22d3ee"/>
|
||||
</marker>
|
||||
<marker id="arrow-emerald" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#34d399"/>
|
||||
</marker>
|
||||
<marker id="arrow-violet" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#a78bfa"/>
|
||||
</marker>
|
||||
<marker id="arrow-amber" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#fbbf24"/>
|
||||
</marker>
|
||||
<marker id="arrow-slate" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#94a3b8"/>
|
||||
</marker>
|
||||
<marker id="arrow-orange" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#fb923c"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Background -->
|
||||
<rect width="2560" height="1980" fill="#0f172a"/>
|
||||
<rect width="2560" height="1980" fill="url(#grid)"/>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
<!-- MODULE BOUNDARIES -->
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
|
||||
<!-- Org Module boundary (cyan) -->
|
||||
<rect x="30" y="60" width="310" height="680" rx="12" fill="none" stroke="#22d3ee" stroke-width="1" stroke-dasharray="8,4" opacity="0.6"/>
|
||||
<text x="44" y="80" fill="#22d3ee" font-size="10" font-weight="600">ORG / HR</text>
|
||||
|
||||
<!-- Region+Complex Module boundary (emerald) -->
|
||||
<rect x="360" y="60" width="680" height="1200" rx="12" fill="none" stroke="#34d399" stroke-width="1" stroke-dasharray="8,4" opacity="0.6"/>
|
||||
<text x="374" y="80" fill="#34d399" font-size="10" font-weight="600">REGION & COMPLEX</text>
|
||||
|
||||
<!-- Property Module boundary (violet) -->
|
||||
<rect x="1060" y="60" width="720" height="1560" rx="12" fill="none" stroke="#a78bfa" stroke-width="1" stroke-dasharray="8,4" opacity="0.6"/>
|
||||
<text x="1074" y="80" fill="#a78bfa" font-size="10" font-weight="600">PROPERTY</text>
|
||||
|
||||
<!-- Client Module boundary (amber) -->
|
||||
<rect x="1800" y="60" width="730" height="1200" rx="12" fill="none" stroke="#fbbf24" stroke-width="1" stroke-dasharray="8,4" opacity="0.6"/>
|
||||
<text x="1814" y="80" fill="#fbbf24" font-size="10" font-weight="600">CLIENT</text>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
<!-- CONNECTION LINES (drawn before boxes) -->
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
|
||||
<!-- OrgUnit → Staff (1:N) -->
|
||||
<line x1="185" y1="220" x2="185" y2="320" stroke="#22d3ee" stroke-width="1.2" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="193" y="275" fill="#22d3ee" font-size="8">1:N</text>
|
||||
|
||||
<!-- Staff → Property (1:N, via created_by) -->
|
||||
<line x1="335" y1="370" x2="1060" y2="370" stroke="#22d3ee" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="690" y="362" fill="#22d3ee" font-size="8">created_by</text>
|
||||
|
||||
<!-- Staff → Client (1:N, via agent) -->
|
||||
<line x1="335" y1="410" x2="1800" y2="410" stroke="#22d3ee" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="1060" y="402" fill="#22d3ee" font-size="8">agent_id</text>
|
||||
|
||||
<!-- District → BusinessArea (1:N) -->
|
||||
<line x1="560" y1="225" x2="560" y2="320" stroke="#34d399" stroke-width="1.2" marker-end="url(#arrow-emerald)"/>
|
||||
<text x="568" y="277" fill="#34d399" font-size="8">1:N</text>
|
||||
|
||||
<!-- District → School (1:N) -->
|
||||
<line x1="700" y1="175" x2="870" y2="175" stroke="#34d399" stroke-width="1.2" marker-end="url(#arrow-emerald)"/>
|
||||
<text x="775" y="167" fill="#34d399" font-size="8">1:N</text>
|
||||
|
||||
<!-- BusinessArea ↔ Complex (N:M via complex_business_areas) -->
|
||||
<line x1="560" y1="420" x2="560" y2="500" stroke="#34d399" stroke-width="1.2" marker-end="url(#arrow-emerald)"/>
|
||||
<text x="568" y="464" fill="#34d399" font-size="8">N:M</text>
|
||||
|
||||
<!-- Complex → Complex_schools join label -->
|
||||
<line x1="700" y1="570" x2="870" y2="400" stroke="#34d399" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow-emerald)"/>
|
||||
<text x="780" y="495" fill="#34d399" font-size="8">N:M</text>
|
||||
|
||||
<!-- Complex → Building (1:N) -->
|
||||
<line x1="560" y1="700" x2="560" y2="790" stroke="#34d399" stroke-width="1.2" marker-end="url(#arrow-emerald)"/>
|
||||
<text x="568" y="749" fill="#34d399" font-size="8">1:N</text>
|
||||
|
||||
<!-- Building → RoomUnit (1:N) -->
|
||||
<line x1="560" y1="980" x2="560" y2="1060" stroke="#34d399" stroke-width="1.2" marker-end="url(#arrow-emerald)"/>
|
||||
<text x="568" y="1024" fill="#34d399" font-size="8">1:N</text>
|
||||
|
||||
<!-- Complex → Property (1:N) -->
|
||||
<line x1="720" y1="600" x2="1060" y2="300" stroke="#a78bfa" stroke-width="1.2" marker-end="url(#arrow-violet)"/>
|
||||
<text x="885" y="445" fill="#a78bfa" font-size="8">1:N</text>
|
||||
|
||||
<!-- Property → PropertyContact (1:N) -->
|
||||
<line x1="1300" y1="390" x2="1300" y2="490" stroke="#a78bfa" stroke-width="1.2" marker-end="url(#arrow-violet)"/>
|
||||
<text x="1308" y="444" fill="#a78bfa" font-size="8">1:N</text>
|
||||
|
||||
<!-- Property → FollowLog (1:N) -->
|
||||
<line x1="1420" y1="300" x2="1570" y2="300" stroke="#a78bfa" stroke-width="1.2" marker-end="url(#arrow-violet)"/>
|
||||
<text x="1482" y="292" fill="#a78bfa" font-size="8">1:N</text>
|
||||
|
||||
<!-- Property → PropertyPhoto (1:N) -->
|
||||
<line x1="1300" y1="670" x2="1300" y2="760" stroke="#a78bfa" stroke-width="1.2" marker-end="url(#arrow-violet)"/>
|
||||
<text x="1308" y="718" fill="#a78bfa" font-size="8">1:N</text>
|
||||
|
||||
<!-- Property → KeyManagement (1:N) -->
|
||||
<line x1="1420" y1="550" x2="1570" y2="550" stroke="#a78bfa" stroke-width="1.2" marker-end="url(#arrow-violet)"/>
|
||||
<text x="1482" y="542" fill="#a78bfa" font-size="8">1:N</text>
|
||||
|
||||
<!-- Property → Commission (1:N) -->
|
||||
<line x1="1420" y1="650" x2="1570" y2="750" stroke="#a78bfa" stroke-width="1.2" marker-end="url(#arrow-violet)"/>
|
||||
<text x="1490" y="695" fill="#a78bfa" font-size="8">1:N</text>
|
||||
|
||||
<!-- Property → Inspection (1:N) -->
|
||||
<line x1="1300" y1="940" x2="1300" y2="1020" stroke="#a78bfa" stroke-width="1.2" marker-end="url(#arrow-violet)"/>
|
||||
<text x="1308" y="984" fill="#a78bfa" font-size="8">1:N</text>
|
||||
|
||||
<!-- Property → Marketing (1:1) -->
|
||||
<line x1="1420" y1="870" x2="1570" y2="960" stroke="#a78bfa" stroke-width="1.2" marker-end="url(#arrow-violet)"/>
|
||||
<text x="1490" y="910" fill="#a78bfa" font-size="8">1:1</text>
|
||||
|
||||
<!-- Property → ListingHistory (1:N) -->
|
||||
<line x1="1180" y1="390" x2="1080" y2="490" stroke="#a78bfa" stroke-width="1.2" marker-end="url(#arrow-violet)"/>
|
||||
<text x="1100" y="435" fill="#a78bfa" font-size="8">1:N</text>
|
||||
|
||||
<!-- Client → ClientRequirement (1:N) -->
|
||||
<line x1="2050" y1="220" x2="2050" y2="310" stroke="#fbbf24" stroke-width="1.2" marker-end="url(#arrow-amber)"/>
|
||||
<text x="2058" y="269" fill="#fbbf24" font-size="8">1:N</text>
|
||||
|
||||
<!-- Client → ClientFollowLog (1:N) -->
|
||||
<line x1="1930" y1="220" x2="1830" y2="310" stroke="#fbbf24" stroke-width="1.2" marker-end="url(#arrow-amber)"/>
|
||||
<text x="1850" y="260" fill="#fbbf24" font-size="8">1:N</text>
|
||||
|
||||
<!-- Client → Viewing (1:N) -->
|
||||
<line x1="2170" y1="220" x2="2270" y2="310" stroke="#fbbf24" stroke-width="1.2" marker-end="url(#arrow-amber)"/>
|
||||
<text x="2210" y="260" fill="#fbbf24" font-size="8">1:N</text>
|
||||
|
||||
<!-- Client → Match (1:N) -->
|
||||
<line x1="2050" y1="490" x2="2050" y2="580" stroke="#fbbf24" stroke-width="1.2" marker-end="url(#arrow-amber)"/>
|
||||
<text x="2058" y="538" fill="#fbbf24" font-size="8">1:N</text>
|
||||
|
||||
<!-- Property → Viewing (1:N) -->
|
||||
<line x1="1780" y1="340" x2="2270" y2="340" stroke="#fb923c" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow-orange)"/>
|
||||
<text x="2020" y="332" fill="#fb923c" font-size="8">1:N</text>
|
||||
|
||||
<!-- Property → Match (1:N) -->
|
||||
<line x1="1780" y1="620" x2="1950" y2="620" stroke="#fb923c" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow-orange)"/>
|
||||
<text x="1845" y="612" fill="#fb923c" font-size="8">1:N</text>
|
||||
|
||||
<!-- MetroStation → Complex (N:M) -->
|
||||
<line x1="620" y1="1280" x2="620" y2="1200" stroke="#34d399" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow-emerald)"/>
|
||||
<text x="628" y="1244" fill="#34d399" font-size="8">N:M</text>
|
||||
|
||||
<!-- MetroLine → MetroStation (1:N) -->
|
||||
<line x1="430" y1="1280" x2="500" y2="1280" stroke="#34d399" stroke-width="1.2" marker-end="url(#arrow-emerald)"/>
|
||||
<text x="452" y="1272" fill="#34d399" font-size="8">1:N</text>
|
||||
|
||||
<!-- ComplexPriceTrend → Complex -->
|
||||
<line x1="870" y1="900" x2="720" y2="660" stroke="#34d399" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow-emerald)"/>
|
||||
<text x="790" y="800" fill="#34d399" font-size="8">1:N</text>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
<!-- ORG MODULE -->
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
|
||||
<!-- OrgUnit -->
|
||||
<rect x="80" y="100" width="210" height="120" rx="6" fill="#0f172a"/>
|
||||
<rect x="80" y="100" width="210" height="120" rx="6" fill="rgba(8,51,68,0.4)" stroke="#22d3ee" stroke-width="1.5"/>
|
||||
<line x1="80" y1="128" x2="290" y2="128" stroke="#22d3ee" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="185" y="120" fill="white" font-size="11" font-weight="700" text-anchor="middle">org_units</text>
|
||||
<text x="90" y="145" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="90" y="158" fill="#94a3b8" font-size="8">parent_id: uuid (FK→self)</text>
|
||||
<text x="90" y="171" fill="#94a3b8" font-size="8">type: varchar(20)</text>
|
||||
<text x="90" y="184" fill="#94a3b8" font-size="8">name, path, depth</text>
|
||||
<text x="90" y="197" fill="#94a3b8" font-size="8">is_active: bool</text>
|
||||
|
||||
<!-- Staff -->
|
||||
<rect x="80" y="320" width="210" height="150" rx="6" fill="#0f172a"/>
|
||||
<rect x="80" y="320" width="210" height="150" rx="6" fill="rgba(8,51,68,0.4)" stroke="#22d3ee" stroke-width="1.5"/>
|
||||
<line x1="80" y1="348" x2="290" y2="348" stroke="#22d3ee" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="185" y="340" fill="white" font-size="11" font-weight="700" text-anchor="middle">staff</text>
|
||||
<text x="90" y="365" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="90" y="378" fill="#94a3b8" font-size="8">FK org_unit_id</text>
|
||||
<text x="90" y="391" fill="#94a3b8" font-size="8">name: varchar(50)</text>
|
||||
<text x="90" y="404" fill="#94a3b8" font-size="8">phone_enc: text (AES)</text>
|
||||
<text x="90" y="417" fill="#94a3b8" font-size="8">phone_hash: varchar(64)</text>
|
||||
<text x="90" y="430" fill="#94a3b8" font-size="8">user_id: uuid (FK→auth)</text>
|
||||
<text x="90" y="443" fill="#94a3b8" font-size="8">is_active, deleted_at</text>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
<!-- REGION + COMPLEX MODULE -->
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
|
||||
<!-- District -->
|
||||
<rect x="440" y="100" width="220" height="125" rx="6" fill="#0f172a"/>
|
||||
<rect x="440" y="100" width="220" height="125" rx="6" fill="rgba(6,78,59,0.4)" stroke="#34d399" stroke-width="1.5"/>
|
||||
<line x1="440" y1="128" x2="660" y2="128" stroke="#34d399" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="550" y="120" fill="white" font-size="11" font-weight="700" text-anchor="middle">districts</text>
|
||||
<text x="450" y="145" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="450" y="158" fill="#94a3b8" font-size="8">city: varchar(50)</text>
|
||||
<text x="450" y="171" fill="#94a3b8" font-size="8">name: varchar(50)</text>
|
||||
<text x="450" y="184" fill="#94a3b8" font-size="8">short_name: varchar(20)</text>
|
||||
<text x="450" y="197" fill="#94a3b8" font-size="8">sort_order, is_active</text>
|
||||
|
||||
<!-- BusinessArea -->
|
||||
<rect x="440" y="320" width="240" height="135" rx="6" fill="#0f172a"/>
|
||||
<rect x="440" y="320" width="240" height="135" rx="6" fill="rgba(6,78,59,0.4)" stroke="#34d399" stroke-width="1.5"/>
|
||||
<line x1="440" y1="348" x2="680" y2="348" stroke="#34d399" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="560" y="340" fill="white" font-size="11" font-weight="700" text-anchor="middle">business_areas</text>
|
||||
<text x="450" y="365" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="450" y="378" fill="#94a3b8" font-size="8">FK district_id</text>
|
||||
<text x="450" y="391" fill="#94a3b8" font-size="8">name: varchar(100)</text>
|
||||
<text x="450" y="404" fill="#94a3b8" font-size="8">latitude, longitude</text>
|
||||
<text x="450" y="417" fill="#94a3b8" font-size="8">sort_order, is_active</text>
|
||||
|
||||
<!-- School -->
|
||||
<rect x="700" y="100" width="220" height="135" rx="6" fill="#0f172a"/>
|
||||
<rect x="700" y="100" width="220" height="135" rx="6" fill="rgba(6,78,59,0.4)" stroke="#34d399" stroke-width="1.5"/>
|
||||
<line x1="700" y1="128" x2="920" y2="128" stroke="#34d399" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="810" y="120" fill="white" font-size="11" font-weight="700" text-anchor="middle">schools</text>
|
||||
<text x="710" y="145" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="710" y="158" fill="#94a3b8" font-size="8">FK district_id</text>
|
||||
<text x="710" y="171" fill="#94a3b8" font-size="8">name: varchar(100)</text>
|
||||
<text x="710" y="184" fill="#94a3b8" font-size="8">type: primary/middle/high</text>
|
||||
<text x="710" y="197" fill="#94a3b8" font-size="8">nature: public/private</text>
|
||||
<text x="710" y="210" fill="#94a3b8" font-size="8">level: normal/key/top</text>
|
||||
|
||||
<!-- Complex -->
|
||||
<rect x="440" y="500" width="300" height="200" rx="6" fill="#0f172a"/>
|
||||
<rect x="440" y="500" width="300" height="200" rx="6" fill="rgba(6,78,59,0.4)" stroke="#34d399" stroke-width="1.5"/>
|
||||
<line x1="440" y1="528" x2="740" y2="528" stroke="#34d399" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="590" y="520" fill="white" font-size="11" font-weight="700" text-anchor="middle">complexes</text>
|
||||
<text x="450" y="545" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="450" y="558" fill="#94a3b8" font-size="8">name: varchar(200) [不可直接修改]</text>
|
||||
<text x="450" y="571" fill="#94a3b8" font-size="8">FK district_id</text>
|
||||
<text x="450" y="584" fill="#94a3b8" font-size="8">address, address_summary</text>
|
||||
<text x="450" y="597" fill="#94a3b8" font-size="8">latitude, longitude</text>
|
||||
<text x="450" y="610" fill="#94a3b8" font-size="8">lock_building/room/info: bool</text>
|
||||
<text x="450" y="623" fill="#94a3b8" font-size="8">property_usage_types: varchar[]</text>
|
||||
<text x="450" y="636" fill="#94a3b8" font-size="8">search_vector: tsvector</text>
|
||||
<text x="450" y="649" fill="#94a3b8" font-size="8">developer, property_company</text>
|
||||
<text x="450" y="662" fill="#94a3b8" font-size="8">deleted_at, created_by</text>
|
||||
<text x="450" y="675" fill="#94a3b8" font-size="8">...</text>
|
||||
|
||||
<!-- complex_business_areas join table (small) -->
|
||||
<rect x="440" y="465" width="220" height="30" rx="4" fill="#0f172a"/>
|
||||
<rect x="440" y="465" width="220" height="30" rx="4" fill="rgba(6,78,59,0.2)" stroke="#34d399" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<text x="550" y="484" fill="#34d399" font-size="8" text-anchor="middle">complex_business_areas (N:M) · is_primary</text>
|
||||
|
||||
<!-- complex_schools join table (small) -->
|
||||
<rect x="700" y="310" width="210" height="30" rx="4" fill="#0f172a"/>
|
||||
<rect x="700" y="310" width="210" height="30" rx="4" fill="rgba(6,78,59,0.2)" stroke="#34d399" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<text x="805" y="329" fill="#34d399" font-size="8" text-anchor="middle">complex_schools · zone_type</text>
|
||||
|
||||
<!-- Building -->
|
||||
<rect x="440" y="790" width="300" height="185" rx="6" fill="#0f172a"/>
|
||||
<rect x="440" y="790" width="300" height="185" rx="6" fill="rgba(6,78,59,0.4)" stroke="#34d399" stroke-width="1.5"/>
|
||||
<line x1="440" y1="818" x2="740" y2="818" stroke="#34d399" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="590" y="810" fill="white" font-size="11" font-weight="700" text-anchor="middle">buildings</text>
|
||||
<text x="450" y="835" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="450" y="848" fill="#94a3b8" font-size="8">FK complex_id</text>
|
||||
<text x="450" y="861" fill="#94a3b8" font-size="8">name: varchar(50)</text>
|
||||
<text x="450" y="874" fill="#94a3b8" font-size="8">is_standard: bool</text>
|
||||
<text x="450" y="887" fill="#94a3b8" font-size="8">total_floors: smallint</text>
|
||||
<text x="450" y="900" fill="#94a3b8" font-size="8">has_elevator: bool</text>
|
||||
<text x="450" y="913" fill="#94a3b8" font-size="8">built_year: smallint</text>
|
||||
<text x="450" y="926" fill="#94a3b8" font-size="8">property_usage_type</text>
|
||||
<text x="450" y="939" fill="#94a3b8" font-size="8">is_active, created_at</text>
|
||||
<text x="450" y="952" fill="#94a3b8" font-size="8">FK school_id</text>
|
||||
|
||||
<!-- RoomUnit -->
|
||||
<rect x="440" y="1060" width="300" height="155" rx="6" fill="#0f172a"/>
|
||||
<rect x="440" y="1060" width="300" height="155" rx="6" fill="rgba(6,78,59,0.4)" stroke="#34d399" stroke-width="1.5"/>
|
||||
<line x1="440" y1="1088" x2="740" y2="1088" stroke="#34d399" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="590" y="1080" fill="white" font-size="11" font-weight="700" text-anchor="middle">room_units</text>
|
||||
<text x="450" y="1105" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="450" y="1118" fill="#94a3b8" font-size="8">FK building_id</text>
|
||||
<text x="450" y="1131" fill="#94a3b8" font-size="8">floor: smallint</text>
|
||||
<text x="450" y="1144" fill="#94a3b8" font-size="8">floor_name: varchar(20)</text>
|
||||
<text x="450" y="1157" fill="#94a3b8" font-size="8">room_no: varchar(30)</text>
|
||||
<text x="450" y="1170" fill="#94a3b8" font-size="8">display_no: varchar(50)</text>
|
||||
<text x="450" y="1183" fill="#94a3b8" font-size="8">is_standard: bool</text>
|
||||
<text x="450" y="1196" fill="#94a3b8" font-size="8">is_active</text>
|
||||
|
||||
<!-- ComplexPriceTrend -->
|
||||
<rect x="770" y="800" width="250" height="140" rx="6" fill="#0f172a"/>
|
||||
<rect x="770" y="800" width="250" height="140" rx="6" fill="rgba(6,78,59,0.3)" stroke="#34d399" stroke-width="1.5"/>
|
||||
<line x1="770" y1="828" x2="1020" y2="828" stroke="#34d399" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="895" y="820" fill="white" font-size="11" font-weight="700" text-anchor="middle">complex_price_trends</text>
|
||||
<text x="780" y="845" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="780" y="858" fill="#94a3b8" font-size="8">FK complex_id</text>
|
||||
<text x="780" y="871" fill="#94a3b8" font-size="8">record_month: date</text>
|
||||
<text x="780" y="884" fill="#94a3b8" font-size="8">avg_unit_price: numeric(10,2)</text>
|
||||
<text x="780" y="897" fill="#94a3b8" font-size="8">avg_sale_price: numeric(12,2)</text>
|
||||
<text x="780" y="910" fill="#94a3b8" font-size="8">transaction_count: int</text>
|
||||
<text x="780" y="923" fill="#94a3b8" font-size="8">listing_count: int</text>
|
||||
|
||||
<!-- MetroLine -->
|
||||
<rect x="370" y="1270" width="200" height="105" rx="6" fill="#0f172a"/>
|
||||
<rect x="370" y="1270" width="200" height="105" rx="6" fill="rgba(6,78,59,0.3)" stroke="#34d399" stroke-width="1.5"/>
|
||||
<line x1="370" y1="1298" x2="570" y2="1298" stroke="#34d399" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="470" y="1290" fill="white" font-size="11" font-weight="700" text-anchor="middle">metro_lines</text>
|
||||
<text x="380" y="1315" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="380" y="1328" fill="#94a3b8" font-size="8">city: varchar(50)</text>
|
||||
<text x="380" y="1341" fill="#94a3b8" font-size="8">name: varchar(50)</text>
|
||||
<text x="380" y="1354" fill="#94a3b8" font-size="8">color: varchar(7) [HEX]</text>
|
||||
|
||||
<!-- MetroStation -->
|
||||
<rect x="580" y="1270" width="240" height="120" rx="6" fill="#0f172a"/>
|
||||
<rect x="580" y="1270" width="240" height="120" rx="6" fill="rgba(6,78,59,0.3)" stroke="#34d399" stroke-width="1.5"/>
|
||||
<line x1="580" y1="1298" x2="820" y2="1298" stroke="#34d399" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="700" y="1290" fill="white" font-size="11" font-weight="700" text-anchor="middle">metro_stations</text>
|
||||
<text x="590" y="1315" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="590" y="1328" fill="#94a3b8" font-size="8">FK metro_line_id</text>
|
||||
<text x="590" y="1341" fill="#94a3b8" font-size="8">name: varchar(50)</text>
|
||||
<text x="590" y="1354" fill="#94a3b8" font-size="8">latitude, longitude</text>
|
||||
<text x="590" y="1367" fill="#94a3b8" font-size="8">sort_order</text>
|
||||
|
||||
<!-- complex_metro_stations join (small) -->
|
||||
<rect x="580" y="1200" width="240" height="28" rx="4" fill="#0f172a"/>
|
||||
<rect x="580" y="1200" width="240" height="28" rx="4" fill="rgba(6,78,59,0.2)" stroke="#34d399" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<text x="700" y="1218" fill="#34d399" font-size="8" text-anchor="middle">complex_metro_stations · distance_meters</text>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
<!-- PROPERTY MODULE -->
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
|
||||
<!-- Property -->
|
||||
<rect x="1080" y="100" width="340" height="290" rx="6" fill="#0f172a"/>
|
||||
<rect x="1080" y="100" width="340" height="290" rx="6" fill="rgba(76,29,149,0.4)" stroke="#a78bfa" stroke-width="1.5"/>
|
||||
<line x1="1080" y1="128" x2="1420" y2="128" stroke="#a78bfa" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="1250" y="120" fill="white" font-size="11" font-weight="700" text-anchor="middle">properties</text>
|
||||
<text x="1090" y="145" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1090" y="158" fill="#94a3b8" font-size="8">FK complex_id FK building_id</text>
|
||||
<text x="1090" y="171" fill="#94a3b8" font-size="8">FK room_unit_id FK agent_id</text>
|
||||
<text x="1090" y="184" fill="#94a3b8" font-size="8">listing_type: sale/rent/both</text>
|
||||
<text x="1090" y="197" fill="#94a3b8" font-size="8">status: varchar(20)</text>
|
||||
<text x="1090" y="210" fill="#94a3b8" font-size="8">sale_price: numeric(12,2)</text>
|
||||
<text x="1090" y="223" fill="#94a3b8" font-size="8">rent_price: numeric(10,2)</text>
|
||||
<text x="1090" y="236" fill="#94a3b8" font-size="8">floor, total_floors</text>
|
||||
<text x="1090" y="249" fill="#94a3b8" font-size="8">area: numeric(8,2) [m²]</text>
|
||||
<text x="1090" y="262" fill="#94a3b8" font-size="8">bedroom, living, bathroom</text>
|
||||
<text x="1090" y="275" fill="#94a3b8" font-size="8">orientation, decoration</text>
|
||||
<text x="1090" y="288" fill="#94a3b8" font-size="8">search_vector: tsvector</text>
|
||||
<text x="1090" y="301" fill="#94a3b8" font-size="8">is_exclusive: bool</text>
|
||||
<text x="1090" y="314" fill="#94a3b8" font-size="8">completeness_score: int</text>
|
||||
<text x="1090" y="327" fill="#94a3b8" font-size="8">deleted_at, created_by</text>
|
||||
<text x="1090" y="340" fill="#94a3b8" font-size="8">...</text>
|
||||
<text x="1090" y="353" fill="#94a3b8" font-size="7">[89,000+ rows · partitioned by status]</text>
|
||||
<text x="1090" y="370" fill="#94a3b8" font-size="7">UNIQUE (complex_id, building_id, floor, room_no)</text>
|
||||
|
||||
<!-- PropertyContact -->
|
||||
<rect x="1080" y="490" width="280" height="155" rx="6" fill="#0f172a"/>
|
||||
<rect x="1080" y="490" width="280" height="155" rx="6" fill="rgba(76,29,149,0.35)" stroke="#a78bfa" stroke-width="1.5"/>
|
||||
<line x1="1080" y1="518" x2="1360" y2="518" stroke="#a78bfa" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="1220" y="510" fill="white" font-size="11" font-weight="700" text-anchor="middle">property_contacts</text>
|
||||
<text x="1090" y="535" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1090" y="548" fill="#94a3b8" font-size="8">FK property_id</text>
|
||||
<text x="1090" y="561" fill="#94a3b8" font-size="8">name: varchar(50)</text>
|
||||
<text x="1090" y="574" fill="#94a3b8" font-size="8">phone_enc: text (AES)</text>
|
||||
<text x="1090" y="587" fill="#94a3b8" font-size="8">phone_hash: varchar(64)</text>
|
||||
<text x="1090" y="600" fill="#94a3b8" font-size="8">role: owner/agent/tenant</text>
|
||||
<text x="1090" y="613" fill="#94a3b8" font-size="8">is_primary: bool</text>
|
||||
|
||||
<!-- PropertyPhoto -->
|
||||
<rect x="1080" y="760" width="280" height="155" rx="6" fill="#0f172a"/>
|
||||
<rect x="1080" y="760" width="280" height="155" rx="6" fill="rgba(76,29,149,0.35)" stroke="#a78bfa" stroke-width="1.5"/>
|
||||
<line x1="1080" y1="788" x2="1360" y2="788" stroke="#a78bfa" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="1220" y="780" fill="white" font-size="11" font-weight="700" text-anchor="middle">property_photos</text>
|
||||
<text x="1090" y="805" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1090" y="818" fill="#94a3b8" font-size="8">FK property_id</text>
|
||||
<text x="1090" y="831" fill="#94a3b8" font-size="8">category: listing/vr/layout</text>
|
||||
<text x="1090" y="844" fill="#94a3b8" font-size="8">file_key: text (R2/S3)</text>
|
||||
<text x="1090" y="857" fill="#94a3b8" font-size="8">is_cover: bool</text>
|
||||
<text x="1090" y="870" fill="#94a3b8" font-size="8">sort_order: smallint</text>
|
||||
<text x="1090" y="883" fill="#94a3b8" font-size="8">width, height, file_size</text>
|
||||
|
||||
<!-- Inspection -->
|
||||
<rect x="1080" y="1020" width="280" height="135" rx="6" fill="#0f172a"/>
|
||||
<rect x="1080" y="1020" width="280" height="135" rx="6" fill="rgba(76,29,149,0.35)" stroke="#a78bfa" stroke-width="1.5"/>
|
||||
<line x1="1080" y1="1048" x2="1360" y2="1048" stroke="#a78bfa" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="1220" y="1040" fill="white" font-size="11" font-weight="700" text-anchor="middle">property_inspections</text>
|
||||
<text x="1090" y="1065" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1090" y="1078" fill="#94a3b8" font-size="8">FK property_id FK staff_id</text>
|
||||
<text x="1090" y="1091" fill="#94a3b8" font-size="8">inspected_at: timestamptz</text>
|
||||
<text x="1090" y="1104" fill="#94a3b8" font-size="8">status: pending/done</text>
|
||||
<text x="1090" y="1117" fill="#94a3b8" font-size="8">notes: text</text>
|
||||
<text x="1090" y="1130" fill="#94a3b8" font-size="8">attachments: jsonb</text>
|
||||
|
||||
<!-- FollowLog (property) -->
|
||||
<rect x="1440" y="100" width="300" height="155" rx="6" fill="#0f172a"/>
|
||||
<rect x="1440" y="100" width="300" height="155" rx="6" fill="rgba(76,29,149,0.35)" stroke="#a78bfa" stroke-width="1.5"/>
|
||||
<line x1="1440" y1="128" x2="1740" y2="128" stroke="#a78bfa" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="1590" y="120" fill="white" font-size="11" font-weight="700" text-anchor="middle">property_follow_logs</text>
|
||||
<text x="1450" y="145" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1450" y="158" fill="#94a3b8" font-size="8">FK property_id FK staff_id</text>
|
||||
<text x="1450" y="171" fill="#94a3b8" font-size="8">log_type: call/visit/note...</text>
|
||||
<text x="1450" y="184" fill="#94a3b8" font-size="8">content: text</text>
|
||||
<text x="1450" y="197" fill="#94a3b8" font-size="8">sensitive_view: bool [不可删]</text>
|
||||
<text x="1450" y="210" fill="#94a3b8" font-size="8">created_at, created_by</text>
|
||||
<text x="1450" y="237" fill="#fb7185" font-size="7">⚠ NO DELETE (audit log)</text>
|
||||
|
||||
<!-- KeyManagement -->
|
||||
<rect x="1440" y="490" width="300" height="120" rx="6" fill="#0f172a"/>
|
||||
<rect x="1440" y="490" width="300" height="120" rx="6" fill="rgba(76,29,149,0.35)" stroke="#a78bfa" stroke-width="1.5"/>
|
||||
<line x1="1440" y1="518" x2="1740" y2="518" stroke="#a78bfa" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="1590" y="510" fill="white" font-size="11" font-weight="700" text-anchor="middle">property_keys</text>
|
||||
<text x="1450" y="535" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1450" y="548" fill="#94a3b8" font-size="8">FK property_id FK holder_id</text>
|
||||
<text x="1450" y="561" fill="#94a3b8" font-size="8">key_no: varchar(50)</text>
|
||||
<text x="1450" y="574" fill="#94a3b8" font-size="8">status: held/returned</text>
|
||||
<text x="1450" y="587" fill="#94a3b8" font-size="8">taken_at, returned_at</text>
|
||||
|
||||
<!-- Commission -->
|
||||
<rect x="1440" y="720" width="300" height="135" rx="6" fill="#0f172a"/>
|
||||
<rect x="1440" y="720" width="300" height="135" rx="6" fill="rgba(76,29,149,0.35)" stroke="#a78bfa" stroke-width="1.5"/>
|
||||
<line x1="1440" y1="748" x2="1740" y2="748" stroke="#a78bfa" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="1590" y="740" fill="white" font-size="11" font-weight="700" text-anchor="middle">property_commissions</text>
|
||||
<text x="1450" y="765" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1450" y="778" fill="#94a3b8" font-size="8">FK property_id</text>
|
||||
<text x="1450" y="791" fill="#94a3b8" font-size="8">commission_type: exclusive/open</text>
|
||||
<text x="1450" y="804" fill="#94a3b8" font-size="8">rate: numeric(5,4)</text>
|
||||
<text x="1450" y="817" fill="#94a3b8" font-size="8">start_date, end_date</text>
|
||||
<text x="1450" y="830" fill="#94a3b8" font-size="8">signed_at, document_key</text>
|
||||
|
||||
<!-- Marketing -->
|
||||
<rect x="1440" y="940" width="300" height="120" rx="6" fill="#0f172a"/>
|
||||
<rect x="1440" y="940" width="300" height="120" rx="6" fill="rgba(76,29,149,0.35)" stroke="#a78bfa" stroke-width="1.5"/>
|
||||
<line x1="1440" y1="968" x2="1740" y2="968" stroke="#a78bfa" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="1590" y="960" fill="white" font-size="11" font-weight="700" text-anchor="middle">property_marketing</text>
|
||||
<text x="1450" y="985" fill="#fbbf24" font-size="8">PK id: uuid [1:1 property]</text>
|
||||
<text x="1450" y="998" fill="#94a3b8" font-size="8">FK property_id (UNIQUE)</text>
|
||||
<text x="1450" y="1011" fill="#94a3b8" font-size="8">title: varchar(200)</text>
|
||||
<text x="1450" y="1024" fill="#94a3b8" font-size="8">highlights: text[]</text>
|
||||
<text x="1450" y="1037" fill="#94a3b8" font-size="8">published_at, platforms: jsonb</text>
|
||||
|
||||
<!-- ListingHistory -->
|
||||
<rect x="1080" y="1250" width="300" height="120" rx="6" fill="#0f172a"/>
|
||||
<rect x="1080" y="1250" width="300" height="120" rx="6" fill="rgba(76,29,149,0.35)" stroke="#a78bfa" stroke-width="1.5"/>
|
||||
<line x1="1080" y1="1278" x2="1380" y2="1278" stroke="#a78bfa" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="1230" y="1270" fill="white" font-size="11" font-weight="700" text-anchor="middle">listing_histories</text>
|
||||
<text x="1090" y="1295" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1090" y="1308" fill="#94a3b8" font-size="8">FK property_id</text>
|
||||
<text x="1090" y="1321" fill="#94a3b8" font-size="8">listed_at, delisted_at</text>
|
||||
<text x="1090" y="1334" fill="#94a3b8" font-size="8">list_price: numeric(12,2)</text>
|
||||
<text x="1090" y="1347" fill="#94a3b8" font-size="8">reason: varchar(50)</text>
|
||||
|
||||
<!-- Arrow from Property to ListingHistory -->
|
||||
<line x1="1230" y1="390" x2="1230" y2="1250" stroke="#a78bfa" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow-violet)"/>
|
||||
<text x="1238" y="820" fill="#a78bfa" font-size="8">1:N</text>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
<!-- CLIENT MODULE -->
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
|
||||
<!-- Client -->
|
||||
<rect x="1870" y="100" width="320" height="250" rx="6" fill="#0f172a"/>
|
||||
<rect x="1870" y="100" width="320" height="250" rx="6" fill="rgba(120,53,15,0.4)" stroke="#fbbf24" stroke-width="1.5"/>
|
||||
<line x1="1870" y1="128" x2="2190" y2="128" stroke="#fbbf24" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="2030" y="120" fill="white" font-size="11" font-weight="700" text-anchor="middle">clients</text>
|
||||
<text x="1880" y="145" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1880" y="158" fill="#94a3b8" font-size="8">FK agent_id (staff)</text>
|
||||
<text x="1880" y="171" fill="#94a3b8" font-size="8">client_type: private/public/closed</text>
|
||||
<text x="1880" y="184" fill="#94a3b8" font-size="8">status: active/inactive/converted</text>
|
||||
<text x="1880" y="197" fill="#94a3b8" font-size="8">name: varchar(50)</text>
|
||||
<text x="1880" y="210" fill="#94a3b8" font-size="8">phone_enc: text (AES)</text>
|
||||
<text x="1880" y="223" fill="#94a3b8" font-size="8">phone_hash: varchar(64)</text>
|
||||
<text x="1880" y="236" fill="#94a3b8" font-size="8">activity_level: 1-5 (Celery daily)</text>
|
||||
<text x="1880" y="249" fill="#94a3b8" font-size="8">is_protected: bool [防止转公客]</text>
|
||||
<text x="1880" y="262" fill="#94a3b8" font-size="8">transfer_to_public_type: auto/manual</text>
|
||||
<text x="1880" y="275" fill="#94a3b8" font-size="8">source: varchar(30)</text>
|
||||
<text x="1880" y="288" fill="#94a3b8" font-size="8">deleted_at, created_by</text>
|
||||
<text x="1880" y="301" fill="#94a3b8" font-size="8">...</text>
|
||||
<text x="1880" y="325" fill="#94a3b8" font-size="7">[私客/公客/成交客 三态状态机]</text>
|
||||
|
||||
<!-- ClientRequirement -->
|
||||
<rect x="1960" y="490" width="280" height="155" rx="6" fill="#0f172a"/>
|
||||
<rect x="1960" y="490" width="280" height="155" rx="6" fill="rgba(120,53,15,0.35)" stroke="#fbbf24" stroke-width="1.5"/>
|
||||
<line x1="1960" y1="518" x2="2240" y2="518" stroke="#fbbf24" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="2100" y="510" fill="white" font-size="11" font-weight="700" text-anchor="middle">client_requirements</text>
|
||||
<text x="1970" y="535" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1970" y="548" fill="#94a3b8" font-size="8">FK client_id</text>
|
||||
<text x="1970" y="561" fill="#94a3b8" font-size="8">req_type: second_hand/new/rent</text>
|
||||
<text x="1970" y="574" fill="#94a3b8" font-size="8">district_ids: uuid[]</text>
|
||||
<text x="1970" y="587" fill="#94a3b8" font-size="8">price_min/max: numeric</text>
|
||||
<text x="1970" y="600" fill="#94a3b8" font-size="8">area_min/max, bedrooms</text>
|
||||
<text x="1970" y="613" fill="#94a3b8" font-size="8">school_ids: uuid[]</text>
|
||||
|
||||
<!-- ClientFollowLog -->
|
||||
<rect x="1820" y="490" width="130" height="155" rx="6" fill="#0f172a"/>
|
||||
<rect x="1820" y="490" width="130" height="155" rx="6" fill="rgba(120,53,15,0.35)" stroke="#fbbf24" stroke-width="1.5"/>
|
||||
<line x1="1820" y1="518" x2="1950" y2="518" stroke="#fbbf24" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="1885" y="510" fill="white" font-size="10" font-weight="700" text-anchor="middle">client_follow_logs</text>
|
||||
<text x="1828" y="535" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1828" y="548" fill="#94a3b8" font-size="8">FK client_id</text>
|
||||
<text x="1828" y="561" fill="#94a3b8" font-size="8">log_type</text>
|
||||
<text x="1828" y="574" fill="#94a3b8" font-size="8">content: text</text>
|
||||
<text x="1828" y="587" fill="#94a3b8" font-size="8">created_at</text>
|
||||
<text x="1828" y="617" fill="#fb7185" font-size="7">⚠ NO DELETE</text>
|
||||
|
||||
<!-- Viewing -->
|
||||
<rect x="2250" y="290" width="250" height="165" rx="6" fill="#0f172a"/>
|
||||
<rect x="2250" y="290" width="250" height="165" rx="6" fill="rgba(120,53,15,0.35)" stroke="#fbbf24" stroke-width="1.5"/>
|
||||
<line x1="2250" y1="318" x2="2500" y2="318" stroke="#fbbf24" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="2375" y="310" fill="white" font-size="11" font-weight="700" text-anchor="middle">client_viewings</text>
|
||||
<text x="2260" y="335" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="2260" y="348" fill="#94a3b8" font-size="8">FK client_id</text>
|
||||
<text x="2260" y="361" fill="#94a3b8" font-size="8">FK property_id</text>
|
||||
<text x="2260" y="374" fill="#94a3b8" font-size="8">FK agent_id (staff)</text>
|
||||
<text x="2260" y="387" fill="#94a3b8" font-size="8">viewed_at: timestamptz</text>
|
||||
<text x="2260" y="400" fill="#94a3b8" font-size="8">feedback: text</text>
|
||||
<text x="2260" y="413" fill="#94a3b8" font-size="8">rating: smallint</text>
|
||||
<text x="2260" y="426" fill="#94a3b8" font-size="8">status: planned/done/cancelled</text>
|
||||
|
||||
<!-- Match -->
|
||||
<rect x="1960" y="700" width="280" height="150" rx="6" fill="#0f172a"/>
|
||||
<rect x="1960" y="700" width="280" height="150" rx="6" fill="rgba(120,53,15,0.35)" stroke="#fbbf24" stroke-width="1.5"/>
|
||||
<line x1="1960" y1="728" x2="2240" y2="728" stroke="#fbbf24" stroke-width="0.5" opacity="0.6"/>
|
||||
<text x="2100" y="720" fill="white" font-size="11" font-weight="700" text-anchor="middle">client_property_matches</text>
|
||||
<text x="1970" y="745" fill="#fbbf24" font-size="8">PK id: uuid</text>
|
||||
<text x="1970" y="758" fill="#94a3b8" font-size="8">FK client_id</text>
|
||||
<text x="1970" y="771" fill="#94a3b8" font-size="8">FK property_id</text>
|
||||
<text x="1970" y="784" fill="#94a3b8" font-size="8">match_type: system/manual</text>
|
||||
<text x="1970" y="797" fill="#94a3b8" font-size="8">score: numeric(5,2)</text>
|
||||
<text x="1970" y="810" fill="#94a3b8" font-size="8">status: pending/sent/viewed</text>
|
||||
<text x="1970" y="823" fill="#94a3b8" font-size="8">created_at</text>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
<!-- LEGEND -->
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
|
||||
<rect x="30" y="1850" width="900" height="100" rx="8" fill="rgba(15,23,42,0.8)" stroke="#334155" stroke-width="1"/>
|
||||
<text x="50" y="1873" fill="#94a3b8" font-size="9" font-weight="600">LEGEND</text>
|
||||
|
||||
<!-- Org -->
|
||||
<rect x="50" y="1885" width="14" height="14" rx="2" fill="rgba(8,51,68,0.4)" stroke="#22d3ee" stroke-width="1.5"/>
|
||||
<text x="70" y="1896" fill="#22d3ee" font-size="8">ORG / HR</text>
|
||||
|
||||
<!-- Complex -->
|
||||
<rect x="155" y="1885" width="14" height="14" rx="2" fill="rgba(6,78,59,0.4)" stroke="#34d399" stroke-width="1.5"/>
|
||||
<text x="175" y="1896" fill="#34d399" font-size="8">REGION & COMPLEX</text>
|
||||
|
||||
<!-- Property -->
|
||||
<rect x="310" y="1885" width="14" height="14" rx="2" fill="rgba(76,29,149,0.4)" stroke="#a78bfa" stroke-width="1.5"/>
|
||||
<text x="330" y="1896" fill="#a78bfa" font-size="8">PROPERTY</text>
|
||||
|
||||
<!-- Client -->
|
||||
<rect x="420" y="1885" width="14" height="14" rx="2" fill="rgba(120,53,15,0.4)" stroke="#fbbf24" stroke-width="1.5"/>
|
||||
<text x="440" y="1896" fill="#fbbf24" font-size="8">CLIENT</text>
|
||||
|
||||
<!-- Relationship lines -->
|
||||
<line x1="50" y1="1920" x2="90" y2="1920" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow-slate)"/>
|
||||
<text x="96" y="1924" fill="#94a3b8" font-size="8">Foreign Key (FK)</text>
|
||||
|
||||
<line x1="210" y1="1920" x2="250" y2="1920" stroke="#94a3b8" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow-slate)"/>
|
||||
<text x="256" y="1924" fill="#94a3b8" font-size="8">Soft reference / optional FK</text>
|
||||
|
||||
<rect x="410" y="1913" width="14" height="14" rx="2" fill="rgba(15,23,42,0.5)" stroke="#34d399" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<text x="430" y="1924" fill="#34d399" font-size="8">Join table (N:M)</text>
|
||||
|
||||
<text x="550" y="1924" fill="#fbbf24" font-size="8">PK Primary Key</text>
|
||||
<text x="640" y="1924" fill="#fb7185" font-size="8">⚠ NO DELETE = append-only audit log</text>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
<!-- TITLE BLOCK -->
|
||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
||||
<text x="1080" y="1930" fill="#475569" font-size="10" text-anchor="middle">Fonrey 房产经纪管理系统 — Entity Relationship Diagram · v1.0 · 2026-04-24 · Schema-per-Tenant (django-tenants)</text>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 40 KiB |
BIN
Project/fonrey/DATA_MODEL/diagram/fonrey-er@2x.png
Normal file
BIN
Project/fonrey/DATA_MODEL/diagram/fonrey-er@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 869 KiB |
Reference in New Issue
Block a user