/ aegisvision / docs / diagrams / data-model.svg
swadhinbiswas feat: AegisVision v2 — AI enterprise surveillance & monitoring platform · 8/8/2026
7ad9221
113 lines · 5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<svg xmlns="http://www.w3.org/2000/svg" width="1260" height="720" viewBox="0 0 1260 720" font-family="'Segoe UI', system-ui, -apple-system, Arial, sans-serif">
  <defs>
    <linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0" stop-color="#0b1019"/>
      <stop offset="1" stop-color="#070b12"/>
    </linearGradient>
    <marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
      <path d="M0 0 L10 5 L0 10 z" fill="#64748b"/>
    </marker>
  </defs>

  <rect width="1260" height="720" fill="url(#bg)"/>
  <text x="630" y="40" text-anchor="middle" font-size="23" font-weight="700" fill="#f8fafc">Data Model</text>
  <text x="630" y="64" text-anchor="middle" font-size="12.5" fill="#64748b">SQLite relational store + ChromaDB vector index — kept in sync on every enroll / delete</text>

  <!-- personnel -->
  <g>
    <rect x="40" y="110" width="300" height="210" rx="10" fill="#0e1522" stroke="#34d399"/>
    <rect x="40" y="110" width="300" height="34" rx="10" fill="#0e1522" stroke="none"/>
    <rect x="40" y="124" width="300" height="20" rx="0" fill="none"/>
    <text x="190" y="136" text-anchor="middle" font-size="13" font-weight="700" fill="#6ee7b7">personnel</text>
    <g font-size="11" fill="#cbd5e1" font-family="monospace">
      <text x="56" y="170">person_id  <tspan fill="#64748b">PK</tspan></text>
      <text x="56" y="190">name · role · employment_type</text>
      <text x="56" y="210">department · email · phone</text>
      <text x="56" y="230">enrolled_at TIMESTAMP</text>
      <text x="56" y="250">metadata_json</text>
      <text x="56" y="270">is_active BOOLEAN</text>
    </g>
  </g>

  <!-- attendance -->
  <g>
    <rect x="392" y="110" width="300" height="190" rx="10" fill="#0e1522" stroke="#22d3ee"/>
    <text x="542" y="136" text-anchor="middle" font-size="13" font-weight="700" fill="#67e8f9">attendance_log</text>
    <g font-size="11" fill="#cbd3e1" font-family="monospace">
      <text x="408" y="156">log_id PK</text>
      <text x="408" y="176">person_id FK → personnel</text>
      <text x="408" y="196">camera_id  (gate)</text>
      <text x="408" y="216">event_type: IN / OUT</text>
      <text x="408" y="236">timestamp · 30 s cooldown</text>
      <text x="408" y="256">confidence · liveness</text>
    </g>
  </g>

  <!-- productivity -->
  <g>
    <rect x="380" y="370" width="270" height="170" rx="10" fill="#0e1522" stroke="#f59e0b"/>
    <text x="515" y="396" text-anchor="middle" font-size="13" font-weight="700" fill="#fcd34d">productivity_log</text>
    <g font-size="11" fill="#cbd3e1" font-family="monospace">
      <text x="396" y="416">log_id PK · person_id</text>
      <text x="396" y="436">camera_id · state: active</text>
      <text x="396" y="456"> / idle_lazy / bunking</text>
      <text x="396" y="476"> / phone_distraction</text>
      <text x="396" y="496">timestamp · duration_s</text>
    </g>
  </g>

  <!-- health -->
  <g>
    <rect x="40" y="380" width="300" height="180" rx="10" fill="#0e1522" stroke="#fb7185"/>
    <text x="190" y="406" text-anchor="middle" font-size="13" font-weight="700" fill="#fda4af">health_log</text>
    <g font-size="11" fill="#cbd3e1" font-family="monospace">
      <text x="56" y="430">log_id PK · person_id</text>
      <text x="56" y="450">eye_stdev (drowsiness)</text>
      <text x="56" y="470">fatigue_score</text>
      <text x="56" y="490">posture: GOOD/SLOUCH</text>
      <text x="56" y="510">say_event: WARNING</text>
      <text x="56" y="530">timestamp</text>
    </g>
  </g>

  <!-- assets -->
  <g>
    <rect x="712" y="110" width="300" height="190" rx="10" fill="#0e1522" stroke="#a78bfa"/>
    <text x="862" y="136" text-anchor="middle" font-size="13" font-weight="700" fill="#c4b5fd">asset_log</text>
    <g font-size="11" fill="#cbd3e1" font-family="monospace">
      <text x="728" y="156">asset_id PK · name</text>
      <text x="728" y="176">owner person_id</text>
      <text x="728" y="196">region bbox (zone)</text>
      <text x="728" y="216">status: NORMAL /</text>
      <text x="728" y="236"> DISPLACED_MISSING</text>
      <text x="728" y="256">last_seen</text>
    </g>
  </g>

  <!-- incidents -->
  <g>
    <rect x="60" y="570" width="324" height="120" rx="10" fill="#0e1522" stroke="#fb7185"/>
    <text x="222" y="594" text-anchor="middle" font-size="13" font-weight="700" fill="#fda4af">incident_alerts</text>
    <g font-size="11" fill="#cbd3e1" font-family="monospace">
      <text x="78" y="616">alert_id PK · person_id / camera_id.</text>
      <text x="78" y="636">type UNKNOWN_FACE · THEFT_SUSPECTED</text>
      <text x="78" y="656">severity · message</text>
      <text x="78" y="676">created_at · resolved_at</text>
    </g>
  </g>

  <!-- face embeddings (chroma) -->
  <g transform="translate(740,600)">
    <rect width="480" height="98" rx="10" fill="#101720" stroke="#22d3ee"/>
    <text x="16" y="24" font-size="13" font-weight="700" fill="#67e8f9">ChromaDB · face_embeddings (vector)</text>
    <g font-size="11" fill="#cbd3e1" font-family="monospace">
      <text x="24" y="46">embedding_idPK  e.g. "EMP01::photo.jpg"</text>
      <text x="24" y="66">person_id → groups multiple photos</text>
      <text x="24" y="86">vector[n] · cosine space · metadata</text>
    </g>
  </g>

  <!-- arrows -->
  <line x1="340" y1="200" x2="398" y2="200" stroke="#64748b" stroke-width="2" marker-end="url(#arr)"/>
  <line x1="500" y1="300" x2="500" y2="368" stroke="#64748b" stroke-width="2" marker-end="url(#arr)"/>
</svg>