81 | | User {user_id} (алтернативен {email}); Elements {element_id} (алтернативен {symbol}); LabEquipment {equipment_id} (алтернативен {equipment_name}); Reaction {reaction_id} (алтернативно тројката (e1,e2,conditions)); Experiment {experiment_id}; лог табели со композитни PK: {user_id,experiment_id}, {user_id,element_id}, {user_id,equipment_id}, {experiment_id,equipment_id}. |
| 85 | User {user_id} (алтернативен {email}); |
| 86 | Elements {element_id} (алтернативен {symbol}); |
| 87 | LabEquipment {equipment_id} (алтернативен {equipment_name}); |
| 88 | Reaction {reaction_id} (алтернативно тројката (e1,e2,conditions)); |
| 89 | Experiment {experiment_id}; |
| 90 | лог табели со композитни PK: {user_id,experiment_id}, {user_id,element_id}, {user_id,equipment_id}, {experiment_id,equipment_id}. |
| 121 | **Главен клуч за целата мега-релација R** |
| 122 | |
| 123 | Во мега-релација се измешани повеќе домени (корисници, елементи, опрема, реакции, експерименти и логови). За да има една композитна множина што „ги покрива“ сите атрибути во R, земаме детерминанти кои ги активираат сите делови од R: |
| 124 | |
| 125 | GK = { user_id, reaction_id, experiment_id, element_id, equipment_id } |
| 126 | |
| 127 | |
| 128 | |
| 129 | |
| 130 | Зошто ова работи: |
| 131 | |
| 132 | Од reaction_id добиваме: element1_id, element2_id, product, conditions, r_teacher_id. |
| 133 | |
| 134 | Од experiment_id добиваме: reaction_fk (→ ист како reaction_id на реакцијата), result, safety_warning, time_stamp, e_teacher_id. |
| 135 | |
| 136 | Од user_id + experiment_id одредуваме participation_timestamp (UPE). |
| 137 | |
| 138 | Од user_id + element_id одредуваме viewed_at_el (UVE). |
| 139 | |
| 140 | Од user_id + equipment_id одредуваме viewed_at_eq (UVL). |
| 141 | |
| 142 | Од experiment_id + equipment_id ја фиксираме N:M табелата ExperimentLabEquipment. |
| 143 | |
| 144 | Од element_id ги добиваме сите својства на елементот (+ кој наставник го креирал). |
| 145 | |
| 146 | Од equipment_id ги добиваме сите својства на опремата (+ кој наставник ја внел). |
| 147 | |
| 148 | Од user_id ги добиваме податоците за корисникот (име/улога/мејл/лозинка-хеш). |
| 149 | |
| 150 | Со ова, GK⁺ го опфаќа целиот атрибутски простор на R. Oд оваа множина на клучеви можеме логички да стигнеме до сите атрибути во R. |
| 151 | |
| 152 | |
| 153 | |
| 154 | **Зошто овие функционалности постојат и како се штитат со модел/ограничувања** |
| 155 | |
| 156 | 1. **Најава/улоги** – безбедност и права |
| 157 | |
| 158 | Зошто: наставник ≠ студент (внес vs. учество). |
| 159 | |
| 160 | Како: User.role, middleware require_login(role), email UNIQUE, хеш-пасворд. |
| 161 | |
| 162 | 2. **Студент → наставник** – менторирање и филтрирање извештаи |
| 163 | |
| 164 | Зошто: наставник следи „свои“ студенти. |
| 165 | |
| 166 | Како: Student(student_id, teacher_id); извештаи филтрираат по teacher_id. |
| 167 | |
| 168 | 3. **Eлементи/опрема** – единствена вистина и безбедност |
| 169 | |
| 170 | Зошто: реакции и експерименти се градат врз точни податоци; безбедносни белешки. |
| 171 | |
| 172 | Како: symbol UNIQUE, equipment_name UNIQUE, физички CHECK-ови. |
| 173 | |
| 174 | 4. **Реакции – научна конзистентност** |
| 175 | |
| 176 | Зошто: за исти елементи и исти услови → ист производ. |
| 177 | |
| 178 | Како: UNIQUE(element1_id,element2_id,COALESCE(conditions,'')), CHECK(element1_id<>element2_id). |
| 179 | |
| 180 | 5. **Експерименти – педагошка трага и репродуцибилност** |
| 181 | |
| 182 | Зошто: резултат, време, безбедност; логика за „последен експеримент по реакција“. |
| 183 | |
| 184 | Како: FK кон Reaction, тригер за safety_warning, индекс (reaction_id, time_stamp DESC). |
| 185 | |
| 186 | 6. **Учество/Прегледи (логови)** – оцена, активност, анализа |
| 187 | |
| 188 | Зошто: кој учествувал, што читале студентите (безбедносна документација). |
| 189 | |
| 190 | Како: композитни PK во лог-табелите; индекси по user_id и време. |
| 191 | |
| 192 | 7. **Опрема по експеримент (N:M)** – точна документација на ресурси |
| 193 | |
| 194 | Зошто: репродуцибилност и планирање ресурси. |
| 195 | |
| 196 | Како: ExperimentLabEquipment со композитен PK; batch ON CONFLICT DO NOTHING. |
| 197 | |
| 198 | 8. **Stored function / транзакција** – атомичност |
| 199 | |
| 200 | Зошто: Reaction+Experiment+(N:M) да се креираат заедно или ништо. |
| 201 | |
| 202 | Како: create_reaction_and_experiment_fn(...) + Python fallback транзакција. |