laudes commited on
Commit
b841990
·
verified ·
1 Parent(s): aff66f3

Upload schema.json

Browse files
Files changed (1) hide show
  1. schema.json +2039 -0
schema.json ADDED
@@ -0,0 +1,2039 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "agent_absences": {
3
+ "comment": "Records instances when agents are absent from classes",
4
+ "columns": [
5
+ {
6
+ "name": "absence_id",
7
+ "data_type": "integer",
8
+ "comment": "Unique internal absence ID"
9
+ },
10
+ {
11
+ "name": "agent_id",
12
+ "data_type": "integer",
13
+ "comment": "Reference to the absent agent"
14
+ },
15
+ {
16
+ "name": "class_id",
17
+ "data_type": "integer",
18
+ "comment": "Reference to the class affected by the absence"
19
+ },
20
+ {
21
+ "name": "absence_date",
22
+ "data_type": "date",
23
+ "comment": "Date of the agent's absence"
24
+ },
25
+ {
26
+ "name": "reported_at",
27
+ "data_type": "timestamp without time zone",
28
+ "comment": "Timestamp when the absence was reported"
29
+ },
30
+ {
31
+ "name": "reason",
32
+ "data_type": "text",
33
+ "comment": "Reason for the agent's absence"
34
+ }
35
+ ],
36
+ "foreign_keys": [
37
+ {
38
+ "column": "agent_id",
39
+ "references": {
40
+ "table": "agents",
41
+ "column": "agent_id"
42
+ }
43
+ },
44
+ {
45
+ "column": "class_id",
46
+ "references": {
47
+ "table": "classes",
48
+ "column": "class_id"
49
+ }
50
+ }
51
+ ]
52
+ },
53
+ "agent_notes": {
54
+ "comment": "Stores historical notes and remarks about agents",
55
+ "columns": [
56
+ {
57
+ "name": "note_id",
58
+ "data_type": "integer",
59
+ "comment": "Unique internal note ID"
60
+ },
61
+ {
62
+ "name": "agent_id",
63
+ "data_type": "integer",
64
+ "comment": "Reference to the agent"
65
+ },
66
+ {
67
+ "name": "note_date",
68
+ "data_type": "timestamp without time zone",
69
+ "comment": "Timestamp when the note was created"
70
+ },
71
+ {
72
+ "name": "note",
73
+ "data_type": "text",
74
+ "comment": "Content of the note regarding the agent"
75
+ }
76
+ ],
77
+ "foreign_keys": [
78
+ {
79
+ "column": "agent_id",
80
+ "references": {
81
+ "table": "agents",
82
+ "column": "agent_id"
83
+ }
84
+ }
85
+ ]
86
+ },
87
+ "agent_orders": {
88
+ "comment": "Stores order information related to agents and classes",
89
+ "columns": [
90
+ {
91
+ "name": "updated_at",
92
+ "data_type": "timestamp without time zone",
93
+ "comment": "Timestamp when the order record was last updated"
94
+ },
95
+ {
96
+ "name": "agent_id",
97
+ "data_type": "integer",
98
+ "comment": "Reference to the agent"
99
+ },
100
+ {
101
+ "name": "class_id",
102
+ "data_type": "integer",
103
+ "comment": "Reference to the class"
104
+ },
105
+ {
106
+ "name": "created_at",
107
+ "data_type": "timestamp without time zone",
108
+ "comment": "Timestamp when the order record was created"
109
+ },
110
+ {
111
+ "name": "order_id",
112
+ "data_type": "integer",
113
+ "comment": "Unique internal order ID"
114
+ },
115
+ {
116
+ "name": "class_time",
117
+ "data_type": "time without time zone",
118
+ "comment": "Time when the class is scheduled"
119
+ },
120
+ {
121
+ "name": "order_hours",
122
+ "data_type": "integer",
123
+ "comment": "Number of hours linked to the agent's order for a specific class"
124
+ },
125
+ {
126
+ "name": "order_number",
127
+ "data_type": "character varying",
128
+ "comment": "Valid order number associated with the agent"
129
+ },
130
+ {
131
+ "name": "class_days",
132
+ "data_type": "character varying",
133
+ "comment": "Days when the class is scheduled"
134
+ }
135
+ ],
136
+ "foreign_keys": [
137
+ {
138
+ "column": "agent_id",
139
+ "references": {
140
+ "table": "agents",
141
+ "column": "agent_id"
142
+ }
143
+ },
144
+ {
145
+ "column": "class_id",
146
+ "references": {
147
+ "table": "classes",
148
+ "column": "class_id"
149
+ }
150
+ }
151
+ ]
152
+ },
153
+ "agent_products": {
154
+ "comment": "Associates agents with the products they are trained to teach",
155
+ "columns": [
156
+ {
157
+ "name": "agent_id",
158
+ "data_type": "integer",
159
+ "comment": "Reference to the agent"
160
+ },
161
+ {
162
+ "name": "product_id",
163
+ "data_type": "integer",
164
+ "comment": "Reference to the product the agent is trained in"
165
+ },
166
+ {
167
+ "name": "trained_start_date",
168
+ "data_type": "date",
169
+ "comment": "Start date when the agent began training in the product"
170
+ },
171
+ {
172
+ "name": "trained_end_date",
173
+ "data_type": "date",
174
+ "comment": "End date when the agent finished training in the product"
175
+ }
176
+ ],
177
+ "foreign_keys": [
178
+ {
179
+ "column": "agent_id",
180
+ "references": {
181
+ "table": "agents",
182
+ "column": "agent_id"
183
+ }
184
+ },
185
+ {
186
+ "column": "product_id",
187
+ "references": {
188
+ "table": "products",
189
+ "column": "product_id"
190
+ }
191
+ }
192
+ ]
193
+ },
194
+ "agent_qa_visits": {
195
+ "comment": "Records QA visits involving agents and classes",
196
+ "columns": [
197
+ {
198
+ "name": "visit_id",
199
+ "data_type": "integer",
200
+ "comment": "Unique internal QA visit ID"
201
+ },
202
+ {
203
+ "name": "agent_id",
204
+ "data_type": "integer",
205
+ "comment": "Reference to the agent"
206
+ },
207
+ {
208
+ "name": "class_id",
209
+ "data_type": "integer",
210
+ "comment": "Reference to the class"
211
+ },
212
+ {
213
+ "name": "visit_date",
214
+ "data_type": "date",
215
+ "comment": "Date of the QA visit"
216
+ },
217
+ {
218
+ "name": "qa_report_id",
219
+ "data_type": "integer",
220
+ "comment": "Reference to the associated QA report"
221
+ }
222
+ ],
223
+ "foreign_keys": [
224
+ {
225
+ "column": "agent_id",
226
+ "references": {
227
+ "table": "agents",
228
+ "column": "agent_id"
229
+ }
230
+ },
231
+ {
232
+ "column": "class_id",
233
+ "references": {
234
+ "table": "classes",
235
+ "column": "class_id"
236
+ }
237
+ },
238
+ {
239
+ "column": "qa_report_id",
240
+ "references": {
241
+ "table": "qa_reports",
242
+ "column": "qa_report_id"
243
+ }
244
+ }
245
+ ]
246
+ },
247
+ "agent_replacements": {
248
+ "comment": "Records instances of agent replacements in classes",
249
+ "columns": [
250
+ {
251
+ "name": "replacement_id",
252
+ "data_type": "integer",
253
+ "comment": "Unique internal replacement ID"
254
+ },
255
+ {
256
+ "name": "class_id",
257
+ "data_type": "integer",
258
+ "comment": "Reference to the class"
259
+ },
260
+ {
261
+ "name": "original_agent_id",
262
+ "data_type": "integer",
263
+ "comment": "Reference to the original agent"
264
+ },
265
+ {
266
+ "name": "replacement_agent_id",
267
+ "data_type": "integer",
268
+ "comment": "Reference to the replacement agent"
269
+ },
270
+ {
271
+ "name": "start_date",
272
+ "data_type": "date",
273
+ "comment": "Date when the replacement starts"
274
+ },
275
+ {
276
+ "name": "end_date",
277
+ "data_type": "date",
278
+ "comment": "Date when the replacement ends"
279
+ },
280
+ {
281
+ "name": "reason",
282
+ "data_type": "text",
283
+ "comment": "Reason for the agent's replacement"
284
+ }
285
+ ],
286
+ "foreign_keys": [
287
+ {
288
+ "column": "class_id",
289
+ "references": {
290
+ "table": "classes",
291
+ "column": "class_id"
292
+ }
293
+ },
294
+ {
295
+ "column": "original_agent_id",
296
+ "references": {
297
+ "table": "agents",
298
+ "column": "agent_id"
299
+ }
300
+ },
301
+ {
302
+ "column": "replacement_agent_id",
303
+ "references": {
304
+ "table": "agents",
305
+ "column": "agent_id"
306
+ }
307
+ }
308
+ ]
309
+ },
310
+ "agents": {
311
+ "comment": "Stores information about agents (instructors or facilitators)",
312
+ "columns": [
313
+ {
314
+ "name": "updated_at",
315
+ "data_type": "timestamp without time zone",
316
+ "comment": "Timestamp when the agent record was last updated"
317
+ },
318
+ {
319
+ "name": "residential_town_id",
320
+ "data_type": "integer",
321
+ "comment": "Reference to the town where the agent lives"
322
+ },
323
+ {
324
+ "name": "preferred_working_area_1",
325
+ "data_type": "integer",
326
+ "comment": "Agent's first preferred working area"
327
+ },
328
+ {
329
+ "name": "preferred_working_area_2",
330
+ "data_type": "integer",
331
+ "comment": "Agent's second preferred working area"
332
+ },
333
+ {
334
+ "name": "preferred_working_area_3",
335
+ "data_type": "integer",
336
+ "comment": "Agent's third preferred working area"
337
+ },
338
+ {
339
+ "name": "sace_registration_date",
340
+ "data_type": "date",
341
+ "comment": "Date when the agent's SACE registration became effective"
342
+ },
343
+ {
344
+ "name": "sace_expiry_date",
345
+ "data_type": "date",
346
+ "comment": "Expiry date of the agent's provisional SACE registration"
347
+ },
348
+ {
349
+ "name": "quantum_assesment",
350
+ "data_type": "numeric",
351
+ "comment": "Agent's competence score in Communications (percentage)"
352
+ },
353
+ {
354
+ "name": "agent_training_date",
355
+ "data_type": "date",
356
+ "comment": "Date when the agent received induction training"
357
+ },
358
+ {
359
+ "name": "signed_agreement",
360
+ "data_type": "boolean",
361
+ "comment": "Indicates if the agent has a signed agreement (true) or not (false)"
362
+ },
363
+ {
364
+ "name": "signed_agreement_date",
365
+ "data_type": "date",
366
+ "comment": "Date when the agent signed the agreement"
367
+ },
368
+ {
369
+ "name": "created_at",
370
+ "data_type": "timestamp without time zone",
371
+ "comment": "Timestamp when the agent record was created"
372
+ },
373
+ {
374
+ "name": "agent_id",
375
+ "data_type": "integer",
376
+ "comment": "Unique internal agent ID"
377
+ },
378
+ {
379
+ "name": "residential_postal_code",
380
+ "data_type": "character varying",
381
+ "comment": "Postal code of the agent's residential area"
382
+ },
383
+ {
384
+ "name": "bank_branch_code",
385
+ "data_type": "character varying",
386
+ "comment": "Branch code of the agent's bank"
387
+ },
388
+ {
389
+ "name": "bank_account_number",
390
+ "data_type": "character varying",
391
+ "comment": "Agent's bank account number"
392
+ },
393
+ {
394
+ "name": "agent_notes",
395
+ "data_type": "text",
396
+ "comment": "Notes regarding the agent's performance, issues, or other relevant information"
397
+ },
398
+ {
399
+ "name": "highest_qualification",
400
+ "data_type": "character varying",
401
+ "comment": "Highest qualification the agent has achieved"
402
+ },
403
+ {
404
+ "name": "sace_registration_number",
405
+ "data_type": "character varying",
406
+ "comment": "Agent's SACE (South African Council for Educators) registration number"
407
+ },
408
+ {
409
+ "name": "first_name",
410
+ "data_type": "character varying",
411
+ "comment": "Agent's first name"
412
+ },
413
+ {
414
+ "name": "initials",
415
+ "data_type": "character varying",
416
+ "comment": "Agent's initials"
417
+ },
418
+ {
419
+ "name": "surname",
420
+ "data_type": "character varying",
421
+ "comment": "Agent's surname"
422
+ },
423
+ {
424
+ "name": "gender",
425
+ "data_type": "character varying",
426
+ "comment": "Agent's gender"
427
+ },
428
+ {
429
+ "name": "race",
430
+ "data_type": "character varying",
431
+ "comment": "Agent's race; options include 'African', 'Coloured', 'White', 'Indian'"
432
+ },
433
+ {
434
+ "name": "sa_id_no",
435
+ "data_type": "character varying",
436
+ "comment": "Agent's South African ID number"
437
+ },
438
+ {
439
+ "name": "passport_number",
440
+ "data_type": "character varying",
441
+ "comment": "Agent's passport number if they are a foreigner"
442
+ },
443
+ {
444
+ "name": "tel_number",
445
+ "data_type": "character varying",
446
+ "comment": "Agent's primary telephone number"
447
+ },
448
+ {
449
+ "name": "email_address",
450
+ "data_type": "character varying",
451
+ "comment": "Agent's email address"
452
+ },
453
+ {
454
+ "name": "residential_address_line",
455
+ "data_type": "character varying",
456
+ "comment": "Agent's residential street address"
457
+ },
458
+ {
459
+ "name": "residential_suburb",
460
+ "data_type": "character varying",
461
+ "comment": "Agent's residential suburb"
462
+ },
463
+ {
464
+ "name": "bank_name",
465
+ "data_type": "character varying",
466
+ "comment": "Name of the agent's bank"
467
+ }
468
+ ],
469
+ "foreign_keys": [
470
+ {
471
+ "column": "preferred_working_area_1",
472
+ "references": {
473
+ "table": "locations",
474
+ "column": "location_id"
475
+ }
476
+ },
477
+ {
478
+ "column": "preferred_working_area_2",
479
+ "references": {
480
+ "table": "locations",
481
+ "column": "location_id"
482
+ }
483
+ },
484
+ {
485
+ "column": "preferred_working_area_3",
486
+ "references": {
487
+ "table": "locations",
488
+ "column": "location_id"
489
+ }
490
+ },
491
+ {
492
+ "column": "residential_town_id",
493
+ "references": {
494
+ "table": "locations",
495
+ "column": "location_id"
496
+ }
497
+ }
498
+ ]
499
+ },
500
+ "attendance_records": {
501
+ "comment": "Associates learners with their attendance status on specific dates",
502
+ "columns": [
503
+ {
504
+ "name": "register_id",
505
+ "data_type": "integer",
506
+ "comment": "Reference to the attendance register"
507
+ },
508
+ {
509
+ "name": "learner_id",
510
+ "data_type": "integer",
511
+ "comment": "Reference to the learner"
512
+ },
513
+ {
514
+ "name": "status",
515
+ "data_type": "character varying",
516
+ "comment": "Attendance status of the learner (e.g., 'Present', 'Absent')"
517
+ }
518
+ ],
519
+ "foreign_keys": [
520
+ {
521
+ "column": "learner_id",
522
+ "references": {
523
+ "table": "learners",
524
+ "column": "learner_id"
525
+ }
526
+ },
527
+ {
528
+ "column": "register_id",
529
+ "references": {
530
+ "table": "attendance_registers",
531
+ "column": "register_id"
532
+ }
533
+ }
534
+ ]
535
+ },
536
+ "attendance_registers": {
537
+ "comment": "Records attendance registers for classes",
538
+ "columns": [
539
+ {
540
+ "name": "register_id",
541
+ "data_type": "integer",
542
+ "comment": "Unique internal attendance register ID"
543
+ },
544
+ {
545
+ "name": "class_id",
546
+ "data_type": "integer",
547
+ "comment": "Reference to the class"
548
+ },
549
+ {
550
+ "name": "date",
551
+ "data_type": "date",
552
+ "comment": "Date of the attendance"
553
+ },
554
+ {
555
+ "name": "agent_id",
556
+ "data_type": "integer",
557
+ "comment": "Reference to the agent who conducted the attendance"
558
+ },
559
+ {
560
+ "name": "created_at",
561
+ "data_type": "timestamp without time zone",
562
+ "comment": "Timestamp when the attendance register was created"
563
+ },
564
+ {
565
+ "name": "updated_at",
566
+ "data_type": "timestamp without time zone",
567
+ "comment": "Timestamp when the attendance register was last updated"
568
+ }
569
+ ],
570
+ "foreign_keys": [
571
+ {
572
+ "column": "agent_id",
573
+ "references": {
574
+ "table": "agents",
575
+ "column": "agent_id"
576
+ }
577
+ },
578
+ {
579
+ "column": "class_id",
580
+ "references": {
581
+ "table": "classes",
582
+ "column": "class_id"
583
+ }
584
+ }
585
+ ]
586
+ },
587
+ "class_agents": {
588
+ "comment": "Associates agents with classes they facilitate, including their roles and durations",
589
+ "columns": [
590
+ {
591
+ "name": "class_id",
592
+ "data_type": "integer",
593
+ "comment": "Reference to the class"
594
+ },
595
+ {
596
+ "name": "agent_id",
597
+ "data_type": "integer",
598
+ "comment": "Reference to the agent facilitating the class"
599
+ },
600
+ {
601
+ "name": "start_date",
602
+ "data_type": "date",
603
+ "comment": "Date when the agent started facilitating the class"
604
+ },
605
+ {
606
+ "name": "end_date",
607
+ "data_type": "date",
608
+ "comment": "Date when the agent stopped facilitating the class"
609
+ },
610
+ {
611
+ "name": "role",
612
+ "data_type": "character varying",
613
+ "comment": "Role of the agent in the class (e.g., 'Original', 'Backup', 'Replacement')"
614
+ }
615
+ ],
616
+ "foreign_keys": [
617
+ {
618
+ "column": "agent_id",
619
+ "references": {
620
+ "table": "agents",
621
+ "column": "agent_id"
622
+ }
623
+ },
624
+ {
625
+ "column": "class_id",
626
+ "references": {
627
+ "table": "classes",
628
+ "column": "class_id"
629
+ }
630
+ }
631
+ ]
632
+ },
633
+ "class_notes": {
634
+ "comment": "Stores historical notes and remarks about classes",
635
+ "columns": [
636
+ {
637
+ "name": "note_id",
638
+ "data_type": "integer",
639
+ "comment": "Unique internal note ID"
640
+ },
641
+ {
642
+ "name": "class_id",
643
+ "data_type": "integer",
644
+ "comment": "Reference to the class"
645
+ },
646
+ {
647
+ "name": "note_date",
648
+ "data_type": "timestamp without time zone",
649
+ "comment": "Timestamp when the note was created"
650
+ },
651
+ {
652
+ "name": "note",
653
+ "data_type": "text",
654
+ "comment": "Content of the note regarding the class"
655
+ }
656
+ ],
657
+ "foreign_keys": [
658
+ {
659
+ "column": "class_id",
660
+ "references": {
661
+ "table": "classes",
662
+ "column": "class_id"
663
+ }
664
+ }
665
+ ]
666
+ },
667
+ "class_schedules": {
668
+ "comment": "Stores scheduling information for classes",
669
+ "columns": [
670
+ {
671
+ "name": "schedule_id",
672
+ "data_type": "integer",
673
+ "comment": "Unique internal schedule ID"
674
+ },
675
+ {
676
+ "name": "class_id",
677
+ "data_type": "integer",
678
+ "comment": "Reference to the class"
679
+ },
680
+ {
681
+ "name": "start_time",
682
+ "data_type": "time without time zone",
683
+ "comment": "Class start time"
684
+ },
685
+ {
686
+ "name": "end_time",
687
+ "data_type": "time without time zone",
688
+ "comment": "Class end time"
689
+ },
690
+ {
691
+ "name": "day_of_week",
692
+ "data_type": "character varying",
693
+ "comment": "Day of the week when the class occurs (e.g., 'Monday')"
694
+ }
695
+ ],
696
+ "foreign_keys": [
697
+ {
698
+ "column": "class_id",
699
+ "references": {
700
+ "table": "classes",
701
+ "column": "class_id"
702
+ }
703
+ }
704
+ ]
705
+ },
706
+ "class_subjects": {
707
+ "comment": "Associates classes with the subjects or products being taught",
708
+ "columns": [
709
+ {
710
+ "name": "class_id",
711
+ "data_type": "integer",
712
+ "comment": "Reference to the class"
713
+ },
714
+ {
715
+ "name": "product_id",
716
+ "data_type": "integer",
717
+ "comment": "Reference to the subject or product taught in the class"
718
+ }
719
+ ],
720
+ "foreign_keys": [
721
+ {
722
+ "column": "class_id",
723
+ "references": {
724
+ "table": "classes",
725
+ "column": "class_id"
726
+ }
727
+ },
728
+ {
729
+ "column": "product_id",
730
+ "references": {
731
+ "table": "products",
732
+ "column": "product_id"
733
+ }
734
+ }
735
+ ]
736
+ },
737
+ "classes": {
738
+ "comment": "Stores information about classes, including scheduling and associations",
739
+ "columns": [
740
+ {
741
+ "name": "updated_at",
742
+ "data_type": "timestamp without time zone",
743
+ "comment": "Timestamp when the class record was last updated"
744
+ },
745
+ {
746
+ "name": "client_id",
747
+ "data_type": "integer",
748
+ "comment": "Reference to the client associated with the class"
749
+ },
750
+ {
751
+ "name": "stop_date",
752
+ "data_type": "date",
753
+ "comment": "Date when the class stopped"
754
+ },
755
+ {
756
+ "name": "restart_date",
757
+ "data_type": "date",
758
+ "comment": "Date when the class restarted"
759
+ },
760
+ {
761
+ "name": "seta_funded",
762
+ "data_type": "boolean",
763
+ "comment": "Indicates if the project is SETA funded (true) or not (false)"
764
+ },
765
+ {
766
+ "name": "exam_class",
767
+ "data_type": "boolean",
768
+ "comment": "Indicates if this is an exam project (true) or not (false)"
769
+ },
770
+ {
771
+ "name": "project_supervisor_id",
772
+ "data_type": "integer",
773
+ "comment": "Reference to the project supervisor managing the class"
774
+ },
775
+ {
776
+ "name": "delivery_date",
777
+ "data_type": "date",
778
+ "comment": "Date when materials or resources must be delivered to the class"
779
+ },
780
+ {
781
+ "name": "collection_date",
782
+ "data_type": "date",
783
+ "comment": "Date when portfolios or materials must be collected from the class"
784
+ },
785
+ {
786
+ "name": "created_at",
787
+ "data_type": "timestamp without time zone",
788
+ "comment": "Timestamp when the class record was created"
789
+ },
790
+ {
791
+ "name": "class_id",
792
+ "data_type": "integer",
793
+ "comment": "Unique internal class ID"
794
+ },
795
+ {
796
+ "name": "class_town_id",
797
+ "data_type": "integer",
798
+ "comment": "Reference to the town where the class takes place"
799
+ },
800
+ {
801
+ "name": "original_start_date",
802
+ "data_type": "date",
803
+ "comment": "Original start date of the class"
804
+ },
805
+ {
806
+ "name": "class_site_name",
807
+ "data_type": "character varying",
808
+ "comment": "Name of the class or site"
809
+ },
810
+ {
811
+ "name": "class_address_line",
812
+ "data_type": "character varying",
813
+ "comment": "Street address where the class takes place"
814
+ },
815
+ {
816
+ "name": "class_suburb",
817
+ "data_type": "character varying",
818
+ "comment": "Suburb where the class takes place"
819
+ },
820
+ {
821
+ "name": "class_notes",
822
+ "data_type": "text",
823
+ "comment": "Notes about the class; important information to remember"
824
+ },
825
+ {
826
+ "name": "class_postal_code",
827
+ "data_type": "character varying",
828
+ "comment": "Postal code of the class location"
829
+ },
830
+ {
831
+ "name": "class_type",
832
+ "data_type": "character varying",
833
+ "comment": "Type of class; determines the 'rules' (e.g., 'Employed', 'Community')"
834
+ },
835
+ {
836
+ "name": "class_status",
837
+ "data_type": "character varying",
838
+ "comment": "Status of the class (e.g., 'New', 'Restarted', 'Stopped')"
839
+ },
840
+ {
841
+ "name": "exam_type",
842
+ "data_type": "character varying",
843
+ "comment": "Type of exam associated with the class"
844
+ },
845
+ {
846
+ "name": "seta",
847
+ "data_type": "character varying",
848
+ "comment": "Name of the SETA (Sector Education and Training Authority) the client belongs to"
849
+ }
850
+ ],
851
+ "foreign_keys": [
852
+ {
853
+ "column": "class_town_id",
854
+ "references": {
855
+ "table": "locations",
856
+ "column": "location_id"
857
+ }
858
+ },
859
+ {
860
+ "column": "client_id",
861
+ "references": {
862
+ "table": "clients",
863
+ "column": "client_id"
864
+ }
865
+ },
866
+ {
867
+ "column": "project_supervisor_id",
868
+ "references": {
869
+ "table": "users",
870
+ "column": "user_id"
871
+ }
872
+ }
873
+ ]
874
+ },
875
+ "client_communications": {
876
+ "comment": "Stores records of communications with clients",
877
+ "columns": [
878
+ {
879
+ "name": "client_id",
880
+ "data_type": "integer",
881
+ "comment": "Reference to the client"
882
+ },
883
+ {
884
+ "name": "communication_date",
885
+ "data_type": "timestamp without time zone",
886
+ "comment": "Date and time when the communication occurred"
887
+ },
888
+ {
889
+ "name": "user_id",
890
+ "data_type": "integer",
891
+ "comment": "Reference to the user who communicated with the client"
892
+ },
893
+ {
894
+ "name": "communication_id",
895
+ "data_type": "integer",
896
+ "comment": "Unique internal communication ID"
897
+ },
898
+ {
899
+ "name": "subject",
900
+ "data_type": "character varying",
901
+ "comment": "Subject of the communication"
902
+ },
903
+ {
904
+ "name": "communication_type",
905
+ "data_type": "character varying",
906
+ "comment": "Type of communication (e.g., 'Email', 'Phone Call')"
907
+ },
908
+ {
909
+ "name": "content",
910
+ "data_type": "text",
911
+ "comment": "Content or summary of the communication"
912
+ }
913
+ ],
914
+ "foreign_keys": [
915
+ {
916
+ "column": "client_id",
917
+ "references": {
918
+ "table": "clients",
919
+ "column": "client_id"
920
+ }
921
+ },
922
+ {
923
+ "column": "user_id",
924
+ "references": {
925
+ "table": "users",
926
+ "column": "user_id"
927
+ }
928
+ }
929
+ ]
930
+ },
931
+ "client_contact_persons": {
932
+ "comment": "Stores contact person information for clients",
933
+ "columns": [
934
+ {
935
+ "name": "contact_id",
936
+ "data_type": "integer",
937
+ "comment": "Unique internal contact person ID"
938
+ },
939
+ {
940
+ "name": "client_id",
941
+ "data_type": "integer",
942
+ "comment": "Reference to the client"
943
+ },
944
+ {
945
+ "name": "first_name",
946
+ "data_type": "character varying",
947
+ "comment": "First name of the contact person"
948
+ },
949
+ {
950
+ "name": "surname",
951
+ "data_type": "character varying",
952
+ "comment": "Surname of the contact person"
953
+ },
954
+ {
955
+ "name": "email",
956
+ "data_type": "character varying",
957
+ "comment": "Email address of the contact person"
958
+ },
959
+ {
960
+ "name": "cellphone_number",
961
+ "data_type": "character varying",
962
+ "comment": "Cellphone number of the contact person"
963
+ },
964
+ {
965
+ "name": "tel_number",
966
+ "data_type": "character varying",
967
+ "comment": "Landline number of the contact person"
968
+ },
969
+ {
970
+ "name": "position",
971
+ "data_type": "character varying",
972
+ "comment": "Position or role of the contact person at the client company"
973
+ }
974
+ ],
975
+ "foreign_keys": [
976
+ {
977
+ "column": "client_id",
978
+ "references": {
979
+ "table": "clients",
980
+ "column": "client_id"
981
+ }
982
+ }
983
+ ]
984
+ },
985
+ "clients": {
986
+ "comment": "Stores information about clients (companies or organizations)",
987
+ "columns": [
988
+ {
989
+ "name": "client_id",
990
+ "data_type": "integer",
991
+ "comment": "Unique internal client ID"
992
+ },
993
+ {
994
+ "name": "branch_of",
995
+ "data_type": "integer",
996
+ "comment": "Reference to the parent client if this client is a branch"
997
+ },
998
+ {
999
+ "name": "town_id",
1000
+ "data_type": "integer",
1001
+ "comment": "Reference to the town where the client is located"
1002
+ },
1003
+ {
1004
+ "name": "financial_year_end",
1005
+ "data_type": "date",
1006
+ "comment": "Date of the client's financial year-end"
1007
+ },
1008
+ {
1009
+ "name": "bbbee_verification_date",
1010
+ "data_type": "date",
1011
+ "comment": "Date of the client's BBBEE verification"
1012
+ },
1013
+ {
1014
+ "name": "created_at",
1015
+ "data_type": "timestamp without time zone",
1016
+ "comment": "Timestamp when the client record was created"
1017
+ },
1018
+ {
1019
+ "name": "updated_at",
1020
+ "data_type": "timestamp without time zone",
1021
+ "comment": "Timestamp when the client record was last updated"
1022
+ },
1023
+ {
1024
+ "name": "postal_code",
1025
+ "data_type": "character varying",
1026
+ "comment": "Postal code of the client's location"
1027
+ },
1028
+ {
1029
+ "name": "client_name",
1030
+ "data_type": "character varying",
1031
+ "comment": "Name of the client company or organization"
1032
+ },
1033
+ {
1034
+ "name": "seta",
1035
+ "data_type": "character varying",
1036
+ "comment": "SETA the client belongs to"
1037
+ },
1038
+ {
1039
+ "name": "company_registration_number",
1040
+ "data_type": "character varying",
1041
+ "comment": "Company registration number of the client"
1042
+ },
1043
+ {
1044
+ "name": "address_line",
1045
+ "data_type": "character varying",
1046
+ "comment": "Client's street address"
1047
+ },
1048
+ {
1049
+ "name": "suburb",
1050
+ "data_type": "character varying",
1051
+ "comment": "Suburb where the client is located"
1052
+ },
1053
+ {
1054
+ "name": "client_status",
1055
+ "data_type": "character varying",
1056
+ "comment": "Current status of the client (e.g., 'Active Client', 'Lost Client')"
1057
+ }
1058
+ ],
1059
+ "foreign_keys": [
1060
+ {
1061
+ "column": "branch_of",
1062
+ "references": {
1063
+ "table": "clients",
1064
+ "column": "client_id"
1065
+ }
1066
+ },
1067
+ {
1068
+ "column": "town_id",
1069
+ "references": {
1070
+ "table": "locations",
1071
+ "column": "location_id"
1072
+ }
1073
+ }
1074
+ ]
1075
+ },
1076
+ "collections": {
1077
+ "comment": "Records collections made from classes",
1078
+ "columns": [
1079
+ {
1080
+ "name": "created_at",
1081
+ "data_type": "timestamp without time zone",
1082
+ "comment": "Timestamp when the collection record was created"
1083
+ },
1084
+ {
1085
+ "name": "updated_at",
1086
+ "data_type": "timestamp without time zone",
1087
+ "comment": "Timestamp when the collection record was last updated"
1088
+ },
1089
+ {
1090
+ "name": "collection_date",
1091
+ "data_type": "date",
1092
+ "comment": "Date when the collection is scheduled or occurred"
1093
+ },
1094
+ {
1095
+ "name": "collection_id",
1096
+ "data_type": "integer",
1097
+ "comment": "Unique internal collection ID"
1098
+ },
1099
+ {
1100
+ "name": "class_id",
1101
+ "data_type": "integer",
1102
+ "comment": "Reference to the class"
1103
+ },
1104
+ {
1105
+ "name": "items",
1106
+ "data_type": "text",
1107
+ "comment": "Items collected from the class"
1108
+ },
1109
+ {
1110
+ "name": "status",
1111
+ "data_type": "character varying",
1112
+ "comment": "Collection status (e.g., 'Pending', 'Collected')"
1113
+ }
1114
+ ],
1115
+ "foreign_keys": [
1116
+ {
1117
+ "column": "class_id",
1118
+ "references": {
1119
+ "table": "classes",
1120
+ "column": "class_id"
1121
+ }
1122
+ }
1123
+ ]
1124
+ },
1125
+ "deliveries": {
1126
+ "comment": "Records deliveries made to classes",
1127
+ "columns": [
1128
+ {
1129
+ "name": "created_at",
1130
+ "data_type": "timestamp without time zone",
1131
+ "comment": "Timestamp when the delivery record was created"
1132
+ },
1133
+ {
1134
+ "name": "updated_at",
1135
+ "data_type": "timestamp without time zone",
1136
+ "comment": "Timestamp when the delivery record was last updated"
1137
+ },
1138
+ {
1139
+ "name": "delivery_date",
1140
+ "data_type": "date",
1141
+ "comment": "Date when the delivery is scheduled or occurred"
1142
+ },
1143
+ {
1144
+ "name": "delivery_id",
1145
+ "data_type": "integer",
1146
+ "comment": "Unique internal delivery ID"
1147
+ },
1148
+ {
1149
+ "name": "class_id",
1150
+ "data_type": "integer",
1151
+ "comment": "Reference to the class"
1152
+ },
1153
+ {
1154
+ "name": "items",
1155
+ "data_type": "text",
1156
+ "comment": "Items included in the delivery"
1157
+ },
1158
+ {
1159
+ "name": "status",
1160
+ "data_type": "character varying",
1161
+ "comment": "Delivery status (e.g., 'Pending', 'Delivered')"
1162
+ }
1163
+ ],
1164
+ "foreign_keys": [
1165
+ {
1166
+ "column": "class_id",
1167
+ "references": {
1168
+ "table": "classes",
1169
+ "column": "class_id"
1170
+ }
1171
+ }
1172
+ ]
1173
+ },
1174
+ "employers": {
1175
+ "comment": "Stores information about employers or sponsors of learners",
1176
+ "columns": [
1177
+ {
1178
+ "name": "employer_id",
1179
+ "data_type": "integer",
1180
+ "comment": "Unique internal employer ID"
1181
+ },
1182
+ {
1183
+ "name": "created_at",
1184
+ "data_type": "timestamp without time zone",
1185
+ "comment": "Timestamp when the employer record was created"
1186
+ },
1187
+ {
1188
+ "name": "updated_at",
1189
+ "data_type": "timestamp without time zone",
1190
+ "comment": "Timestamp when the employer record was last updated"
1191
+ },
1192
+ {
1193
+ "name": "employer_name",
1194
+ "data_type": "character varying",
1195
+ "comment": "Name of the employer or sponsoring organization"
1196
+ }
1197
+ ],
1198
+ "foreign_keys": []
1199
+ },
1200
+ "exam_results": {
1201
+ "comment": "Stores detailed exam results for learners",
1202
+ "columns": [
1203
+ {
1204
+ "name": "updated_at",
1205
+ "data_type": "timestamp without time zone",
1206
+ "comment": "Timestamp when the exam result was last updated"
1207
+ },
1208
+ {
1209
+ "name": "exam_id",
1210
+ "data_type": "integer",
1211
+ "comment": "Reference to the exam"
1212
+ },
1213
+ {
1214
+ "name": "learner_id",
1215
+ "data_type": "integer",
1216
+ "comment": "Reference to the learner"
1217
+ },
1218
+ {
1219
+ "name": "created_at",
1220
+ "data_type": "timestamp without time zone",
1221
+ "comment": "Timestamp when the exam result was created"
1222
+ },
1223
+ {
1224
+ "name": "result_id",
1225
+ "data_type": "integer",
1226
+ "comment": "Unique internal exam result ID"
1227
+ },
1228
+ {
1229
+ "name": "mock_exam_number",
1230
+ "data_type": "integer",
1231
+ "comment": "Number of the mock exam (e.g., 1, 2, 3)"
1232
+ },
1233
+ {
1234
+ "name": "score",
1235
+ "data_type": "numeric",
1236
+ "comment": "Learner's score in the exam"
1237
+ },
1238
+ {
1239
+ "name": "exam_date",
1240
+ "data_type": "date",
1241
+ "comment": "Date when the exam was taken"
1242
+ },
1243
+ {
1244
+ "name": "subject",
1245
+ "data_type": "character varying",
1246
+ "comment": "Subject of the exam"
1247
+ },
1248
+ {
1249
+ "name": "result",
1250
+ "data_type": "character varying",
1251
+ "comment": "Exam result (e.g., 'Pass', 'Fail')"
1252
+ }
1253
+ ],
1254
+ "foreign_keys": [
1255
+ {
1256
+ "column": "exam_id",
1257
+ "references": {
1258
+ "table": "exams",
1259
+ "column": "exam_id"
1260
+ }
1261
+ },
1262
+ {
1263
+ "column": "learner_id",
1264
+ "references": {
1265
+ "table": "learners",
1266
+ "column": "learner_id"
1267
+ }
1268
+ }
1269
+ ]
1270
+ },
1271
+ "exams": {
1272
+ "comment": "Stores exam results for learners",
1273
+ "columns": [
1274
+ {
1275
+ "name": "exam_id",
1276
+ "data_type": "integer",
1277
+ "comment": "Unique internal exam ID"
1278
+ },
1279
+ {
1280
+ "name": "learner_id",
1281
+ "data_type": "integer",
1282
+ "comment": "Reference to the learner"
1283
+ },
1284
+ {
1285
+ "name": "product_id",
1286
+ "data_type": "integer",
1287
+ "comment": "Reference to the product or subject"
1288
+ },
1289
+ {
1290
+ "name": "exam_date",
1291
+ "data_type": "date",
1292
+ "comment": "Date when the exam was taken"
1293
+ },
1294
+ {
1295
+ "name": "created_at",
1296
+ "data_type": "timestamp without time zone",
1297
+ "comment": "Timestamp when the exam record was created"
1298
+ },
1299
+ {
1300
+ "name": "updated_at",
1301
+ "data_type": "timestamp without time zone",
1302
+ "comment": "Timestamp when the exam record was last updated"
1303
+ },
1304
+ {
1305
+ "name": "score",
1306
+ "data_type": "numeric",
1307
+ "comment": "Learner's score in the exam"
1308
+ },
1309
+ {
1310
+ "name": "exam_type",
1311
+ "data_type": "character varying",
1312
+ "comment": "Type of exam (e.g., 'Mock', 'Final')"
1313
+ },
1314
+ {
1315
+ "name": "result",
1316
+ "data_type": "character varying",
1317
+ "comment": "Exam result (e.g., 'Pass', 'Fail')"
1318
+ }
1319
+ ],
1320
+ "foreign_keys": [
1321
+ {
1322
+ "column": "learner_id",
1323
+ "references": {
1324
+ "table": "learners",
1325
+ "column": "learner_id"
1326
+ }
1327
+ },
1328
+ {
1329
+ "column": "product_id",
1330
+ "references": {
1331
+ "table": "products",
1332
+ "column": "product_id"
1333
+ }
1334
+ }
1335
+ ]
1336
+ },
1337
+ "files": {
1338
+ "comment": "Stores references to files associated with various entities",
1339
+ "columns": [
1340
+ {
1341
+ "name": "file_id",
1342
+ "data_type": "integer",
1343
+ "comment": "Unique internal file ID"
1344
+ },
1345
+ {
1346
+ "name": "owner_id",
1347
+ "data_type": "integer",
1348
+ "comment": "ID of the owner entity"
1349
+ },
1350
+ {
1351
+ "name": "uploaded_at",
1352
+ "data_type": "timestamp without time zone",
1353
+ "comment": "Timestamp when the file was uploaded"
1354
+ },
1355
+ {
1356
+ "name": "owner_type",
1357
+ "data_type": "character varying",
1358
+ "comment": "Type of entity that owns the file (e.g., 'Learner', 'Class', 'Agent')"
1359
+ },
1360
+ {
1361
+ "name": "file_path",
1362
+ "data_type": "character varying",
1363
+ "comment": "File path or URL to the stored file"
1364
+ },
1365
+ {
1366
+ "name": "file_type",
1367
+ "data_type": "character varying",
1368
+ "comment": "Type of file (e.g., 'Scanned Portfolio', 'QA Report')"
1369
+ }
1370
+ ],
1371
+ "foreign_keys": []
1372
+ },
1373
+ "history": {
1374
+ "comment": "Records historical changes and actions performed on entities",
1375
+ "columns": [
1376
+ {
1377
+ "name": "action_date",
1378
+ "data_type": "timestamp without time zone",
1379
+ "comment": "Timestamp when the action occurred"
1380
+ },
1381
+ {
1382
+ "name": "user_id",
1383
+ "data_type": "integer",
1384
+ "comment": "Reference to the user who performed the action"
1385
+ },
1386
+ {
1387
+ "name": "entity_id",
1388
+ "data_type": "integer",
1389
+ "comment": "ID of the entity"
1390
+ },
1391
+ {
1392
+ "name": "history_id",
1393
+ "data_type": "integer",
1394
+ "comment": "Unique internal history ID"
1395
+ },
1396
+ {
1397
+ "name": "changes",
1398
+ "data_type": "jsonb",
1399
+ "comment": "Details of the changes made, stored in JSON format"
1400
+ },
1401
+ {
1402
+ "name": "action",
1403
+ "data_type": "character varying",
1404
+ "comment": "Type of action performed (e.g., 'Created', 'Updated', 'Deleted')"
1405
+ },
1406
+ {
1407
+ "name": "entity_type",
1408
+ "data_type": "character varying",
1409
+ "comment": "Type of entity the history record refers to (e.g., 'Learner', 'Agent', 'Class')"
1410
+ }
1411
+ ],
1412
+ "foreign_keys": [
1413
+ {
1414
+ "column": "user_id",
1415
+ "references": {
1416
+ "table": "users",
1417
+ "column": "user_id"
1418
+ }
1419
+ }
1420
+ ]
1421
+ },
1422
+ "learner_products": {
1423
+ "comment": "Associates learners with the products they are enrolled in",
1424
+ "columns": [
1425
+ {
1426
+ "name": "learner_id",
1427
+ "data_type": "integer",
1428
+ "comment": "Reference to the learner"
1429
+ },
1430
+ {
1431
+ "name": "product_id",
1432
+ "data_type": "integer",
1433
+ "comment": "Reference to the product the learner is enrolled in"
1434
+ },
1435
+ {
1436
+ "name": "start_date",
1437
+ "data_type": "date",
1438
+ "comment": "Start date of the learner's enrollment in the product"
1439
+ },
1440
+ {
1441
+ "name": "end_date",
1442
+ "data_type": "date",
1443
+ "comment": "End date of the learner's enrollment in the product"
1444
+ }
1445
+ ],
1446
+ "foreign_keys": [
1447
+ {
1448
+ "column": "learner_id",
1449
+ "references": {
1450
+ "table": "learners",
1451
+ "column": "learner_id"
1452
+ }
1453
+ },
1454
+ {
1455
+ "column": "product_id",
1456
+ "references": {
1457
+ "table": "products",
1458
+ "column": "product_id"
1459
+ }
1460
+ }
1461
+ ]
1462
+ },
1463
+ "learner_progressions": {
1464
+ "comment": "Tracks the progression of learners between products",
1465
+ "columns": [
1466
+ {
1467
+ "name": "progression_id",
1468
+ "data_type": "integer",
1469
+ "comment": "Unique internal progression ID"
1470
+ },
1471
+ {
1472
+ "name": "learner_id",
1473
+ "data_type": "integer",
1474
+ "comment": "Reference to the learner"
1475
+ },
1476
+ {
1477
+ "name": "from_product_id",
1478
+ "data_type": "integer",
1479
+ "comment": "Reference to the initial product"
1480
+ },
1481
+ {
1482
+ "name": "to_product_id",
1483
+ "data_type": "integer",
1484
+ "comment": "Reference to the new product after progression"
1485
+ },
1486
+ {
1487
+ "name": "progression_date",
1488
+ "data_type": "date",
1489
+ "comment": "Date when the learner progressed to the new product"
1490
+ },
1491
+ {
1492
+ "name": "notes",
1493
+ "data_type": "text",
1494
+ "comment": "Additional notes regarding the progression"
1495
+ }
1496
+ ],
1497
+ "foreign_keys": [
1498
+ {
1499
+ "column": "from_product_id",
1500
+ "references": {
1501
+ "table": "products",
1502
+ "column": "product_id"
1503
+ }
1504
+ },
1505
+ {
1506
+ "column": "learner_id",
1507
+ "references": {
1508
+ "table": "learners",
1509
+ "column": "learner_id"
1510
+ }
1511
+ },
1512
+ {
1513
+ "column": "to_product_id",
1514
+ "references": {
1515
+ "table": "products",
1516
+ "column": "product_id"
1517
+ }
1518
+ }
1519
+ ]
1520
+ },
1521
+ "learners": {
1522
+ "comment": "Stores personal, educational, and assessment information about learners",
1523
+ "columns": [
1524
+ {
1525
+ "name": "updated_at",
1526
+ "data_type": "timestamp without time zone",
1527
+ "comment": "Timestamp when the learner record was last updated"
1528
+ },
1529
+ {
1530
+ "name": "city_town_id",
1531
+ "data_type": "integer",
1532
+ "comment": "Reference to the city or town where the learner lives"
1533
+ },
1534
+ {
1535
+ "name": "province_region_id",
1536
+ "data_type": "integer",
1537
+ "comment": "Reference to the province/region where the learner lives"
1538
+ },
1539
+ {
1540
+ "name": "placement_assessment_date",
1541
+ "data_type": "date",
1542
+ "comment": "Date when the learner took the placement assessment"
1543
+ },
1544
+ {
1545
+ "name": "employment_status",
1546
+ "data_type": "boolean",
1547
+ "comment": "Indicates if the learner is employed (true) or not (false)"
1548
+ },
1549
+ {
1550
+ "name": "employer_id",
1551
+ "data_type": "integer",
1552
+ "comment": "Reference to the learner's employer or sponsor"
1553
+ },
1554
+ {
1555
+ "name": "disability_status",
1556
+ "data_type": "boolean",
1557
+ "comment": "Indicates if the learner has a disability (true) or not (false)"
1558
+ },
1559
+ {
1560
+ "name": "created_at",
1561
+ "data_type": "timestamp without time zone",
1562
+ "comment": "Timestamp when the learner record was created"
1563
+ },
1564
+ {
1565
+ "name": "learner_id",
1566
+ "data_type": "integer",
1567
+ "comment": "Unique internal learner ID"
1568
+ },
1569
+ {
1570
+ "name": "alternative_tel_number",
1571
+ "data_type": "character varying",
1572
+ "comment": "Learner's alternative contact number"
1573
+ },
1574
+ {
1575
+ "name": "email_address",
1576
+ "data_type": "character varying",
1577
+ "comment": "Learner's email address"
1578
+ },
1579
+ {
1580
+ "name": "address_line_1",
1581
+ "data_type": "character varying",
1582
+ "comment": "First line of learner's physical address"
1583
+ },
1584
+ {
1585
+ "name": "address_line_2",
1586
+ "data_type": "character varying",
1587
+ "comment": "Second line of learner's physical address"
1588
+ },
1589
+ {
1590
+ "name": "scanned_portfolio",
1591
+ "data_type": "character varying",
1592
+ "comment": "File path or URL to the learner's scanned portfolio in PDF format"
1593
+ },
1594
+ {
1595
+ "name": "placement_level",
1596
+ "data_type": "character varying",
1597
+ "comment": "Learner's initial placement level in Communications (e.g., 'CL1b', 'CL1', 'CL2')"
1598
+ },
1599
+ {
1600
+ "name": "postal_code",
1601
+ "data_type": "character varying",
1602
+ "comment": "Postal code of the learner's area"
1603
+ },
1604
+ {
1605
+ "name": "highest_qualification",
1606
+ "data_type": "character varying",
1607
+ "comment": "Highest qualification the learner has achieved"
1608
+ },
1609
+ {
1610
+ "name": "assessment_status",
1611
+ "data_type": "character varying",
1612
+ "comment": "Assessment status; indicates if the learner was assessed ('Assessed', 'Not Assessed')"
1613
+ },
1614
+ {
1615
+ "name": "first_name",
1616
+ "data_type": "character varying",
1617
+ "comment": "Learner's first name"
1618
+ },
1619
+ {
1620
+ "name": "initials",
1621
+ "data_type": "character varying",
1622
+ "comment": "Learner's initials"
1623
+ },
1624
+ {
1625
+ "name": "surname",
1626
+ "data_type": "character varying",
1627
+ "comment": "Learner's surname"
1628
+ },
1629
+ {
1630
+ "name": "gender",
1631
+ "data_type": "character varying",
1632
+ "comment": "Learner's gender"
1633
+ },
1634
+ {
1635
+ "name": "race",
1636
+ "data_type": "character varying",
1637
+ "comment": "Learner's race; options include 'African', 'Coloured', 'White', 'Indian'"
1638
+ },
1639
+ {
1640
+ "name": "sa_id_no",
1641
+ "data_type": "character varying",
1642
+ "comment": "Learner's South African ID number"
1643
+ },
1644
+ {
1645
+ "name": "passport_number",
1646
+ "data_type": "character varying",
1647
+ "comment": "Learner's passport number if they are a foreigner"
1648
+ },
1649
+ {
1650
+ "name": "tel_number",
1651
+ "data_type": "character varying",
1652
+ "comment": "Learner's primary telephone number"
1653
+ }
1654
+ ],
1655
+ "foreign_keys": [
1656
+ {
1657
+ "column": "city_town_id",
1658
+ "references": {
1659
+ "table": "locations",
1660
+ "column": "location_id"
1661
+ }
1662
+ },
1663
+ {
1664
+ "column": "employer_id",
1665
+ "references": {
1666
+ "table": "employers",
1667
+ "column": "employer_id"
1668
+ }
1669
+ },
1670
+ {
1671
+ "column": "province_region_id",
1672
+ "references": {
1673
+ "table": "locations",
1674
+ "column": "location_id"
1675
+ }
1676
+ }
1677
+ ]
1678
+ },
1679
+ "locations": {
1680
+ "comment": "Stores geographical location data for addresses",
1681
+ "columns": [
1682
+ {
1683
+ "name": "location_id",
1684
+ "data_type": "integer",
1685
+ "comment": "Unique internal location ID"
1686
+ },
1687
+ {
1688
+ "name": "longitude",
1689
+ "data_type": "numeric",
1690
+ "comment": "Geographical longitude coordinate"
1691
+ },
1692
+ {
1693
+ "name": "latitude",
1694
+ "data_type": "numeric",
1695
+ "comment": "Geographical latitude coordinate"
1696
+ },
1697
+ {
1698
+ "name": "created_at",
1699
+ "data_type": "timestamp without time zone",
1700
+ "comment": "Timestamp when the location record was created"
1701
+ },
1702
+ {
1703
+ "name": "updated_at",
1704
+ "data_type": "timestamp without time zone",
1705
+ "comment": "Timestamp when the location record was last updated"
1706
+ },
1707
+ {
1708
+ "name": "suburb",
1709
+ "data_type": "character varying",
1710
+ "comment": "Suburb name"
1711
+ },
1712
+ {
1713
+ "name": "town",
1714
+ "data_type": "character varying",
1715
+ "comment": "Town name"
1716
+ },
1717
+ {
1718
+ "name": "province",
1719
+ "data_type": "character varying",
1720
+ "comment": "Province name"
1721
+ },
1722
+ {
1723
+ "name": "postal_code",
1724
+ "data_type": "character varying",
1725
+ "comment": "Postal code"
1726
+ }
1727
+ ],
1728
+ "foreign_keys": []
1729
+ },
1730
+ "products": {
1731
+ "comment": "Stores information about educational products or courses",
1732
+ "columns": [
1733
+ {
1734
+ "name": "product_id",
1735
+ "data_type": "integer",
1736
+ "comment": "Unique internal product ID"
1737
+ },
1738
+ {
1739
+ "name": "product_duration",
1740
+ "data_type": "integer",
1741
+ "comment": "Total duration of the product in hours"
1742
+ },
1743
+ {
1744
+ "name": "learning_area_duration",
1745
+ "data_type": "integer",
1746
+ "comment": "Duration of each learning area in hours"
1747
+ },
1748
+ {
1749
+ "name": "parent_product_id",
1750
+ "data_type": "integer",
1751
+ "comment": "Reference to a parent product for hierarchical structuring"
1752
+ },
1753
+ {
1754
+ "name": "created_at",
1755
+ "data_type": "timestamp without time zone",
1756
+ "comment": "Timestamp when the product record was created"
1757
+ },
1758
+ {
1759
+ "name": "updated_at",
1760
+ "data_type": "timestamp without time zone",
1761
+ "comment": "Timestamp when the product record was last updated"
1762
+ },
1763
+ {
1764
+ "name": "product_notes",
1765
+ "data_type": "text",
1766
+ "comment": "Notes or additional information about the product"
1767
+ },
1768
+ {
1769
+ "name": "product_name",
1770
+ "data_type": "character varying",
1771
+ "comment": "Name of the product or course"
1772
+ },
1773
+ {
1774
+ "name": "product_rules",
1775
+ "data_type": "text",
1776
+ "comment": "Rules or guidelines associated with the product"
1777
+ },
1778
+ {
1779
+ "name": "learning_area",
1780
+ "data_type": "character varying",
1781
+ "comment": "Learning areas covered by the product (e.g., 'Communication', 'Numeracy')"
1782
+ },
1783
+ {
1784
+ "name": "product_flags",
1785
+ "data_type": "text",
1786
+ "comment": "Flags or alerts for the product (e.g., attendance thresholds)"
1787
+ },
1788
+ {
1789
+ "name": "reporting_structure",
1790
+ "data_type": "text",
1791
+ "comment": "Structure of progress reports for the product"
1792
+ }
1793
+ ],
1794
+ "foreign_keys": [
1795
+ {
1796
+ "column": "parent_product_id",
1797
+ "references": {
1798
+ "table": "products",
1799
+ "column": "product_id"
1800
+ }
1801
+ }
1802
+ ]
1803
+ },
1804
+ "progress_reports": {
1805
+ "comment": "Stores progress reports for learners in specific classes and products",
1806
+ "columns": [
1807
+ {
1808
+ "name": "updated_at",
1809
+ "data_type": "timestamp without time zone",
1810
+ "comment": "Timestamp when the progress report was last updated"
1811
+ },
1812
+ {
1813
+ "name": "class_id",
1814
+ "data_type": "integer",
1815
+ "comment": "Reference to the class"
1816
+ },
1817
+ {
1818
+ "name": "learner_id",
1819
+ "data_type": "integer",
1820
+ "comment": "Reference to the learner"
1821
+ },
1822
+ {
1823
+ "name": "product_id",
1824
+ "data_type": "integer",
1825
+ "comment": "Reference to the product or subject"
1826
+ },
1827
+ {
1828
+ "name": "progress_percentage",
1829
+ "data_type": "numeric",
1830
+ "comment": "Learner's progress percentage in the product"
1831
+ },
1832
+ {
1833
+ "name": "report_date",
1834
+ "data_type": "date",
1835
+ "comment": "Date when the progress report was generated"
1836
+ },
1837
+ {
1838
+ "name": "report_id",
1839
+ "data_type": "integer",
1840
+ "comment": "Unique internal progress report ID"
1841
+ },
1842
+ {
1843
+ "name": "created_at",
1844
+ "data_type": "timestamp without time zone",
1845
+ "comment": "Timestamp when the progress report was created"
1846
+ },
1847
+ {
1848
+ "name": "remarks",
1849
+ "data_type": "text",
1850
+ "comment": "Additional remarks or comments"
1851
+ }
1852
+ ],
1853
+ "foreign_keys": [
1854
+ {
1855
+ "column": "class_id",
1856
+ "references": {
1857
+ "table": "classes",
1858
+ "column": "class_id"
1859
+ }
1860
+ },
1861
+ {
1862
+ "column": "learner_id",
1863
+ "references": {
1864
+ "table": "learners",
1865
+ "column": "learner_id"
1866
+ }
1867
+ },
1868
+ {
1869
+ "column": "product_id",
1870
+ "references": {
1871
+ "table": "products",
1872
+ "column": "product_id"
1873
+ }
1874
+ }
1875
+ ]
1876
+ },
1877
+ "qa_reports": {
1878
+ "comment": "Stores QA (Quality Assurance) reports for classes and agents",
1879
+ "columns": [
1880
+ {
1881
+ "name": "qa_report_id",
1882
+ "data_type": "integer",
1883
+ "comment": "Unique internal QA report ID"
1884
+ },
1885
+ {
1886
+ "name": "class_id",
1887
+ "data_type": "integer",
1888
+ "comment": "Reference to the class"
1889
+ },
1890
+ {
1891
+ "name": "agent_id",
1892
+ "data_type": "integer",
1893
+ "comment": "Reference to the agent"
1894
+ },
1895
+ {
1896
+ "name": "report_date",
1897
+ "data_type": "date",
1898
+ "comment": "Date when the QA report was created"
1899
+ },
1900
+ {
1901
+ "name": "created_at",
1902
+ "data_type": "timestamp without time zone",
1903
+ "comment": "Timestamp when the QA report was created"
1904
+ },
1905
+ {
1906
+ "name": "updated_at",
1907
+ "data_type": "timestamp without time zone",
1908
+ "comment": "Timestamp when the QA report was last updated"
1909
+ },
1910
+ {
1911
+ "name": "report_file",
1912
+ "data_type": "character varying",
1913
+ "comment": "File path or URL to the QA report"
1914
+ },
1915
+ {
1916
+ "name": "notes",
1917
+ "data_type": "text",
1918
+ "comment": "Additional notes or observations from the QA report"
1919
+ }
1920
+ ],
1921
+ "foreign_keys": [
1922
+ {
1923
+ "column": "agent_id",
1924
+ "references": {
1925
+ "table": "agents",
1926
+ "column": "agent_id"
1927
+ }
1928
+ },
1929
+ {
1930
+ "column": "class_id",
1931
+ "references": {
1932
+ "table": "classes",
1933
+ "column": "class_id"
1934
+ }
1935
+ }
1936
+ ]
1937
+ },
1938
+ "user_permissions": {
1939
+ "comment": "Grants specific permissions to users",
1940
+ "columns": [
1941
+ {
1942
+ "name": "permission_id",
1943
+ "data_type": "integer",
1944
+ "comment": "Unique internal permission ID"
1945
+ },
1946
+ {
1947
+ "name": "user_id",
1948
+ "data_type": "integer",
1949
+ "comment": "Reference to the user"
1950
+ },
1951
+ {
1952
+ "name": "permission",
1953
+ "data_type": "character varying",
1954
+ "comment": "Specific permission granted to the user"
1955
+ }
1956
+ ],
1957
+ "foreign_keys": [
1958
+ {
1959
+ "column": "user_id",
1960
+ "references": {
1961
+ "table": "users",
1962
+ "column": "user_id"
1963
+ }
1964
+ }
1965
+ ]
1966
+ },
1967
+ "user_roles": {
1968
+ "comment": "Defines roles and associated permissions for users",
1969
+ "columns": [
1970
+ {
1971
+ "name": "role_id",
1972
+ "data_type": "integer",
1973
+ "comment": "Unique internal role ID"
1974
+ },
1975
+ {
1976
+ "name": "permissions",
1977
+ "data_type": "jsonb",
1978
+ "comment": "Permissions associated with the role, stored in JSON format"
1979
+ },
1980
+ {
1981
+ "name": "role_name",
1982
+ "data_type": "character varying",
1983
+ "comment": "Name of the role (e.g., 'Admin', 'Project Supervisor')"
1984
+ }
1985
+ ],
1986
+ "foreign_keys": []
1987
+ },
1988
+ "users": {
1989
+ "comment": "Stores system user information",
1990
+ "columns": [
1991
+ {
1992
+ "name": "user_id",
1993
+ "data_type": "integer",
1994
+ "comment": "Unique internal user ID"
1995
+ },
1996
+ {
1997
+ "name": "created_at",
1998
+ "data_type": "timestamp without time zone",
1999
+ "comment": "Timestamp when the user record was created"
2000
+ },
2001
+ {
2002
+ "name": "updated_at",
2003
+ "data_type": "timestamp without time zone",
2004
+ "comment": "Timestamp when the user record was last updated"
2005
+ },
2006
+ {
2007
+ "name": "email",
2008
+ "data_type": "character varying",
2009
+ "comment": "User's email address"
2010
+ },
2011
+ {
2012
+ "name": "cellphone_number",
2013
+ "data_type": "character varying",
2014
+ "comment": "User's cellphone number"
2015
+ },
2016
+ {
2017
+ "name": "role",
2018
+ "data_type": "character varying",
2019
+ "comment": "User's role in the system, e.g., 'Admin', 'Project Supervisor'"
2020
+ },
2021
+ {
2022
+ "name": "password_hash",
2023
+ "data_type": "character varying",
2024
+ "comment": "Hashed password for user authentication"
2025
+ },
2026
+ {
2027
+ "name": "first_name",
2028
+ "data_type": "character varying",
2029
+ "comment": "User's first name"
2030
+ },
2031
+ {
2032
+ "name": "surname",
2033
+ "data_type": "character varying",
2034
+ "comment": "User's surname"
2035
+ }
2036
+ ],
2037
+ "foreign_keys": []
2038
+ }
2039
+ }