import sys, io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') from docx import Document from docx.shared import Inches, Pt, Cm, RGBColor from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.enum.table import WD_TABLE_ALIGNMENT from docx.enum.section import WD_ORIENT from docx.oxml.ns import qn from docx.oxml import OxmlElement import datetime doc = Document() # ── Page margins ── for section in doc.sections: section.top_margin = Cm(2.5) section.bottom_margin = Cm(2) section.left_margin = Cm(2.5) section.right_margin = Cm(2.5) style = doc.styles['Normal'] font = style.font font.name = 'Calibri' font.size = Pt(11) font.color.rgb = RGBColor(0x33, 0x33, 0x33) style.paragraph_format.space_after = Pt(6) style.paragraph_format.line_spacing = 1.15 # Heading styles for level, size, color in [(1, 16, 0x0D9488), (2, 13, 0x0F766E), (3, 11, 0x115E59)]: hs = doc.styles[f'Heading {level}'] hs.font.name = 'Calibri' hs.font.size = Pt(size) hs.font.color.rgb = RGBColor((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF) hs.font.bold = True hs.paragraph_format.space_before = Pt(18 if level == 1 else 14) hs.paragraph_format.space_after = Pt(8) def add_bullet(text, bold_prefix=None, level=0): p = doc.add_paragraph(style='List Bullet') p.paragraph_format.left_indent = Cm(1.2 + level * 0.8) p.paragraph_format.space_after = Pt(3) if bold_prefix: run = p.add_run(bold_prefix) run.bold = True run.font.size = Pt(10) run2 = p.add_run(text) run2.font.size = Pt(10) else: run = p.add_run(text) run.font.size = Pt(10) return p def add_para(text, bold=False, italic=False, size=11, align=None, space_after=6): p = doc.add_paragraph() run = p.add_run(text) run.font.size = Pt(size) run.bold = bold run.italic = italic if align: p.alignment = align p.paragraph_format.space_after = Pt(space_after) return p def add_table_row(table, cells_data, bold=False, bg_color=None): row = table.add_row() for i, text in enumerate(cells_data): cell = row.cells[i] cell.text = '' p = cell.paragraphs[0] run = p.add_run(str(text)) run.font.size = Pt(9) run.bold = bold if bg_color: shading = OxmlElement('w:shd') shading.set(qn('w:fill'), bg_color) shading.set(qn('w:val'), 'clear') cell._tc.get_or_add_tcPr().append(shading) return row def set_table_header_bg(table, color='0D9488'): for cell in table.rows[0].cells: shading = OxmlElement('w:shd') shading.set(qn('w:fill'), color) shading.set(qn('w:val'), 'clear') cell._tc.get_or_add_tcPr().append(shading) for p in cell.paragraphs: for run in p.runs: run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF) run.bold = True # ═══════════════════════════════════════════════════════ # COVER PAGE # ═══════════════════════════════════════════════════════ for _ in range(6): doc.add_paragraph() add_para('PROPUNERE TEHNICA', bold=True, size=24, align=WD_ALIGN_PARAGRAPH.CENTER, space_after=4) add_para('RAPORT INTERMEDIAR DE IMPLEMENTARE', bold=True, size=14, align=WD_ALIGN_PARAGRAPH.CENTER, space_after=20) # Separator line p = doc.add_paragraph() p.alignment = WD_ALIGN_PARAGRAPH.CENTER run = p.add_run('_' * 60) run.font.color.rgb = RGBColor(0x0D, 0x94, 0x88) p.paragraph_format.space_after = Pt(20) add_para('Dezvoltare website cu e-commerce,\ncu ERP si CRM in cloud', bold=True, size=13, align=WD_ALIGN_PARAGRAPH.CENTER, space_after=8) add_para('in cadrul proiectului', italic=True, size=10, align=WD_ALIGN_PARAGRAPH.CENTER, space_after=4) add_para('PLATFORMA DIGITALA INTELIGENTA PENTRU\nPREVENIREA SI COMBATEREA DEZINFORMARII', bold=True, size=12, align=WD_ALIGN_PARAGRAPH.CENTER, space_after=30) add_para(f'Data document: {datetime.date.today().strftime("%d.%m.%Y")}', size=10, align=WD_ALIGN_PARAGRAPH.CENTER, space_after=4) add_para('Stadiu: Implementare in curs', italic=True, size=10, align=WD_ALIGN_PARAGRAPH.CENTER) doc.add_page_break() # ═══════════════════════════════════════════════════════ # CUPRINS # ═══════════════════════════════════════════════════════ doc.add_heading('CUPRINS', level=1) cuprins = [ '1. Scopul documentului', '2. Stiva tehnologica propusa', '3. Arhitectura generala si interconectare componente', '4. Componenta Website — Stadiu implementare', '5. Componenta ERP/CRM — Stadiu implementare', '6. Integrari realizate si flux de date', '7. Securitate si protectia datelor (GDPR)', '8. Stadiu general si pasi urmatori', '9. Tabel de conformitate — stadiu curent', ] for item in cuprins: add_para(item, size=11, space_after=4) doc.add_page_break() # ═══════════════════════════════════════════════════════ # 1. SCOPUL DOCUMENTULUI # ═══════════════════════════════════════════════════════ doc.add_heading('1. Scopul documentului', level=1) add_para( 'Prezentul document constituie un raport intermediar de implementare al solutiei tehnice ' 'pentru dezvoltarea website-ului cu e-commerce, ERP si CRM in cloud. ' 'Documentul prezinta stadiul actual al dezvoltarii, arhitectura implementata, ' 'tehnologiile utilizate, functionalitatile livrate pana in acest moment si pasii urmatori.' ) add_para( 'Scopul este de a oferi Beneficiarului o imagine clara asupra progresului tehnic, ' 'a deciziilor arhitecturale luate si a modului in care solutia propusa raspunde ' 'cerintelor din Caietul de Sarcini (Capitolul II).' ) add_para( 'Acest document nu reprezinta livrabilul final — este un punct de referinta intermediar ' 'care permite validarea directiei tehnice si colectarea de feedback inainte de finalizare.', italic=True ) # ═══════════════════════════════════════════════════════ # 2. STIVA TEHNOLOGICA # ═══════════════════════════════════════════════════════ doc.add_heading('2. Stiva tehnologica propusa', level=1) add_para( 'Solutia a fost construita folosind o stiva tehnologica moderna, bazata exclusiv pe ' 'tehnologii open-source si frameworkuri cu suport activ pe termen lung. ' 'Alegerea fiecarei componente a fost facuta in concordanta cu cerintele din Caietul de Sarcini ' 'si cu principiile de modularitate, scalabilitate si securitate.' ) doc.add_heading('2.1. Componente principale', level=2) table = doc.add_table(rows=1, cols=4) table.style = 'Light Grid Accent 1' table.alignment = WD_TABLE_ALIGNMENT.CENTER hdr = table.rows[0].cells hdr[0].text = 'Componenta' hdr[1].text = 'Tehnologie' hdr[2].text = 'Versiune' hdr[3].text = 'Rol in solutie' set_table_header_bg(table) tech_rows = [ ['Website (Frontend)', 'Next.js (React)', 'v16', 'Website prezentare, e-commerce, dashboard client; Server-Side Rendering pentru SEO'], ['Website (Backend API)', 'Node.js / API Routes', 'v22', 'API-uri server-side pentru checkout, facturare, comunicare cu servicii externe'], ['Limbaj programare', 'TypeScript', 'v5', 'Tipizare statica pe intregul proiect, reducerea erorilor la compilare'], ['Stilizare', 'Tailwind CSS', 'v4', 'Framework CSS utility-first, design responsive, componente consistente'], ['ERP + CRM', 'ERPNext', 'v15', 'Contabilitate, facturare, CRM, rapoarte; solutie open-source GPL, configurata pentru legislatia RO'], ['Baza de date ERP', 'MariaDB', 'v10.11', 'Baza de date relationala pentru ERPNext, optimizata pentru tranzactii'], ['Cache si cozi', 'Redis', 'v7 (Alpine)', 'Cache pentru performanta si coada de taskuri asincrone ERPNext'], ['Autentificare (IAM)', 'Keycloak (SSO)', '-', 'Autentificare unificata prin OpenID Connect, gestionata de platforma existenta'], ['Procesor plati', 'Stripe', 'API v2024', 'Plati securizate cu card, checkout sessions, webhook-uri pentru confirmare'], ['Containerizare', 'Docker + Compose', '-', 'Izolare servicii, deployment reproducibil, orchestrare multi-container'], ['Reverse proxy', 'Nginx', '-', 'Rutare trafic, servire assets statice, proxy catre aplicatie'], ['Internationalizare', 'Custom i18n', '-', 'Suport complet romana (RO) si engleza (EN), comutare dinamica'], ] for row_data in tech_rows: add_table_row(table, row_data) doc.add_heading('2.2. Justificarea alegerii tehnologiilor', level=2) add_para('Next.js (React)', bold=True, size=10, space_after=2) add_para( 'Framework-ul Next.js a fost ales pentru capacitatea de Server-Side Rendering (SSR) si ' 'Static Site Generation (SSG), esentiale pentru performanta si SEO. App Router-ul permite ' 'o structura clara a rutelor, iar React ofera un ecosistem matur de componente reutilizabile. ' 'Ref. CS: II.6.1 — "Website dezvoltat cu tehnologii web moderne".', size=10 ) add_para('ERPNext v15', bold=True, size=10, space_after=2) add_para( 'ERPNext este o solutie ERP open-source (licenta GPL) cu module native de contabilitate, ' 'facturare si CRM. Versiunea 15 ofera API REST complet, suport pentru custom DocTypes ' 'si un sistem de permisiuni granulare. Configurarea pentru legislatia romaneasca (plan de conturi, ' 'TVA 19%, serie facturi) este realizata prin scripturi de setup automate. ' 'Ref. CS: II.6.2 — "Solutia ERP/CRM gazduita in cloud, configurabila".', size=10 ) add_para('Stripe', bold=True, size=10, space_after=2) add_para( 'Stripe a fost ales ca procesor de plati pentru suportul nativ de plati recurente (subscriptii), ' 'webhook-uri pentru confirmare in timp real, compatibilitate cu piata din Romania si conformitate PCI DSS. ' 'Ref. CS: II.6.3 — "Procesor de plati cu suport plati recurente, compatibil Romania".', size=10 ) add_para('Docker', bold=True, size=10, space_after=2) add_para( 'Containerizarea cu Docker asigura un mediu de deployment reproductibil si izolat. ' 'Fiecare componenta (ERPNext, MariaDB, Redis, workers) ruleaza in container propriu, ' 'facilitand scalarea independenta si deployment-ul in cloud EU. ' 'Ref. CS: II.3 — "Cloud hosting EU", II.6.2 — "Backup automat".', size=10 ) doc.add_page_break() # ═══════════════════════════════════════════════════════ # 3. ARHITECTURA # ═══════════════════════════════════════════════════════ doc.add_heading('3. Arhitectura generala si interconectare componente', level=1) add_para( 'Arhitectura solutiei este modulara, cu separare clara intre componenta de prezentare (website), ' 'componenta de business logic (ERP/CRM) si serviciile externe (autentificare, plati, email). ' 'Comunicarea intre componente se realizeaza exclusiv prin API-uri REST securizate.' ) doc.add_heading('3.1. Diagrama de interconectare', level=2) add_para( 'Schema de mai jos ilustreaza fluxul de date intre componentele principale:', size=10, space_after=10 ) # ASCII-style architecture diagram arch_text = """ ┌─────────────────────────────────────────────────────────────┐ │ UTILIZATOR (Browser) │ │ Desktop / Tableta / Mobil │ └──────────────────────────┬──────────────────────────────────┘ │ HTTPS ┌──────────────────────────▼──────────────────────────────────┐ │ WEBSITE (Next.js / React) │ │ ┌──────────────┐ ┌──────────────┐ ┌───────────────────┐ │ │ │ Pagini │ │ Dashboard │ │ API Routes │ │ │ │ Publice │ │ Client │ │ (Server-side) │ │ │ │ (SSR/SSG) │ │ (Protejat) │ │ │ │ │ └──────────────┘ └──────────────┘ └─────┬─────────────┘ │ └────────────────────────────────────────────┬┼────────────────┘ ┌────────────────────────┘│ │ ┌──────────┘ API REST │ │ API REST + Webhooks ┌───────────────────▼───┐ ┌────▼──────────────────────────┐ │ ERP/CRM (ERPNext) │ │ SERVICII EXTERNE │ │ ┌─────────────────┐ │ │ ┌────────────────────────┐ │ │ │ Contabilitate │ │ │ │ IAM (SSO/OpenID) │ │ │ │ Facturare │ │ │ │ Autentificare unificata│ │ │ │ CRM / Pipeline │ │ │ └────────────────────────┘ │ │ │ CMS (Continut) │ │ │ ┌────────────────────────┐ │ │ │ DocTypes Custom │ │ │ │ Procesor Plati │ │ │ └────────┬────────┘ │ │ │ Checkout + Webhooks │ │ │ ┌────────▼────────┐ │ │ └────────────────────────┘ │ │ │ MariaDB + Redis │ │ │ ┌────────────────────────┐ │ │ │ (Persistenta) │ │ │ │ API Platforma DiDi │ │ │ └─────────────────┘ │ │ │ Analize + Credite │ │ └───────────────────────┘ └───────────────────────────────┘ """ p = doc.add_paragraph() run = p.add_run(arch_text) run.font.name = 'Consolas' run.font.size = Pt(7.5) p.paragraph_format.space_after = Pt(12) doc.add_heading('3.2. Principii arhitecturale implementate', level=2) add_bullet('Comunicarea intre website si ERP/CRM se realizeaza prin proxy server-side — ' 'credentialele API nu sunt niciodata expuse in browser', bold_prefix='Securitate API: ') add_bullet('Website-ul (frontend + API) si ERPNext (ERP/CRM) ruleaza in containere Docker separate, ' 'cu retea interna partajata; pot fi deployate pe servere diferite', bold_prefix='Separare componente: ') add_bullet('Continutul paginilor publice (homepage, servicii, despre, privacy, termeni) este gestionat ' 'din interfata ERPNext si preluat dinamic de website prin API', bold_prefix='CMS centralizat: ') add_bullet('Toate paginile publice beneficiaza de Server-Side Rendering pentru indexare optima ' 'de catre motoarele de cautare', bold_prefix='SEO prin SSR: ') add_bullet('Suport complet pentru romana si engleza, cu posibilitate de extindere; ' 'comutare dinamica din interfata', bold_prefix='Internationalizare: ') add_bullet('Utilizator unic autentificat prin SSO — o singura sesiune valida ' 'pentru website, dashboard si platforma', bold_prefix='Autentificare unificata: ') doc.add_heading('3.3. Fluxuri de date principale', level=2) add_para('Flux 1 — Autentificare utilizator', bold=True, size=10, space_after=2) add_para( 'Utilizatorul acceseaza pagina de login → este redirectionat catre serverul IAM (OpenID Connect) ' '→ se autentifica → primeste un token JWT → este redirectionat inapoi in website cu sesiune activa ' '→ middleware-ul protejeaza rutele din dashboard pe baza sesiunii.', size=10 ) add_para('Flux 2 — Achizitie serviciu (one-time)', bold=True, size=10, space_after=2) add_para( 'Utilizatorul selecteaza un serviciu din pagina de pricing → este redirectionat catre checkout-ul ' 'procesorului de plati → efectueaza plata → procesorul trimite un webhook la API-ul website-ului ' '→ API-ul creeaza automat: clientul in ERP (daca nu exista), factura fiscala (Sales Invoice), ' 'log-ul tranzactiei → factura este disponibila in dashboard pentru vizualizare si download PDF.', size=10 ) add_para('Flux 3 — Analiza continut (DiDi API)', bold=True, size=10, space_after=2) add_para( 'Utilizatorul acceseaza sectiunea de analize din dashboard → selecteaza un serviciu achizitionat ' 'si neconsmat → introduce textul sau URL-ul de analizat → API-ul website-ului trimite cererea catre ' 'API-ul platformei DiDi → rezultatele sunt preluate prin polling → sunt afisate detaliat ' '(scor de risc, tehnici detectate, verificare afirmatii, detectie AI, credibilitate sursa).', size=10 ) add_para('Flux 4 — Lead din formular contact', bold=True, size=10, space_after=2) add_para( 'Vizitatorul completeaza formularul de contact de pe website → datele sunt trimise catre API-ul ' 'website-ului → API-ul creeaza automat un Lead in modulul CRM al ERPNext cu sursa, ' 'pagina de origine si parametri UTM → Lead-ul intra in pipeline-ul de vanzari.', size=10 ) add_para('Flux 5 — Gestiune continut CMS', bold=True, size=10, space_after=2) add_para( 'Administratorul editeaza continutul paginilor (texte, imagini) din interfata ERPNext ' '→ website-ul preia automat continutul actualizat prin API REST ' '→ paginile publice se actualizeaza fara interventie tehnica (fara deploy).', size=10 ) doc.add_page_break() # ═══════════════════════════════════════════════════════ # 4. WEBSITE # ═══════════════════════════════════════════════════════ doc.add_heading('4. Componenta Website — Stadiu implementare', level=1) add_para( 'Website-ul a fost dezvoltat integral cu Next.js (React) si TypeScript, folosind App Router ' 'pentru structurarea rutelor si Tailwind CSS pentru stilizare. Toate paginile sunt responsive ' 'si au suport bilingv (RO/EN).' ) doc.add_heading('4.1. Pagini publice implementate', level=2) add_para('Ref. CS: II.5.1 — Website de prezentare', italic=True, size=9, space_after=4) table = doc.add_table(rows=1, cols=3) table.style = 'Light Grid Accent 1' hdr = table.rows[0].cells hdr[0].text = 'Pagina' hdr[1].text = 'Functionalitate' hdr[2].text = 'Sursa continut' set_table_header_bg(table) pages_data = [ ['Homepage', 'Sectiune hero, prezentare servicii (carduri), cum functioneaza (pasi), statistici platforma, cazuri de utilizare, apel la actiune', 'CMS din ERP (dinamic)'], ['Servicii', '6 module AI detaliate cu capabilitati tehnice: analiza text, deepfake, fact-checking, evaluare surse, tehnici manipulare, monitorizare media', 'CMS din ERP (dinamic)'], ['Despre', 'Prezentare companie, misiune, proiect, tehnologie utilizata', 'CMS din ERP (dinamic)'], ['Pricing', 'Grila de preturi pentru 4 tipuri de servicii x 4 tipuri media (text, imagine, audio, video); buton achizitie integrat cu procesorul de plati', 'Configuratie locala + ERP'], ['Contact', 'Formular de contact (nume, email, mesaj) cu trimitere automata in CRM; informatii de contact companie', 'CMS din ERP + formular'], ['Politica confidentialitate', 'Pagina GDPR completa cu descrierea datelor colectate, scopuri, drepturi utilizator, stocare', 'CMS din ERP (dinamic)'], ['Termeni si conditii', 'Definitii, servicii, plati, proprietate intelectuala, raspundere, legislatie aplicabila', 'CMS din ERP (dinamic)'], ] for row_data in pages_data: add_table_row(table, row_data) doc.add_heading('4.2. Zona client autentificata (Dashboard)', level=2) add_para('Ref. CS: II.4 — Zona client dashboard, II.5.2 — Gestiune abonamente', italic=True, size=9, space_after=4) table = doc.add_table(rows=1, cols=3) table.style = 'Light Grid Accent 1' hdr = table.rows[0].cells hdr[0].text = 'Pagina' hdr[1].text = 'Functionalitate' hdr[2].text = 'Sursa date' set_table_header_bg(table) dash_data = [ ['Overview', 'Sumar: numar facturi, analize achizitionate, ultimele facturi emise, acces rapid la achizitie', 'ERP (API REST)'], ['Facturi', 'Lista completa facturi cu numar, data, suma, status; download PDF pentru fiecare factura', 'ERP (Sales Invoice)'], ['Analize', 'Lista servicii achizitionate si neconsumate; selectare si rulare analiza; afisare rezultate detaliate (scor risc, tehnici, verificari, detectie AI)', 'ERP + API Platforma'], ['Profil', 'Vizualizare si editare date personale (companie, cod fiscal); sectiune GDPR cu export date si solicitare stergere', 'ERP (Customer)'], ['Abonament', 'Detalii plan activ, lista functionalitati per nivel, data activare', 'ERP (Customer)'], ['Achizitioneaza', 'Grila servicii disponibile cu preturi; flux de achizitie integrat cu procesorul de plati', 'Configuratie + Stripe'], ['Checkout', 'Flux in 2 pasi: selectare plan + date facturare cu acceptare termeni; creare acord de servicii', 'ERP + Stripe'], ['Credite', 'Afisare credite disponibile si consum (pregatit pentru integrare cu API platforma)', 'API Platforma (partial)'], ] for row_data in dash_data: add_table_row(table, row_data) doc.add_heading('4.3. API Routes implementate (Server-side)', level=2) table = doc.add_table(rows=1, cols=3) table.style = 'Light Grid Accent 1' hdr = table.rows[0].cells hdr[0].text = 'Endpoint' hdr[1].text = 'Metoda' hdr[2].text = 'Functionalitate' set_table_header_bg(table) api_data = [ ['Autentificare', 'GET/POST', 'Handler OpenID Connect — login, callback, refresh token, logout'], ['Proxy ERP', 'GET/POST/PUT', 'Proxy server-side catre API-ul ERP; credentialele nu ajung in browser'], ['Lead-uri', 'POST', 'Creare Lead in CRM din formularul de contact website'], ['Checkout', 'POST', 'Creare sesiune de plata in procesorul de plati; redirect catre pagina de plata'], ['Webhook plati', 'POST', 'Procesare confirmare plata; creare automata client, factura si log tranzactie in ERP'], ['PDF Factura', 'GET', 'Download factura in format PDF din ERP, livrata prin proxy securizat'], ['Analize', 'GET/POST', 'Listare analize disponibile, trimitere cerere analiza, preluare rezultate'], ] for row_data in api_data: add_table_row(table, row_data) doc.add_heading('4.4. Functionalitati transversale', level=2) add_bullet('Suport complet romana (RO) si engleza (EN) cu comutare din navbar; ' 'dictionare JSON pentru toate textele interfetei', bold_prefix='Internationalizare (i18n): ') add_bullet('Banner cookie consent cu 3 categorii (necesare, functionale, analitice); ' 'preferintele se salveaza in browser si se respecta la navigare', bold_prefix='Cookie consent GDPR: ') add_bullet('Generare automata sitemap.xml si robots.txt; meta tags SEO pe toate paginile; ' 'Open Graph tags pentru partajare pe retele sociale', bold_prefix='SEO: ') add_bullet('Navbar responsive cu meniu hamburger pe mobil; footer cu linkuri utile; ' 'sidebar dashboard pe desktop cu navigare vizuala', bold_prefix='Componente layout: ') add_bullet('Rutele din zona client sunt protejate prin middleware — ' 'utilizatorii neautentificati sunt redirectionati automat la pagina de login', bold_prefix='Protectie rute: ') doc.add_page_break() # ═══════════════════════════════════════════════════════ # 5. ERP/CRM # ═══════════════════════════════════════════════════════ doc.add_heading('5. Componenta ERP/CRM — Stadiu implementare', level=1) add_para( 'Componenta ERP/CRM este construita pe ERPNext v15 (open-source, licenta GPL), ' 'containerizata cu Docker si configurata specific pentru legislatia romaneasca si ' 'nevoile proiectului. Intreaga configurare este automatizata prin scripturi Python ' 'reproductibile.' ) doc.add_heading('5.1. Infrastructura Docker', level=2) add_para('Ref. CS: II.6.2 — ERP/CRM gazduita in cloud', italic=True, size=9, space_after=4) add_para('Mediul ERP/CRM este compus din 7 containere Docker orchestrate prin Docker Compose:') table = doc.add_table(rows=1, cols=3) table.style = 'Light Grid Accent 1' hdr = table.rows[0].cells hdr[0].text = 'Serviciu' hdr[1].text = 'Tehnologie' hdr[2].text = 'Rol' set_table_header_bg(table) docker_data = [ ['Aplicatie ERP', 'ERPNext v15 (Frappe)', 'Aplicatia principala ERP/CRM; interfata web de administrare; API REST'], ['Baza de date', 'MariaDB 10.11', 'Stocare persistenta; configurata cu InnoDB, UTF8MB4, buffer pool optimizat'], ['Cache', 'Redis (Alpine)', 'Cache pentru performanta — reduce timpul de raspuns al interfetei ERP'], ['Coada de taskuri', 'Redis (Alpine)', 'Coada pentru procesare asincrona (emailuri, taskuri background)'], ['Worker scurt', 'Frappe Worker', 'Procesare taskuri rapide (notificari, actualizari cache)'], ['Worker lung', 'Frappe Worker', 'Procesare taskuri de durata (rapoarte, import-uri, backup)'], ['Scheduler', 'Frappe Scheduler', 'Executie taskuri programate (facturare recurenta, cleanup)'], ] for row_data in docker_data: add_table_row(table, row_data) add_para( 'Toate containerele comunica pe o retea Docker interna izolata. ' 'Reverse proxy-ul Nginx gestioneaza traficul HTTP, serveste asseturile statice ' 'si ofera suport WebSocket pentru interfata in timp real.', size=10 ) doc.add_heading('5.2. Configurare contabilitate si facturare', level=2) add_para('Ref. CS: II.5.3, II.5.4 — Facturare automata, Componenta ERP', italic=True, size=9, space_after=4) add_bullet('Plan de conturi adaptat legislatiei romanesti (OMFP 1802/2014)', bold_prefix='Plan conturi: ') add_bullet('TVA 19% Romania — aplicat automat pe net total la emitere factura', bold_prefix='Taxe: ') add_bullet('Format personalizat cu serie anuala secventiala (format: PREFIX-YYYY-#####)', bold_prefix='Serie facturi: ') add_bullet('Template PDF personalizat cu antet, date companie, detaliere articole, ' 'subtotal + TVA + total, nota legala conform art. 106 alin. 2 din Legea 227/2015', bold_prefix='Print Format custom: ') add_bullet('Conturi de cheltuieli configurate: hosting, servicii software, marketing, comisioane plati', bold_prefix='Conturi cheltuieli: ') add_bullet('Evidenta furnizori principali (hosting EU, procesor plati, email tranzactional)', bold_prefix='Furnizori: ') doc.add_heading('5.3. Configurare CRM', level=2) add_para('Ref. CS: II.5.5 — Componenta CRM', italic=True, size=9, space_after=4) add_bullet('4 etape configurate: Lead → Calificat → Demo → Client', bold_prefix='Pipeline vanzari: ') add_bullet('Surse configurate: formular contact website, pagina pricing, cerere demo', bold_prefix='Surse lead-uri: ') add_bullet('Campuri pentru sursa formular, pagina de origine si parametri UTM ' '(sursa, mediu, campanie) — permit analiza eficientei canalelor de marketing', bold_prefix='Campuri custom pe Lead: ') add_bullet('Campuri pentru ID utilizator in platforma IAM, rol activ (free/paid/enterprise), ' 'plan activ si data activarii', bold_prefix='Campuri custom pe Client: ') doc.add_heading('5.4. DocTypes custom create', level=2) add_para('Ref. CS: II.5.6 — Gestiune contractuala, II.8 — Audit', italic=True, size=9, space_after=4) add_para( 'Pe langa configurarea modulelor standard ERPNext, au fost create 3 DocTypes (entitati de date) ' 'custom, specifice nevoilor proiectului:' ) add_para('Acord de Servicii (Service Agreement)', bold=True, size=10, space_after=2) add_para( 'Se genereaza automat la activarea unui serviciu platit. Contine: clientul, planul selectat, ' 'status-ul acordului (Draft / Acceptat / Expirat / Anulat), data si ora acceptarii, ' 'versiunea termenilor, continutul HTML al acordului si legatura catre abonament. ' 'Numerotare automata secventiala. Asigura trasabilitate completa (audit trail) conform cerintei II.5.6.', size=10 ) add_para('Log Plati (Payment Log)', bold=True, size=10, space_after=2) add_para( 'Inregistreaza fiecare eveniment de plata receptionat prin webhook de la procesorul de plati. ' 'Contine: clientul, tipul evenimentului (plata reusita, esec, rambursare, modificare abonament), ' 'status-ul, suma, moneda si datele brute ale webhook-ului in format JSON. ' 'Permite audit complet al tranzactiilor financiare conform cerintei II.8.', size=10 ) add_para('Continut Website / CMS (Website Content)', bold=True, size=10, space_after=2) add_para( 'Permite administratorului sa editeze continutul tuturor paginilor publice direct din interfata ERP, ' 'fara interventie tehnica. Fiecare intrare are: pagina (homepage, pricing, contact, despre, privacy, termeni), ' 'cheie sectiune, ordine afisare, status activ/inactiv, continut in limba romana, continut in limba engleza, ' 'imagine si date structurate suplimentare in format JSON. ' 'In prezent sunt configurate 26 de intrari CMS corespunzand tuturor sectiunilor de pe paginile publice.', size=10 ) doc.add_heading('5.5. Catalog servicii', level=2) add_para( 'In ERP au fost create 14 articole (Item) corespunzand serviciilor platformei, ' 'organizate pe 4 categorii de servicii x tipuri de media suportate:' ) table = doc.add_table(rows=1, cols=2) table.style = 'Light Grid Accent 1' hdr = table.rows[0].cells hdr[0].text = 'Categorie serviciu' hdr[1].text = 'Tipuri media' set_table_header_bg(table) items_data = [ ['Detectie tehnici de manipulare', 'Text, Imagine, Audio, Video'], ['Detectie AI si Deepfake', 'Text, Imagine, Audio, Video'], ['Verificare automata afirmatii (Fact-checking)', 'Text, Imagine, Audio, Video'], ['Evaluare sursa si domeniu', 'Text, URL'], ] for row_data in items_data: add_table_row(table, row_data) doc.add_heading('5.6. Utilizator API dedicat', level=2) add_para( 'Pentru comunicarea securizata intre website si ERP, a fost creat un utilizator API dedicat ' 'cu rol custom ("Website Integration") si permisiuni limitate strict la operatiile necesare:', size=10 ) add_bullet('Citire si scriere: Client, Lead, Factura, Abonament, Continut Website, Acord Servicii, Log Plati, Articol', bold_prefix='Permisiuni read/write: ') add_bullet('Doar citire: Companie, Conturi, Taxe, Template-uri email, Etape vanzari', bold_prefix='Permisiuni read-only: ') add_para( 'Autentificarea se face prin API Key + Secret, transmise exclusiv server-side (nu ajung in browser).', size=10, italic=True ) doc.add_page_break() # ═══════════════════════════════════════════════════════ # 6. INTEGRARI # ═══════════════════════════════════════════════════════ doc.add_heading('6. Integrari realizate si flux de date', level=1) add_para('Ref. CS: II.6.3 — Integrari', italic=True, size=9, space_after=4) doc.add_heading('6.1. Autentificare IAM (SSO / OpenID Connect)', level=2) add_para( 'Website-ul este integrat cu componenta IAM a platformei existente prin protocolul OpenID Connect. ' 'Fluxul de autentificare:', size=10 ) add_bullet('Utilizatorul apasa butonul de login pe website') add_bullet('Este redirectionat catre serverul IAM (pagina de autentificare centralizata)') add_bullet('Dupa autentificare, primeste un token JWT (cu roluri din realm)') add_bullet('Este redirectionat inapoi pe website cu sesiune activa') add_bullet('Token-ul se reinnoieste automat (refresh token) fara interventie') add_bullet('Middleware-ul Next.js protejeaza toate rutele din zona client') add_para( 'Rolurile din IAM (free_tier, paid_tier, enterprise_tier) sunt mapate in sesiunea website ' 'si utilizate pentru controlul accesului bazat pe roluri (RBAC).', size=10 ) doc.add_heading('6.2. Procesor plati (Stripe)', level=2) add_para( 'Integrarea cu procesorul de plati este realizata prin doua mecanisme complementare:', size=10 ) add_para('Checkout Sessions', bold=True, size=10, space_after=2) add_para( 'La initierea unei achizitii, API-ul website-ului creeaza o sesiune de checkout securizata ' 'pe serverele procesorului de plati. Utilizatorul este redirectionat catre pagina de plata ' '(gazduita de procesorul de plati — conformitate PCI DSS) si, dupa plata reusita, ' 'revine pe website pe pagina de confirmare.', size=10 ) add_para('Webhook-uri', bold=True, size=10, space_after=2) add_para( 'La confirmarea platii, procesorul de plati trimite un webhook (notificare HTTP) catre API-ul website-ului. ' 'Webhook-ul declanseaza automat:', size=10 ) add_bullet('Crearea sau identificarea clientului in ERP (pe baza ID-ului din IAM)') add_bullet('Crearea facturii fiscale (Sales Invoice) cu articolele achizitionate si TVA') add_bullet('Inregistrarea tranzactiei in Log Plati (Payment Log) pentru audit') add_bullet('Crearea articolului in catalog daca nu exista deja') add_para( 'Au fost configurate 14 produse in procesorul de plati, corespunzand celor 14 articole din ERP, ' 'cu preturi in RON.', size=10 ) doc.add_heading('6.3. Website ↔ ERP/CRM (API REST)', level=2) add_para( 'Comunicarea intre website si ERP se realizeaza prin API REST, cu un proxy server-side ' 'implementat in Next.js. Aceasta abordare ofera doua avantaje majore:', size=10 ) add_bullet('Credentialele API nu sunt niciodata expuse in browserul utilizatorului') add_bullet('Website-ul poate adauga logica intermediara (validare, transformare date, caching)') add_para('Operatii implementate:', bold=True, size=10, space_after=2) add_bullet('Citire continut CMS (Homepage, Servicii, Despre, Privacy, Termeni) → cache 60 secunde') add_bullet('Creare Lead din formular contact (cu sursa, pagina, UTM)') add_bullet('Citire facturi client din ERP + download PDF') add_bullet('Citire/actualizare date profil client') add_bullet('Creare Acord de Servicii la checkout') add_bullet('Creare factura si client la confirmare plata') doc.add_heading('6.4. API Platforma DiDi (Analize)', level=2) add_para( 'Website-ul este integrat cu API-ul platformei DiDi pentru submisia si preluarea analizelor. ' 'Integrarea acopera 4 endpoint-uri corespunzand celor 4 categorii de servicii:', size=10 ) table = doc.add_table(rows=1, cols=2) table.style = 'Light Grid Accent 1' hdr = table.rows[0].cells hdr[0].text = 'Serviciu' hdr[1].text = 'Endpoint API' set_table_header_bg(table) api_didi = [ ['Detectie tehnici de manipulare', '/v3/techniques/analyze'], ['Detectie AI si deepfake', '/v3/ai-tampered/analyze'], ['Verificare afirmatii', '/v3/claims/analyze'], ['Evaluare sursa/domeniu', '/v3/domain/analyze'], ] for row_data in api_didi: add_table_row(table, row_data) add_para( 'Autentificarea catre API-ul platformei se face cu Bearer token (obtinut din sesiunea IAM). ' 'Rezultatele analizelor includ: scor de risc, nivel de incredere, tehnici de manipulare detectate, ' 'verificarea afirmatiilor (adevarat/fals/neverificat), probabilitate de generare AI, ' 'scor de credibilitate domeniu si factori de viralitate.', size=10 ) doc.add_page_break() # ═══════════════════════════════════════════════════════ # 7. SECURITATE # ═══════════════════════════════════════════════════════ doc.add_heading('7. Securitate si protectia datelor (GDPR)', level=1) add_para('Ref. CS: II.8 — Securitate cibernetica si protectia datelor', italic=True, size=9, space_after=4) doc.add_heading('7.1. Masuri de securitate implementate', level=2) table = doc.add_table(rows=1, cols=3) table.style = 'Light Grid Accent 1' hdr = table.rows[0].cells hdr[0].text = 'Categorie' hdr[1].text = 'Masura' hdr[2].text = 'Implementare' set_table_header_bg(table) sec_data = [ ['Autentificare', 'SSO / OpenID Connect', 'Autentificare centralizata prin IAM; token JWT cu expirare si refresh automat'], ['Autorizare', 'RBAC (Role-Based Access Control)', 'Roluri mapate din IAM: free_tier, paid_tier, enterprise_tier; middleware pe rute protejate'], ['Transport', 'HTTPS obligatoriu', 'Certificat SSL; comunicatie criptata TLS 1.2+ pe toate endpoint-urile'], ['API Security', 'Proxy server-side', 'Credentialele ERP nu ajung in browser; validare pe server a tuturor cererilor'], ['Plati', 'PCI DSS compliance', 'Datele cardurilor nu tranziteaza serverele noastre — plata se face pe pagina procesorului de plati'], ['Webhook-uri', 'Validare semnatura', 'Fiecare webhook de la procesorul de plati este validat prin semnatura criptografica'], ['Sesiuni', 'JWT + Refresh Token', 'Token-uri cu expirare scurta, reinnoite automat; sesiune invalidata la logout'], ['API ERP', 'Utilizator dedicat cu permisiuni minime', 'Principiul least privilege: acces doar la DocType-urile necesare, fara acces admin'], ] for row_data in sec_data: add_table_row(table, row_data) doc.add_heading('7.2. Conformitate GDPR', level=2) add_bullet('Pagina completa de politica de confidentialitate, editabila din CMS', bold_prefix='Politica confidentialitate: ') add_bullet('Pagina completa de termeni si conditii, editabila din CMS', bold_prefix='Termeni si conditii: ') add_bullet('Banner cookie consent cu 3 categorii: necesare (always on), functionale, analitice; ' 'preferintele se salveaza si se respecta', bold_prefix='Cookie consent: ') add_bullet('Buton "Exporta datele mele" in pagina de profil din dashboard (format CSV)', bold_prefix='Drept de portabilitate: ') add_bullet('Buton "Solicita stergerea contului" in pagina de profil din dashboard', bold_prefix='Drept la stergere: ') add_bullet('Checkbox obligatoriu de acceptare a termenilor in fluxul de checkout, ' 'cu inregistrare data, ora si versiune termeni', bold_prefix='Consimtamant explicit: ') add_bullet('Toate datele sunt stocate pe servere localizate in Uniunea Europeana', bold_prefix='Stocare exclusiv in EU: ') doc.add_heading('7.3. Audit si trasabilitate', level=2) add_para( 'Toate actiunile critice sunt inregistrate si trasabile:', size=10 ) add_bullet('Fiecare tranzactie financiara este logata in DocType-ul Payment Log cu date brute webhook') add_bullet('Fiecare acord de servicii inregistreaza data acceptarii, versiunea termenilor') add_bullet('Lead-urile captate inregistreaza sursa, pagina de origine si parametri UTM') add_bullet('ERPNext ofera nativ audit trail pe toate modificarile de documente (Version Log)') doc.add_page_break() # ═══════════════════════════════════════════════════════ # 8. STADIU GENERAL # ═══════════════════════════════════════════════════════ doc.add_heading('8. Stadiu general si pasi urmatori', level=1) doc.add_heading('8.1. Ce este implementat si functional', level=2) add_bullet('Infrastructura Docker completa (7 containere ERP + website)') add_bullet('Website cu 7 pagini publice, toate responsive si bilingve (RO/EN)') add_bullet('Dashboard client cu 8 pagini functionale') add_bullet('7 API routes server-side') add_bullet('ERP configurat: contabilitate RO, TVA, serie facturi, print format PDF custom') add_bullet('CRM configurat: pipeline 4 etape, campuri custom pe Lead si Client') add_bullet('3 DocTypes custom: Acord Servicii, Log Plati, Continut Website (CMS)') add_bullet('26 intrari CMS populate (toate paginile publice, RO + EN)') add_bullet('14 articole servicii in catalog ERP') add_bullet('Integrare IAM/SSO functionala (OpenID Connect)') add_bullet('Integrare procesor plati functionala (checkout + webhook)') add_bullet('Integrare API platforma DiDi pentru analize (4 endpoint-uri)') add_bullet('Proxy API securizat (credentiale server-side)') add_bullet('Cookie consent, sitemap.xml, robots.txt, SEO metadata') add_bullet('i18n complet (romana + engleza)') doc.add_heading('8.2. In curs de finalizare', level=2) table = doc.add_table(rows=1, cols=3) table.style = 'Light Grid Accent 1' hdr = table.rows[0].cells hdr[0].text = 'Element' hdr[1].text = 'Stadiu' hdr[2].text = 'Detalii' set_table_header_bg(table) wip_data = [ ['Interfata admin ERP (workspace-uri)', 'In lucru', 'Organizare sidebar ERP cu sectiuni clare: Facturi, Clienti, CRM, Plati, CMS'], ['Email tranzactional (SendGrid)', 'De implementat', 'Trimitere automata factura PDF pe email la emitere; notificari expirare/esec'], ['Rapoarte ERP custom', 'De implementat', 'Dashboard financiar (MRR, churn), rapoarte CRM (conversie, timp mediu)'], ['Sincronizare credite/consum DiDi API', 'Partial', 'Endpoint-uri testate si functionale; necesita configurare acces retea'], ['Design si assets vizuale', 'De rafinat', 'Adaugare imagini, ilustratii, animatii pe paginile publice'], ['Testare WCAG 2.1 AA', 'De realizat', 'Audit automat (axe/Lighthouse) + verificare manuala navigare tastatura'], ['Testare securitate OWASP', 'De realizat', 'Scan vulnerabilitati, verificare CSRF/XSS/SQLi, rate limiting'], ['Testare cross-browser', 'De realizat', 'Chrome, Firefox, Safari, Edge — ultimele 2 versiuni; responsive pe 5 rezolutii'], ['Deployment productie', 'De realizat', 'VPS-uri cloud EU, Nginx, SSL, backup automat zilnic'], ['Documentatie si training', 'De realizat', 'Manual utilizare, documentatie API, ghid admin ERP, 2 sesiuni training'], ] for row_data in wip_data: add_table_row(table, row_data) doc.add_page_break() # ═══════════════════════════════════════════════════════ # 9. TABEL CONFORMITATE # ═══════════════════════════════════════════════════════ doc.add_heading('9. Tabel de conformitate — stadiu curent', level=1) add_para( 'Tabelul de mai jos prezinta stadiul de implementare pentru fiecare cerinta din Caietul de Sarcini ' '(Capitolul II.10). Stadiul "Implementat" indica functionalitatile livrate si testate; ' '"Partial" indica functionalitatile in curs; "Planificat" indica elementele programate.', size=10 ) table = doc.add_table(rows=1, cols=4) table.style = 'Light Grid Accent 1' hdr = table.rows[0].cells hdr[0].text = 'Nr.' hdr[1].text = 'Cerinta CS' hdr[2].text = 'Stadiu' hdr[3].text = 'Observatii' set_table_header_bg(table) conf_data = [ ['1', 'Website prezentare firma si servicii', 'Implementat', '7 pagini publice, continut dinamic din CMS'], ['2', 'Design responsive (desktop, tableta, mobil)', 'Implementat', 'Tailwind CSS, layout-uri responsive pe toate paginile'], ['3', 'Accesibilitate WCAG 2.1 nivel AA', 'Partial', 'Structura semantica implementata; audit formal planificat'], ['4', 'Modul e-commerce cu plati recurente', 'Implementat', 'Checkout integrat cu procesor plati; servicii one-time functionale'], ['5', 'Gestiune abonamente/servicii', 'Implementat', 'Planuri configurate in ERP; sincronizare cu IAM'], ['6', 'Facturare automata conform legislatiei RO', 'Implementat', 'Facturi automate la plata; serie, TVA 19%, PDF custom'], ['7', 'Componenta ERP — contabilitate si gestiune', 'Implementat', 'Plan conturi RO, conturi cheltuieli, furnizori, jurnale'], ['8', 'Componenta CRM — clienti si pipeline', 'Implementat', 'Pipeline 4 etape, lead capture din website, campuri custom'], ['9', 'Integrare IAM platforma (SSO)', 'Implementat', 'OpenID Connect functional; sesiune, token refresh, RBAC'], ['10', 'Sincronizare abonamente si credite API', 'Partial', 'Endpoint-uri testate; configurare acces retea in curs'], ['11', 'Integrare procesor de plati', 'Implementat', '14 produse configurate; checkout + webhook functional'], ['12', 'Integrare email tranzactional', 'Planificat', 'Template-uri email create in ERP; integrare SendGrid planificata'], ['13', 'Integrare website — ERP/CRM', 'Implementat', 'API REST proxy; facturare, lead-uri, CMS, facturi PDF'], ['14', 'Conformitate GDPR', 'Implementat', 'Cookie consent, privacy policy, export date, stergere cont'], ['15', 'Hosting in EU', 'Planificat', 'Infrastructura Docker pregatita; deployment pe VPS EU planificat'], ['16', 'Disponibilitate minim 99.5% uptime', 'Planificat', 'Se va valida in productie cu monitorizare'], ['17', 'Backup automat zilnic', 'Planificat', 'Procedura definita; implementare la deployment productie'], ['18', 'Documentatie utilizare si tehnica', 'Planificat', 'Manual utilizare, documentatie API, ghid admin'], ['19', 'Training echipa', 'Planificat', '2 sesiuni planificate (website + ERP), cu inregistrare video'], ['20', 'Garantie si suport minim 36 luni', 'Conform oferta', 'SLA definit: Critica 4h/24h, Majora 8h/3zile, Minora 24h/10zile'], ] for row_data in conf_data: add_table_row(table, row_data) # ── Footer note ── doc.add_paragraph() p = doc.add_paragraph() run = p.add_run( 'Acest document a fost generat ca raport intermediar de progres. ' 'Versiunea finala a propunerii tehnice va include toate livrabilele complete, ' 'rapoartele de testare si documentatia aferenta.' ) run.font.size = Pt(9) run.italic = True p.alignment = WD_ALIGN_PARAGRAPH.CENTER # ── Save ── output_path = r'C:\Users\avedev\Desktop\Achizitii TOP\livrabile\didi\Propunere_Tehnica_Raport_Intermediar.docx' doc.save(output_path) print(f'Document salvat: {output_path}')