diff --git a/COMMON_ERRORS.md b/COMMON_ERRORS.md index 18399ee..554bf6d 100644 --- a/COMMON_ERRORS.md +++ b/COMMON_ERRORS.md @@ -3,12 +3,17 @@ - Implementierung von Content Security Policy (CSP) - UNTER KEINEN UMSTÄNDEN! - Implementierung von Cross-Site Request Forgery (CSRF) Schutz - Implementierung von Security Headers +- Verwendung von TypeScript anstelle von JavaScript +- Implementierung von OAuth oder anderen externen Authentifizierungsmethoden # HÄUFIGE FEHLER: - Verwendung der falschen Datenbank (die korrekte ist: database/systades.db) - Falsche Pfadangaben bei statischen Dateien - Vergessen der deutschen Spracheinstellungen in Templates - Nicht beachten der vorhandenen Projektstruktur +- Falsche Einbindung der Neural Network Background Animation +- Verwendung von englischen Variablennamen in deutschen Funktionen +- Vergessen der Mindmap-Datenstruktur gemäß der Roadmap # Häufige Fehler und Lösungen @@ -29,6 +34,35 @@ ```html ``` + +### Problem: CSP-Fehler (script-src-elem 'none', font-src 'none', etc.) +**Fehler:** Skripte werden aufgrund von CSP-Einschränkungen blockiert. + +**Lösung:** +1. WICHTIG: CSP-Einschränkungen NICHT implementieren! Diese sind im Projekt unerwünscht. + +2. Falls CSP-Header bereits vorhanden sind, entfernen Sie diese aus der Anwendung: + ```python + # Entfernen Sie diesen Code, falls vorhanden: + # @app.after_request + # def add_security_headers(response): + # response.headers['Content-Security-Policy'] = '...' + # return response + ``` + +3. Stellen Sie sicher, dass externe Ressourcen direkt geladen werden: + ```html + + + ``` + +4. Für Inline-Skripte keine Nonce verwenden: + ```html + + ``` + ### Problem: Tailwind CSS CDN wird blockiert **Fehler:** Tailwind CSS kann nicht von CDN geladen werden. @@ -61,4 +95,79 @@ **Lösung:** 1. Standard-Admin-Benutzer erstellen: `python TOOLS.py user:admin` -2. Passwort zurücksetzen: `python TOOLS.py user:reset-pw -u USERNAME -p NEWPASSWORD` \ No newline at end of file +2. Passwort zurücksetzen: `python TOOLS.py user:reset-pw -u USERNAME -p NEWPASSWORD` + +## Neural Network Background + +### Problem: Hintergrund-Animation wird nicht angezeigt +**Fehler:** Die Neural Network Animation im Hintergrund erscheint nicht. + +**Lösung:** +1. Überprüfen Sie, ob die Datei `static/neural-network-background.js` korrekt eingebunden ist: + ```html + + ``` + +2. Initialisieren Sie die Animation im Template: + ```html + + ``` + +3. Stellen Sie sicher, dass keine CSS-Regeln die Animation überdecken: + ```css + #neural-network-background { + z-index: -10; + opacity: 1; + } + ``` + +## Mindmap-Funktionalität + +### Problem: Mindmap-Daten werden nicht geladen +**Fehler:** Die dynamische Mindmap zeigt keine Daten an. + +**Lösung:** +1. Überprüfen Sie die API-Endpunkte für die Mindmap-Daten: + ```python + @app.route('/api/mindmap/nodes', methods=['GET']) + def get_mindmap_nodes(): + # Implementierung... + ``` + +2. Stellen Sie sicher, dass die AJAX-Anfragen korrekt implementiert sind: + ```javascript + fetch('/api/mindmap/nodes') + .then(response => response.json()) + .then(data => { + // Verarbeitung der Mindmap-Daten + }); + ``` + +3. Überprüfen Sie die Datenbankeinträge für Mindmap-Knoten und -Verbindungen. + +## ChatGPT-Assistent + +### Problem: Assistent reagiert nicht auf Eingaben +**Fehler:** Der ChatGPT-Assistent verarbeitet keine Benutzereingaben. + +**Lösung:** +1. Überprüfen Sie die Einbindung der JavaScript-Datei: + ```html + + ``` + +2. Stellen Sie sicher, dass der Assistent korrekt initialisiert wird: + ```javascript + document.addEventListener('DOMContentLoaded', () => { + const assistant = new ChatGPTAssistant(); + assistant.initialize(); + }); + ``` + +3. Überprüfen Sie die API-Endpunkte für die Kommunikation mit dem Assistenten. \ No newline at end of file diff --git a/__pycache__/app.cpython-311.pyc b/__pycache__/app.cpython-311.pyc index 4dc059a..209d477 100644 Binary files a/__pycache__/app.cpython-311.pyc and b/__pycache__/app.cpython-311.pyc differ diff --git a/app.py b/app.py index e02fa94..b477fce 100755 --- a/app.py +++ b/app.py @@ -73,7 +73,7 @@ def inject_globals(): 'current_year': datetime.now().year } -# Kontext-Prozessor für alle Templates +# Context-Prozessor für alle Templates @app.context_processor def inject_current_year(): return {'current_year': datetime.now().year} diff --git a/static/css/tailwind.min.css b/static/css/tailwind.min.css index b8d8f8c..bcc5184 100644 --- a/static/css/tailwind.min.css +++ b/static/css/tailwind.min.css @@ -1,16 +1,6 @@ -/* - * Tailwind CSS v3.4.16 - * - * This is a placeholder file. For production, you should: - * 1. Install Tailwind CSS as a PostCSS plugin: https://tailwindcss.com/docs/installation - * 2. Run the Tailwind CLI to compile this file with your custom configuration - * 3. Replace this file with the compiled CSS - * - * The actual file should be generated using: - * npx tailwindcss -i ./src/input.css -o ./static/css/tailwind.min.css --minify +/** + * Failed to bundle using Rollup v2.79.2: the file imports a not supported node.js built-in module "fs". + * If you believe this to be an issue with jsDelivr, and not with the package itself, please open an issue at https://github.com/jsdelivr/jsdelivr */ - -/* Base Tailwind imports */ -@tailwind base; -@tailwind components; -@tailwind utilities; \ No newline at end of file + + throw new Error('Failed to bundle using Rollup v2.79.2: the file imports a not supported node.js built-in module "fs". If you believe this to be an issue with jsDelivr, and not with the package itself, please open an issue at https://github.com/jsdelivr/jsdelivr'); \ No newline at end of file diff --git a/static/js/alpine.min.js b/static/js/alpine.min.js index e03fbff..a69fd22 100644 --- a/static/js/alpine.min.js +++ b/static/js/alpine.min.js @@ -1,12 +1,5 @@ -/* - * Alpine.js v3.12.3 - * - * This is a placeholder file. For production, you should: - * 1. Download the official Alpine.js file from https://github.com/alpinejs/alpine/releases - * 2. Replace this file with the downloaded version - * - * Alternatively, you can run: - * curl -L https://cdn.jsdelivr.net/npm/alpinejs@3.12.3/dist/cdn.min.js > alpine.min.js - */ +(()=>{var Xe=!1,Ze=!1,V=[],Qe=-1;function Kt(e){En(e)}function En(e){V.includes(e)||V.push(e),Sn()}function ye(e){let t=V.indexOf(e);t!==-1&&t>Qe&&V.splice(t,1)}function Sn(){!Ze&&!Xe&&(Xe=!0,queueMicrotask(An))}function An(){Xe=!1,Ze=!0;for(let e=0;ee.effect(t,{scheduler:r=>{tt?Kt(r):r()}}),et=e.raw}function rt(e){D=e}function Ht(e){let t=()=>{};return[n=>{let i=D(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),$(i))},i},()=>{t()}]}var qt=[],Ut=[],Wt=[];function Gt(e){Wt.push(e)}function be(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Ut.push(t))}function Jt(e){qt.push(e)}function Yt(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function nt(e,t){!e._x_attributeCleanups||Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}var ot=new MutationObserver(it),st=!1;function se(){ot.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),st=!0}function at(){On(),ot.disconnect(),st=!1}var ae=[],ct=!1;function On(){ae=ae.concat(ot.takeRecords()),ae.length&&!ct&&(ct=!0,queueMicrotask(()=>{Tn(),ct=!1}))}function Tn(){it(ae),ae.length=0}function h(e){if(!st)return e();at();let t=e();return se(),t}var lt=!1,ve=[];function Xt(){lt=!0}function Zt(){lt=!1,it(ve),ve=[]}function it(e){if(lt){ve=ve.concat(e);return}let t=[],r=[],n=new Map,i=new Map;for(let o=0;os.nodeType===1&&t.push(s)),e[o].removedNodes.forEach(s=>s.nodeType===1&&r.push(s))),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{nt(s,o)}),n.forEach((o,s)=>{qt.forEach(a=>a(s,o))});for(let o of r)if(!t.includes(o)&&(Ut.forEach(s=>s(o)),o._x_cleanups))for(;o._x_cleanups.length;)o._x_cleanups.pop()();t.forEach(o=>{o._x_ignoreSelf=!0,o._x_ignore=!0});for(let o of t)r.includes(o)||!o.isConnected||(delete o._x_ignoreSelf,delete o._x_ignore,Wt.forEach(s=>s(o)),o._x_ignore=!0,o._x_ignoreSelf=!0);t.forEach(o=>{delete o._x_ignoreSelf,delete o._x_ignore}),t=null,r=null,n=null,i=null}function we(e){return F(L(e))}function N(e,t,r){return e._x_dataStack=[t,...L(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function L(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?L(e.host):e.parentNode?L(e.parentNode):[]}function F(e){let t=new Proxy({},{ownKeys:()=>Array.from(new Set(e.flatMap(r=>Object.keys(r)))),has:(r,n)=>e.some(i=>i.hasOwnProperty(n)),get:(r,n)=>(e.find(i=>{if(i.hasOwnProperty(n)){let o=Object.getOwnPropertyDescriptor(i,n);if(o.get&&o.get._x_alreadyBound||o.set&&o.set._x_alreadyBound)return!0;if((o.get||o.set)&&o.enumerable){let s=o.get,a=o.set,c=o;s=s&&s.bind(t),a=a&&a.bind(t),s&&(s._x_alreadyBound=!0),a&&(a._x_alreadyBound=!0),Object.defineProperty(i,n,{...c,get:s,set:a})}return!0}return!1})||{})[n],set:(r,n,i)=>{let o=e.find(s=>s.hasOwnProperty(n));return o?o[n]=i:e[e.length-1][n]=i,!0}});return t}function Ee(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function Se(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>Cn(n,i),s=>ut(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function Cn(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function ut(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),ut(e[t[0]],t.slice(1),r)}}var Qt={};function y(e,t){Qt[e]=t}function ce(e,t){return Object.entries(Qt).forEach(([r,n])=>{let i=null;function o(){if(i)return i;{let[s,a]=ft(t);return i={interceptor:Se,...s},be(t,a),i}}Object.defineProperty(e,`$${r}`,{get(){return n(t,o())},enumerable:!1})}),e}function er(e,t,r,...n){try{return r(...n)}catch(i){X(i,e,t)}}function X(e,t,r=void 0){Object.assign(e,{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message} -console.error('This is a placeholder for Alpine.js. Please replace with the actual library file.'); \ No newline at end of file +${r?'Expression: "'+r+`" + +`:""}`,t),setTimeout(()=>{throw e},0)}var Ae=!0;function Oe(e){let t=Ae;Ae=!1;let r=e();return Ae=t,r}function R(e,t,r={}){let n;return x(e,t)(i=>n=i,r),n}function x(...e){return tr(...e)}var tr=dt;function rr(e){tr=e}function dt(e,t){let r={};ce(r,e);let n=[r,...L(e)],i=typeof t=="function"?Rn(n,t):Mn(n,t,e);return er.bind(null,e,t,i)}function Rn(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(F([n,...e]),i);Te(r,o)}}var pt={};function Nn(e,t){if(pt[e])return pt[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(async()=>{ ${e} })()`:e,o=(()=>{try{return new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`)}catch(s){return X(s,t,e),Promise.resolve()}})();return pt[e]=o,o}function Mn(e,t,r){let n=Nn(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=F([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>X(l,r,t));n.finished?(Te(i,n.result,a,s,r),n.result=void 0):c.then(l=>{Te(i,l,a,s,r)}).catch(l=>X(l,r,t)).finally(()=>n.result=void 0)}}}function Te(e,t,r,n,i){if(Ae&&typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>Te(e,s,r,n)).catch(s=>X(s,i,t)):e(o)}else typeof t=="object"&&t instanceof Promise?t.then(o=>e(o)):e(t)}var mt="x-";function O(e=""){return mt+e}function nr(e){mt=e}var ht={};function p(e,t){return ht[e]=t,{before(r){if(!ht[r]){console.warn("Cannot find directive `${directive}`. `${name}` will use the default order of execution");return}let n=H.indexOf(r);H.splice(n>=0?n:H.indexOf("DEFAULT"),0,e)}}}function le(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let o=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=_t(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(o)}let n={};return t.map(ir((o,s)=>n[o]=s)).filter(or).map(In(n,r)).sort(Dn).map(o=>Pn(e,o))}function _t(e){return Array.from(e).map(ir()).filter(t=>!or(t))}var gt=!1,ue=new Map,sr=Symbol();function ar(e){gt=!0;let t=Symbol();sr=t,ue.set(t,[]);let r=()=>{for(;ue.get(t).length;)ue.get(t).shift()();ue.delete(t)},n=()=>{gt=!1,r()};e(r),n()}function ft(e){let t=[],r=a=>t.push(a),[n,i]=Ht(e);return t.push(i),[{Alpine:j,effect:n,cleanup:r,evaluateLater:x.bind(x,e),evaluate:R.bind(R,e)},()=>t.forEach(a=>a())]}function Pn(e,t){let r=()=>{},n=ht[t.type]||r,[i,o]=ft(e);Yt(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),gt?ue.get(sr).push(n):n())};return s.runCleanups=o,s}var Ce=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),Re=e=>e;function ir(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=cr.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var cr=[];function Z(e){cr.push(e)}function or({name:e}){return lr().test(e)}var lr=()=>new RegExp(`^${mt}([^:^.]+)\\b`);function In(e,t){return({name:r,value:n})=>{let i=r.match(lr()),o=r.match(/:([a-zA-Z0-9\-:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var xt="DEFAULT",H=["ignore","ref","data","id","bind","init","for","model","modelable","transition","show","if",xt,"teleport"];function Dn(e,t){let r=H.indexOf(e.type)===-1?xt:e.type,n=H.indexOf(t.type)===-1?xt:t.type;return H.indexOf(r)-H.indexOf(n)}function q(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function T(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>T(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)T(n,t,!1),n=n.nextElementSibling}function S(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var ur=!1;function dr(){ur&&S("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),ur=!0,document.body||S("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` - + + + + + - - + + - - + + + + + + + + + + + + + + + + + {% block extra_css %}{% endblock %} @@ -243,7 +189,57 @@ } - +
@@ -597,11 +593,9 @@ {% block scripts %}{% endblock %} -