Ergänzt 26.10.: Mail-Dienst, Warteschlange, Rahmen und Kopfzeilen liegen als Fundament in Karte 1a (2.2, Teil 3); 1b bringt nur die Vorlagen b15 bis b17 und v04. Hilfe-Artikel für Bewerber und Betriebe (L1) als Inhalte, erreichbar über Kontaktseite und Konto-Menü, kein Fußzeilen-Link (F1 A).
Hinweis 22.10.: Der gemeinsame Ordner von B liegt im Projektordner untergemeinsam/(Bilder, Berufeliste, daten-neu.js, werbung, suche); die B-Seiten binden ihn als.ein. Weichen in Teil 7 sind je Spalte A entschieden (Annahme, jederzeit korrigierbar).. / gemeinsam/
Grundlage: PLAN-BACKEND Fassung 5 (Zeitplan 1b, Menüs, Listen, Lebensläufe Job-Alarm/Kontaktanfrage/Fachbereich, Fristen, Sprachen und Inhalte, Sicherheit), USABILITY-KONZEPT 3.21/3.23, 5.4, Teil A, B.4, B.7, C.4, D, TEXTE-UND-MAILS 1.1, 1.5, 1.10, 2, 3.1 bis 3.3, 4.1, 4.4, 6.2 (B15 bis B17), 6.5 (V04, V05), 8, FUNKTIONEN-CHECK, Entwurf B (kategorien.html, unternehmen.html, firma.html, arbeitgeber.html, ratgeber.html, ratgeber-*.html, ueber-uns.html, kontakt.html, merkliste.html, job-alarm.html, impressum.html, datenschutz.html, agb.html, assets/style.css, assets/app.js). Der Ordner entwurf-b/ fehlt auf dem Rechner (Bilder und Werbemotive werden in B aus . geladen); Karte 1a nennt ihn als Quelle, 1b verweist nur darauf.
Umfang 1b laut Zeitplan: Fachbereiche, Firmen (Liste und Profil), Für Arbeitgeber, Ratgeber (Übersicht und Artikel), Über uns, Kontakt, Merkliste und Job-Alarm ohne Konto (mit Bestätigung, Sammelmail, Ändern und Abbestellen aus der Mail), Recht (Impressum, Datenschutz, Nutzungsbedingungen, AGB; Texte von Nomad aus RECHTSTEXTE P-5050-RT), Sprachen (en/tr für alle 1b-Schlüssel, Inhalte je Sprache), Google for Jobs (Sitemap, robots, Freigabe des JSON-LD aus 1a), Musterdaten für die Testumgebung. Nicht in 1b (nur verlinkt, Muster A1 aus 1a): Anmelden und Firma registrieren (2a), Bewerben-Fenster (2a), Werbung planen (Konfigurator, Abschnitt 3), „Anzeige melden“ (3), Konto-Merkliste und Konto-Job-Alarme (2a).
Was 1a schon baut und hier nur benutzt wird (nicht doppelt geplant): Seitenrahmen mit Kopf, Handy-Menü, Fußzeile, Cookie-Hinweis, Toasts, Sprachwahl und Sprachhinweis (1a 1.1, 2.1), Suchleiste mit Vorschlägen (1a 2.1 suche/), Stellenkarte mit Herz und Variante „merkliste“ (1a 2.1 stellenkarte/), Werbefläche (1a 2.1 werbeflaeche/), Leerzustand, Platzhalter, Sonderseiten, Brotkrumen, Zähler, fachlich/ (dieselbe Suche für den Job-Alarm), fachlich/ und google., fachlich/ und liste., fachlich/, fachlich/, dienste/, dienste/, Tabellen firmen, stellen, fachbereiche, plz, einstellungen, protokoll (1a Teil 3), Hintergrund-Startpunkt hintergrund/.
Entschieden: D-6, D-7 (Merkliste), D-8, D-9, D-10 (Fußzeile), D-11 (Fachbereiche), D-12 (Über uns), D-13 (Ratgeber), D-14 (Für Arbeitgeber). Geplant ist der Stand von B mit genau diesen Änderungen; sie stehen je an ihrer Stelle. Fußzeile (D-8 bis D-10) liegt in 1a (Baustein seitenrahmen/Fusszeile.tsx, Karte 1a 1.1); hier stehen nur die Folgen für die Zielseiten.
Fundstellen: B:kontakt. = Datei und Zeile in entwurf-b/; css:919 = assets/style.css; js:1236 = assets/app.js; T oeffentlich. = Textschlüssel aus TEXTE-UND-MAILS; U 3. = Usability-Bildschirm; P Listen = Abschnitt im Plan.
Seiten
Jede Inhaltsseite von oben nach unten: was dort steht, welche Knöpfe es gibt und was gegenüber dem Entwurf B geändert wurde.
Adressen unter / (de, en, tr; ar ab 2b). Alle Seiten liegen in app/, der Rahmen kommt aus layout. (1a). Jede Seite hat generateMetadata (Titel „{Seitenname} | bululu“, Beschreibung, hreflang über die Hilfe aus proxy.ts) und ist auf dem Server gebaut; Client-Bausteine nur, wo etwas bedient wird (Formulare, Herz, Entfernen, Folgen, Firmensuche).
Reihenfolge und Zusammenfassung:
| Nr | Seite | Adresse | B-Datei | Daten |
|---|---|---|---|---|
| 1 | Fachbereiche | /fachbereiche | kategorien.html | fachbereiche + Anzahl |
| 2 | Unternehmen | /firmen?q=&fachbereich=&ort=&sort= | unternehmen.html | firmen + Anzahl Stellen |
| 3 | Firmenprofil | /firmen/[adresse] | firma.html (js-erzeugt) | firma, Stellen, Folgen |
| 4 | Für Arbeitgeber | /fuer-arbeitgeber (#inserieren, #werbung, #kontakt) | arbeitgeber.html | Kontaktanfrage, Entwurf im Gerätespeicher |
| 5 | Ratgeber | /ratgeber | ratgeber.html | inhalte (art ratgeber) |
| 6 | Artikel | /ratgeber/[adresse] | ratgeber-lebenslauf.html u. a. | inhalte |
| 7 | Über uns | /ueber-uns | ueber-uns.html | inhalte (seitentext) + fachbereiche |
| 8 | Kontakt | /kontakt | kontakt.html | kontaktanfragen, einstellungen.betreiber |
| 9 | Merkliste | /merkliste | merkliste.html | Gerätespeicher + Stellen |
| 10 | Job-Alarm | /job-alarm?q=&ort=&umkreis=&fachbereich=&mail= | job-alarm.html | job_alarme |
| 11 | Job-Alarm-Zielseiten | /job-alarm/bestaetigt · /job-alarm/aendern · /job-alarm/abbestellt (je ?t=) | kontakt-erfolg-Muster | job_alarme |
| 12 | Recht | /impressum · /datenschutz · /agb | impressum.html, datenschutz.html, agb.html | inhalte (rechtstext) |
1.1 Fachbereiche
Datei fachbereiche/ · Teile in fachbereiche/. Handy = Desktop, nur das Raster bricht um (css:338, 1267).
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis |
|---|---|---|---|---|
| 1 | Seitenkopf | u-kopf u-kopf--schmal, h1 „Alle Fachbereiche“ (tabindex -1), lead | kategorien.html:93–100, css:862–866 | T oeffentlich.fachbereiche.titel, .einleitung (T 7.5) |
| 2 | Raster | box · ul. · je Fachbereich a. mit kat_ (SVG aus KAT_ICON js:58–75), Name, small Anzahl (T oeffentlich.fachbereich.anzahl); ohne Stellen div. mit „Stellen folgen“ und Link kat_ „Job-Alarm einrichten“ (T oeffentlich.fachbereich.jobAlarm) | kategorien.html:102–108, css:338–348, 1267–1268, js:1293–1303 | Kachel → /jobs?fachbereich={schluessel}; leer → /job-alarm?fachbereich={schluessel}. Reihenfolge nach Anzahl offener Stellen, dann sortierung (P Listen). Inline-Style :102 wird Klasse (1a A17). Symbol je Fachbereich kommt aus fachbereiche. (Teil 3). D-11 (entschieden 26.10.): Spaltenzahl je Breite so, dass keine Kachel allein steht (Regel „keine allein stehende Box“, für alle Breiten durchgerechnet). Der Server kennt die Anzahl n und setzt je Stufe (Desktop höchstens 4, unter 1100 px höchstens 3, Handy höchstens 2) die größte Spaltenzahl c, bei der n ohne Rest teilbar ist oder der Rest mindestens 2 beträgt; c = 1 ist immer erlaubt (einspaltige Liste). Klassen kat-raster--4 bis --1 im Baustein-CSS fachbereiche. (vorhandene Werte), Berechnung in _ mit Test für n = 6 bis 14; dieselbe Regel gilt für das Fachbereiche-Raster der Startseite (1a 1.2 Nr. 4, höchstens 8 Kacheln: 8 → 4 · 2 · 2, 7 → 3 · 3 · 1, 6 → 3 · 3 · 2). Die Verwaltung (Karte 3 Inhalte › Fachbereiche) zeigt bei einer Anzahl, die auf dem Handy einspaltig wird, den Satz T verwaltung.fachbereiche.rasterHinweis. |
Keine Einzelseite je Fachbereich (B hat keine; die Kachel führt in die gefilterte Trefferliste, Annahme B1). Keine Werbefläche (B hat keine; 1a 2.1 nennt „später Fachbereiche“, das wird hier zurückgenommen: Werbeflächen bleiben wie in B).
1.2 Unternehmen
Datei firmen/ · Teile in firmen/. Parameter q (Name), fachbereich, ort, sort (stellen | az).
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis |
|---|---|---|---|---|
| 1 | Seitenkopf | u-kopf--schmal, h1 „Unternehmen auf Bululu“, lead | unternehmen.html:93–100 | Schlüssel in T 7.5 |
| 2 | Suche | firmen-suche mit eingabe (Name, T oeffentlich.unternehmen.suche, .suchePlatzhalter), dazu Sortierung (Baustein bausteine/ aus 1a, Variante firmen) mit „Meiste offene Stellen“ · „A bis Z“ (T …sortStellen, …sortAZ); Filter Fachbereich und Ort als zwei select im Stil der Filter-Fieldsets | unternehmen.html:102–107, css:1271, js:1305–1322 | B filtert nur live nach Name (js:1312). P Listen verlangt Sortierung und Filter Fachbereich/Ort/Name: Formular mit GET, ohne JS wirkt es auf Absenden, mit JS live (Client-Baustein FirmenSuche., Liste wird über Server-Aktion firmenSuchen() nachgeladen, Adresse trägt die Wahl). Umbau der B-Optik: nur ein Sortier-Ausklapp und zwei Auswahlfelder neben dem Suchfeld (kein neuer Farbwert; firmen-suche bekommt ein Raster im Baustein-CSS). |
| 3 | Raster | ul. (aria-live polite) aus a.: Monogramm/Logo (mono--gross, 1a Monogramm.tsx), Name, small „{n} offene Stellen · {ort}“ (T oeffentlich.unternehmen.offene) | unternehmen.html:108, css:390–395, 1272–1273, js:1315–1318 | → /firmen/[adresse]. Aufgenommen werden Firmen mit zustand aktiv und mindestens einer öffentlich sichtbaren Stelle (wie B: Firmen entstehen dort aus Stellen; Annahme B2). 24 je Seite, „Mehr laden“ als echter Link wie bei Jobs (1a MehrLaden.tsx). |
| 4 | Leer | Baustein Leerzustand data-unternehmen-leer: T oeffentlich.leer.unternehmen, Knopf „Alle Unternehmen“ (→ /firmen) | unternehmen.html:109, css:1274 | |
| 5 | Kasten „Ihr Betrieb fehlt?“ | box mit h2, Satz, Knopf „Firmenprofil anlegen“ (T oeffentlich.unternehmen.fehlt*) | unternehmen.html:110–118 | → /anmelden?modus=firma (Firma registrieren, 2a; bis dahin 404, Muster A1) |
1.3 Firmenprofil
Datei firmen/ · Teile in firmen/. In B vollständig aus app.js erzeugt (js:1324–1353, Markup dort), CSS css:1277–1288. Adresse aus firmen. (1a Teil 3, bereits gefüllt).
Handy, von oben: Kopf · Folgen · Über uns · Offene Stellen · Eckdaten. Desktop firma-layout zweispaltig: links Über uns und Stellen, rechts Eckdaten.
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis | |
|---|---|---|---|---|---|
| 1 | Kopf | header.: Logo oder Monogramm (mono--gross), h1 Name, ul. Branche · Ort · „{n} offene Stellen“ | js:1335, css:1278–1280 | Branche = Fachbereich mit den meisten Stellen der Firma (wie B js:1286), kein eigenes Feld. Seitentitel „{Firma} | bululu“ |
| 2 | Folgen | firma-kopf_ Knopf „Folgen“ (btn btn-primary btn-gross, aria-pressed), Bestätigungszeile bestaetigung firma-folgt (T oeffentlich.ok.folgen) | js:1336–1337, 1347–1353, css:1281–1282 | Folgen = Job-Alarm für diese Firma (P Bewerberbereich, T oeffentlich.firma.folgen). Ohne Konto braucht das eine Mail-Adresse: Klick klappt unter dem Knopf ein kleines Formular auf (E-Mail, Einwilligung T oeffentlich.jobAlarm.einwilligung, Knopf „Folgen“), Markup und CSS wie jobalarm-form in klein (folgen-form im Baustein-CSS, vorhandene Werte). Nach dem Senden: aria-pressed true, Zeile „Fast geschafft …“ (T 3.3 Job-Alarm ohne Konto). Mit Konto (2a) sofort aktiv, Text „Sie folgen“. Annahme B3. | |
| 3 | Über uns | section. h2 (T oeffentlich.firma.ueberUns), Text aus firmen.; fehlt er: p. (B-Satz „Hier stellt sich der Betrieb vor …“, Schlüssel in T 7.5) | js:1339, css:1284–1286 | Firmenprofile bleiben zum Start deutsch (P Sprachen) | |
| 4 | Offene Stellen | h2 (T oeffentlich.firma.offeneStellen), ul. aus Stellenkarte „zeile“, Top zuerst, dann neueste (P Listen); leer: Leerzustand T oeffentlich.leer.firmaStellen mit Knopf „Folgen“ (springt zum Folgen-Formular) | js:1340 | fachlich/ bekommt stellenDerFirma(firmaId) | |
| 5 | Eckdaten | aside. mit dl.: Branche, Standort (Ort), Webseite (T oeffentlich.firma.webseite, nur wenn firmen.), Telefon (nur wenn freigegeben) | js:1341, css:1287 | Sticky am Desktop wie B | |
| 6 | Nicht gefunden / gesperrt | Firma unbekannt oder gelöscht → not-found 404 (B js:1329 „Diesen Betrieb finden wir nicht.“ + „Alle Unternehmen“; Schlüssel in T 7.5). Firma registriert (noch keine Stelle veröffentlicht) → 404 für Besucher, 200 für angemeldete Nutzer dieser Firma (2a Vorschau-Link). Firma gesperrt → 410 mit fehler.gesperrt.firmaBewerber und Knopf „Alle Unternehmen“ (Baustein sonderseiten/Fehlerseite). Alte Adresse (firmen_adressen, 1a) → 301 | css:1288 |
„Anzeige melden“ auf dem Firmenprofil (P Lebenslauf Meldung) kommt mit Abschnitt 3 (wie 1a A6). Keine Werbefläche (B hat keine).
1.4 Für Arbeitgeber
Datei fuer-arbeitgeber/ · Teile in fuer-arbeitgeber/. Reihenfolge wie B; Pakete-Block fällt (U 3.23).
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis |
|---|---|---|---|---|
| 1 | Hero | hero · ag-teaser: ueber „Für Arbeitgeber“, h1, lead, knopf-reihe mit einem farbigen Knopf „Stelle kostenlos inserieren“ (T oeffentlich.arbeitgeber.knopf → /anmelden?modus=firma) und Textlink „Beratung anfragen“ (T …beratung → #kontakt); bildflaeche mit arbeitgeber.webp | arbeitgeber.html:95–112, css:378, 890 | B hat zwei Knöpfe (Primär + Rand, :102–104); U 3.23: Beratung wird Textlink. Inline-Style :101 → Klasse. |
| 2 | Preissätze | zwei Sätze T oeffentlich.arbeitgeber.preisSatz1, .preisSatz2 + Knopf wie Nr. 1 (als box) | ersetzt arbeitgeber.html:113–149 (paket, css:579–584 bleiben ungenutzt) | U 3.23: „Pakete-Block wird zwei Sätzen mit einem Knopf“ |
| 3 | Nutzen | kopf + drei Karten „Regional gefunden“, „Für Ihre Branche gemacht“, „Weniger Aufwand“ | arbeitgeber.html:151–172 | Texte in T 7.5 |
| 4 | Schritte | box · ol. mit drei schritt (Konto anlegen, Anzeige erstellen, Bewerbungen erhalten) | arbeitgeber.html:174–186, css:368–375 | Schritt 1 nennt keine Pakete; Texte in T 7.5 |
| 5 | Ausprobieren | box[data-editor] · h2 (T …ausprobieren), Formular Stellentitel, Ort, Beschäftigungsart, Fachbereich (aus Tabelle), Text; rechts Vorschau-Karte (data-vorschau); Knopf „Weiter zur Registrierung“ (T …ausprobierenWeiter) | arbeitgeber.html:188–218, js:835–900 inseratEditor | Client-Baustein Ausprobieren.: Live-Vorschau wie B; Absenden schreibt die Eingaben als inserat_ in den Gerätespeicher und führt auf /anmelden?modus=firma&weiter=stelle-neu (2a liest den Entwurf; Annahme B4). KI-Statuszeile :203 und data-ki-status entfallen (KI-Texte erst 2b, Funktion aus = unsichtbar). |
| 6 | Werbung | box box--gruen werbe-teaser: ueber, h2 (T …werbungTitel), lead, Knopf „Werbung planen“ (T …werbungKnopf) | arbeitgeber.html:220–231, css:1134–1136 | Knopf → /fuer-arbeitgeber/werbung (Konfigurator, Abschnitt 3; bis dahin 404, Muster A1). Die Werbeflächen-Platzhalter aller Seiten (1a W6) verlinken schon auf /fuer-arbeitgeber#werbung, das Ziel steht damit ab 1b. D-14 (entschieden 26.10.): Knopf als btn-rand statt btn-primary; farbig bleiben auf der Seite nur „Stelle kostenlos inserieren“ (Kopf), „Weiter zur Registrierung“ und „Nachricht senden“. |
| 7 | Kontakt | kontakt-raster: links Ansprechpartner-Karte (h3, Name, Telefon; aus einstellungen.betreiber), rechts Formular formular box[data-kontakt] mit Name, Firma, E-Mail, Telefon (freiwillig), Nachricht | arbeitgeber.html:233–262, css:596, js:901–916 kontaktFormular | Dasselbe Formular wie die Kontakt-Seite: Baustein bausteine/ Variante „arbeitgeber“ (Rolle fest „Betrieb“, Feld Firma sichtbar, Einwilligungs-Haken dazu, in B fehlt er hier). Erfolg wie 1.8 Nr. 4. Inline-Style :248 → Klasse. Ansprechpartner-Foto: offene Frage „bilder“, bis dahin ohne Bild. |
1.5 Ratgeber (Übersicht)
Datei ratgeber/ · Teile in ratgeber/.
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis |
|---|---|---|---|---|
| 1 | Seitenkopf | u-kopf, h1 „Ratgeber für Bewerber“, lead | ratgeber.html:96–103 | Schlüssel in T 7.5 |
| 2 | Werbefläche | Werbefläche (1a) neue Variante „ratgeber“ (Billboard wie Start, data-flaeche="ratgeber") | ratgeber.html:107–118, css: wie ad-zone | ohne Kampagne Platzhalter-Motiv „Hier werben“ (1a W6); Variante wird in Werbeflaeche. ergänzt (T werbung.flaecheRatgeber nennt die Fläche) |
| 3 | Artikel-Raster | ul. · je Artikel article.: Bild (rg-karte_, 16:10), rg-karte_ mit rg-karte_ (Link, ::after deckt die Karte), rg-karte_, rg-karte_ Lesezeit | ratgeber.html:120–130, css:939–954 | aus inhalte (art ratgeber, veröffentlicht, ohne Rubrik „Hilfe“), Reihenfolge sortierung; 6 zum Start. D-13 (entschieden 26.10.): Der Artikel „Bewerben ohne Anschreiben: So überzeugt Ihre Kurzbewerbung“ heißt „Bewerben ohne Anschreiben: Datei oder Foto reicht“, Adresse / (Datei inhalte/), und das Wort „Kurzbewerbung“ kommt im Text, im Abschluss-Block und in der Ratgeber-Liste nicht mehr vor (T 0 und T 8: „Bewerbung“, „Bewerben mit Datei oder Foto“); nur Daten in inhalte_fassungen, kein Code. |
| 4 | Band | band h2 „Gleich passende Stellen finden?“, Satz, Knopf „Stellen ansehen“ (btn-dunkel) → /jobs | ratgeber.html:133–143 | Schlüssel in T 7.5 |
1.6 Artikel
Datei ratgeber/ · Teile in ratgeber/. Adresse = inhalte. (lebenslauf, bewerben-ohne-anschreiben (D-13, 26.10.), nachweise, vorstellungsgespraech, gehalt, einstieg; B-Dateinamen). Dazu die beiden Hilfe-Artikel hilfe-bewerber und hilfe-betriebe: je 5 bis 8 Fragen als h2 mit kurzer Antwort, abgeleitet aus den Karten; Schluss-Block führt auf /kontakt. Sie laufen über dieselbe Artikelseite, erscheinen aber nicht im Ratgeber-Raster (1.5) und nicht unter „Weitere Artikel“; erreichbar über die Kontaktseite (1.8 Nr. 2) und „Hilfe und Kontakt“ im Konto-Menü (2a H75: Firmen-Sitzung → hilfe-betriebe, sonst hilfe-bewerber). Kein neuer Fußzeilen-Link (F1 A). Pflege wie Ratgeber in Karte 3 1.10; nach dem Livegang aus den Kontaktanfragen ergänzen.
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis |
|---|---|---|---|---|
| 1 | Kopf | header. · artikel-kopf_: ueber „Ratgeber · {Rubrik}“, h1, lead, lesezeit | ratgeber-lebenslauf.html:96–108, css:958–961 | Rubrik aus inhalte. |
| 2 | Bühne | artikel-buehne Bild | :109, css:963–964 | Bild aus inhalte. (Verwaltungs-Upload, Karte 3), sonst inhalte. (Pfad unter public/bilder/ratgeber/, Erstbestand aus gemeinsam/bilder) |
| 3 | Text | artikel-layout: article. mit h2, p, ul, ol, artikel-hinweis; danach section. (h2, Satz, knopf-reihe mit „Stellen ansehen“ und Textlink) | :111–144, css:965–988 | Text aus inhalte_ (bereinigtes HTML, erlaubt: h2, h3, p, ul, ol, li, a, strong, em, br); Schluss-Block aus Feldern schluss_, schluss_, schluss_ |
| 4 | Textanzeige im Artikel | aside. (Werbefläche Variante „suche“ aus 1a, hier mit data-flaeche="ratgeber") + ad-hier-zeile | :145–155, css:992 | Platzhalter wie Übersicht |
| 5 | Seitenleiste | artikel-seite (sticky) mit Werbefläche „ratgeber“ (300×250 wie Stelle) | :157–165, css:993 | nur Desktop (Raster bricht um) |
| 6 | Weitere Artikel | section. · kopf h2 + mehr-link „Alle Artikel“ · rg-raster rg-raster--drei mit 3 anderen Artikeln | :168–176, css:994 | nächste drei nach sortierung, ohne den aktuellen |
Übersetzte Fassung (en/tr): aus inhalte_ je Sprache; fehlt sie, deutscher Text mit Hinweis gemeinsam.sprache.nochNichtUebersetzt (U B.7). Google: Artikel in der Sitemap, kein JSON-LD.
1.7 Über uns
Datei ueber-uns/ · Teile in ueber-uns/. D-12 (entschieden 26.10.): drei Abschnitte statt sieben: Seitenkopf · Wer wir sind · Fachbereiche · Ansprechpartner. Die B-Abschnitte Für Bewerber, Für Betriebe, Werte und das Band „Was suchen Sie?“ (ueber-uns.html:138–205) entfallen, weil sie die Startseite wiederholen; ihre Seitentexte (ueber-uns.bewerber, .werte) und Schlüssel (oeffentlich.ueberUns.band*) bleiben ungenutzt.
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis |
|---|---|---|---|---|
| 1 | Seitenkopf | u-kopf · ueber „Über uns“, h1 „Zusammenbringen ist Bululu.“, lead | ueber-uns.html:94–107 | Lead „Seit acht Jahren …“ nur mit belegtem Jahr (T-Regel „Seit {jahr}“); Text aus inhalte (seitentext ueber-uns.kopf) |
| 2 | Wer wir sind | abschnitt · zweispalt: h2, fliess mit 3 Absätzen | :109–118 | inhalte seitentext ueber-uns.wer |
| 3 | Fachbereiche | box box--gruen · h2, lead, ul. mit kat_ + Name | :120–136, css:877–880 | aus Tabelle fachbereiche (aktiv), nicht aus Text |
| 4 | Ansprechpartner | abschnitt · h2 (T oeffentlich.ueberUns.ansprechTitel), Karte wie der Ansprechpartner-Block auf Für Arbeitgeber (1.4 Nr. 7: Name, Rolle, Telefon-Link tel-inline, Foto aus Frage „bilder“, bis dahin ohne Bild) | neu nach arbeitgeber.html:233–246, Telefon-Zeile :167 | aus einstellungen.betreiber (Name, Telefon); D-12 |
1.8 Kontakt
Datei kontakt/ · Teile in kontakt/; Formular aus bausteine/.
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis |
|---|---|---|---|---|
| 1 | Seitenkopf | u-kopf--schmal, h1 „Kontakt“, lead | kontakt.html:94–101 | Schlüssel in T 7.5 |
| 2 | Kontaktwege | abschnitt--eng · wege mit zwei weg (Telefon mit tel-Link, E-Mail), wege_ mit Link ins Impressum | :103–121 | Telefon und Mail aus einstellungen.betreiber; ist keine Mail-Adresse eingetragen, fehlt die zweite Karte (B-Satz „Bis dahin erreichen Sie uns über das Formular“ entfällt: nichts zeigen, was es nicht gibt). Schlüssel in T 7.5. Darunter eine zweite wege_ mit zwei Textlinks „Hilfe für Bewerber“ · „Hilfe für Betriebe“ (T oeffentlich.kontakt.hilfeBewerber, .hilfeBetriebe, T 7.9) → /ratgeber/hilfe-bewerber, /ratgeber/hilfe-betriebe (L1, 26.10.; nur Links im vorhandenen Zeilen-Muster, kein neues Element). |
| 3 | Formular | form. · h2 „Schreiben Sie uns“ · Felder: Ich bin (select Bewerber/Betrieb/Sonstiges, T oeffentlich.kontakt.ichBin, .bewerber, .betrieb, .sonstiges), Name, E-Mail, Telefon (freiwillig, Hinweis), Nachricht (Platzhalter), Einwilligung mit Datenschutz-Link, Knopf „Nachricht senden“; Fehlerzeilen p. je Feld (T fehler.feld.ichBin, .name, .mail, .nachrichtLeer, .zustimmung) | :123–166, css:919–924, js:1236–1270 kontaktSeite | Client-Baustein Kontaktformular. (Variante „seite“): Prüfung im Browser wie B, Absenden über fachlich/ → kontaktanfrageAnlegen(); ohne JS funktioniert das Formular als normales POST (Server-Aktion in <form action>). Spamschutz: unsichtbares Feld + Bremse (Teil 3). Parameter ?anliegen=adresse (Link aus den Einstellungen „E-Mail-Adresse ändern“, 2a 1.9, Karte 3 1.4a): „Ich bin“ und Nachricht sind vorbelegt (T oeffentlich.kontakt.adresseVorbelegt, TEXTE 7.9), die Anfrage landet in der Verwaltung als Art „Adresse ändern“. |
| 4 | Erfolg | kontakt-erfolg (role status, h2 tabindex -1 bekommt Fokus): T 3.3 „Kontakt gesendet“ (Titel, Satz mit Telefon, Knopf „Stellen ansehen“, Textlink „Zur Startseite“) | :168–176, css:925–929 | Formular wird ausgeblendet, Erfolg an seiner Stelle; ohne JS: Weiterleitung auf /kontakt?gesendet=1 mit demselben Block |
| 5 | FAQ | faq h2 „Häufige Fragen“ + 4 details | :178–195, css:930–936 | Texte in kontakt.json (kurz, fest; nicht in inhalte). FAQ 2 und 3 werden an den Plan angepasst („Ihr Konto entsteht beim Bewerben“; keine „Pakete“). Schlüssel in T 7.5. |
1.9 Merkliste
Datei merkliste/ · Teile in merkliste/. Ohne Konto liegen die Kennungen im Gerätespeicher (1a HerzKnopf); die Seite ist deshalb ein Client-Baustein, der die Stellen zu den Kennungen über die Server-Aktion stellenFuerMerkliste(ids) lädt. Mit Konto (2a) liest dieselbe Seite aus dem Konto (P Menüs).
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis |
|---|---|---|---|---|
| 1 | Kopf | u-kopf--schmal · merk-kopf: h1 „Ihre Merkliste“ (T oeffentlich.merkliste.titel), lead „{n} gemerkte Stellen“ (T …anzahl, versteckt bei 0), Knopf „Alle entfernen“ (btn-rand, versteckt bei 0) | merkliste.html:93–103, css:1305–1307, js:1385–1392 | T 1.5 sagt „Alle entfernen nur hinter „…“, mehrere über die Auswahl-Leiste“; B hat den Knopf im Kopf. Geplant: Knopf wie B (Weiche W1). Nach Klick Toast mit Rückgängig 10 s (T oeffentlich.rg.merklisteLeeren, gemeinsam.rg.knopf). |
| 2 | Liste | ul. aus Stellenkarte Variante „merkliste“ (1a): li. wie Variante „zeile“ mit Monogramm, Firma, h3-Titel-Link (deckender Link: die ganze Zeile öffnet die Stelle), MetaListe und gefülltem Herz (HerzKnopf 1a, aria-pressed=true, Vorlesetext T oeffentlich.merkliste.entfernenVon) als „Entfernen“; kein Knopf „Jetzt bewerben“ je Zeile. Nur bei der Marke „Läuft in {n} Tagen ab“ steht rechts ein Zustands-Knopf „Jetzt bewerben“ (btn-rand btn-klein → /stelle/[adresse]#bewerben) | merkliste.html:107, css:1308–1309, js:1393–1398 (B: zwei Knöpfe je Zeile, entfallen) | D-6 (entschieden 26.10.): keine Reihe oranger Knöpfe; Herz wie in der Trefferliste, Rückgängig beim Entfernen. Sortierung zuletzt gemerkt (P Listen); Marken: „Läuft in {n} Tagen ab“ bei ≤ 5 Tagen (T …laeuftAb), abgelaufene Stellen unten mit „Nicht mehr verfügbar“ (T …abgelaufen), ohne Zustands-Knopf, Titel ohne Link (Stelle liefert 410), Herz bleibt. Entfernen: Toast mit Rückgängig 10 s (T oeffentlich.rg.merkeEntfernen), Fokus auf den Rückgängig-Knopf (U D). Schlüssel oeffentlich.merkliste.entfernen bleibt ungenutzt. |
| 3 | Leer | div.: T oeffentlich.leer.merkliste + Knopf „Stellen ansehen“ (→ /jobs) | merkliste.html:108–111, css:489–493 | Baustein Leerzustand (1a) |
| 4 | Hinweis | p. ganz unten, unter der Liste: ein Satz T oeffentlich.merkliste.geraet + Textlink „Konto anlegen“ (T …kontoAnlegen → /anmelden?modus=registrieren); kein Kasten, kein Symbol | merkliste.html:112, css:617–619, 1310–1311 (B: info-box, entfällt) | nur ohne Anmeldung. D-7 (entschieden 26.10.): schlichte Zeile statt Kasten, vorhandene Werte (kleine Schrift, --text-leise). |
Gerätespeicher-Format: {stellen: [{id, gemerktAm}]} (Zeitpunkt für „zuletzt gemerkt“), festgelegt in 1a dienste/geraetespeicher.ts; 1a HerzKnopf schreibt es so (Annahme B5). Beim Anmelden (2a) wandert die Liste ins Konto (P Bewerberbereich, T oeffentlich.ok.merklisteUebernommen).
1.10 Job-Alarm
Datei job-alarm/ · Teile in job-alarm/. Parameter aus Startseite (1a A4: q, mail), Trefferliste leer (q, ort, umkreis), Fachbereich-Kachel und „Stelle nicht verfügbar“ (fachbereich).
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis |
|---|---|---|---|---|
| 1 | Seitenkopf | u-kopf--schmal, h1 (T oeffentlich.jobAlarm.titel), lead (T …einleitung) | job-alarm.html:93–100 | |
| 2 | Formular | form.: zwei Was (name q) · Wo (ort); zwei Umkreis (select 0 · 10 · 25 · 50 · 100, Werte nur als Zahl, U D) · fieldset. „Wie oft?“ mit takt_ täglich/wöchentlich (T …wieOft, …taeglich, …woechentlich); E-Mail-Adresse (T …mail); Haken Einwilligung (T …einwilligung); Knopf „Job-Alarm anlegen“ (T …anlegen) | job-alarm.html:104–123, css:1291–1301, js:1355–1383 | Was/Wo bekommen die Vorschläge aus 1a (Baustein Vorschlaege, Annahme B6). Fachbereich aus der Adresse: Feld Was wird mit dem Fachbereichsnamen vorbelegt (wie B js:1361) und fachbereich_ als verstecktes Feld mitgeschickt. „Keine E-Mail, nur speichern“ nur angemeldet (2a). Prüfung: Mail (T fehler.feld.mail), Einwilligung (T fehler.feld.zustimmung), Ort unbekannt (T fehler.feld.ortUnbekannt), nichts ausgefüllt außer Mail ist erlaubt („Alle Stellen“ wie B). Absenden über fachlich/ → jobAlarmAnlegen(); ohne JS normales POST. Spamschutz wie Kontakt. |
| 3 | Erfolg | kontakt-erfolg[data-jobalarm-ok] (role status, Fokus): Haken-SVG + erfolg-satz „Fast geschafft. Bitte bestätigen Sie Ihre E-Mail-Adresse …“ (T 3.3 Job-Alarm ohne Konto) | job-alarm.html:125–129, css:1301 | gleiche Meldung, wenn derselbe Alarm schon unbestätigt existiert (B16 geht erneut, höchstens 3 je Tag und Adresse); existiert er bestätigt, Satz „Diesen Job-Alarm haben Sie schon.“ (Schlüssel in T 7.5) |
1.11 Job-Alarm-Zielseiten (aus Mails, ohne Anmeldung)
Dateien job-alarm/, job-alarm/, job-alarm/; Aufbau wie kontakt-erfolg in einer box (U Zustandsseiten „Zielseiten aus Mails“), Texte T 3.3 „Job-Alarm“. Kennung t = Token aus der Mail (Teil 3).
| Fall | Adresse | Inhalt | Hinweis |
|---|---|---|---|
| bestätigt | /job-alarm/bestaetigt?t= | GET zeigt „Fast geschafft: noch ein Tipp“, Satz „Dann ist Ihr Job-Alarm „{was}“ in {ort} aktiv.“ und genau einen Knopf „Ja, {mail} ist meine Adresse“; danach „Ihr Job-Alarm ist aktiv. Sie bekommen {wieOft} neue Stellen für „{was}“ in {ort}.“ + Knopf „Treffer jetzt ansehen“ (→ /jobs mit den Parametern des Alarms) | erst der POST setzt zustand aktiv, bestaetigt_am (_ Nr. 29: Firmen-Postfächer rufen Links vorab auf); Knopf aus B16 |
| ändern | /job-alarm/aendern?t= | das Formular aus 1.10 vorbelegt, Knopf „Speichern“; mit behalten=1 (aus B17) oben eine Box „Job-Alarm behalten?“ mit Knopf „Job-Alarm behalten“ (POST); danach „Job-Alarm geändert.“ + „Treffer ansehen“ | aus B15-Fuß „Job-Alarm ändern“ und B17 „Job-Alarm behalten“; erst der POST setzt zuletzt_geklickt_am und leert hinweis_ende_am (Nr. 29) |
| abbestellt | /job-alarm/abbestellt?t= | GET zeigt „Job-Alarm „{was}“ abbestellen?“ mit genau einem Knopf „Ja, abbestellen“ (POST); danach „Abbestellt. Sie bekommen keine E-Mails mehr zu „{was}“.“ + Textlink „Doch wieder bestellen“ (ebenfalls POST, setzt wieder aktiv) | ein Knopf, kein weiteres Formular; der Link allein ändert nichts (_ Nr. 29). Ein-Klick bleibt nur der Kopf List-Unsubscribe-Post (RFC 8058, Mailprogramme senden POST an /api/mail-klick/abbestellen); dieselbe Aktion |
| Link ungültig/abgelaufen | alle drei | fehler.link.falsch bzw. fehler.link.abgelaufen (Bestätigungslink älter als 7 Tage: Alarm ist gelöscht) + Knopf „Job-Alarm neu anlegen“ (→ /job-alarm) |
1.12 Recht
Datei [rechtstext]/ mit dynamicParams = false und generateStaticParams = impressum, datenschutz, nutzungsbedingungen, agb; bei Bedarf barrierefreiheit (Dokument „Offene Fragen“ R5). Teile in [rechtstext]/.
| Nr | Bereich | Bausteine | B-Fundstelle | Hinweis |
|---|---|---|---|---|
| 1 | Hinweis | entfällt: die Texte sind ab dem ersten Einspielen vollständig (RECHTSTEXTE P-5050-RT); der B-Hinweis impressum.html:96 wird nicht gebaut | ||
| 2 | Impressum | recht · h1 · recht-zeilen mit Abschnitten (DDG-Angaben, Vertreten durch, Kontakt, Register, USt-IdNr., Verantwortlich MStV, Verbraucherstreitbeilegung) · recht-fuss „Stand“ | impressum.html:93–112, css:997–1011 | Text aus inhalte (rechtstext impressum). Fest im Code dazu: Zeile „Postleitzahlen und Koordinaten: GeoNames (CC BY 4.0)“ (P Technik, 1a dienste/geo) und Nennung der lokal ausgelieferten Schriften (keine Google-Fonts). Dazu Abschnitt Bildnachweis, erzeugt aus bilder. (je Bild: datei, herkunft eigen · pexels · ki · platzhalter · unbekannt, beleg (Erzeugungsprotokoll, Datei-Metadaten, Quelle oder Auskunft dessen, der das Bild erzeugt hat; Pflicht bei pexels und ki), urheber, link, bestaetigt_, bestaetigt_): Pexels- und andere Stock-Bilder mit Name und Link zur Quellseite, KI-Bilder als Satz T oeffentlich.recht.bildnachweisKi. Die B-Bilder in gemeinsam/ (Hero, Arbeitgeber, Ratgeber, Team) haben das Format 1376 × 768, das für KI-Erzeugung spricht; das ist eine Vermutung, kein Beleg. Darum trägt jedes Bild unbekannt, bis der Beleg in bilder. steht (Baureihenfolge S10, vor 1a.10); mit unbekannt gibt es weder Marke noch Nachweis-Zeile, und Karte 4 T14 lässt kein Bild mit unbekannt oder platzhalter live gehen (Dokument „Offene Fragen zum Abschluss“, Gruppe Bilder). ODR-Link nirgends. |
| 3 | Datenschutz | h1 · 18 h2-Abschnitte · Stand | datenschutz.html:93–128 (Optik) | aus inhalte, Text RECHTSTEXTE P-5050-RT Abschnitt 2 (ersetzt die 28 B-Abschnitte; Pool, KI-Texte und Zahlungen kommen erst mit ihrer Funktion dazu) |
| 3a | Nutzungsbedingungen | h1 „Nutzungsbedingungen für Bewerberinnen und Bewerber“ · 11 h2-Abschnitte · Stand | wie Nr. 3 | aus inhalte, Text RECHTSTEXTE P-5050-RT Abschnitt 3 |
| 4 | AGB | h1 „Allgemeine Geschäftsbedingungen für Arbeitgeber“ · 12 Paragrafen · Stand | agb.html:93–120 (Optik) | aus inhalte, Text RECHTSTEXTE P-5050-RT Abschnitt 4 (ohne Pakete, Abo, Rechnungen und Import, die es zum Livegang nicht gibt) |
KI-Kennzeichnung: Nur Bilder mit herkunft: ki in bilder. tragen am Bild selbst die kleine Marke T gemeinsam.bild.kiHinweis „KI-generiert“ (<span class="ki-marke" aria-hidden="true">, unten rechts, kleine Schrift auf halbdurchsichtigem Grund, nicht anklickbar, wie auf dynora-physio.de), und ihr Alt-Text endet mit T gemeinsam.bild.kiAlt „KI-generiertes Bild.“; Baustein bild/ in 1a gemeinsam liest bilder.. Pexels- und Stock-Bilder bekommen keine Marke, nur die Nachweis-Zeile im Impressum mit Name und Link. Platzhalter-Bilder (platzhalter) sind nur für die Testumgebung erlaubt und gehen nie live (Karte 4 T14). Dieselbe Regel für alle anderen KI-Stellen: maschinell übersetzte Anzeigen zeigen den Hinweis T gemeinsam.sprache.maschinell „Mit KI übersetzt. Verbindlich ist die deutsche Fassung.“ (1a, vorhanden), KI-Texte für Arbeitgeber (2b.5) tragen an der Anzeige den kleinen Hinweis „Mit KI erstellt“ (Schlüssel kommt mit 2b), und ein künftiger KI-Radierer oder Bildumbau kennzeichnet das Bild wie ein KI-Bild.
Barrierefreiheitserklärung: erst wenn der Kunde das BFSG bejaht (U A.8, offene Frage R5 im Dokument „Offene Fragen zum Abschluss“); dann vierter Schlüssel barrierefreiheit ohne Code-Änderung. Fußzeile (entschieden 26.10., gebaut in 1a 1.1): D-8 kein Link „Cookie-Einstellungen“ (Schlüssel gemeinsam.fuss.cookies ungenutzt), der Cookie-Hinweis bleibt. D-9 Sozial-Symbole erst, wenn die Adressen in einstellungen.betreiber stehen (1a A2). D-10 „Lebenslauf hinterlegen“ (Fußzeile, Start) fehlt bis Abschnitt 2b (1a A3).
1.13 Sprachen, Google for Jobs, Musterdaten (ohne eigene Seite)
- Sprachen: alle 1b-Schlüssel in
sprachen/(fachbereiche.json, unternehmen.json, firma.json, arbeitgeber.json, ratgeber.json, ueberuns.json, kontakt.json, merkliste.json, jobalarm.json, recht.json); Inhalte (Ratgeber, Rechtstexte, Seitentexte) je Sprache in{de,en,tr}/ inhalte_, fehlende Fassung → deutsch mit Hinweis (U B.7). Erstfassungen unterfassungen inhalte/+<sprache>/ <art>/ <schluessel>. html .(Titel, Teaser, Bild), Einspielskriptjson db/(idempotent, prüft vorher Textprüfung). Gegenlesen tr vor dem Livegang (Kunde nennt wen).inhalte-einspielen. ts - Google for Jobs:
app/(Stellen aktiv und läuft ab, Firmenprofile mit sichtbaren Stellen, Fachbereiche, Ratgeber, Über uns, Kontakt, Für Arbeitgeber, Recht; je Sprache mit hreflang-Alternates; bei > 5.000 Einträgen Sitemap-Index),sitemap. ts app/(Testadresse: alles gesperrt + noindex-Kopfzeile aus 1a; Live: erlaubt, Sitemap-Adresse; Umschaltung über Umgebungsvariablerobots. ts BULULU_), JSON-LD aus 1a google.ts bleibt, Regel W5 (nur aktiv). Search Console und Domain erst Abschnitt 4.UMGEBUNG - Musterdaten:
db/aus 1a wird ergänzt (Teil 6): 6 Ratgeber-Artikel und 2 Hilfe-Artikel (hilfe-bewerber, hilfe-betriebe), 3 Rechtstexte (B-Platzhalter), Seitentexte Über uns, 4 Firmen mit Logo (COPLA, Induserv + 2 Monogramm-Firmen) und Beschreibung, 2 Job-Alarme (unbestätigt, aktiv), 2 Kontaktanfragen, Fachbereich-Symbole. Nur Testumgebung, Livegang löscht (Zeitplan 4).musterdaten/
Bausteinkatalog-Ergänzung (nur Neues gegenüber 1a)
Welche wiederverwendbaren Teile, etwa Kontaktformular und Spamschutz, für diese Seiten neu gebaut werden.
Dieser Abschnitt beschreibt nur die technische Umsetzung. Mit dem Schalter „Technische Angaben“ blenden Sie ihn ein.
Regel wie 1a: Was zwei Seiten brauchen, liegt in bausteine/, fachlich/, dienste/; was nur eine Seite braucht, liegt bei ihr. CSS von B bleibt in stile/; neues CSS nur beim Baustein mit vorhandenen Werten.
2.1 Neue gemeinsame Bausteine
| Baustein (Ordner) | Dateien | Aus B: HTML | Aus B: CSS-Klassen | Aus B: app.js | Benutzt von |
|---|---|---|---|---|---|
| kontaktformular/ | Kontaktformular.tsx (Client; Varianten seite · arbeitgeber), Erfolg.tsx, felder.ts (Feldliste + Prüfregeln, auch vom Server genutzt) | kontakt.html:126–176, arbeitgeber.html:248–262 | kontakt-form, kontakt-erfolg, formular, feld, zwei, check, check-feld, fehler, hinweis-klein | 1236–1270 kontaktSeite, 901–916 kontaktFormular, 388 mailOk, 389 fehlerZeigen | Kontakt, Für Arbeitgeber |
| sortierung/ | Sortierung.tsx (liegt seit 1a in bausteine/; hier kommt die Variante firmen dazu) | jobs.html:174–184 | wie 1a | 588 | Jobs (1a), Unternehmen |
| seitenkopf/ | Seitenkopf.tsx (u-kopf, Varianten normal · schmal; h1 mit tabindex -1, lead, optional ueber, optional rechter Knopf wie merk-kopf) | kategorien.html:93–100, merkliste.html:93–103 | u-kopf, u-kopf__raster, u-kopf--schmal, ueber, lead, merk-kopf | Fachbereiche, Unternehmen, Ratgeber, Über uns, Kontakt, Merkliste, Job-Alarm | |
| band/ | Band.tsx (h2, Satz, bis zwei Knöpfe) | ratgeber.html:135–142 | band, knopf-reihe, btn-dunkel | Ratgeber (Über uns ohne Band, D-12) | |
| inhalt/ | InhaltHtml.tsx (gibt bereinigtes HTML aus), bereinigen.ts (Allowlist, läuft beim Einspielen und beim Speichern aus der Verwaltung 2b) | ratgeber-*.html:111–135 | artikel, artikel-hinweis | Artikel, Recht, Über uns, Firmenprofil (Beschreibung als Absätze) | |
| ratgeberkarte/ | RatgeberKarte.tsx (rg-karte), Raster.tsx (rg-raster, Variante drei) | ratgeber.html:122–128, ratgeber-*.html:170–175 | rg-raster, rg-raster--drei, rg-karte*, lesezeit | Ratgeber, Artikel | |
| firmenkachel/ | FirmenKachel.tsx (Variante gross; nutzt Monogramm aus 1a) | unternehmen.html:108 (js-erzeugt), index.html:259–264 | firma-kachel, firma-kachel--gross, firmen-raster, firmen-raster--seite | 436 firmenKacheln, 1315–1318 | Unternehmen, Start-Firmenraster (1a FirmenRaster.tsx ruft ab 1b diesen Baustein) |
| bremse/ (in dienste/) | bremse.ts (Zähler je Schlüssel im Speicher der App, Fenster 10 Minuten; Schlüssel = Hash aus Formularname + Mail bzw. IP, IP nur gehasht und flüchtig) | neu (P Sicherheit Spamschutz) | Kontaktformular, Job-Alarm, Folgen; ab 2a Registrierung, Bewerben | ||
| honigfeld/ | Honigfeld.tsx (unsichtbares Feld, Name aus Zufall je Bau; Server verwirft ausgefüllte) | neu (P Sicherheit) | wie bremse |
Erweiterungen vorhandener 1a-Bausteine (keine neuen Ordner): Werbeflaeche. Variante „ratgeber“ (Billboard) und Fläche „ratgeber“ an „suche“/„stelle“; Stellenkarte. Variante „merkliste“ bekommt die Marken „Läuft in n Tagen ab“ und „Nicht mehr verfügbar“ und den Zustand ohne Link; Leerzustand. unverändert; Fehlerseite. bekommt den Fall „Link ungültig/abgelaufen“ (Zielseiten); geraetespeicher. bekommt inseratEntwurf lesen/schreiben und das Merklisten-Format mit Zeitpunkt.
2.2 Fachlich und Dienste (neu)
| Ordner | Dateien | Inhalt | |
|---|---|---|---|
| fachlich/jobalarm/ | anlegen.ts (jobAlarmAnlegen(eingabe) → {status: 'bestaetigen' | 'schonAktiv'}; Dublettenprüfung über suchschluessel), bestaetigen.ts (per Token), aendern.ts, abbestellen.ts (+ wiederBestellen), treffer.ts (trefferSeit(alarm, seit) über fachlich/suche/suchen.ts, nur zustand aktiv), token.ts (erzeugen, Hash, prüfen), felder.ts (Typ JobAlarm, Takt, Zustand), suchschluessel.ts (normierte Zeichenkette aus q, plz, umkreis, fachbereich, firma) | eine Suche, zwei Nutzer (Seite und Sammelmail) |
| fachlich/kontakt/ | anlegen.ts (kontaktanfrageAnlegen(eingabe, quelle)), felder.ts | Zustand „eingegangen“, Mail V04 | |
| fachlich/inhalte/ | lesen.ts (inhalt(art, schluessel, locale) → Fassung oder deutsche mit Hinweis), liste.ts (ratgeberListe(locale) und weitereArtikel(ausser, n=3), beide ohne Rubrik „Hilfe“; hilfeAdresse(rolle) für Konto-Menü und Kontaktseite), felder.ts (Art, Stand, Typ) | Verwaltung (Editor) erst 2b | |
| fachlich/firma/ | ergänzt: liste.ts (firmenSuchen({q, fachbereich, ort, sort, seite}) → {treffer, gesamt}), profil.ts (firmaNachAdresse(adresse, sitzung?) mit Sichtbarkeit: aktiv → 200, gesperrt → 410, registriert → 200 nur für angemeldete Nutzer dieser Firma (2a Link „So sehen Bewerber Ihren Betrieb“), sonst 404; alte Adresse aus firmen_adressen (1a) → 301), branche.ts (häufigster Fachbereich) | ||
| fachlich/stelle/abfragen.ts | ergänzt: stellenDerFirma(firmaId), stellenNachIds(ids) (für die Merkliste; liefert auch nicht sichtbare mit Kennzeichen verfuegbar: false), ablaufInTagen(stelle) | ||
| fachlich/fachbereich/liste.ts | ergänzt: mitAnzahl(locale) sortiert nach Anzahl, Symbol | ||
| dienste/mail/ (1a) | ergänzt um vorlagen/b15.tsx, b16.tsx, b17.tsx, v04.tsx; einstellungen. liefert ab hier den Absender; bezug_art-Werte alarm und kontaktanfrage | Dienst (senden.ts), Warteschlange (warteschlange.ts, Tabelle mail_warteschlange), Kopfzeilen und Rahmen kommen aus 1a 2.2 (Fundament, 26.10.); V05 (Antwort der Verwaltung) baut Abschnitt 3 mit der Verwaltung | |
| dienste/bremse.ts, dienste/honigfeld.ts | siehe 2.1 | ||
| hintergrund/aufgaben/ | job-alarm-versand.ts (täglich 07:00: je aktivem Alarm Treffer seit letzter Mail; wöchentliche nur montags; höchstens eine Mail je Adresse und Tag: Alarme derselben Adresse in einer Sammelmail), job-alarm-aufraeumen.ts, sitemap-waermen.ts (nicht nötig, Sitemap wird je Abruf gebaut; gestrichen) | pg-boss wie 1a | |
| sprachen/{de,en,tr}/ | 10 neue Dateien (1.13) |
2.3 Nur in 1b (seitenspezifisch)
| Ort | Dateien |
|---|---|
| …/fachbereiche/page.tsx · _liste/Raster.tsx · fachbereiche.css (nur D-11-Regel) | |
| …/firmen/page.tsx · _liste/FirmenSuche.tsx (Client) · Filter.tsx · daten.ts | |
| …/firmen/[adresse]/page.tsx · _profil/FirmenKopf.tsx · Folgen.tsx (Client, mit Formular) · UeberUns.tsx · OffeneStellen.tsx · Eckdaten.tsx · folgen.css | |
| …/fuer-arbeitgeber/page.tsx · _seite/Hero.tsx · Preissaetze.tsx · Nutzen.tsx · Schritte.tsx · Ausprobieren.tsx (Client) · Vorschau.tsx · WerbungTeaser.tsx · KontaktBlock.tsx | |
| …/ratgeber/page.tsx · _uebersicht/Uebersicht.tsx | |
| …/ratgeber/[adresse]/page.tsx · _artikel/ArtikelKopf.tsx · ArtikelText.tsx · Schluss.tsx · Seitenleiste.tsx · WeitereArtikel.tsx | |
| …/ueber-uns/page.tsx · _seite/Wer.tsx · Bereiche.tsx · Ansprechpartner.tsx | |
| …/kontakt/page.tsx · _seite/Wege.tsx · Faq.tsx | |
| …/merkliste/page.tsx · _liste/Merkliste.tsx (Client) · AlleEntfernen.tsx · Hinweis.tsx | |
| …/job-alarm/page.tsx · _formular/JobAlarmFormular.tsx (Client) · Erfolg.tsx · parameter.ts | |
| …/job-alarm/bestaetigt/page.tsx · aendern/page.tsx · abbestellt/page.tsx · _ziel/Zielseite.tsx | |
| …/[rechtstext]/page.tsx · _recht/Rechtstext.tsx · Hinweis.tsx | |
| app/sitemap.ts · app/robots.ts | |
| app/api/mail-klick/route.ts | zählt den Klick aus Alarm-Mails (zuletzt_geklickt_am) und leitet auf das Ziel; kein Zählpixel |
| db/migrationen/0002_inhalte.sql + rueckweg · musterdaten/inhalte.ts · job-alarme.ts · kontaktanfragen.ts · firmen.ts (erweitert) | |
| inhalte/de/ratgeber/.html+json · inhalte/de/recht/.html · inhalte/de/seitentexte/ueber-uns.json · en/, tr/ (Ratgeber-Übersetzungen erst, wenn de gegengelesen ist) |
Nicht übernommen aus B (bewusst): paket-Block und css:579–584 (U 3.23), data-ki-status (2b), speicher./("alarme") (ersetzt durch Server), Werbe-Konfigurator-Aufrufe data-werbe-konfigurator (Abschnitt 3; Links zeigen auf /fuer-arbeitgeber#werbung), Inline-Styles (Klassen wie A17), „Stellen folgen“-Kleintext bleibt (oeffentlich.fachbereiche.stellenFolgen, T 7.5).
Datenmodell-Ergänzung
Was Bululu zu Job-Alarmen, Kontaktanfragen, Ratgeber- und Rechtstexten speichert, und dass dabei keine IP-Adressen anfallen.
Dieser Abschnitt beschreibt nur die technische Umsetzung. Mit dem Schalter „Technische Angaben“ blenden Sie ihn ein.
Migration db/ mit Rückweg; Regeln wie 1a (UUID v7, angelegt_am/geaendert_am, echte Felder für alles Filterbare). 1a-Tabellen werden nur ergänzt, nichts umbenannt.
job_alarme
| Feld | Typ | Hinweis |
|---|---|---|
| id | uuid PK | |
| citext, Pflicht | kleingeschrieben, Tippfehler-Prüfung nur im Browser (T fehler.feld.mailTippfehler) | |
| konto_id | uuid, leer | FK konten (2a); beim Anmelden werden Alarme mit derselben Mail übernommen (P Bewerberbereich) |
| firma_id | uuid FK firmen, leer | „Firma folgen“; dann q/ort/fachbereich leer |
| q | text, leer | Suchbegriff |
| ort_text, plz_id, lat, lng | text / FK plz / double | wie suchen(): aufgelöster Ort; leer = überall |
| umkreis_km | smallint, Standard 25 | 0, 10, 25, 50, 100 |
| fachbereich_id | FK fachbereiche, leer | |
| art | beschaeftigungsart[] , leer | aus Trefferliste leer übernommen (H13), sonst leer |
| deutsch | deutschstufe[], leer | |
| homeoffice | boolean, leer | |
| suchschluessel | text, generiert aus den Suchfeldern | eindeutig mit mail: UNIQUE (mail, suchschluessel) |
| takt | enum alarm_takt: taeglich, woechentlich, keine | „keine“ nur mit konto_id (Prüfung im Code) |
| sprache | text (de/en/tr) | Sprache der Mails |
| zustand | enum alarm_zustand: angelegt, aktiv, abbestellt, beendet | angelegt = wartet auf Bestätigung; beendet = Alarm ohne Konto nach 12 Monaten ohne Klick (B17); Alarme mit Konto leben mit dem Konto |
| token_hash | text eindeutig | Hash eines Zufallswerts (32 Byte); der Klartext steht nur in den Mails. Ein Token je Alarm für Bestätigen, Ändern, Abbestellen, Behalten (Annahme B8) |
| bestaetigt_am, abbestellt_am, beendet_am | timestamptz, leer | |
| letzte_mail_am | timestamptz, leer | Stand für „seit {letzteMail}“ und trefferSeit |
| zuletzt_geklickt_am | timestamptz, leer | Klick auf einen Link einer Alarm-Mail (api/mail-klick); Grundlage für B17 |
| hinweis_ende_am | timestamptz, leer | B17 gesendet |
| quelle | enum alarm_quelle: start, suche, fachbereich, stelle_weg, firma, seite | für die Zählung, nicht fachlich |
| Indizes | (zustand, takt); (mail); (firma_id) wo gesetzt; (fachbereich_id) |
job_alarm_mails: id, alarm_id FK (bei Löschung mit), gesendet_am, anzahl_stellen smallint, art enum (sammel, bestaetigen, ende). Zweck: „seit {letzteMail}“, Nachweis, dass höchstens eine Sammelmail am Tag ging. 13 Monate.
mail_warteschlange (1a Teil 3, Fundament): 1b legt keine eigene Tabelle an, sondern nutzt sie mit bezug_art alarm und kontaktanfrage.
kontaktanfragen
| Feld | Typ | Hinweis |
|---|---|---|
| id | uuid PK | |
| quelle | enum anfrage_quelle: kontakt, arbeitgeber | Seite; Premium- und Werbeanfragen haben in Abschnitt 3 eigene Tabellen (premium_anfragen, werbung_anfragen) und eine gemeinsame Sicht anfragen_gesamt |
| rolle | enum anfrage_rolle: bewerber, betrieb, sonstiges | Für Arbeitgeber fest betrieb |
| name, firma (leer), mail citext, telefon (leer), nachricht | text | nachricht höchstens 4.000 Zeichen (T fehler.feld.zuLang) |
| sprache | text | für die Antwort |
| zustand | enum anfrage_zustand: eingegangen, in_bearbeitung, beantwortet, erledigt, weitergegeben | P Lebenslauf Kontaktanfrage; in 1b nur „eingegangen“ gesetzt |
| frist_am | timestamptz | angelegt + einstellungen.fristen.kontaktanfrage_werktage (1; Karte 3 Einstellungen › Fristen); Verwaltung sortiert danach (P Listen; Annahme B9) |
| uebernommen_von, beantwortet_am, antwort, notiz | leer in 1b | Abschnitt 3 |
| weitergeleitet_an_3bs_am | timestamptz, leer | V04-Kopie an einstellungen.betreiber.kontakt_mail_3bs |
| Index | (zustand, frist_am) |
Keine IP-Adresse, kein Browser-Kennzeichen (P Zählung ohne IP); die Bremse hält ihre Zähler nur im Speicher.
inhalte
| Feld | Typ | Hinweis |
|---|---|---|
| id | uuid PK | |
| art | enum inhalt_art: ratgeber, rechtstext, seitentext | Mailvorlagen liegen ab Abschnitt 3 in der eigenen Tabelle mailvorlagen, nicht hier |
| schluessel | text | eindeutig mit art: ratgeber „lebenslauf“, rechtstext „impressum“, seitentext „ueber-uns.wer“ |
| rubrik | text, leer | Ratgeber-Rubrik („Einstieg“) |
| sortierung | smallint | Ratgeber-Reihenfolge |
| bild | text, leer | Pfad unter public/bilder/ratgeber/ für den Erstbestand aus dem Einspielskript (B-Bilder); ab Abschnitt 3 lädt die Verwaltung Bilder über die Ablage in dateien (zweck ratgeberbild, öffentlich über /api/datei/[id]) und inhalte. (Karte 3 Teil 3) geht vor bild |
| bild_alt_de | text, leer | Alt-Text (B liefert ihn) |
| lesezeit_min | smallint, leer | |
| zustand | enum inhalt_zustand: entwurf, veroeffentlicht | Platzhalter-Rechtstexte sind veröffentlicht mit entwurf-Marke (unten) |
| entwurf_hinweis | boolean, Standard false | bleibt für Rechtstexte false (Texte vollständig, RECHTSTEXTE P-5050-RT); nur für künftige Entwürfe |
| veroeffentlicht_am | date, leer | „Stand“ in der Fußzeile des Rechtstexts |
| UNIQUE (art, schluessel) |
inhalte_fassungen: inhalt_id FK, sprache (de, en, tr, ar), titel, untertitel (lead), teaser (Karte), html text (bereinigt), schluss_titel, schluss_text, schluss_knopf_ziel (leer), stand enum (original, maschinell, geprueft), quelle_geaendert_am; PK (inhalt_id, sprache). Deutsch ist immer „original“.
fachbereiche (ergänzt): symbol text (Schlüssel aus KAT_ICON js:58–75, Standard industrie).
firmen (ergänzt): beschreibung text leer („Über uns“, Absätze), webseite text leer (https-Prüfung), telefon_frei boolean Standard false (Eckdaten zeigen Telefon nur dann).
einstellungen (ergänzt): betreiber {name, strasse, plz, ort, telefon, kontakt_mail, kontakt_mail_3bs, absender_mail, absender_name, sozial: {facebook, instagram, xing, linkedin}} (P „Einstellungs-Karte Betreiber“); kontakt_mail_3bs bleibt leer, bis der Kunde antwortet (Sammel-Anfrage Z3, Karte 4 Teil 1a, spätestens 25.11.); fehlt sie, geht V04 nur an die Verwaltung. job_ „07:00“.
Merkliste ohne Konto: keine Tabelle (P Fristen: „liegt nur im Browser“). Gerätespeicher-Format siehe 1.9. merkliste_ (2a): konto_id, stelle_id, gemerkt_am; beim Anmelden Zusammenführung.
Fachbereich-Zustand „zusammengeführt“ (1a) wirkt in 1b: Kacheln, Filter, Alarme und Über-uns-Liste zeigen nur aktive; ein Alarm mit zusammengeführtem Fachbereich sucht im Ziel (zusammengefuehrt_), Auflösung in fachlich/jobalarm/treffer.ts.
3.2 Abfragen und Aktionen 1b (Signaturen)
jobAlarmAnlegen({mail, q, ort, umkreis, fachbereich, art[], deutsch[], homeoffice, takt, sprache, quelle, firmaId?}) → {status: 'bestaetigen'|'schonAktiv'|'bestaetigenErneut'}: löst Ort auf (fehler.feld.ortUnbekannt), bildet suchschluessel, legt an oder findet Dublette; schreibt B16 in die Warteschlange; Bremse 3 je Mail und Tag, 20 je IP-Hash und 10 Minuten; gesperrte Adresse (Karte 3adresseGesperrt()in dienste/bremse.ts) → Erfolg zeigen, nichts schreiben.jobAlarmBestaetigen(token) → {alarm} | 'ungueltig' | 'abgelaufen',jobAlarmAendern(token, eingabe),jobAlarmAbbestellen(token),jobAlarmWiederBestellen(token),jobAlarmBehalten(token)(setzt zuletzt_geklickt_am, löscht hinweis_ende_am).trefferSeit(alarm, seit) → {treffer: StellenKarte[], gesamt}: suchen() mit den Feldern des Alarms, zusätzlichveroeffentlicht_, nur zustand aktiv (nicht pruefung, W5), bei firma_id: alle neuen Stellen der Firma.am > seit kontaktanfrageAnlegen({quelle, rolle, name, firma, mail, telefon, nachricht, sprache}) → {id}: Prüfung (felder.ts), Honigfeld, Bremse 5 je Mail und Tag, gesperrte Adresse wie beim Job-Alarm; V04 an Verwaltung + 3BS-Kopie; Zählungzaehle("kontakt", {quelle, rolle}).stellenFuerMerkliste(ids: string[]) → MerkKarte[](höchstens 100, Reihenfolge wie übergeben,verfuegbar,laeuftAbInTagen).firmenSuchen({q, fachbereich, ort, sort, seite, locale}) → {treffer: FirmenKachel[], gesamt},firmaNachAdresse(adresse, locale),stellenDerFirma(firmaId).inhalt(art, schluessel, locale) → {fassung, sprachHinweis: boolean},ratgeberListe(locale),weitereArtikel(schluessel, 3, locale).fachbereicheMitAnzahl(locale) → {schluessel, name, symbol, anzahl}[].- Zählung neu:
zaehle("job_,alarm", {quelle, status}) zaehle("kontakt", …),zaehle("folgen"),zaehle("merkliste_,entfernt") zaehle("ratgeber_.aufruf", {schluessel})
Handlungen der Rolle Besucher in 1b
Jeder Klick eines Besuchers auf diesen Seiten mit seiner Wirkung und dem Test, der ihn absichert.
Aus der Aktionen-Matrix (FUNKTIONEN-CHECK, Besucher) und den Abläufen 1 und 11. Nummern laufen nach 1a weiter (H29 ff.). Tests wie 1a ohne Browser (PGlite, Testing Library im jsdom); Mails werden in der Prüfung aus der Warteschlange gelesen, nicht gesendet.
| Nr | Bildschirm | Knopf/Link (Wortlaut T) | Wirkung | Test (Datei · prüft) |
|---|---|---|---|---|
| H29 | Fachbereiche | Kachel | /jobs?fachbereich=metall; Kachel mit 0 Stellen → /job-alarm?fachbereich=metall, Text „Job-Alarm einrichten“ | pruefung/seiten/fachbereiche.test.ts · Reihenfolge nach Anzahl, leere Kachel ohne Link auf Jobs, zusammengeführter Fachbereich fehlt |
| H30 | Unternehmen | Name tippen, Fachbereich/Ort wählen, Sortierung | Adresse trägt q/fachbereich/ort/sort; Liste neu (mit JS live, ohne JS nach Absenden); Leerzustand bei 0 | pruefung/seiten/firmen.test.ts · firmenSuchen() findet Teilnamen, A–Z und meiste Stellen sortieren richtig, Firma ohne sichtbare Stelle fehlt |
| H31 | Unternehmen | Kachel · „Firmenprofil anlegen“ · „Mehr laden“ | /firmen/[adresse] · /anmelden?modus=firma · ?seite=2 | firmen.test.ts · Links |
| H32 | Firmenprofil | „Folgen“ (ohne Konto) | Formular klappt auf; Senden legt job_alarme mit firma_id an (zustand angelegt), B16 in der Warteschlange, aria-pressed true, Satz „Fast geschafft …“ | pruefung/seiten/firmenprofil.test.ts + pruefung/fachlich/jobalarm/anlegen.test.ts · Alarm mit firma_id, zweites Senden derselben Mail legt keinen zweiten an |
| H33 | Firmenprofil | Stelle öffnen · Webseite · Telefon | /stelle/[adresse]; Webseite nur mit Feld, rel noopener; Telefon nur bei telefon_frei | firmenprofil.test.ts · Top zuerst, dann neueste; Eckdaten je Fall |
| H34 | Firmenprofil (gesperrt/unbekannt) | 410 mit fehler.gesperrt.firmaBewerber bzw. 404 | firmenprofil.test.ts | |
| H35 | Für Arbeitgeber | „Stelle kostenlos inserieren“ · „Beratung anfragen“ · „Werbung planen“ | /anmelden?modus=firma · #kontakt · /fuer-arbeitgeber/werbung | pruefung/seiten/arbeitgeber.test.ts · Adressen, kein „Paket“-Wort auf der Seite (links.test.ts erweitert: alle 1b-Links auf bekannte Adressen) |
| H36 | Für Arbeitgeber | Ausprobieren: Felder füllen, „Weiter zur Registrierung“ | Vorschau live; Eingaben als inserat_entwurf im Gerätespeicher; Navigation zu /anmelden?modus=firma&weiter=stelle-neu | pruefung/seiten/arbeitgeber/ausprobieren.test.ts · Vorschau zeigt Titel/Ort/Art/Fachbereich, Gerätespeicher-Baustein wird mit allen Feldern aufgerufen |
| H37 | Für Arbeitgeber, Kontakt | Kontaktformular „Nachricht senden“ | kontaktanfragen (eingegangen, quelle), V04 an Verwaltung (+ 3BS, wenn Adresse da), Erfolgsblock mit Fokus; Fehler je Feld; Honigfeld gefüllt → still verwerfen (Erfolg zeigen, nichts speichern) | pruefung/seiten/kontakt.test.ts · Pflichtfelder, Einwilligung, Rolle fest „betrieb“ in Variante arbeitgeber; pruefung/fachlich/kontakt/anlegen.test.ts · Datensatz, V04-Inhalt (Art, Von, Ich bin, Nachricht), 3BS-Kopie nur mit Adresse, Bremse ab 6. Anfrage |
| H38 | Kontakt | Telefon-Link · Impressum-Link · „Hilfe für Bewerber“ · „Hilfe für Betriebe“ · FAQ auf/zu | tel: aus Betreiber; Hilfe-Links → /ratgeber/hilfe-bewerber, /ratgeber/hilfe-betriebe (1.6); details nativ | kontakt.test.ts · ohne kontakt_mail fehlt die E-Mail-Karte; beide Hilfe-Links vorhanden, Ziel liefert 200 mit Rubrik „Hilfe“ |
| H39 | Ratgeber | Karte öffnen · „Stellen ansehen“ | /ratgeber/[adresse] · /jobs | pruefung/seiten/ratgeber.test.ts · 6 Karten aus Musterdaten in sortierung, nur veröffentlichte; Werbefläche „ratgeber“ zeigt Platzhalter |
| H40 | Artikel | Lesen · „Weitere Artikel“ · Schluss-Knopf | HTML bereinigt; 3 andere Artikel; Knopf-Ziel | pruefung/seiten/artikel.test.ts · Script-Tag im HTML wird entfernt (bereinigen.test.ts), aktueller Artikel fehlt in „Weitere“, en ohne Fassung zeigt deutsch + Hinweis |
| H41 | Über uns | Telefon (Ansprechpartner) | tel: aus einstellungen.betreiber | pruefung/seiten/ueberuns.test.ts · genau drei Abschnitte (Wer wir sind, Fachbereiche, Ansprechpartner; D-12), kein Band, keine Haken-Listen; Fachbereiche-Liste = aktive Fachbereiche; „Seit {jahr}“ fehlt ohne Jahr |
| H42 | Merkliste | Öffnen | Kennungen aus dem Gerätespeicher → stellenFuerMerkliste; Reihenfolge zuletzt gemerkt; je Zeile Herz gefüllt, kein „Jetzt bewerben“ (D-6), Zustands-Knopf nur bei „Läuft in {n} Tagen ab“; abgelaufene unten mit Marke; Hinweis-Zeile ganz unten (D-7); Zähler im Kopf stimmt | pruefung/seiten/merkliste.test.ts · 3 Kennungen, eine läuft in 3 Tagen ab (einziger Knopf), eine abgelaufen, eine unbekannt (fehlt still); kein btn-primary in der Liste; p. nach der Liste |
| H43 | Merkliste | Herz „{titel} von der Merkliste entfernen“ (gefüllt, D-6) | Zeile weg, Toast „Von der Merkliste entfernt.“ + Rückgängig 10 s (Fokus darauf); Rückgängig stellt Zeile und Reihenfolge wieder her; Kopf-Zähler | merkliste.test.ts · Gerätespeicher nach Entfernen und nach Rückgängig; Timer 10 s |
| H44 | Merkliste | „Alle entfernen“ | Liste leer, Leerzustand, Toast mit Rückgängig | merkliste.test.ts |
| H45 | Merkliste | Zeile/Titel (deckender Link) · „Jetzt bewerben“ (nur bei „Läuft ab“) · „Konto anlegen“ (Hinweis-Zeile) · „Stellen ansehen“ (leer) | /stelle/[adresse] · /stelle/[adresse]#bewerben · /anmelden?modus=registrieren · /jobs | merkliste.test.ts · Links; die Zeile ohne Ablauf-Marke hat keinen Bewerben-Link |
| H46 | Job-Alarm | „Job-Alarm anlegen“ | Prüfung (Mail, Einwilligung, Ort); job_alarme „angelegt“ mit aufgelöstem Ort und suchschluessel; B16 in Warteschlange mit Token-Link; Erfolgsblock mit Fokus; Dublette unbestätigt → B16 erneut (höchstens 3/Tag), bestätigt → „Diesen Job-Alarm haben Sie schon.“ | pruefung/seiten/jobalarm.test.ts · Vorbelegung aus q/ort/umkreis/fachbereich/mail; anlegen.test.ts · Felder, Dublette, Bremse, B16-Text mit „{was}“, {ort} + {km} km, {wieOft} |
| H47 | Mail B16 | „Job-Alarm bestätigen“ → Zielseite „Ja, {mail} ist meine Adresse“ | /job-alarm/bestaetigt?t= (GET zeigt nur an), POST → zustand aktiv, bestaetigt_am; Zielseite mit „Treffer jetzt ansehen“ (→ /jobs mit Parametern) | pruefung/seiten/jobalarm-ziel.test.ts · gültiger Token, zweiter Aufruf bleibt aktiv, falscher Token → fehler.link.falsch, Alarm älter 7 Tage gelöscht → fehler.link.abgelaufen + „Job-Alarm neu anlegen“ |
| H48 | Mail B15 | „Alle {n} Stellen ansehen“ · Stellen-Zeilen · „Job-Alarm ändern“ · „Abbestellen“ | Links laufen über /api/mail-klick?t=&ziel= (setzt zuletzt_geklickt_am, 302 aufs Ziel; Stellen-Links tragen von=job_, bei „Firma folgen“ von=folgen, für die Herkunftszählung, Karte 1a A24); Ändern → Formular vorbelegt → „Job-Alarm geändert.“; Abbestellen → zustand abbestellt, Zielseite mit „Doch wieder bestellen“ | pruefung/api/mail-klick.test.ts · nur Ziele auf bululu-Adressen, sonst Startseite; jobalarm-ziel.test.ts · ändern speichert neue Suche und bleibt aktiv; abbestellen/wieder bestellen wechseln Zustand |
| H49 | Mail B17 | „Job-Alarm behalten“ | /job-alarm/aendern?t=&behalten=1 → zuletzt_geklickt_am jetzt, hinweis_ende_am leer, Text „Job-Alarm geändert.“ | jobalarm-ziel.test.ts |
| H50 | Hintergrund | Sammelmail | täglich 07:00: je aktivem Alarm trefferSeit(letzte_mail_am ?? bestaetigt_am); 0 Treffer → keine Mail; mehrere Alarme einer Adresse → eine Mail mit Blöcken; wöchentlich nur montags; „pruefung“-Stellen nie; job_alarm_mails + letzte_mail_am; List-Unsubscribe-Kopfzeile | pruefung/hintergrund/job-alarm-versand.test.ts · Fälle 0/1/12 Treffer (höchstens 10 Zeilen + „und 2 weitere“), zwei Alarme eine Mail, Montag/Dienstag, Firma-Alarm Betreff „Neue Stelle bei {firma}“ |
| H51 | Hintergrund | Aufräumen | angelegt > 7 Tage → gelöscht; nur ohne konto_id: aktiv und zuletzt_geklickt_am (oder bestaetigt_am) > 12 Monate → B17 einmal, 14 Tage später beendet; Alarme mit Konto nie | pruefung/hintergrund/job-alarm-aufraeumen.test.ts |
| H52 | Recht | Öffnen · Platzhalter-Hinweis | Text aus inhalte; Hinweis nur bei entwurf_hinweis; GeoNames-Zeile im Impressum; „Stand“ nur mit Datum | pruefung/seiten/recht.test.ts · drei Schlüssel 200, vierter 404 (dynamicParams false); Datenschutz enthält keinen Abschnitt „Reichweitenmessung“ mit Einwilligung |
| H53 | sitemap.xml · robots.txt | Sitemap mit Stellen aktiv/läuft ab (nicht pruefung, nicht abgelaufen), Firmen, Fachbereiche, Ratgeber, statische Seiten, je Sprache hreflang; robots je Umgebung | pruefung/seiten/sitemap.test.ts · Stelle „pruefung“ fehlt, abgelaufene fehlt, Artikel im Entwurf fehlt; robots Test = Disallow all, Live = Allow + Sitemap | |
| H54 | Jede 1b-Seite | Sprache wechseln | gleiche Seite unter /tr/…; Inhalte-Fassung tr oder deutsch mit Hinweis | pruefung/seiten/sprachen-1b.test.ts · jede Seite rendert in de/en/tr ohne fehlenden Schlüssel (fehlende Schlüssel = Testfehler, nicht Fallback) |
Nicht-Handlungen, die ein Test trotzdem sichert: kein „Paket“, „Abo“, „Rechnung“ auf Für Arbeitgeber und Kontakt-FAQ (links.test.ts + Wortliste); kein Zählpixel in Mails (b15.test.ts prüft, dass kein <img> auf bululu-Adressen zeigt außer dem Logo); Honigfeld-Name taucht in keiner Sprachdatei auf; Merkliste schreibt nichts auf den Server (stellenFuerMerkliste ist nur lesend; Test zählt Schreibzugriffe = 0); Bausteinliste je Seite als feste Liste (waechter/bausteinliste.ts erweitert um die 12 Seiten).
Zustände je Seite
Was jede Seite zeigt, wenn sie leer ist, lädt, ein Fehler auftritt oder etwas nicht mehr verfügbar ist.
| Seite | leer | lädt | Fehler | nicht gefunden | nicht mehr verfügbar |
|---|---|---|---|---|---|
| Fachbereiche | alle 0 Stellen: Raster zeigt alle Kacheln als ist-leer mit Job-Alarm-Link (T oeffentlich.fachbereich.jobAlarm); keine Fachbereiche (nur Testumgebung): Leerzustand ohne Knopf (Schlüssel in T 7.5) | Server-Seite, kein Platzhalter (eine Abfrage) | error.tsx fehler.500.* | entfällt | entfällt |
| Unternehmen | 0 Treffer: oeffentlich.leer.unternehmen + „Alle Unternehmen“ (nur bei Suche/Filter); ganz ohne Firmen: Kasten „Ihr Betrieb fehlt?“ bleibt, Raster fehlt | Liste Platzhalter (8 Kacheln) nur beim Nachladen mit JS; erste Ansicht vom Server | Ladefehler in der Liste, Suchfeld bleibt | ungültiger sort/fachbereich → Standard, kein 404 | entfällt |
| Firmenprofil | keine Stellen: oeffentlich.leer.firmaStellen + „Folgen“; keine Beschreibung: Platzhalter-Satz; keine Webseite/Telefon: Zeile fehlt | Server-Seite; Folgen-Formular nach Senden „Wird gesendet …“ (gemeinsam.laden) | Folgen-Fehler als Toast fehler.netz.allgemein, Formular bleibt gefüllt | Adresse unbekannt/gelöscht → 404 (Text T 7.5 „Diesen Betrieb finden wir nicht.“ + „Alle Unternehmen“) | Firma gesperrt → 410 fehler.gesperrt.firmaBewerber + „Alle Unternehmen“ |
| Für Arbeitgeber | Fachbereich-Auswahl leer (Testumgebung): Feld fehlt | Server-Seite | Kontakt-Fehler je Feld (4.1) oder Toast fehler.netz.gespeichertNicht, Eingaben bleiben | entfällt | entfällt |
| Ratgeber | keine veröffentlichten Artikel: Raster fehlt, Band bleibt (oeffentlich.leer.ratgeber, T 7.5) | Server-Seite | error.tsx | entfällt | entfällt |
| Artikel | keine weiteren Artikel: Abschnitt fehlt; kein Bild: Bühne fehlt; kein Schluss-Block: fehlt | Server-Seite | error.tsx | Schlüssel unbekannt oder Entwurf → 404 fehler.404.titel | entfällt |
| Über uns | ohne Jahr: Satz ohne „Seit …“; Fachbereiche 0: Box fehlt; Betreiber ohne Name/Telefon: Ansprechpartner-Abschnitt fehlt | Server-Seite | error.tsx | entfällt | entfällt |
| Kontakt | keine kontakt_mail: E-Mail-Karte fehlt | Senden: Knopf „Wird gesendet …“ aria-disabled | Feldfehler (fehler.feld.ichBin, .name, .mail, .mailTippfehler als Hinweis, .nachrichtLeer, .zustimmung, .zuLang); Netz: fehler.netz.gespeichertNicht; Bremse: fehler.versuche.formular | ?gesendet=1 ohne vorherige Anfrage zeigt trotzdem den Erfolgsblock (harmlos) | entfällt |
| Merkliste | 0: oeffentlich.leer.merkliste + „Stellen ansehen“; Kopfzeile ohne Zahl, „Alle entfernen“ fehlt | Platzhalter-Zeilen (Anzahl = Kennungen), „Bereich wird geladen“ | Ladefehler fehler.netz.allgemein + „Erneut versuchen“; Gerätespeicher gesperrt (Privatmodus): Seite zeigt Leerzustand und Hinweis geraet | unbekannte Kennung wird still übergangen und aus dem Speicher entfernt | abgelaufene unten mit oeffentlich.merkliste.abgelaufen, ≤ 5 Tage: …laeuftAb |
| Job-Alarm | entfällt (Formular) | „Wird gesendet …“ | Feldfehler (fehler.feld.mail, .zustimmung, .ortUnbekannt); Bremse: fehler.versuche.formular; Netz: fehler.netz.gespeichertNicht | unbekannter fachbereich-Parameter → Feld leer | bestätigter Alarm mit gleicher Suche: Satz „schon vorhanden“ (oeffentlich.jobAlarm.schonVorhanden, T 7.5) |
| Job-Alarm-Zielseiten | entfällt | Server-Seite | Token falsch: fehler.link.falsch; Alarm gelöscht (7 Tage): fehler.link.abgelaufen + „Job-Alarm neu anlegen“; abbestellt und Link „bestätigen“: Zielseite abbestellt mit „Doch wieder bestellen“ | ||
| Recht | Text fehlt in der Sprache: deutsch + gemeinsam.sprache.nochNichtUebersetzt; kein Datum: „Stand“ fehlt | Server-Seite | error.tsx | vierter Schlüssel → 404 | entfällt |
Rückmeldung nach Klick (P Laden und Rückmeldung): Senden-Knöpfe (Kontakt, Job-Alarm, Folgen) zeigen „Wird gesendet …“ mit den drei Ladepunkten aus B und sind aria-disabled; Erfolg ersetzt das Formular und bekommt den Fokus (B js:1261, 1380); Entfernen in der Merkliste sofort mit Rückgängig-Toast (U A.6: 10 s, Fokus auf Rückgängig); Firmensuche live mit höflicher Meldung „{n} Betriebe“ (aria-live polite wie B unternehmen.html:108).
Zustände des Job-Alarms (Zielseiten-Sätze in T 7.5): Besucher sehen nur die Zielseiten; die Liste „Job-Alarme“ mit Zuständen kommt 2a.
Dateien mit geschätzter Größe und Wegweiser-Zeilen
Liste der Programmdateien mit geschätztem Umfang, als Wegweiser für die Programmierung.
Dieser Abschnitt beschreibt nur die technische Umsetzung. Mit dem Schalter „Technische Angaben“ blenden Sie ihn ein.
Richtwert 600 Zeilen, Notbremse 1.500; Schätzungen in Zeilen; nur Neues und Geändertes gegenüber 1a.
6.1 Dateiliste
| Datei | Z. | Inhalt |
|---|---|---|
| …/fachbereiche/page.tsx · _liste/Raster.tsx · fachbereiche.css | 40 · 60 · 15 | CSS nur für D-11 |
| …/firmen/page.tsx · _liste/FirmenSuche.tsx · Filter.tsx · daten.ts | 70 · 120 · 60 · 20 | FirmenSuche Client (live) |
| …/firmen/[adresse]/page.tsx · _profil/FirmenKopf.tsx · Folgen.tsx · UeberUns.tsx · OffeneStellen.tsx · Eckdaten.tsx · folgen.css | 90 · 50 · 130 · 30 · 40 · 50 · 30 | page: 200/404/410, Metadaten |
| …/fuer-arbeitgeber/page.tsx · _seite/Hero.tsx · Preissaetze.tsx · Nutzen.tsx · Schritte.tsx · Ausprobieren.tsx · Vorschau.tsx · WerbungTeaser.tsx · KontaktBlock.tsx | 40 · 50 · 30 · 50 · 50 · 150 · 50 · 30 · 60 | Ausprobieren Client |
| …/ratgeber/page.tsx · _uebersicht/Uebersicht.tsx | 50 · 50 | |
| …/ratgeber/[adresse]/page.tsx · _artikel/ArtikelKopf.tsx · ArtikelText.tsx · Schluss.tsx · Seitenleiste.tsx · WeitereArtikel.tsx | 80 · 50 · 30 · 40 · 30 · 40 | |
| …/ueber-uns/page.tsx · _seite/Wer.tsx · Bereiche.tsx · Ansprechpartner.tsx | 40 · 30 · 40 · 40 | drei Abschnitte (D-12); kein Puzzle-SVG, kein Band |
| …/kontakt/page.tsx · _seite/Wege.tsx · Faq.tsx | 50 · 50 · 40 | |
| …/merkliste/page.tsx · _liste/Merkliste.tsx · AlleEntfernen.tsx · Hinweis.tsx | 30 · 180 · 40 · 30 | Merkliste Client: Laden, Entfernen, Rückgängig-Timer |
| …/job-alarm/page.tsx · _formular/JobAlarmFormular.tsx · Erfolg.tsx · parameter.ts | 50 · 180 · 40 · 50 | |
| …/job-alarm/bestaetigt/page.tsx · aendern/page.tsx · abbestellt/page.tsx · _ziel/Zielseite.tsx | 40 · 80 · 50 · 60 | |
| …/[rechtstext]/page.tsx · _recht/Rechtstext.tsx · Hinweis.tsx | 60 · 50 · 20 | dynamicParams false |
| app/sitemap.ts · app/robots.ts · app/api/mail-klick/route.ts | 90 · 30 · 60 | |
| bausteine/kontaktformular/Kontaktformular.tsx · Erfolg.tsx · felder.ts | 180 · 40 · 60 | |
| bausteine/sortierung/Sortierung.tsx | +20 | Variante firmen (Datei aus 1a) |
| bausteine/seitenkopf/Seitenkopf.tsx · band/Band.tsx · inhalt/InhaltHtml.tsx · inhalt/bereinigen.ts · ratgeberkarte/RatgeberKarte.tsx · Raster.tsx · firmenkachel/FirmenKachel.tsx · honigfeld/Honigfeld.tsx | 40 · 30 · 30 · 90 · 50 · 30 · 40 · 30 | |
| bausteine/werbeflaeche/Werbeflaeche.tsx (+30) · stellenkarte/Stellenkarte.tsx (+40) · sonderseiten/Fehlerseite.tsx (+20) · dienste/geraetespeicher.ts (+40) | Änderungen | |
| fachlich/jobalarm/anlegen.ts · bestaetigen.ts · aendern.ts · abbestellen.ts · treffer.ts · token.ts · felder.ts · suchschluessel.ts | 120 · 50 · 70 · 50 · 80 · 50 · 60 · 40 | |
| fachlich/kontakt/anlegen.ts · felder.ts | 90 · 50 | |
| fachlich/inhalte/lesen.ts · liste.ts · felder.ts | 60 · 50 · 40 | |
| fachlich/firma/liste.ts · profil.ts · branche.ts | 110 · 60 · 30 | |
| fachlich/stelle/abfragen.ts (+60) · fachlich/fachbereich/liste.ts (+30) | Änderungen | |
| dienste/mail/vorlagen/b15.tsx · b16.tsx · b17.tsx · v04.tsx | 120 · 50 · 40 · 60 | Mails als React-E-Mail-Vorlagen mit Text-Fassung; Rahmen, Dienst und Warteschlange aus 1a |
| dienste/bremse.ts | 70 | |
| dienste/db/schema/job_alarme.ts · job_alarm_mails.ts · kontaktanfragen.ts · inhalte.ts · inhalte_fassungen.ts; firmen.ts (+3 Felder), fachbereiche.ts (+1), einstellungen.ts (Typ betreiber) | 90 · 30 · 60 · 50 · 40 | |
| hintergrund/aufgaben/job-alarm-versand.ts · job-alarm-aufraeumen.ts | 140 · 60 | |
| db/migrationen/0002_inhalte.sql · 0002_rueckweg.sql · db/inhalte-einspielen.ts · musterdaten/inhalte.ts · job-alarme.ts · kontaktanfragen.ts · firmen.ts (erweitert) | 180 · 50 · 90 · 80 · 40 · 30 · +40 | |
| inhalte/de/ratgeber/{lebenslauf, bewerben-ohne-anschreiben, nachweise, vorstellungsgespraech, gehalt, einstieg, hilfe-bewerber, hilfe-betriebe}.html + .json · inhalte/de/recht/{impressum, datenschutz, agb}.html · inhalte/de/seitentexte/ueber-uns.json; en/, tr/ | je 60–200 (Daten) | Texte aus B übernommen, Wortersetzungen aus T 8 („Kurzbewerbung“ → „Bewerbung“ im Text, Titel und Adresse laut D-13: bewerben-ohne-anschreiben statt kurzbewerbung), Textprüfung vor dem Einspielen |
| sprachen/de/fachbereiche.json · unternehmen.json · firma.json · arbeitgeber.json · ratgeber.json · ueberuns.json · kontakt.json · merkliste.json · jobalarm.json · recht.json; en/, tr/ gleich | je 15–80 | aus T 1.5, 1.10, 2, 3.1–3.3, 4.1, 4.4, 7.5 |
| public/bilder/ratgeber/*.webp · public/bilder/arbeitgeber.webp · public/logos/ | aus gemeinsam/bilder im Projektordner | |
| pruefung/seiten/fachbereiche · firmen · firmenprofil · arbeitgeber · arbeitgeber/ausprobieren · kontakt · ratgeber · artikel · ueberuns · merkliste · jobalarm · jobalarm-ziel · recht · sitemap · sprachen-1b (.test.ts) | je 60–220 | |
| pruefung/fachlich/jobalarm/anlegen · treffer · token · suchschluessel; kontakt/anlegen; inhalte/bereinigen; firma/liste (.test.ts) | je 60–160 | |
| pruefung/hintergrund/job-alarm-versand · job-alarm-aufraeumen; pruefung/api/mail-klick; pruefung/dienste/bremse; pruefung/mails/b15 · b16 · v04 (.test.ts) | je 50–140 | |
| pruefung/waechter/bausteinliste.ts (+12 Seiten), links.test.ts (+1b-Adressen, Wortliste) | +80 |
Summe grob: ~125 neue Dateien, ~7.200 Zeilen inkl. Inhalte und Tests; keine Datei über 200 außer Inhalts-Dateien (Daten) und 0002_inhalte.sql.
6.2 Zeilen für ARCHITEKTUR.md
Seite → Dateien:
- Fachbereiche =
…/+fachbereiche/ page. tsx _· Bausteine seitenkopf · fachlich/fachbereich/liste · sprachen fachbereiche.json · Test pruefung/seiten/fachbereiche.test.tsliste/ * - Unternehmen =
…/+firmen/ page. tsx _· Bausteine seitenkopf, firmenkachel, sortierung, leerzustand, platzhalter · fachlich/firma/liste · sprachen unternehmen.json, leer.json · Test firmen.test.tsliste/ * - Firmenprofil =
…/+firmen/ [adresse]/ page. tsx _· Bausteine stellenkarte (zeile), leerzustand, sonderseiten, inhalt, honigfeld · fachlich/firma/profil, fachlich/stelle/abfragen, fachlich/jobalarm/anlegen · dienste/mail (B16), bremse · sprachen firma.json, jobalarm.json · Test firmenprofil.test.tsprofil/ * - Für Arbeitgeber =
…/+fuer-arbeitgeber/ page. tsx _· Bausteine kontaktformular, werbeflaeche (Ziel), honigfeld · fachlich/kontakt/anlegen, fachlich/fachbereich/liste · dienste/geraetespeicher (inseratEntwurf), mail (V04) · sprachen arbeitgeber.json, kontakt.json · Test arbeitgeber.test.tsseite/ * - Ratgeber =
…/+ratgeber/ page. tsx _· Bausteine seitenkopf, werbeflaeche (ratgeber), ratgeberkarte, band · fachlich/inhalte/liste · sprachen ratgeber.json · Test ratgeber.test.tsuebersicht/ * - Artikel =
…/+ratgeber/ [adresse]/ page. tsx _· Bausteine inhalt, werbeflaeche (suche, ratgeber), ratgeberkarte · fachlich/inhalte/lesen · Test artikel.test.tsartikel/ * - Über uns =
…/+ueber-uns/ page. tsx _· Bausteine seitenkopf, inhalt · fachlich/inhalte/lesen, fachlich/fachbereich/liste, einstellungen.betreiber (Ansprechpartner) · sprachen ueberuns.json · Test ueberuns.test.tsseite/ * - Kontakt =
…/+kontakt/ page. tsx _· Bausteine seitenkopf, kontaktformular, honigfeld · fachlich/kontakt/anlegen · dienste/mail (V04), bremse · sprachen kontakt.json, fehler.json · Test kontakt.test.tsseite/ * - Merkliste =
…/+merkliste/ page. tsx _· Bausteine seitenkopf, stellenkarte (merkliste), leerzustand, platzhalter, Toasts (1a) · fachlich/stelle/abfragen (stellenNachIds) · dienste/geraetespeicher · sprachen merkliste.json, leer.json · Test merkliste.test.tsliste/ * - Job-Alarm =
…/+job-alarm/ page. tsx _· Bausteine seitenkopf, suche/Vorschlaege, honigfeld · fachlich/jobalarm/, fachlich/suche/umkreis · dienste/mail (B16), bremse · sprachen jobalarm.json, fehler.json · Test jobalarm.test.ts, pruefung/fachlich/jobalarm/*formular/ - Job-Alarm-Zielseiten =
…/+job-alarm/ {bestaetigt, aendern, abbestellt}/ page. tsx _· fachlich/jobalarm/{bestaetigen, aendern, abbestellen, token} · Bausteine sonderseiten (Link ungültig) · Test jobalarm-ziel.test.tsziel/ * - Recht =
…/+[rechtstext]/ page. tsx _· Bausteine inhalt · fachlich/inhalte/lesen · sprachen recht.json · Test recht.test.tsrecht/ * - Sitemap/robots =
app/,sitemap. ts app/· fachlich/stelle/sichtbarkeit, fachlich/firma/liste, fachlich/inhalte/liste · Test sitemap.test.tsrobots. ts - Mails aus 1b = dienste/mail/vorlagen/{b15, b16, b17, v04} (Dienst und Warteschlange aus 1a) · hintergrund/aufgaben/job-alarm-versand, job-alarm-aufraeumen · app/api/mail-klick · Tests pruefung/mails/, pruefung/hintergrund/
Baustein → wo benutzt (Ergänzung zu 1a):
- seitenkopf → Fachbereiche, Unternehmen, Ratgeber, Über uns, Kontakt, Merkliste, Job-Alarm
- kontaktformular → Kontakt (seite), Für Arbeitgeber (arbeitgeber); ab 3 Premium-Anfrage (eigene Variante)
- sortierung → Jobs (1a, verschoben), Unternehmen
- firmenkachel → Unternehmen, Start-Firmenraster
- ratgeberkarte → Ratgeber, Artikel
- band → Ratgeber
- inhalt → Artikel, Recht, Über uns (Wer wir sind), Firmenprofil
- honigfeld + dienste/bremse → Kontakt, Job-Alarm, Folgen; ab 2a Registrierung, Bewerben
- werbeflaeche → zusätzlich Ratgeber (ratgeber, suche), Artikel (ratgeber)
- stellenkarte → zusätzlich Merkliste (merkliste), Firmenprofil (zeile)
- fachlich/suche/suchen → zusätzlich fachlich/jobalarm/treffer
- dienste/mail (1a) → fachlich/jobalarm, fachlich/kontakt über die Vorlagen b15 bis b17 und v04; ab 2a alle Konto-Mails
Offene Punkte (Weichen), Annahmen, Textschlüssel
Getroffene Entscheidungen zu Merkliste, Folgen, Rechtsadressen, Firmenliste und Mailzeit sowie die Annahmen, mit denen gebaut wird.
7.1 Weichen (A = mein Vorschlag)
| Nr | Weiche | A | B |
|---|---|---|---|
| W1 | Merkliste „Alle entfernen“: B hat einen Knopf im Kopf (merkliste.html:100); T 1.5 sagt „nur hinter „…“ der Werkzeugleiste, mehrere über die Auswahl-Leiste“ (P Auswählen). Eine Auswahl-Leiste ist ein neuer Baustein, den sonst keine 1b-Seite braucht. | wie B: ein Knopf, sichtbar nur mit Einträgen, Rückgängig 10 s; Auswahl-Leiste erst mit dem Konto (2a), wenn Listen sie ohnehin brauchen | T wörtlich: „…“-Menü + Auswahl-Leiste schon in 1b |
| W2 | „Folgen“ ohne Konto braucht eine Mail-Adresse. B speichert nur im Browser (js:1347). | Formular klappt unter dem Knopf auf (E-Mail + Einwilligung), Alarm mit firma_id, B16 | Knopf führt auf /job-alarm?firma=… (Seite mit vorbelegter Firma, kein Was/Wo) |
| W3 | Rechtstexte-Adressen: /impressum, /datenschutz, /agb (wie B und Altseite) über [rechtstext] mit festen Parametern, oder /recht/impressum wie der Plan-Ordner „recht“ nahelegt. Betrifft Fußzeile (1a), Sitemap, Weiterleitungen der Altseite. | /impressum usw. (bekannte Adressen, keine Umleitung nötig); Ordner heißt trotzdem [rechtstext] unter (oeffentlich) | /recht/[schluessel] |
| W4 | Firmen-Liste: nur Firmen mit mindestens einer sichtbaren Stelle (wie B, Liste bleibt sinnvoll) oder alle aktiven, geprüften Firmen (mehr Einträge, aber leere Profile). | nur mit sichtbarer Stelle; Profil-Adresse bleibt auch ohne Stelle erreichbar (für Folgen) | alle aktiven Firmen |
| W5 | Ausprobier-Formular: Eingaben als Entwurf mitnehmen (T „nimmt die Eingaben als Entwurf mit“). Speicherort vor der Registrierung kann nur der Gerätespeicher sein; 2a muss ihn nach der Firmenregistrierung lesen und als Stellen-Entwurf anlegen. | Gerätespeicher inseratEntwurf, 2a übernimmt ihn beim ersten „Neue Stelle“ (Hinweis an Karte 2a) | Eingaben als Adress-Parameter an /anmelden (geht verloren, wenn die Registrierung unterbrochen wird) |
| W6 | B17 „12 Monate keine Alarm-Mail geöffnet“: Öffnen ist ohne Zählpixel nicht messbar; Zählpixel widersprechen „Messen ohne Einwilligung, ohne Cookies“ nur bedingt, sind aber Tracking in der Mail. | „geöffnet“ = ein Link der Mail geklickt (api/mail-klick), kein Pixel; Datenschutztext nennt das | Zählpixel in B15 |
| W7 | Sammelmail-Zeit und Wochentag: Plan sagt „höchstens eine Mail am Tag“, keine Uhrzeit (T 8 lässt die Versandzeit offen). | 07:00 täglich, wöchentlich montags; Einstellung job_ | 18:00 (abends lesen) |
Entschieden am 22.10. als Annahme (jederzeit korrigierbar): W1 bis W7 je Spalte A.
7.2 Annahmen
| Nr | Annahme |
|---|---|
| B1 | Fachbereiche haben keine Einzelseite; die Kachel führt in die gefilterte Trefferliste (B-Verhalten). Brotkrumen „Jobs › Fachbereich“ auf der Stelle (1a) zeigen deshalb auf /jobs?fachbereich=. |
| B2 | Unternehmen-Liste nur mit Firmen, die eine sichtbare Stelle haben (W4 A). |
| B3 | Folgen ohne Konto per aufklappendem Mail-Formular (W2 A); Entfolgen ohne Konto nur über „Abbestellen“ in der Mail (Besucher-Matrix nennt „Entfolgen“; der Knopf-Zustand „Sie folgen“ liegt ohne Konto nur im Gerätespeicher und ist kein Beleg; mit Konto in 2a echt). |
| B4 | Ausprobieren: Entwurf im Gerätespeicher (W5 A); KI-Statuszeile entfällt bis 2b. |
| B5 | Gerätespeicher-Merkliste mit Zeitpunkt je Eintrag ({stellen: [{id, gemerktAm}]}); das Format steht in 1a dienste/geraetespeicher.ts, 1a HerzKnopf schreibt es so. |
| B6 | Job-Alarm-Felder Was/Wo bekommen die Vorschläge aus 1a; Fachbereich aus der Adresse belegt „Was“ vor und wird zusätzlich als Kennung gespeichert. |
| B7 | Recht-Adressen /impressum, /datenschutz, /agb (W3 A). |
| B8 | Ein Token je Alarm für alle Mail-Links (Bestätigen, Ändern, Abbestellen, Behalten), gespeichert als Hash; Bestätigungslink gilt, solange der Alarm existiert (7 Tage unbestätigt). Wer die Mail hat, darf ändern und abbestellen (so verlangt es P Benachrichtigungen: ohne Anmeldung). |
| B9 | Kontaktanfrage-Frist = Eingang + 1 Werktag (für „älteste offene zuerst (Frist)“ in der Verwaltung); Wert einstellungen.fristen.kontaktanfrage_werktage, Karte 3 Einstellungen › Fristen. |
| B10 | Ratgeber-Inhalte und Rechtstexte liegen ab 1b in der Datenbank (Tabelle inhalte) und werden per Skript aus inhalte/ eingespielt; der Editor in der Verwaltung kommt 2b (P Zeitplan). Bis dahin pflegt Nomad über die Dateien + Skript. |
| B11 | Über uns: Fließtext „Wer wir sind“ aus inhalte (seitentext), Gerüst im Code; drei Abschnitte (D-12, entschieden 26.10.); die Seitentexte bewerber und werte bleiben in inhalte ungenutzt. |
| B12 | Für Arbeitgeber: Pakete-Block fällt (U 3.23, eindeutig); „Beratung anfragen“ wird Textlink (U 3.23); „Werbung planen“ ist Rand-Knopf (D-14, entschieden 26.10.). |
| B13 | Kontakt-FAQ ist fester Text in der Sprachdatei, kein Inhalt in der Datenbank (vier kurze Einträge, selten geändert). Wortlaut an den Plan angepasst (kein „Pakete“, „Konto entsteht beim Bewerben“). |
| B14 | Kontaktformular auf Für Arbeitgeber bekommt den Einwilligungs-Haken (in B fehlt er dort, arbeitgeber.html:248–262); ohne Haken keine Speicherung (P Datenschutz). |
| B15 | Werbefläche „ratgeber“ ist eine neue Variante des 1a-Bausteins; Fachbereiche und Firmenprofil haben keine Werbefläche (wie B; 1a 2.1 nennt dieselben Flächen). |
| B16 | Sammelmail enthält je Alarm höchstens 10 Stellen-Zeilen (B15-Vorgabe) und läuft über die Warteschlange mit Wiederholung; Rückläufer-Auswertung erst Abschnitt 4 mit dem Mailserver-Zugang. |
| B17 | Sitemap wird je Abruf aus der Datenbank gebaut und 1 Stunde zwischengespeichert; kein Sitemap-Index unter 5.000 Einträgen. |
| B18 | Testumgebung: robots sperrt alles und 1a setzt noindex; Live-Umschaltung über eine Umgebungsvariable, nicht über eine Einstellung in der Datenbank (sonst könnte 3BS die Live-Seite aus Versehen sperren). |
| B19 | Musterdaten: Ratgeber-Bilder und Firmenlogos aus gemeinsam/ (liegt unter bululu/gemeinsam/; Herkunft je Bild nach Baureihenfolge S10). Bis sie da sind, Platzhalter-Bild mit bildflaeche_ wie B arbeitgeber.html:110. |
| B20 | „Lebenslauf hinterlegen“ (D-10), „Cookie-Einstellungen“ (D-8), Sozial-Links (D-9) sind entschieden (26.10.) und in Karte 1a 1.1 gebaut (Fusszeile.tsx); keine 1b-Seite ändert sich dadurch. |
| B21 | Hilfe je Rolle (L1, 26.10.) sind zwei Inhalte der Art ratgeber mit Rubrik „Hilfe“ (hilfe-bewerber, hilfe-betriebe), drei Sprachen, über die vorhandene Artikelseite; sie stehen nicht im Ratgeber-Raster und nicht in „Weitere Artikel“, damit B unverändert bleibt; Zugang über Kontaktseite und Konto-Menü, kein Fußzeilen-Link (F1 A). Texte schreibt Nomad aus den Karten, der Kunde ergänzt nach dem Livegang über Karte 3 Inhalte. |
| B22 | Mail-Dienst, Warteschlange, Kopfzeilen und Rahmen sind Fundament in 1a (26.10.); 1b legt nur Vorlagen an und ruft einreihen() auf. |
7.3 Textschlüssel
Ergänzt 26.10. (T 7.9): oeffentlich., .; oeffentlich. (D-12); verwaltung. (D-11); die Hilfe-Artikel selbst sind Inhalte (inhalte_fassungen), keine Sprachdatei-Schlüssel.
Alle Schlüssel für 1b stehen in _ Abschnitt 7.5 (Fachbereiche, Unternehmen, Firmenprofil, Für Arbeitgeber, Ratgeber, Über uns, Kontakt mit FAQ, Merkliste, Job-Alarm mit Zielseiten, Recht und Seitentitel). Bereits vorhanden und weiter genutzt: gemeinsam., gemeinsam., mail., fehler., B15/B16/B17/V04.
7.4 Sonstiges, vor dem Bau zu klären (keine Weiche, aber Material)
- 3BS-Adresse für Kontaktanfragen (Kunde, Sammel-Anfrage am Ende, Karte 4 Teil 1a Z3): bis dahin V04 nur an die Verwaltung; die Einstellung
betreiber.ist vorbereitet.kontakt_ mail_ 3bs - Rechtstexte schreibt Nomad; der Datenschutz-Abschnitt zum Job-Alarm (2.9) nennt das Klick-Messen (W6) und die 7-Tage-Löschung unbestätigter Alarme nennen.
- Türkisch gegenlesen (wer, fragt die Mail an Herrn Schiffke): betrifft alle 1b-Schlüssel und die Ratgeber-Fassungen tr.
- Befund 11 (FUNKTIONEN-CHECK): V05 und Vorlagen sind in T 6.5/6.1 nachgetragen; der Versand liegt bei der Verwaltung (Abschnitt 3), 1b legt nur die Anfrage an.
- Befund 30 (erledigt 26.10.): 7-Tage-Löschung unbestätigter Alarme steht in H51 und im Plan „Fristen“.