Files
nexus/Project/fonrey/DATA_MODEL/fonrey-data-model.xml
2026-04-24 15:16:42 +08:00

369 lines
49 KiB
XML

<mxfile host="drawio.ishenwei.online" agent="OpenCode">
<diagram name="Fonrey ER Diagram" id="fonrey-er-v1">
<mxGraphModel dx="815" dy="389" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="3300" pageHeight="2340" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="region-org" parent="1" style="swimlane;startSize=30;fillColor=#0d3349;strokeColor=#22d3ee;fontColor=#22d3ee;fontSize=12;fontStyle=1;swimlaneLine=1;rounded=1;arcSize=3;" value="ORG / HR" vertex="1">
<mxGeometry height="760" width="340" x="40" y="60" as="geometry">
<mxRectangle height="30" width="100" x="40" y="60" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="org-units" parent="region-org" style="text;html=1;strokeColor=#22d3ee;fillColor=#0d3349;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;org_units&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;parent_id: uuid (FK → self)&#xa;type: varchar(20)&#xa;name: varchar(100)&#xa;path: varchar(500) [物化路径]&#xa;depth: smallint&#xa;sort_order: int&#xa;is_active: bool&#xa;created_at: timestamptz&#xa;deleted_at: timestamptz" vertex="1">
<mxGeometry height="185" width="280" x="30" y="60" as="geometry" />
</mxCell>
<mxCell id="staff" parent="region-org" style="text;html=1;strokeColor=#22d3ee;fillColor=#0d3349;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;staff&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;FK org_unit_id → org_units&#xa;name: varchar(50)&#xa;phone_enc: text [AES-256-GCM]&#xa;phone_hash: varchar(64) [SHA-256]&#xa;id_no_enc: text [AES]&#xa;user_id: uuid [FK → auth_user]&#xa;entry_date: date&#xa;status: active/resigned/...&#xa;is_active: bool&#xa;created_at: timestamptz&#xa;deleted_at: timestamptz" vertex="1">
<mxGeometry height="215" width="280" x="30" y="280" as="geometry" />
</mxCell>
<mxCell id="e-org-self" edge="1" parent="region-org" source="org-units" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.3;entryDx=0;entryDy=0;strokeColor=#22d3ee;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="org-units">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="340" y="153" />
<mxPoint x="340" y="108" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="e-org-self-lbl" connectable="0" parent="e-org-self" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#22d3ee;" value="自引用 parent_id" vertex="1">
<mxGeometry relative="1" x="0.1" as="geometry" />
</mxCell>
<mxCell id="e-org-staff" edge="1" parent="region-org" source="org-units" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#22d3ee;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="staff">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-org-staff-lbl" connectable="0" parent="e-org-staff" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#22d3ee;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="region-complex" parent="1" style="swimlane;startSize=30;fillColor=#063b2f;strokeColor=#34d399;fontColor=#34d399;fontSize=12;fontStyle=1;swimlaneLine=1;rounded=1;arcSize=3;" value="REGION &amp; COMPLEX" vertex="1">
<mxGeometry height="1380" width="820" x="420" y="60" as="geometry" />
</mxCell>
<mxCell id="districts" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;districts&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;city: varchar(50)&#xa;name: varchar(50)&#xa;short_name: varchar(20)&#xa;sort_order: int&#xa;is_active: bool&#xa;created_at: timestamptz" vertex="1">
<mxGeometry height="150" width="280" x="30" y="60" as="geometry" />
</mxCell>
<mxCell id="business-areas" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;business_areas&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK district_id → districts&#xa;name: varchar(100)&#xa;latitude: numeric(10,7)&#xa;longitude: numeric(10,7)&#xa;sort_order: int&#xa;is_active: bool" vertex="1">
<mxGeometry height="155" width="280" x="10" y="300" as="geometry" />
</mxCell>
<mxCell id="schools" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;schools&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK district_id → districts&#xa;name: varchar(100)&#xa;type: primary/middle/high/k9/k12&#xa;nature: public/private/international&#xa;level: normal/key/top&#xa;is_active: bool" vertex="1">
<mxGeometry height="155" width="290" x="490" y="60" as="geometry" />
</mxCell>
<mxCell id="complexes" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;complexes&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK district_id → districts&#xa;🔗 FK created_by → staff&#xa;name: varchar(200) [⚠ 不可直接修改]&#xa;address: varchar(500) [只读]&#xa;address_summary: varchar(100)&#xa;latitude: numeric(10,7)&#xa;longitude: numeric(10,7)&#xa;property_usage_types: varchar[]&#xa;building_structure: varchar(30)&#xa;building_type: slab/tower/slab_tower&#xa;land_use_years: varchar(30)&#xa;built_years: smallint[]&#xa;total_units: int&#xa;total_households: int&#xa;total_floor_area: numeric(12,2)&#xa;plot_area: numeric(12,2)&#xa;plot_ratio: numeric(5,2)&#xa;green_rate: numeric(5,2)&#xa;developer: varchar(200)&#xa;property_company: varchar(200)&#xa;property_fee: numeric(8,2)&#xa;property_phone: varchar(30)&#xa;parking_total: int&#xa;parking_underground: int&#xa;parking_ratio: varchar(20)&#xa;water_type: civil/commercial&#xa;electricity_type: civil/commercial&#xa;has_central_heating: bool&#xa;has_gas: bool&#xa;lock_building: bool&#xa;lock_room: bool&#xa;lock_info: bool&#xa;lock_standard_room: bool&#xa;search_vector: tsvector&#xa;remarks: text&#xa;is_active: bool&#xa;created_at: timestamptz&#xa;updated_at: timestamptz&#xa;deleted_at: timestamptz" vertex="1">
<mxGeometry height="570" width="340" x="20" y="615" as="geometry" />
</mxCell>
<mxCell id="complex-aliases" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;complex_aliases&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK complex_id → complexes&#xa;alias: varchar(200)&#xa;is_system: bool [系统别名只读]&#xa;created_at: timestamptz&#xa;🔗 FK created_by → staff" vertex="1">
<mxGeometry height="130" width="290" x="490" y="570" as="geometry" />
</mxCell>
<mxCell id="complex-biz-areas" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#0a2e22;strokeWidth=1;dashed=1;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#6ee7b7;whiteSpace=pre;" value="&lt;b&gt;complex_business_areas&lt;/b&gt; [N:M join]&#xa;&lt;hr/&gt;&#xa;🔗 FK complex_id → complexes&#xa;🔗 FK business_area_id → business_areas&#xa;is_primary: bool [UNIQUE where TRUE]" vertex="1">
<mxGeometry height="100" width="380" x="20" y="490" as="geometry" />
</mxCell>
<mxCell id="complex-schools" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#0a2e22;strokeWidth=1;dashed=1;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#6ee7b7;whiteSpace=pre;" value="&lt;b&gt;complex_schools&lt;/b&gt; [N:M join]&#xa;&lt;hr/&gt;&#xa;🔗 FK complex_id → complexes&#xa;🔗 FK school_id → schools&#xa;zone_type: guaranteed/reference/lottery" vertex="1">
<mxGeometry height="75" width="300" x="490" y="250" as="geometry" />
</mxCell>
<mxCell id="buildings" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;buildings&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK complex_id → complexes&#xa;🔗 FK school_id → schools [楼栋级学区]&#xa;name: varchar(50)&#xa;is_standard: bool&#xa;property_usage_type: varchar(20)&#xa;built_year: smallint&#xa;total_floors: smallint&#xa;land_use_years: varchar(30)&#xa;has_elevator: bool&#xa;is_active: bool&#xa;created_at: timestamptz&#xa;🔗 FK created_by → staff" vertex="1">
<mxGeometry height="225" width="310" x="30" y="1000" as="geometry" />
</mxCell>
<mxCell id="room-units" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;room_units&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK building_id → buildings&#xa;floor: smallint&#xa;floor_name: varchar(20)&#xa;room_no: varchar(30)&#xa;display_no: varchar(50)&#xa;is_standard: bool&#xa;is_active: bool&#xa;created_at: timestamptz&#xa;updated_at: timestamptz&#xa;UNIQUE(building_id, floor, room_no)" vertex="1">
<mxGeometry height="200" width="310" x="30" y="1260" as="geometry" />
</mxCell>
<mxCell id="complex-price-trends" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;complex_price_trends&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK complex_id → complexes&#xa;record_month: date [存月份1日]&#xa;avg_sale_price: numeric(12,2)&#xa;avg_unit_price: numeric(10,2)&#xa;transaction_count: int&#xa;listing_count: int&#xa;created_at: timestamptz&#xa;UNIQUE(complex_id, record_month)" vertex="1">
<mxGeometry height="185" width="380" x="400" y="1000" as="geometry" />
</mxCell>
<mxCell id="metro-lines" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;metro_lines&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;city: varchar(50)&#xa;name: varchar(50)&#xa;color: varchar(7) [HEX]&#xa;sort_order: int&#xa;is_active: bool" vertex="1">
<mxGeometry height="130" width="260" x="30" y="1520" as="geometry" />
</mxCell>
<mxCell id="metro-stations" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;metro_stations&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK metro_line_id → metro_lines&#xa;name: varchar(50)&#xa;latitude: numeric(10,7)&#xa;longitude: numeric(10,7)&#xa;sort_order: int&#xa;is_active: bool" vertex="1">
<mxGeometry height="150" width="280" x="320" y="1520" as="geometry" />
</mxCell>
<mxCell id="complex-metro-stations" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#0a2e22;strokeWidth=1;dashed=1;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#6ee7b7;whiteSpace=pre;" value="&lt;b&gt;complex_metro_stations&lt;/b&gt; [N:M join]&#xa;&lt;hr/&gt;&#xa;🔗 FK complex_id → complexes&#xa;🔗 FK station_id → metro_stations&#xa;distance_meters: int [步行距离]" vertex="1">
<mxGeometry height="70" width="320" x="320" y="1700" as="geometry" />
</mxCell>
<mxCell id="complex-photos" parent="region-complex" style="text;html=1;strokeColor=#34d399;fillColor=#063b2f;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;complex_photos&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK complex_id → complexes&#xa;category: complex/layout/vr/other&#xa;file_key: text [R2/S3]&#xa;thumbnail_key: text&#xa;file_name: varchar(255)&#xa;file_size: int&#xa;width, height: int&#xa;is_cover: bool [UNIQUE where TRUE]&#xa;sort_order: smallint&#xa;created_at: timestamptz&#xa;🔗 FK created_by → staff" vertex="1">
<mxGeometry height="205" width="300" x="490" y="770" as="geometry" />
</mxCell>
<mxCell id="e-dist-biz" edge="1" parent="region-complex" source="districts" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="business-areas">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-dist-biz-lbl" connectable="0" parent="e-dist-biz" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#34d399;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-dist-school" edge="1" parent="region-complex" source="districts" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="schools">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-dist-school-lbl" connectable="0" parent="e-dist-school" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#34d399;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-dist-complex" edge="1" parent="region-complex" source="districts" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="complexes">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-dist-complex-lbl" connectable="0" parent="e-dist-complex" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#34d399;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-biz-join" edge="1" parent="region-complex" source="business-areas" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;dashed=1;endArrow=open;startArrow=open;fontSize=9;" target="complex-biz-areas">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-join-complex" edge="1" parent="region-complex" source="complex-biz-areas" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;dashed=1;endArrow=open;startArrow=open;fontSize=9;" target="complexes">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-school-join" edge="1" parent="region-complex" source="schools" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;dashed=1;endArrow=open;startArrow=open;fontSize=9;" target="complex-schools">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-school-join2" edge="1" parent="region-complex" source="complex-schools" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;dashed=1;endArrow=open;startArrow=open;fontSize=9;" target="complexes">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-complex-alias" edge="1" parent="region-complex" source="complexes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="complex-aliases">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-complex-alias-lbl" connectable="0" parent="e-complex-alias" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#34d399;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-complex-photos" edge="1" parent="region-complex" source="complexes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="complex-photos">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-complex-photos-lbl" connectable="0" parent="e-complex-photos" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#34d399;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-complex-trend" edge="1" parent="region-complex" source="complexes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="complex-price-trends">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-complex-trend-lbl" connectable="0" parent="e-complex-trend" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#34d399;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-complex-bldg" edge="1" parent="region-complex" source="complexes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="buildings">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-complex-bldg-lbl" connectable="0" parent="e-complex-bldg" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#34d399;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-bldg-room" edge="1" parent="region-complex" source="buildings" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="room-units">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-bldg-room-lbl" connectable="0" parent="e-bldg-room" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#34d399;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-metro-line-station" edge="1" parent="region-complex" source="metro-lines" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="metro-stations">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-metro-lbl" connectable="0" parent="e-metro-line-station" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#34d399;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-metro-join1" edge="1" parent="region-complex" source="metro-stations" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;dashed=1;endArrow=open;startArrow=open;fontSize=9;" target="complex-metro-stations">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-metro-join2" edge="1" parent="region-complex" source="complex-metro-stations" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#34d399;dashed=1;endArrow=open;startArrow=open;fontSize=9;" target="complexes">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="region-property" parent="1" style="swimlane;startSize=30;fillColor=#2d1a5e;strokeColor=#a78bfa;fontColor=#a78bfa;fontSize=12;fontStyle=1;swimlaneLine=1;rounded=1;arcSize=3;" value="PROPERTY" vertex="1">
<mxGeometry height="1700" width="900" x="1280" y="60" as="geometry" />
</mxCell>
<mxCell id="properties" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;properties&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK complex_id → complexes&#xa;🔗 FK building_id → buildings&#xa;🔗 FK room_unit_id → room_units&#xa;🔗 FK agent_id → staff&#xa;listing_type: sale/rent/both&#xa;status: varchar(20)&#xa;sale_price: numeric(12,2) [万元]&#xa;rent_price: numeric(10,2) [元/月]&#xa;area: numeric(8,2) [m²]&#xa;floor: smallint&#xa;total_floors: smallint&#xa;bedroom: smallint&#xa;living_room: smallint&#xa;bathroom: smallint&#xa;orientation: varchar(30)&#xa;decoration: varchar(20)&#xa;has_elevator: bool&#xa;built_year: smallint&#xa;ownership_years: varchar(20)&#xa;is_exclusive: bool [独家委托]&#xa;completeness_score: int&#xa;search_vector: tsvector&#xa;source: varchar(30)&#xa;remarks: text&#xa;created_at: timestamptz&#xa;updated_at: timestamptz&#xa;deleted_at: timestamptz&#xa;🔗 FK created_by → staff&#xa;🔗 FK updated_by → staff&#xa;&lt;i&gt;[89,000+ rows · 复合索引 · 分区预留]&lt;/i&gt;" vertex="1">
<mxGeometry height="560" width="380" x="30" y="60" as="geometry" />
</mxCell>
<mxCell id="property-contacts" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;property_contacts&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK property_id → properties&#xa;name: varchar(50)&#xa;phone_enc: text [AES-256-GCM]&#xa;phone_hash: varchar(64) [SHA-256]&#xa;role: owner/agent/tenant&#xa;is_primary: bool&#xa;created_at: timestamptz&#xa;deleted_at: timestamptz" vertex="1">
<mxGeometry height="170" width="310" x="30" y="670" as="geometry" />
</mxCell>
<mxCell id="property-follow-logs" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;property_follow_logs&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK property_id → properties&#xa;🔗 FK staff_id → staff&#xa;log_type: call/visit/price_change/note/...&#xa;content: text&#xa;phone_no_viewed: bool [敏感操作]&#xa;created_at: timestamptz&#xa;🔗 FK created_by → staff&#xa;⚠ NO DELETE — append-only audit log" vertex="1">
<mxGeometry height="185" width="380" x="470" y="60" as="geometry" />
</mxCell>
<mxCell id="listing-histories" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;listing_histories&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK property_id → properties&#xa;listed_at: timestamptz&#xa;delisted_at: timestamptz&#xa;list_price: numeric(12,2)&#xa;reason: varchar(50)&#xa;created_at: timestamptz" vertex="1">
<mxGeometry height="155" width="310" x="470" y="300" as="geometry" />
</mxCell>
<mxCell id="property-photos" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;property_photos&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK property_id → properties&#xa;category: listing/vr/layout/other&#xa;file_key: text [R2/S3]&#xa;thumbnail_key: text&#xa;is_cover: bool&#xa;sort_order: smallint&#xa;width, height: int&#xa;file_size: int&#xa;created_at: timestamptz&#xa;🔗 FK created_by → staff" vertex="1">
<mxGeometry height="205" width="310" x="30" y="900" as="geometry" />
</mxCell>
<mxCell id="property-keys" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;property_keys&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK property_id → properties&#xa;🔗 FK holder_id → staff&#xa;key_no: varchar(50)&#xa;status: held/returned&#xa;taken_at: timestamptz&#xa;returned_at: timestamptz&#xa;notes: text" vertex="1">
<mxGeometry height="165" width="310" x="470" y="510" as="geometry" />
</mxCell>
<mxCell id="property-commissions" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;property_commissions&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK property_id → properties&#xa;commission_type: exclusive/open&#xa;rate: numeric(5,4)&#xa;amount: numeric(12,2)&#xa;start_date: date&#xa;end_date: date&#xa;signed_at: timestamptz&#xa;document_key: text&#xa;created_at: timestamptz" vertex="1">
<mxGeometry height="185" width="330" x="470" y="740" as="geometry" />
</mxCell>
<mxCell id="property-inspections" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;property_inspections&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK property_id → properties&#xa;🔗 FK staff_id → staff&#xa;inspected_at: timestamptz&#xa;status: pending/done/cancelled&#xa;notes: text&#xa;attachments: jsonb&#xa;created_at: timestamptz" vertex="1">
<mxGeometry height="165" width="320" x="30" y="1160" as="geometry" />
</mxCell>
<mxCell id="property-marketing" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;property_marketing&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK property_id → properties [UNIQUE 1:1]&#xa;title: varchar(200)&#xa;highlights: text[]&#xa;description: text&#xa;tags: varchar[]&#xa;platforms: jsonb&#xa;published_at: timestamptz&#xa;updated_at: timestamptz" vertex="1">
<mxGeometry height="175" width="340" x="470" y="990" as="geometry" />
</mxCell>
<mxCell id="property-certificates" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;property_certificates&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK property_id → properties [UNIQUE 1:1]&#xa;cert_no: varchar(50)&#xa;owner_name: varchar(100)&#xa;ownership_type: varchar(30)&#xa;area_registered: numeric(8,2)&#xa;issue_date: date&#xa;document_key: text" vertex="1">
<mxGeometry height="165" width="330" x="30" y="1390" as="geometry" />
</mxCell>
<mxCell id="completeness-scores" parent="region-property" style="text;html=1;strokeColor=#a78bfa;fillColor=#2d1a5e;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;completeness_scores&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK property_id → properties [UNIQUE 1:1]&#xa;score: int [0-100]&#xa;missing_fields: text[]&#xa;calculated_at: timestamptz&#xa;version: int" vertex="1">
<mxGeometry height="135" width="310" x="470" y="1230" as="geometry" />
</mxCell>
<mxCell id="e-prop-contact" edge="1" parent="region-property" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#a78bfa;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="property-contacts">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-contact-lbl" connectable="0" parent="e-prop-contact" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-follow" edge="1" parent="region-property" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#a78bfa;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="property-follow-logs">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-follow-lbl" connectable="0" parent="e-prop-follow" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-listing" edge="1" parent="region-property" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#a78bfa;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="listing-histories">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-listing-lbl" connectable="0" parent="e-prop-listing" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-photos" edge="1" parent="region-property" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#a78bfa;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="property-photos">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-photos-lbl" connectable="0" parent="e-prop-photos" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-keys" edge="1" parent="region-property" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#a78bfa;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="property-keys">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-keys-lbl" connectable="0" parent="e-prop-keys" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-comm" edge="1" parent="region-property" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#a78bfa;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="property-commissions">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-comm-lbl" connectable="0" parent="e-prop-comm" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-insp" edge="1" parent="region-property" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#a78bfa;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="property-inspections">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-insp-lbl" connectable="0" parent="e-prop-insp" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-marketing" edge="1" parent="region-property" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#a78bfa;endArrow=ERone;startArrow=ERone;fontSize=9;" target="property-marketing">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-marketing-lbl" connectable="0" parent="e-prop-marketing" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:1" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-cert" edge="1" parent="region-property" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#a78bfa;endArrow=ERone;startArrow=ERone;fontSize=9;" target="property-certificates">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-cert-lbl" connectable="0" parent="e-prop-cert" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:1" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-score" edge="1" parent="region-property" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#a78bfa;endArrow=ERone;startArrow=ERone;fontSize=9;" target="completeness-scores">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-score-lbl" connectable="0" parent="e-prop-score" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:1" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="region-client" parent="1" style="swimlane;startSize=30;fillColor=#3d1f06;strokeColor=#fbbf24;fontColor=#fbbf24;fontSize=12;fontStyle=1;swimlaneLine=1;rounded=1;arcSize=3;" value="CLIENT" vertex="1">
<mxGeometry height="1380" width="860" x="2220" y="60" as="geometry" />
</mxCell>
<mxCell id="clients" parent="region-client" style="text;html=1;strokeColor=#fbbf24;fillColor=#3d1f06;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;clients&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK agent_id → staff&#xa;client_type: private/public/closed&#xa;status: active/inactive/converted&#xa;name: varchar(50)&#xa;phone_enc: text [AES-256-GCM]&#xa;phone_hash: varchar(64) [SHA-256]&#xa;budget_min/max: numeric&#xa;activity_level: 1-5 [Celery每日计算]&#xa;is_protected: bool [防自动转公客]&#xa;transfer_to_public_type: auto/manual&#xa;last_follow_at: timestamptz&#xa;source: varchar(30)&#xa;remarks: text&#xa;created_at: timestamptz&#xa;deleted_at: timestamptz&#xa;🔗 FK created_by → staff&#xa;&lt;i&gt;[私客/公客/成交客 三态状态机]&lt;/i&gt;" vertex="1">
<mxGeometry height="360" width="370" x="30" y="60" as="geometry" />
</mxCell>
<mxCell id="client-requirements" parent="region-client" style="text;html=1;strokeColor=#fbbf24;fillColor=#3d1f06;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;client_requirements&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK client_id → clients&#xa;req_type: second_hand/new/rent&#xa;district_ids: uuid[]&#xa;business_area_ids: uuid[]&#xa;price_min: numeric&#xa;price_max: numeric&#xa;area_min: numeric&#xa;area_max: numeric&#xa;bedrooms: int[]&#xa;school_ids: uuid[]&#xa;has_elevator: bool&#xa;is_active: bool&#xa;created_at: timestamptz" vertex="1">
<mxGeometry height="260" width="350" x="30" y="480" as="geometry" />
</mxCell>
<mxCell id="client-follow-logs" parent="region-client" style="text;html=1;strokeColor=#fbbf24;fillColor=#3d1f06;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;client_follow_logs&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK client_id → clients&#xa;🔗 FK staff_id → staff&#xa;log_type: call/visit/match/note/status_change&#xa;content: text&#xa;next_follow_date: date&#xa;created_at: timestamptz&#xa;🔗 FK created_by → staff&#xa;⚠ NO DELETE — append-only audit log" vertex="1">
<mxGeometry height="200" width="380" x="430" y="70" as="geometry" />
</mxCell>
<mxCell id="client-viewings" parent="region-client" style="text;html=1;strokeColor=#fbbf24;fillColor=#3d1f06;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;client_viewings&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK client_id → clients&#xa;🔗 FK property_id → properties&#xa;🔗 FK agent_id → staff&#xa;viewed_at: timestamptz&#xa;feedback: text&#xa;rating: smallint [1-5]&#xa;status: planned/done/cancelled&#xa;created_at: timestamptz" vertex="1">
<mxGeometry height="195" width="360" x="430" y="310" as="geometry" />
</mxCell>
<mxCell id="client-matches" parent="region-client" style="text;html=1;strokeColor=#fbbf24;fillColor=#3d1f06;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;client_property_matches&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK client_id → clients&#xa;🔗 FK property_id → properties&#xa;🔗 FK agent_id → staff&#xa;match_type: system/manual&#xa;score: numeric(5,2)&#xa;status: pending/sent/viewed/dismissed&#xa;sent_at: timestamptz&#xa;viewed_at: timestamptz&#xa;created_at: timestamptz" vertex="1">
<mxGeometry height="205" width="380" x="30" y="800" as="geometry" />
</mxCell>
<mxCell id="client-status-logs" parent="region-client" style="text;html=1;strokeColor=#fbbf24;fillColor=#3d1f06;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;client_status_logs&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK client_id → clients&#xa;from_status: varchar(20)&#xa;to_status: varchar(20)&#xa;transfer_type: auto/manual&#xa;reason: text&#xa;created_at: timestamptz&#xa;🔗 FK created_by → staff&#xa;⚠ NO DELETE — append-only audit log" vertex="1">
<mxGeometry height="195" width="370" x="430" y="560" as="geometry" />
</mxCell>
<mxCell id="client-fav-folders" parent="region-client" style="text;html=1;strokeColor=#fbbf24;fillColor=#3d1f06;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;client_favorite_folders&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK client_id → clients&#xa;name: varchar(100)&#xa;sort_order: int&#xa;created_at: timestamptz" vertex="1">
<mxGeometry height="130" width="300" x="30" y="1070" as="geometry" />
</mxCell>
<mxCell id="client-folder-items" parent="region-client" style="text;html=1;strokeColor=#fbbf24;fillColor=#3d1f06;align=left;verticalAlign=top;spacingLeft=8;spacingTop=4;overflow=hidden;rotatable=0;fontSize=11;fontFamily=monospace;fontColor=#e2e8f0;whiteSpace=pre;" value="&lt;b&gt;client_folder_items&lt;/b&gt;&#xa;&lt;hr/&gt;&#xa;🔑 PK id: uuid&#xa;🔗 FK folder_id → client_favorite_folders&#xa;🔗 FK property_id → properties&#xa;sort_order: int&#xa;created_at: timestamptz" vertex="1">
<mxGeometry height="130" width="320" x="370" y="1070" as="geometry" />
</mxCell>
<mxCell id="e-client-req" edge="1" parent="region-client" source="clients" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#fbbf24;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="client-requirements">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-req-lbl" connectable="0" parent="e-client-req" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#fbbf24;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-follow" edge="1" parent="region-client" source="clients" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#fbbf24;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="client-follow-logs">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-follow-lbl" connectable="0" parent="e-client-follow" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#fbbf24;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-viewing" edge="1" parent="region-client" source="clients" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#fbbf24;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="client-viewings">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-viewing-lbl" connectable="0" parent="e-client-viewing" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#fbbf24;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-match" edge="1" parent="region-client" source="clients" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#fbbf24;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="client-matches">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-match-lbl" connectable="0" parent="e-client-match" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#fbbf24;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-statuslog" edge="1" parent="region-client" source="clients" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#fbbf24;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="client-status-logs">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-statuslog-lbl" connectable="0" parent="e-client-statuslog" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#fbbf24;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-fav" edge="1" parent="region-client" source="clients" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#fbbf24;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="client-fav-folders">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-client-fav-lbl" connectable="0" parent="e-client-fav" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#fbbf24;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-fav-items" edge="1" parent="region-client" source="client-fav-folders" style="edgeStyle=orthogonalEdgeStyle;rounded=0;strokeColor=#fbbf24;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="client-folder-items">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-fav-items-lbl" connectable="0" parent="e-fav-items" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#fbbf24;" value="1:N" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-complex-prop" edge="1" parent="1" source="complexes" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;strokeColor=#a78bfa;dashed=0;endArrow=ERmany;startArrow=ERone;fontSize=9;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" target="properties">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-complex-prop-lbl" connectable="0" parent="e-complex-prop" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:N complex_id" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-bldg-prop" edge="1" parent="1" source="buildings" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;strokeColor=#a78bfa;dashed=1;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="properties">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-bldg-prop-lbl" connectable="0" parent="e-bldg-prop" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:N building_id" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-room-prop" edge="1" parent="1" source="room-units" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;strokeColor=#a78bfa;dashed=1;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="properties">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-room-prop-lbl" connectable="0" parent="e-room-prop" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#a78bfa;" value="1:N room_unit_id" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-staff-prop" edge="1" parent="1" source="staff" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;strokeColor=#22d3ee;dashed=1;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="properties">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-staff-prop-lbl" connectable="0" parent="e-staff-prop" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#22d3ee;" value="agent_id" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-staff-client" edge="1" parent="1" source="staff" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;strokeColor=#22d3ee;dashed=1;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="clients">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-staff-client-lbl" connectable="0" parent="e-staff-client" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#22d3ee;" value="agent_id" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-viewing" edge="1" parent="1" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;strokeColor=#fb923c;dashed=1;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="client-viewings">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-viewing-lbl" connectable="0" parent="e-prop-viewing" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#fb923c;" value="property_id" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-match" edge="1" parent="1" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;strokeColor=#fb923c;dashed=1;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="client-matches">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-match-lbl" connectable="0" parent="e-prop-match" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#fb923c;" value="property_id" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-folder" edge="1" parent="1" source="properties" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;strokeColor=#fb923c;dashed=1;endArrow=ERmany;startArrow=ERone;fontSize=9;" target="client-folder-items">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-prop-folder-lbl" connectable="0" parent="e-prop-folder" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;fontSize=9;fontColor=#fb923c;" value="property_id" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>