You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+146-9Lines changed: 146 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -87,15 +87,152 @@ src/
87
87
88
88
### Tabeller
89
89
90
-
| Tabell | Beskrivelse |
91
-
|-----------------|-------------|
92
-
|`events`| Arrangementer med dato, sted, registreringsperiode |
93
-
|`courses`| Kurs innenfor et arrangement (aldersgruppe, kapasitet) |
94
-
|`registrations`| Påmeldinger med status (confirmed/waitlisted/cancelled) |
95
-
|`adminUsers`| Admin-brukere (opprettet via seed) |
96
-
|`sessions`| Admin-sesjoner (cookie-basert) |
97
-
|`siteContent`| Nøkkel/verdi-par for redigerbart sideinnhold |
98
-
|`contactCards`| Kontaktkort for kontaktsiden |
90
+
Drizzle-skjemaet ligger i `src/lib/server/db/schema.ts`. Alle `timestamp`-kolonner lagres uten tidssone, alle UUID-kolonner er `gen_random_uuid()`-defaulted der ikke annet er spesifisert.
91
+
92
+
#### `events`
93
+
94
+
Arrangementer — én rad per javaBin Kids-dag (f.eks. "javaBin Kids Vår 2026"). Kurs og forslag henger under et arrangement.
95
+
96
+
| Kolonne | Type | Beskrivelse |
97
+
|---|---|---|
98
+
|`arrangementId`| uuid, PK | Unik ID |
99
+
|`title`| text | Visningstittel |
100
+
|`description`| text | Markdown-beskrivelse |
101
+
|`date`| timestamp | Dato for arrangementet |
102
+
|`location`| text | Sted/adresse |
103
+
|`cancelled`| boolean | Om arrangementet er avlyst |
104
+
|`registrationOpens`| timestamp | Start for påmelding |
105
+
|`registrationCloses`| timestamp | Slutt for påmelding |
106
+
|`imageUrl`| text, nullable | URL til forsidebilde (fra `images`-tabellen eller ekstern) |
107
+
|`openForSubmissions`| boolean | Om åpent for innsending av kursforslag |
108
+
|`submissionDeadline`| timestamp, nullable | Frist for innsending av forslag |
109
+
|`createdAt`, `updatedAt`| timestamp | Auto |
110
+
111
+
#### `courses`
112
+
113
+
Kurs som arrangeres innenfor et gitt arrangement. Hvert kurs har egen alders- og kapasitetsgrense.
114
+
115
+
| Kolonne | Type | Beskrivelse |
116
+
|---|---|---|
117
+
|`courseId`| uuid, PK | Unik ID |
118
+
|`arrangementId`| uuid, FK → `events`| Hvilket arrangement kurset tilhører (`ON DELETE RESTRICT`) |
119
+
|`title`| text | Kurstittel |
120
+
|`introduction`| text | Kort introduksjonstekst |
121
+
|`description`| text | Fullstendig Markdown-beskrivelse |
122
+
|`thumbnailUrl`| text, nullable | URL til thumbnail |
|`maxParticipants`| integer | Foreslått maks antall |
141
+
|`speakerName`| text | Foredragsholders navn |
142
+
|`speakerEmail`| text | E-post (brukes til mottatt/godkjent/avvist-mail) |
143
+
|`speakerBio`| text | Kort bio |
144
+
|`editToken`| uuid | Token i redigeringslenke, lar foredragsholder endre forslaget uten innlogging |
145
+
|`createdAt`, `updatedAt`| timestamp | Auto |
146
+
147
+
#### `registrations`
148
+
149
+
Påmeldinger fra foreldre til et spesifikt kurs. Unik på `(courseId, parentEmail, childName)` for å hindre duplikater.
150
+
151
+
| Kolonne | Type | Beskrivelse |
152
+
|---|---|---|
153
+
|`registrationId`| uuid, PK | Unik ID |
154
+
|`courseId`| uuid, FK → `courses`| Kurset barnet meldes på |
155
+
|`parentName`| text | Forelders navn |
156
+
|`parentEmail`| text | E-post (brukes til bekreftelse/påminnelse) |
157
+
|`parentPhone`| text | Telefonnummer |
158
+
|`childName`| text | Barnets navn |
159
+
|`childAge`| integer | Barnets alder |
160
+
|`status`| text |`confirmed`, `waitlisted` eller `cancelled`|
161
+
|`waitlistPosition`| integer, nullable | Posisjon på venteliste (1 = først i køen); `null` for confirmed/cancelled |
162
+
|`consentGiven`| boolean | Om samtykke til databehandling er gitt |
163
+
|`cancellationToken`| uuid | Token i bekreftelse/avmeldings-lenke — gjør at forelder kan avmelde uten innlogging |
164
+
|`createdAt`, `updatedAt`| timestamp | Auto |
165
+
166
+
#### `adminUsers`
167
+
168
+
Admin-brukere som kan logge inn i admin-panelet. Opprettes via `npm run db:seed`.
169
+
170
+
| Kolonne | Type | Beskrivelse |
171
+
|---|---|---|
172
+
|`adminUserId`| uuid, PK | Unik ID |
173
+
|`username`| text, unique | Brukernavn |
174
+
|`passwordHash`| text | bcrypt-hash av passord |
175
+
|`createdAt`| timestamp | Auto |
176
+
177
+
#### `sessions`
178
+
179
+
Aktive admin-sesjoner. Sesjons-ID-en lagres som HTTP-cookie og valideres på hver admin-request.
180
+
181
+
| Kolonne | Type | Beskrivelse |
182
+
|---|---|---|
183
+
|`sessionId`| uuid, PK | ID som lagres i cookien |
184
+
|`adminUserId`| uuid, FK → `adminUsers`| Hvilken bruker sesjonen tilhører |
185
+
|`expiresAt`| timestamp | Utløp (typisk 24 timer etter innlogging) |
186
+
|`createdAt`| timestamp | Auto |
187
+
188
+
#### `siteContent`
189
+
190
+
Nøkkel/verdi-tekst som admin kan redigere fra `/admin/innhold`. Brukes for forside-hero, om-siden osv.
191
+
192
+
| Kolonne | Type | Beskrivelse |
193
+
|---|---|---|
194
+
|`key`| text, PK | Identifikator, f.eks. `hero_title`, `om_content`|
195
+
|`content`| text | Fritekst/Markdown |
196
+
|`updatedAt`| timestamp | Auto |
197
+
198
+
#### `images`
199
+
200
+
Binær-lagring av opplastede bilder (thumbnails, forsidebilder). Serveres via `/api/images/{imageId}` som bruker `mimeType` som `Content-Type`.
201
+
202
+
| Kolonne | Type | Beskrivelse |
203
+
|---|---|---|
204
+
|`imageId`| uuid, PK | Unik ID (del av serve-URL) |
205
+
|`filename`| text | Opprinnelig filnavn |
206
+
|`mimeType`| text |`image/jpeg`, `image/png`, osv. |
207
+
|`data`| bytea | Rå bilde-bytes |
208
+
|`createdAt`| timestamp | Auto |
209
+
210
+
#### `emailTemplates`
211
+
212
+
Redigerbare e-postmaler for de åtte transaksjonelle e-postene (bekreftelse, venteliste, forslag-godkjent, osv.). Hvis en rad mangler eller et felt er tomt, faller `email.ts` tilbake på hardkodet default. Tekstfelter kan inneholde `{{variabel}}`-plassholdere og `**fet tekst**`.
213
+
214
+
| Kolonne | Type | Beskrivelse |
215
+
|---|---|---|
216
+
|`templateKey`| text, PK | Én av `confirmation`, `waitlist`, `promotion`, `cancellation`, `reminder`, `submissionReceived`, `submissionApproved`, `submissionRejected`|
217
+
|`subject`| text | Emnelinje |
218
+
|`heading`| text | Overskrift i e-post-kroppen |
219
+
|`introText`| text | Paragrafer før info-bokser (tom linje = ny paragraf) |
220
+
|`outroText`| text | Paragrafer etter knapp/info-bokser |
221
+
|`buttonText`| text, nullable | CTA-knappens tekst (kun for maler med knapp) |
222
+
|`updatedAt`| timestamp | Auto |
223
+
224
+
#### `contactCards`
225
+
226
+
Kontaktkort som vises på kontaktsiden, administreres fra `/admin/innhold`.
227
+
228
+
| Kolonne | Type | Beskrivelse |
229
+
|---|---|---|
230
+
|`contactCardId`| uuid, PK | Unik ID |
231
+
|`title`| text | Kort-tittel |
232
+
|`actionType`| text |`email`, `link` eller `phone`|
233
+
|`actionValue`| text | E-post, URL eller telefonnummer |
0 commit comments