PIVOT 1.1.0
This commit is contained in:
commit
8a53234eb6
161 files changed
+31109
No files matched your search
+203
@@ -0,0 +1,203 @@
|
||||
# PIVOT-database (structuur 2026-27)
|
||||
|
||||
De database volgt `pivot_database_structuur_26-27` en is verdeeld zoals PIVOT 1.1.0 met meerdere scholen werkt:
|
||||
|
||||
| Database | Inhoud |
|
||||
|---|---|
|
||||
| **centraal** (`pivot`, zie `config.ini › centrale_database`) | `Scholen`, `Gebruikers`, `Veiligheidsgroepen`, `Onderdelen`, `Gebruiker_rechten`, `Leerlingenaantal_tellingen`, `Personeelsaantal_tellingen`, `Personeelsaantal_huidig`, `IP_blokkades`, `PIVOT_instellingen`, `Koppeling_tests`, `Handleidingen`, `Handleidingen_versies`, `Logs`, `Bugs`, `Status` |
|
||||
| **één per school** (bv. `pivot_sg_antwerpen`) | `Campus`, `Lokalen`, `Wifi`, `Toestellen`, `Signpost_DB`, `Opmerkingen`, `Signpost_herstellingen_DB`, `Leerlingen`, `Eigendom`, `Co_accounts`, `CO2_Metingen`, `Schooljaar` + de tabellen van de modules (2FA, afwezigheden, personeel, licenties, mailbox-delegatie) |
|
||||
|
||||
## Installeren
|
||||
|
||||
```
|
||||
mysql -u <gebruiker> -p < sql/installatie_pivot_26-27.sql
|
||||
```
|
||||
|
||||
Daarmee heb je:
|
||||
|
||||
- de centrale database `pivot`
|
||||
- de school **Scholengroep Antwerpen** (code `sg-antwerpen`) met database `pivot_sg_antwerpen`
|
||||
- de gebruiker **Marijn**, wachtwoord `Binnenin10`, rol **Administrator**
|
||||
|
||||
Je kan het script ook in MySQL Workbench of phpMyAdmin importeren. Het mag meermaals uitgevoerd worden.
|
||||
|
||||
**Andere naam voor de centrale database** (bv. `pivot_test`)? Pas dan de naam aan op **beide** regels
|
||||
(`CREATE DATABASE` én `USE`) onder *1. Centrale database*, en zet dezelfde naam in `config.ini › centrale_database`.
|
||||
|
||||
**Gebruik een nieuwe, lege database.** Staan er nog tabellen van de vorige versie in (bv. `scholen` of
|
||||
`gebruikers`), dan stopt het script met de melding *"STOP: deze database bevat nog oude PIVOT-tabellen"*,
|
||||
en PIVOT start niet met die database. MySQL op Windows maakt geen onderscheid tussen `Scholen` en `scholen`,
|
||||
dus anders zou de nieuwe tabel stilletjes niet aangemaakt worden.
|
||||
Log daarna in, kies *Scholengroep Antwerpen* en vul via **🏫 Alle scholen beheren › Bewerken** het e-maildomein,
|
||||
Smartschool, Informat, Google, ... in.
|
||||
|
||||
Losse bestanden:
|
||||
|
||||
- `sql/centraal.sql`: enkel de centrale tabellen
|
||||
- `sql/school.sql`: de tabellen van één school (uit te voeren in een lege database)
|
||||
|
||||
## Een database voor een nieuwe school
|
||||
|
||||
Kies één van deze manieren:
|
||||
|
||||
1. **In PIVOT**: 🏫 Alle scholen beheren › Nieuwe school › *Database aanmaken?* › **Ja, nieuwe lege PIVOT-database**.
|
||||
Vergeten? Open de school via *Bewerken*: onder *Database* staat dan **🗄️ Database nu aanmaken**.
|
||||
2. **Opdrachtregel**: `python beheer.py nieuwe-schooldatabase pivot_<school>`
|
||||
3. **Met de hand**: `CREATE DATABASE pivot_<school>;` en daarna `sql/school.sql` in die database uitvoeren.
|
||||
|
||||
De MySQL-gebruiker uit `config.ini` moet daarvoor databases mogen aanmaken.
|
||||
|
||||
## Een kopie van een school
|
||||
|
||||
🏫 Alle scholen beheren › Nieuwe school › *Database aanmaken?* › **Ja, kopie van … (met gegevens)**.
|
||||
PIVOT kopieert alle tabellen mét gegevens naar een **nieuwe** database (bestaat ze al en bevat ze tabellen, dan stopt het).
|
||||
Vink aan wat je nog wil overnemen:
|
||||
|
||||
- **Koppelingen en instellingen** (Smartschool, Informat, Google-sleutel, …): na het aanmaken kom je op *Bewerken* om ze na te kijken.
|
||||
- **Gebruikersrechten**: wie rechten heeft in de bronschool, krijgt dezelfde rechten in de kopie.
|
||||
|
||||
Een testkopie zet je best op *niet actief*: dan lopen er geen geplande synchronisaties (afwezigheden, Skore, 2FA) voor.
|
||||
Op de opdrachtregel: `python beheer.py kopieer-school BRONCODE pivot_<kopie>` (enkel de database).
|
||||
|
||||
## Rechten
|
||||
|
||||
Iedereen heeft **één account** voor alle scholen (tabel `Gebruikers`). Per school vink je aan op welke **onderdelen**
|
||||
iemand rechten heeft (tabel `Gebruiker_rechten`: gebruiker × school × onderdeel).
|
||||
Zo kan iemand in school A *2FA tijdelijk uitzetten* en in school B niet.
|
||||
|
||||
- **Administrator** (Veiligheidsgroep 1): alle rechten in alle scholen. Beheert gebruikers, rechten en scholen.
|
||||
- **Gebruiker** (Veiligheidsgroep 2): enkel wat per school aangevinkt is. Zonder vinkje in een school kan hij er niet inloggen.
|
||||
- Wie in een school het recht **Gebruikers & rechten** heeft, kan in díe school gebruikers aanmaken en hun rechten instellen.
|
||||
Administrators wijzigen kan hij niet.
|
||||
- Leerkrachten zonder account die met Google inloggen, krijgen zoals vroeger enkel de personeelsmodule.
|
||||
|
||||
Een wijziging in de rechten geldt meteen, ook als de gebruiker al ingelogd is.
|
||||
Wie in meerdere scholen rechten heeft, wisselt bovenaan van school.
|
||||
|
||||
Beheren kan in PIVOT via **⚙️ Beheer › 🔐 Gebruikers & rechten**, of op de opdrachtregel:
|
||||
|
||||
```
|
||||
python beheer.py gebruiker jan --email jan@school.be # nieuwe gebruiker (vraagt wachtwoord)
|
||||
python beheer.py gebruiker marijn --admin # administrator maken
|
||||
python beheer.py rechten jan sg-antwerpen tweestaps_uitzetten co2
|
||||
python beheer.py rechten jan sg-antwerpen # rechten tonen
|
||||
python beheer.py rechten jan sg-antwerpen alles | geen
|
||||
```
|
||||
|
||||
| Onderdeel (code) | Wat |
|
||||
|---|---|
|
||||
| `eigendom_bekijken` | Eigendom bekijken |
|
||||
| `toestellen_uitdelen` | Toestellen uitdelen en inleveren |
|
||||
| `toestellen_beheren` | Toestelleninventaris beheren |
|
||||
| `toestel_blokkeren` | Chromebook blokkeren / deblokkeren |
|
||||
| `herstellingen` | Herstellingen |
|
||||
| `signpost` | Signpost-toestellen |
|
||||
| `leerlingen_bekijken` | Leerlingen bekijken en bewerken |
|
||||
| `leerlingen_synchroniseren` | Leerlingen toevoegen en synchroniseren (Informat, Google) |
|
||||
| `google_wachtwoord` | Google-wachtwoord resetten |
|
||||
| `google_accounts` | Google-accounts aanmaken |
|
||||
| `tweestaps_codes` | 2FA: back-upcodes tonen / aanmaken |
|
||||
| `tweestaps_uitzetten` | 2FA tijdelijk uitzetten (uitzondering) |
|
||||
| `google_licenties` | Google-licenties |
|
||||
| `gmail_delegatie` | Mailbox-delegatie |
|
||||
| `verzendlijsten` | Verzendlijsten (Google Groepen) bekijken, aanmaken en aanpassen |
|
||||
| `smartschool` | Smartschool-wachtwoorden & info |
|
||||
| `smartschool_activiteit` | Activiteit co-accounts & berichten |
|
||||
| `afwezigheden` | Afwezigheden leerlingen (B-codes) |
|
||||
| `laatkomers` | Laatkomers (codes voor te laat uit Smartschool) |
|
||||
| `skore` | Skore-synchronisatie starten en plannen |
|
||||
| `personeel_directie` | Personeel: aanvragen goedkeuren |
|
||||
| `personeel_secretariaat` | Personeel: dagoverzicht |
|
||||
| `co2` | CO2-sensoren |
|
||||
| `qr_codes` | QR-code generator |
|
||||
| `bugs_bekijken` / `bugs_beheren` | Bugs bekijken / status wijzigen |
|
||||
| `nieuw_schooljaar` | Nieuw schooljaar (accounts & toestellen) |
|
||||
| `leerlingenaantal` | Leerlingenaantallen van alle scholen (blok *Leerlingen*) |
|
||||
| `personeelsaantal` | Personeelsaantallen van alle scholen (blok *Personeel*) |
|
||||
| `gopro` | GO! Pro: personeel van de school uit Informat, rollen en export (blok *Personeel*) |
|
||||
| `koppelingen` | Koppelingen van deze school |
|
||||
| `gebruikersbeheer` | Gebruikers & rechten van deze school |
|
||||
| `database_toestellen` | Beheer › Database: toestellen importeren uit Excel |
|
||||
|
||||
Een nieuw onderdeel voeg je toe in `rechten.py › ONDERDELEN`. Bij het opstarten komt het automatisch in de tabel `Onderdelen`.
|
||||
|
||||
## Verschillen met de PDF
|
||||
|
||||
Wat PIVOT extra nodig heeft, staat in `sql/school.sql` gemarkeerd met `[+]`.
|
||||
|
||||
- **Scholen**: `Instellingsnummer` is het officiële nummer van de school; het nummer voor de Informat-koppeling
|
||||
staat apart in `Informat_instellingsnummer` (die twee verschillen). `Onderwijsniveau` (`kleuter`, `basis` of `secundair`)
|
||||
bepaalt de subtotalen bij de leerlingenaantallen. Scholen heeft naast de PDF-velden ook `Code`, `Hostnamen`, `Actief`, `Db_naam`, `Instellingen` (versleutelde koppelingen)
|
||||
en `Google_sleutel`. `Domein` mag meerdere domeinen bevatten, gescheiden door komma's.
|
||||
- **Gebruikers** bevat `Passwoordhash` (werkzeug-hash, nooit het wachtwoord zelf) plus `Actief`.
|
||||
`Veiligheidsgroep` verwijst naar de tabel `Veiligheidsgroepen`.
|
||||
- **Leerlingenaantal_tellingen** (extra): de leerlingenaantallen per school op een gekozen peildatum
|
||||
- **gmail_delegaties** / **gmail_delegaties_scan** (extra, per school): alle lopende e-mailmachtigingen (Mailbox-delegatie), opgehaald door alle mailboxen af te gaan (dagelijks of met 🔄 Vernieuwen) en meteen bijgewerkt bij wijzigingen in PIVOT
|
||||
- **internaat_aanwezigheid** (extra, per school): aanwezigheidsregister van het internaat (per intern, dag en moment ochtend/avond)
|
||||
- **gmail_label_log** / **gmail_label_items** (extra, per school): opdrachten "e-mails met een label naar een andere mailbox" en welke berichten al gekopieerd zijn (zodat een herstart ze overslaat). Vereist het Google-bereik `gmail.modify`.
|
||||
- **gmail_handtekening** / **gmail_handtekening_log** (extra, per school): Gmail › Handtekeningen: het HTML-sjabloon, het logo (publiek op `/handtekening-logo/<school>/<sleutel>`), de gekozen OU's en de schakelaar voor nachtelijk opnieuw toepassen (één rij, ID = 1), en per gebruiker wanneer de handtekening gezet werd. Functie en telefoon staan niet in PIVOT maar in Google. Vereist `gmail.settings.basic` en `admin.directory.user`.
|
||||
- **contact_lijsten** / **contact_lijst_items** (extra, per school): Gmail › Contacten › Contactlijsten: een label met vaste contacten dat PIVOT in de persoonlijke contacten van iedereen in de gekozen OU's zet (People API, scope `contacts`). PIVOT herkent zijn contacten in de mailboxen aan het eigen veld `PIVOT` = `lijst<ID>:<item-ID>#<hash>`. De zichtbaarheid in het adresboek staat enkel in Google.
|
||||
- **Leerlingen.Vertrokken_op** (extra): datum waarop de leerling bij "Informat & SS sync" niet meer actief was in Informat (NULL = actief). Vertrokken leerlingen worden niet verwijderd, enkel verborgen in de lijst.
|
||||
(Scholengroep › Leerlingenaantallen › *Telling op peildatum*). Wordt bij het opstarten automatisch aangemaakt.
|
||||
- **Personeelsaantal_huidig** en **Personeelsaantal_tellingen** (extra): de personeelsaantallen per school, nu en op
|
||||
een gekozen peildatum (Personeel › Personeelsaantallen). Geteld uit de Informat Personeel-API: wie op die dag een
|
||||
lopende opdracht heeft. Worden bij het opstarten automatisch aangemaakt.
|
||||
- **GoPro_verzameltabel** (extra, centraal): de groene personeelsleden (account in Google) van alle scholen samen voor één GO! Pro-CSV; wie hierin staat, wordt op de GO! Pro-pagina van zijn school niet meer getoond (herkend aan school + personeelslid of aan het e-mailadres); met de schakelaar 🌙 op de GO! Pro-pagina (PIVOT_instellingen `gopro_nachtelijk`) gebeurt het verzamelen elke nacht tussen 2 en 6 uur voor alle scholen; kolom `Soort`: `groen` (gaat mee in de CSV), `genegeerd` (rode lijst: nooit meer tonen, niet exporteren) of `verzonden` (met ✅ Markeer als verzonden: al naar GO! Pro gestuurd, nooit opnieuw toevoegen; `Verzonden`, `Verzonden_door`)
|
||||
- **IP_blokkades** (extra): IP-adressen en reeksen die geweigerd (of altijd toegelaten) worden, voor alle scholen; bij "altijd toestaan" kunnen één of meer scholen aangeduid worden (`Scholen`, codes met komma gescheiden, ter info)
|
||||
(Beheer › Beveiliging › IP-blokkades, enkel administrators; een gebruiker met het recht `ip_whitelist` ziet enkel de toegestane adressen van zijn school, voegt er toe voor die school en verwijdert enkel zijn eigen regels — `Gebruiker_ID`). Staat PIVOT achter een reverse proxy, zet dan
|
||||
`config.ini › [algemeen] proxy_aantal` op het aantal proxy's (meestal 1), anders ziet PIVOT het adres van de proxy.
|
||||
De schakelaar *Enkel "Altijd toestaan" binnenlaten* staat in **PIVOT_instellingen** (`ip_enkel_toegestaan` = 1).
|
||||
Toch buitengesloten? Zet hem rechtstreeks in de database uit:
|
||||
`UPDATE PIVOT_instellingen SET Waarde = '0' WHERE Sleutel = 'ip_enkel_toegestaan';` (geldt binnen 30 seconden).
|
||||
- **Handleidingen** en **Handleidingen_versies** (extra): de handleidingen onder 📘 Handleidingen op het dashboard
|
||||
(HTML, met schermafbeeldingen) en de laatste 30 vorige versies per handleiding. PIVOT levert er twee mee
|
||||
(2FA-uitzondering en mailbox-delegatie in Google Admin); die komen bij het opstarten in de tabel.
|
||||
Enkel administrators kunnen ze bewerken.
|
||||
- **Logs** bevat ook `School_ID`, `Actie` en `IP`. PIVOT schrijft er elke bezochte pagina in
|
||||
(uit te zetten met `config.ini › logboek = nee`).
|
||||
- **Bugs** bevat ook wie de bug meldde (`Gebruiker_ID`, `Gebruikersnaam`) en in welke school.
|
||||
- **Toestellen** bevat `Serienummer`, `Type`, `Status` en `Geblokkeerd` (nodig om te blokkeren in Google en voor uitdelen/inleveren).
|
||||
`Geblokkeerd` (1 = geblokkeerd in Google Admin) wordt vanzelf toegevoegd; de knop in 💻 Alle toestellen en 🔒 bij Eigendom
|
||||
houden hem bij, en "Chromebooks ophalen uit Google" neemt de status uit Google over.
|
||||
`Schooleigen_ID` is het toestelnummer van de school; in de code heette dat vroeger `KAMXM_nummer`.
|
||||
Aanvullen kan ook in bulk via **⚙️ Beheer › 🗄️ Database › Toestellen importeren**: sjabloon downloaden, Excel uploaden,
|
||||
voorbeeld nakijken en bevestigen. Toestellen worden herkend aan `Schooleigen_ID` (anders `Serienummer`); er wordt nooit
|
||||
iets verwijderd en een lege cel wist niets (`services/toestellen_import.py`).
|
||||
- **Signpost_DB**: één rij per toestel (`Toestel_ID` = sleutel). Het veld "Aankoopberdrag" heet `Aankoopbedrag`.
|
||||
De synchronisatie met Signpost maakt een toestel aan als het serienummer nog niet bestaat.
|
||||
- **Opmerkingen** en **Signpost_herstellingen_DB** verwijzen naar `Toestellen.Toestel_ID`. Dat is hetzelfde nummer als
|
||||
`Signpost_DB.Toestel_ID`, maar zo werkt het ook voor toestellen die niet via Signpost gekocht zijn.
|
||||
Herstellingen hebben ook een `Datum` en de leerling (`Leerling_ID`).
|
||||
- **Eigendom** houdt ook de geschiedenis bij: `Datum_inlevering` leeg betekent dat de leerling het toestel nu heeft.
|
||||
De vroegere tabel `Eigendom_archief` is niet meer nodig.
|
||||
- **Co-accounts** heet `Co_accounts` en "Laatste aanmelding" heet `Laatste_aanmelding` (geen streepjes of spaties in namen).
|
||||
- **Campus.School_ID** verwijst naar `Scholen.School_ID` in de centrale database. Een harde foreign key kan niet,
|
||||
want een schooldatabase kan op een andere server staan.
|
||||
- **Lokalen.Campus_ID** mag leeg zijn: een CO2-sensor met een nieuwe lokaalnaam maakt automatisch een lokaal aan.
|
||||
Koppel het daarna aan een campus.
|
||||
- **Wifi** kreeg een optionele `Campus_ID`.
|
||||
- **Schooljaar** (`2026` → `2026-27`) is een extra tabel voor `Leerlingen.Schooljaar_ID`.
|
||||
- **smartschool_coaccounts** (extra, per school): alle co-accounts uit Smartschool met klas, leerling en laatste
|
||||
aanmelding (Smartschool › Co-accounts). Wordt automatisch aangemaakt en één keer per dag opnieuw opgehaald.
|
||||
- **gopro_keuzes** (extra, per school): de GO! Pro-functie en -rol per personeelslid (`Person_ID` uit Informat).
|
||||
Wordt automatisch aangemaakt; zonder keuze is het *Leerkracht* (een directeur: *Directeur*).
|
||||
|
||||
## Windows → Linux: tabelnamen met hoofdletters
|
||||
|
||||
MySQL op Windows bewaart tabelnamen in kleine letters (`lower_case_table_names = 1`); op Linux (`= 0`) zijn
|
||||
`toestellen` en `Toestellen` verschillende tabellen. Bij het opstarten (en bij **Testen** van een school) herstelt
|
||||
PIVOT dit automatisch voor de centrale database en alle schooldatabases (`services/tabelnamen.py`), enkel op een
|
||||
server met `lower_case_table_names = 0` en enkel voor de tabellen die PIVOT kent:
|
||||
|
||||
- alleen `toestellen` bestaat → hernoemd naar `Toestellen`;
|
||||
- beide bestaan en `Toestellen` is leeg → de lege tabel weg, `toestellen` hernoemd;
|
||||
- beide bevatten gegevens → niets gewijzigd, melding in het serverlogboek (zelf samenvoegen).
|
||||
|
||||
Wat er gebeurde, staat in het serverlogboek (regels die beginnen met `PIVOT tabelnamen:`).
|
||||
|
||||
## Aantal verbindingen ("Too many connections")
|
||||
|
||||
PIVOT houdt per database (centraal + elke school) een pool van verbindingen open: `config.ini › [database] ›
|
||||
pool_size` (standaard 3). In totaal dus ongeveer (aantal scholen + 1) × pool_size per draaiend PIVOT-proces. Dat moet
|
||||
onder `max_connections` van MySQL blijven (standaard 151). Krijg je "1040 Too many connections", verhoog dan
|
||||
`max_connections` in `my.ini` / `my.cnf` (bv. `max_connections = 500`) of verlaag `pool_size`.
|
||||
Reference in new issue
Block a user