|
| 1 | +# Documentație Tehnică - Bursa Binelui |
| 2 | + |
| 3 | +## Cuprins |
| 4 | +1. [Prezentare generală](#1-prezentare-generală) |
| 5 | +2. [Stack tehnologic](#2-stack-tehnologic) |
| 6 | +3. [Arhitectura aplicației](#3-arhitectura-aplicației) |
| 7 | +4. [Modul Organizații](#4-modul-organizații) |
| 8 | +5. [Modul Proiecte](#5-modul-proiecte) |
| 9 | +6. [Fluxuri principale](#6-fluxuri-principale) |
| 10 | +7. [Baza de date](#7-baza-de-date) |
| 11 | +8. [Autentificare și autorizare](#8-autentificare-și-autorizare) |
| 12 | +9. [Integrări externe](#9-integrări-externe) |
| 13 | +10. [Medii de deployment](#10-medii-de-deployment) |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +## 1. Prezentare generală |
| 18 | + |
| 19 | +**Bursa Binelui** este o platformă civic tech dezvoltată de Code for Romania care conectează organizațiile neguvernamentale (ONG-uri) cu donatori și voluntari. Platforma permite: |
| 20 | + |
| 21 | +- **ONG-urilor** să se înregistreze, să creeze proiecte și să colecteze donații |
| 22 | +- **Donatorilor** să doneze către proiecte aprobate |
| 23 | +- **Voluntarilor** să se oferte pentru proiecte sau organizații |
| 24 | + |
| 25 | +### 1.1 Obiective principale |
| 26 | +- Facilitarea colectării de fonduri pentru proiecte sociale |
| 27 | +- Vizibilitate pentru organizațiile neguvernamentale |
| 28 | +- Transparență în gestionarea donațiilor |
| 29 | +- Conectarea voluntarilor cu organizațiile care au nevoie de suport |
| 30 | + |
| 31 | +--- |
| 32 | + |
| 33 | +## 2. Stack tehnologic |
| 34 | + |
| 35 | +| Componentă | Tehnologie | |
| 36 | +|------------|------------| |
| 37 | +| **Backend** | PHP 8.2, Laravel 10.x | |
| 38 | +| **Frontend** | Vue 3, Inertia.js, Tailwind CSS | |
| 39 | +| **Admin Panel** | Filament v2 | |
| 40 | +| **Baza de date** | MySQL (compatibil MariaDB) | |
| 41 | +| **Fișiere** | AWS S3 / Storage local | |
| 42 | +| **Plăți** | EuPlatesc | |
| 43 | +| **Deployment** | Docker, Terraform | |
| 44 | + |
| 45 | +### 2.1 Dependențe principale |
| 46 | +- `inertiajs/inertia-laravel` - integrare SPA fără API REST |
| 47 | +- `filament/filament` - panou administrare |
| 48 | +- `spatie/laravel-medialibrary` - gestionare imagini |
| 49 | +- `spatie/laravel-activitylog` - jurnalizare acțiuni |
| 50 | +- `spatie/laravel-query-builder` - filtrare și sortare |
| 51 | +- `tightenco/ziggy` - rute Laravel în JavaScript |
| 52 | + |
| 53 | +--- |
| 54 | + |
| 55 | +## 3. Arhitectura aplicației |
| 56 | + |
| 57 | +### 3.1 Structura directorelor |
| 58 | +``` |
| 59 | +app/ |
| 60 | +├── Concerns/ # Traits reutilizabile (BelongsToOrganization, HasCounties, etc.) |
| 61 | +├── Console/ # Comenzi Artisan (import, EndProjectPeriod) |
| 62 | +├── Enums/ # Enum-uri (ProjectStatus, OrganizationStatus, UserRole) |
| 63 | +├── Filament/ # Resurse admin (ProjectResource, OrganizationResource) |
| 64 | +├── Http/ |
| 65 | +│ ├── Controllers/ # Controllere public (ProjectController, OrganizationController) |
| 66 | +│ │ └── Dashboard/ # Controllere pentru ONG-uri autentificate |
| 67 | +│ ├── Filters/ # Filtre Query Builder |
| 68 | +│ ├── Requests/ # Form Requests |
| 69 | +│ └── Resources/ # API Resources (transformări JSON) |
| 70 | +├── Models/ # Eloquent models |
| 71 | +├── Policies/ # Politici autorizare |
| 72 | +├── Services/ # Logică business (ProjectService, OrganizationService) |
| 73 | +├── Notifications/ # Notificări email |
| 74 | +└── Listeners/ # Event listeners |
| 75 | +
|
| 76 | +resources/js/ |
| 77 | +├── Pages/ |
| 78 | +│ ├── Public/ # Pagini publice (Projects, Organizations) |
| 79 | +│ └── AdminOng/ # Pagini dashboard ONG (Projects, Organizations, Volunteers) |
| 80 | +└── Components/ # Componente Vue reutilizabile |
| 81 | +``` |
| 82 | + |
| 83 | +### 3.2 Modes de rulare |
| 84 | +- **Public** - Site-ul vizibil vizitatorilor (proiecte, organizații, donații) |
| 85 | +- **Dashboard ONG** - Interfață pentru utilizatorii organizațiilor (`/dashboard`) |
| 86 | +- **Filament Admin** - Panou administrare pentru superadmin (`/admin`) |
| 87 | + |
| 88 | +--- |
| 89 | + |
| 90 | +## 4. Modul Organizații |
| 91 | + |
| 92 | +### 4.1 Model și relații |
| 93 | +**Fișier:** `app/Models/Organization.php` |
| 94 | + |
| 95 | +| Câmp | Tip | Descriere | |
| 96 | +|------|-----|-----------| |
| 97 | +| name | string | Denumire organizație | |
| 98 | +| slug | string | URL-friendly identifier | |
| 99 | +| cif | string | CUI unic | |
| 100 | +| description | text | Descriere | |
| 101 | +| address | string | Adresă | |
| 102 | +| contact_person | string | Persoană de contact | |
| 103 | +| contact_phone | string | Telefon | |
| 104 | +| contact_email | string | Email | |
| 105 | +| website | string | Site web | |
| 106 | +| facebook | string | Pagină Facebook | |
| 107 | +| accepts_volunteers | boolean | Acceptă voluntari | |
| 108 | +| why_volunteer | text | Motivație voluntariat | |
| 109 | +| status | enum | pending, approved, rejected, pending_changes | |
| 110 | +| eu_platesc_merchant_id | string | ID merchant EuPlatesc (criptat) | |
| 111 | +| eu_platesc_private_key | string | Cheie privată EuPlatesc (criptată) | |
| 112 | + |
| 113 | +**Relații:** |
| 114 | +- `projects` - HasMany Project |
| 115 | +- `users` - HasMany User (membrii organizației) |
| 116 | +- `activityDomains` - BelongsToMany ActivityDomain (domenii de activitate) |
| 117 | +- `counties` - MorphToMany County (județe de acoperire) |
| 118 | +- `tickets` - HasMany Ticket (tichete suport) |
| 119 | +- `badges` - BelongsToMany Badge |
| 120 | +- `donations` - HasManyThrough Donation (prin Project) |
| 121 | + |
| 122 | +### 4.2 Statusuri organizație |
| 123 | +| Status | Descriere | |
| 124 | +|--------|-----------| |
| 125 | +| pending | În așteptarea aprobării inițiale | |
| 126 | +| approved | Aprobată, poate crea proiecte | |
| 127 | +| rejected | Respinasă | |
| 128 | +| pending_changes | Modificări în așteptarea aprobării | |
| 129 | + |
| 130 | +### 4.3 Flux înregistrare organizație |
| 131 | +1. Utilizatorul completează formularul de înregistrare (tip: organizație) |
| 132 | +2. Se creează User cu rol `admin` și Organization cu status `pending` |
| 133 | +3. Se încarcă logo și statut |
| 134 | +4. Se atașează domenii de activitate și județe |
| 135 | +5. Adminul Bursa Binelui aprobă/respinge organizația în Filament |
| 136 | +6. La respingere, se creează tichet cu motivul |
| 137 | + |
| 138 | +### 4.4 Serviciu organizație |
| 139 | +**Fișier:** `app/Services/OrganizationService.php` |
| 140 | +- `update()` - Actualizare atribute; câmpurile din `requiresApproval` (name, cif, statute) trec prin flow de aprobare |
| 141 | + |
| 142 | +### 4.5 Rute |
| 143 | +| Metodă | URL | Controller | Descriere | |
| 144 | +|--------|-----|------------|-----------| |
| 145 | +| GET | /organizations | OrganizationController@index | Lista organizații publice | |
| 146 | +| GET | /organizations/{slug} | OrganizationController@show | Pagina organizație | |
| 147 | +| POST | /organizations/{slug}/volunteer | OrganizationController@volunteer | Înscriere voluntar | |
| 148 | +| GET | /dashboard/organization | Dashboard\OrganizationController@edit | Editare organizație (ONG) | |
| 149 | +| POST | /dashboard/organization | Dashboard\OrganizationController@update | Salvare organizație | |
| 150 | + |
| 151 | +--- |
| 152 | + |
| 153 | +## 5. Modul Proiecte |
| 154 | + |
| 155 | +### 5.1 Tipuri de proiecte |
| 156 | +| Tip | Model | Tabel | Descriere | |
| 157 | +|-----|-------|-------|-----------| |
| 158 | +| Proiect standard | Project | projects | Proiecte principale ale platformei | |
| 159 | +| Proiect Gala | GalaProject | gala_projects | Proiecte pentru evenimente Gala | |
| 160 | +| Proiect regional | RegionalProject | regional_projects | Proiecte regionale | |
| 161 | +| Proiect BCR | BCRProject | b_c_r_projects | Proiecte parteneriat BCR | |
| 162 | + |
| 163 | +### 5.2 Model Project |
| 164 | +**Fișier:** `app/Models/Project.php` |
| 165 | + |
| 166 | +| Câmp | Tip | Descriere | |
| 167 | +|------|-----|-----------| |
| 168 | +| organization_id | FK | Organizația proprietară | |
| 169 | +| name | string | Denumire proiect | |
| 170 | +| slug | string | URL (generat la aprobare) | |
| 171 | +| status | enum | draft, pending, approved, rejected, archived | |
| 172 | +| target_budget | integer | Buget țintă (lei) | |
| 173 | +| start | date | Data început | |
| 174 | +| end | date | Data sfârșit | |
| 175 | +| archived_at | date | Data arhivării | |
| 176 | +| description | text | Descriere | |
| 177 | +| scope | text | Domeniu de aplicare | |
| 178 | +| beneficiaries | text | Beneficiari | |
| 179 | +| reason_to_donate | text | Motiv donație | |
| 180 | +| is_national | boolean | Proiect național (toate județele) | |
| 181 | +| accepting_volunteers | boolean | Acceptă voluntari | |
| 182 | +| accepting_comments | boolean | Acceptă comentarii | |
| 183 | +| videos | json | Array URL-uri video | |
| 184 | +| external_links | json | Link-uri externe | |
| 185 | + |
| 186 | +**Relații:** |
| 187 | +- `organization` - BelongsTo Organization |
| 188 | +- `donations` - HasMany Donation |
| 189 | +- `categories` - MorphToMany ProjectCategory |
| 190 | +- `counties` - MorphToMany County (dacă nu e național) |
| 191 | +- `volunteers` - MorphToMany Volunteer (prin model_has_volunteers) |
| 192 | +- `stages` - BelongsToMany ChampionshipStage |
| 193 | +- `tickets` - HasManyThrough Organization |
| 194 | + |
| 195 | +**Colecții media (Spatie Media Library):** |
| 196 | +- `preview` - Imagine principală |
| 197 | +- `gallery` - Galerie imagini |
| 198 | + |
| 199 | +### 5.3 Statusuri proiect |
| 200 | +| Status | Vizibil public | Descriere | |
| 201 | +|--------|----------------|-----------| |
| 202 | +| draft | Nu | Proiect în lucru | |
| 203 | +| pending | Nu | În așteptarea aprobării | |
| 204 | +| approved | Da | Aprobat, vizibil | |
| 205 | +| rejected | Nu | Respins | |
| 206 | +| archived | Nu | Arhivat (după perioada de colectare) | |
| 207 | + |
| 208 | +**Statusuri vizibile (atribute derivate):** |
| 209 | +- `starting_soon` - În curând |
| 210 | +- `open` - Deschis pentru donații |
| 211 | +- `close` - Închis |
| 212 | +- `archived` - Arhivat |
| 213 | + |
| 214 | +### 5.4 Flow aprobare proiect |
| 215 | +1. ONG creează proiect cu status `draft` (ProjectService) |
| 216 | +2. ONG trimite la aprobare → status `pending` |
| 217 | +3. Admin aprobă/respinge în Filament |
| 218 | +4. La aprobare: generare slug unic, actualizare status |
| 219 | +5. La respingere: creare tichet cu motiv, notificare ONG |
| 220 | +6. Câmpurile `requiresApproval`: name, target_budget, start, end - modificările trec prin flow aprobare (LogsActivityForApproval) |
| 221 | + |
| 222 | +### 5.5 Serviciu proiect |
| 223 | +**Fișier:** `app/Services/ProjectService.php` |
| 224 | +- `create()` - Creare proiect draft |
| 225 | +- `update()` - Actualizare (counties, categories, image, gallery sau câmpuri simple) |
| 226 | +- `changeStatus()` - Schimbare status (pending, archived, publish pentru Gala) |
| 227 | + |
| 228 | +### 5.6 Rute proiecte |
| 229 | +| Metodă | URL | Controller | Descriere | |
| 230 | +|--------|-----|------------|-----------| |
| 231 | +| GET | /projects | ProjectController@index | Lista proiecte (listă/hartă) | |
| 232 | +| GET | /projects/map | ProjectController@map | Hartă proiecte | |
| 233 | +| GET | /projects/{slug} | ProjectController@show | Pagina proiect | |
| 234 | +| POST | /projects/{slug}/donate | ProjectController@donate | Inițiere donație | |
| 235 | +| POST | /projects/{slug}/volunteer | ProjectController@volunteer | Înscriere voluntar | |
| 236 | +| GET | /dashboard/projects | Dashboard\ProjectController@index | Lista proiecte ONG | |
| 237 | +| GET | /dashboard/projects/create | Dashboard\ProjectController@create | Formular creare | |
| 238 | +| POST | /dashboard/projects | Dashboard\ProjectController@store | Creare proiect | |
| 239 | +| GET | /dashboard/projects/{id}/edit | Dashboard\ProjectController@edit | Editare proiect | |
| 240 | +| POST | /dashboard/projects/{id} | Dashboard\ProjectController@update | Actualizare proiect | |
| 241 | +| POST | /dashboard/projects/{id}/status | Dashboard\ProjectController@changeStatus | Schimbare status | |
| 242 | + |
| 243 | +### 5.7 Filtre și sortări (lista publică) |
| 244 | +- **Filtre:** județ, categorie, interval date, status, voluntari, căutare, național |
| 245 | +- **Sortări:** data publicare, data încheiere, buget țintă, total donații, număr donații |
| 246 | + |
| 247 | +--- |
| 248 | + |
| 249 | +## 6. Fluxuri principale |
| 250 | + |
| 251 | +### 6.1 Donare la proiect |
| 252 | +1. Utilizator selectează proiect și suma pe pagina proiectului |
| 253 | +2. POST `/projects/{slug}/donate` → creare Donation cu status INITIALIZE |
| 254 | +3. Redirect către `/doneaza/{uuid}` (DonationController) |
| 255 | +4. Integrare EuPlatesc pentru plată |
| 256 | +5. Callback EuPlatesc actualizează status donație |
| 257 | +6. Job-uri: CaptureAuthorizedDonationJob, ProcessAuthorizedTransactionsJob |
| 258 | + |
| 259 | +### 6.2 Înscriere voluntar |
| 260 | +- **Pentru proiect:** POST `/projects/{slug}/volunteer` |
| 261 | +- **Pentru organizație:** POST `/organizations/{slug}/volunteer` |
| 262 | +- Se creează/actualizează Volunteer și pivot model_has_volunteers cu status `pending` |
| 263 | +- ONG-ul aprobă/respinge în dashboard (`/dashboard/volunteers`) |
| 264 | + |
| 265 | +### 6.3 Ciclu de viață proiect |
| 266 | +``` |
| 267 | +draft → pending → approved (public) → archived |
| 268 | + ↘ rejected |
| 269 | +``` |
| 270 | +- Comanda `EndProjectPeriod` (Console) arhivează proiectele care au depășit perioada |
| 271 | +- Notificare `ProjectEndingNotification` trimisă ONG-urilor cu proiecte care se apropie de sfârșit |
| 272 | + |
| 273 | +--- |
| 274 | + |
| 275 | +## 7. Baza de date |
| 276 | + |
| 277 | +### 7.1 Migrații relevante |
| 278 | +| Fișier | Descriere | |
| 279 | +|--------|-----------| |
| 280 | +| 2023_05_05_142228_create_organizations_table | Tabel organizații | |
| 281 | +| 2023_05_15_123613_create_projects_table | Tabel proiecte | |
| 282 | +| 2023_05_05_142245_add_organization_column_to_users_table | organization_id pe users | |
| 283 | +| 2023_06_20_001911_create_activity_domain_organization | Pivot organizații-domenii | |
| 284 | +| 2023_08_13_072825_create_project_categories_table | Categorii proiecte | |
| 285 | +| 2023_08_13_072830_create_model_has_project_categories_table | Pivot proiecte-categorii | |
| 286 | +| model_has_counties | Pivot polimorf pentru județe (organizații, proiecte) | |
| 287 | +| model_has_volunteers | Pivot polimorf voluntari (proiecte, organizații) | |
| 288 | + |
| 289 | +### 7.2 Diagramă relații (simplificată) |
| 290 | +``` |
| 291 | +Organization 1──* Project |
| 292 | +Organization 1──* User |
| 293 | +Organization *──* ActivityDomain |
| 294 | +Organization *──* County (morph) |
| 295 | +Organization 1──* Ticket |
| 296 | +
|
| 297 | +Project 1──* Donation |
| 298 | +Project *──* ProjectCategory (morph) |
| 299 | +Project *──* County (morph) |
| 300 | +Project *──* Volunteer (morph, pivot: VolunteerRequest) |
| 301 | +Project *──* ChampionshipStage (pivot) |
| 302 | +``` |
| 303 | + |
| 304 | +--- |
| 305 | + |
| 306 | +## 8. Autentificare și autorizare |
| 307 | + |
| 308 | +### 8.1 Roluri utilizatori |
| 309 | +| Rol | Cod | Acces | |
| 310 | +|-----|-----|-------| |
| 311 | +| Super Admin | superadmin | Filament admin, tot | |
| 312 | +| Super Manager | supermanager | Filament admin | |
| 313 | +| Admin ONG | admin | Dashboard ONG, organizație proprie | |
| 314 | +| Manager ONG | manager | Dashboard ONG, organizație proprie | |
| 315 | +| User | user | Donator, profil personal | |
| 316 | + |
| 317 | +### 8.2 Politici |
| 318 | +- **ProjectPolicy:** view/update doar dacă user aparține organizației proiectului sau e superadmin |
| 319 | +- **OrganizationPolicy:** update doar superuser sau admin/manager al organizației; create/delete restricționat |
| 320 | + |
| 321 | +### 8.3 Middleware |
| 322 | +- `hasOrganization` - Utilizatorii dashboard trebuie să aibă organization_id (ONG) |
| 323 | +- `auth`, `verified` - Pentru zone protejate |
| 324 | + |
| 325 | +--- |
| 326 | + |
| 327 | +## 9. Integrări externe |
| 328 | + |
| 329 | +### 9.1 EuPlatesc |
| 330 | +- Plăți card pentru donații |
| 331 | +- Configurare per organizație: `eu_platesc_merchant_id`, `eu_platesc_private_key` |
| 332 | +- Flux: autorizare → încărcare (charge) prin job-uri |
| 333 | +- Config: `config/euplatesc.php` |
| 334 | + |
| 335 | +### 9.2 AWS S3 |
| 336 | +- Stocare imagini (logo, preview, gallery) și documente (statut) |
| 337 | +- Config: `config/filesystems.php`, `config/media-library.php` |
| 338 | + |
| 339 | +### 9.3 Google Maps |
| 340 | +- Hartă proiecte pe județe |
| 341 | +- Config: `services.google_maps_api_key` |
| 342 | + |
| 343 | +### 9.4 Newsletter (Mailchimp) |
| 344 | +- Abonare la înregistrare |
| 345 | +- Config: `config/newsletter.php` |
| 346 | + |
| 347 | +--- |
| 348 | + |
| 349 | +## 10. Medii de deployment |
| 350 | + |
| 351 | +### 10.1 Docker |
| 352 | +- Configurare în `docker/` (nginx, php, s6 services) |
| 353 | +- Cron, queue worker, Laravel, SSR pentru Vue |
| 354 | + |
| 355 | +### 10.2 Terraform |
| 356 | +- Infrastructură în `terraform/` |
| 357 | + |
| 358 | +### 10.3 Comenzi utile |
| 359 | +```bash |
| 360 | +# Setup inițial |
| 361 | +composer install |
| 362 | +npm install |
| 363 | +php artisan key:generate |
| 364 | +php artisan migrate:fresh --seed |
| 365 | + |
| 366 | +# Development |
| 367 | +npm run dev |
| 368 | +php artisan serve |
| 369 | + |
| 370 | +# Build production |
| 371 | +npm run build |
| 372 | +``` |
| 373 | + |
| 374 | +--- |
| 375 | + |
| 376 | +## Glosar |
| 377 | + |
| 378 | +| Termen | Definiție | |
| 379 | +|--------|-----------| |
| 380 | +| ONG | Organizație neguvernamentală | |
| 381 | +| EuPlatesc | Gateway plăți românesc | |
| 382 | +| Filament | Framework admin Laravel | |
| 383 | +| Inertia | Bridge Laravel-Vue fără API REST | |
| 384 | +| Spatie Media Library | Gestionare fișiere pe modele | |
| 385 | + |
| 386 | +--- |
| 387 | + |
| 388 | +*Documentație generată pentru predarea proiectului către o nouă echipă. Ultima actualizare: februarie 2025.* |
0 commit comments