Backend de conținut pentru aplicația PTSD Help: Learn, Support, media pentru tool-uri și feature flags.
Design: ../docs/superpowers/specs/2026-09-28-strapi-cms-design.md.
Dezvoltarea locală folosește MySQL 8.4 local configurat în .env (DATABASE_CLIENT=mysql, 127.0.0.1:3306, baza
ptsd-help-backend, user strapi). Fără Docker. Baza se creează o singură dată, ca root:
CREATE DATABASE `ptsd-help-backend` CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
CREATE USER 'strapi'@'localhost' IDENTIFIED BY '...';
GRANT ALL PRIVILEGES ON `ptsd-help-backend`.* TO 'strapi'@'localhost';Tabelele le creează Strapi la primul npm run develop. Proiectul a rulat inițial pe PostgreSQL; datele au fost mutate
cu npx strapi export / npx strapi import.
cp .env.example .env # completează secretele și datele bazei locale
npm install
npm run develop # http://localhost:1337/adminnode ../pull-s3-content.mjs # actualizează ../s3-content
npm run build
npm run import:s3 # --reset pentru re-import
npm run develop
npm run parity # compară cu JSON-urile S3Importul aplică și două corecții pentru date legacy (vezi scripts/lib/legacy-fixes.ts: URL-uri externe/webview fără schemă și butoane fără label) și afișează avertismente WARN: pentru fiecare valoare corectată.
| Endpoint | Înlocuiește |
|---|---|
GET /api/app/config/foggles/:country |
config/foggles_{C}.json |
GET /api/app/config/tools-assets/:country/:locale |
config/CMSToolsAssetsMapping_{C}_{l}.json |
GET /api/app/content/:country/:locale/learn |
content/resources/{C}/{l}/learn.json |
GET /api/app/content/:country/:locale/support |
content/resources/{C}/{l}/support.json |
Draft & Publish e dezactivat pe toate tipurile: orice modificare salvată în admin apare imediat în endpoint-uri.
Media pentru tool-uri și simptome se gestionează în Content Manager → Tool asset: o intrare per fișier, adică
per (țară, cheie). key (enumerare din ASSET_KEYS) și country sunt comune tuturor limbilor; file e
localizat, deci fiecare limbă a țării poate avea alt fișier (adaugă limba din selectorul de locale al intrării).
Lista se poate căuta și filtra după cheie și țară. O a doua intrare cu aceeași cheie în aceeași țară e refuzată la
salvare. key și country se aleg la Create și nu se mai pot schimba după (serverul refuză salvarea). GET /api/app/config/tools-assets/:country/:locale întoarce { [key]: { uri, lastUpdatedAt } } din
toate intrările țării în limba cerută.
Pentru o țară sau o limbă nouă, intrările nu se creează de mână: butonul „Copiază din altă țară/limbă” din
lista Tool asset (src/admin/components/CopyToolAssets.tsx) copiază toate cheile unei țări/limbi existente, cu
aceleași fișiere din Media Library (fără upload nou). Cheile care lipsesc la destinație se creează, cele care există
fără limba destinație primesc limba, iar cele care o au deja nu se modifică. Butonul apelează
POST /ptsd-admin/tool-assets/copy (rută de admin, doar cu login de admin; src/admin-api/tool-asset-copy.ts).
Limbile permise pe țară sunt în src/constants/country-languages.ts (AM → hy; RO → ro, en, uk; UA → uk) și trebuie
să fie identice cu CountryLanguageMap din ptsd-help-mobile/constants/languages.ts. La salvarea unei Content page
sau a unui Tool asset într-o limbă pe care țara nu o are, Strapi refuză cu un mesaj. La o țară sau limbă nouă se
actualizează ambele fișiere. Pașii compleți (mobil, backend, Strapi): ../docs/adaugare-tara-limba.docx.
src/constants/keys.ts, enumerarea key din api::tool-asset.tool-asset și componentele shared.tool-flag, shared.subtool-flag se generează din
../s3-content și ../ptsd-help-mobile/hooks/useTools.ts:
npm run generate:keysRulează din nou când aplicația adaugă tool-uri sau chei de media.
Câmpurile rich text folosesc editorul Strapi Rich text (Blocks): section.rich-text.body și shared.block.body
(pentru blocurile de tip rich-text; blocurile de tip text folosesc câmpul text simplu content). Endpoint-urile
aplicației trimit în continuare HTML: src/lib/rich-text.ts convertește blocurile în HTML (paragrafele devin <div>,
iar cele importate din <p> legacy rămân <p>). npm run import:s3 convertește HTML-ul legacy direct în blocuri.
După primul start, în Settings → Administration panel → Roles → Editor: debifează Country și Feature flags
(le gestionează doar Super Admin). Rolul Public (Users & Permissions) nu primește nicio permisiune.
Docker este doar pentru staging. docker-compose.yml pornește serviciul strapi (build din Dockerfile,
env_file: .env, port 1337:1337, restart: unless-stopped). Baza de date vine din variabilele DATABASE_*
din .env-ul de staging și poate fi o bază externă/managed.
docker compose up -d --build # DB externă, din .env
docker compose --profile with-db up -d --build # + serviciul mysql inclus (opțional)
docker compose logs -f strapi
docker compose down.env-ul de staging (aceleași chei ca .env.example) trebuie să conțină:
- secrete reale, puternice, unice (
APP_KEYS,API_TOKEN_SALT,ADMIN_JWT_SECRET,TRANSFER_TOKEN_SALT,JWT_SECRET,ENCRYPTION_KEY,DATABASE_PASSWORD) — niciodată valorile din.env.example; NODE_ENV=production;PUBLIC_URL= URL-ul public al serverului;IS_PROXIED=truedacă serverul rulează în spatele unui reverse proxy TLS (altfelfalse);UPLOAD_PROVIDER=aws-s3și variabileleS3_*;- variabilele bazei de date:
DATABASE_CLIENT,DATABASE_HOST,DATABASE_PORT,DATABASE_NAME,DATABASE_USERNAME,DATABASE_PASSWORD,DATABASE_SSL.
Opțional, --profile with-db: pentru un host de staging fără bază de date proprie. Pornește și serviciul
mysql (MySQL 8.4, utf8mb4, date în volumul mysqldata), expus doar pe 127.0.0.1:3307. În acest caz setează în
.env DATABASE_CLIENT=mysql, DATABASE_HOST=mysql și DATABASE_PORT=3306 (rețeaua internă Docker);
DATABASE_NAME, DATABASE_USERNAME și DATABASE_PASSWORD sunt folosite și pentru inițializarea bazei și a userului.
Parola de root e generată aleator la prima pornire (apare în docker compose logs mysql).