Partage AdminEnfantUserCard entre fiche parent et onglet Enfants, enrichit ParentChildSummary (photo, dates) et compacte la modale parent. Co-authored-by: Cursor <cursoragent@cursor.com>
154 lines
5.7 KiB
JavaScript
154 lines
5.7 KiB
JavaScript
/**
|
|
* Met à jour l'issue Gitea #140 — epic dashboard admin ch.6 famille.
|
|
* Usage: node backend/scripts/update-gitea-issue-140-ch6-famille.js
|
|
* Token : .gitea-token (racine), GITEA_TOKEN, ou docs/27_BRIEFING-FRONTEND.md
|
|
*/
|
|
const https = require('https');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const repoRoot = path.join(__dirname, '../..');
|
|
let token = process.env.GITEA_TOKEN;
|
|
if (!token) {
|
|
try {
|
|
const tokenFile = path.join(repoRoot, '.gitea-token');
|
|
if (fs.existsSync(tokenFile)) token = fs.readFileSync(tokenFile, 'utf8').trim();
|
|
} catch (_) {}
|
|
}
|
|
if (!token) {
|
|
try {
|
|
const briefing = fs.readFileSync(
|
|
path.join(repoRoot, 'docs/27_BRIEFING-FRONTEND.md'),
|
|
'utf8',
|
|
);
|
|
const m = briefing.match(/Token:\s*(giteabu_[a-f0-9]+)/);
|
|
if (m) token = m[1].trim();
|
|
} catch (_) {}
|
|
}
|
|
if (!token) {
|
|
console.error('Token non trouvé : .gitea-token ou GITEA_TOKEN (voir docs/26_GITEA-API.md)');
|
|
process.exit(1);
|
|
}
|
|
|
|
const body = `## Rôle de ce ticket
|
|
|
|
**#140 est un ticket epic / livraison** : il regroupe la mise en œuvre du **chapitre 6** du doc [28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md](../docs/28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md) (§6.1 et §6.2) sur la branche \`feature/140-dashboard-admin-ch6-famille\`.
|
|
|
|
Il **ne remplace pas** les tickets détaillés ci-dessous : il sert de **fil de livraison** (PR, recette, fermeture coordonnée). Chaque sous-ticket garde son périmètre propre ; #140 est clos quand l'ensemble est **fonctionnel et homogène en UI**.
|
|
|
|
---
|
|
|
|
## Tickets couverts (périmètres embarqués)
|
|
|
|
| Ticket | Sujet | Rôle dans #140 |
|
|
|--------|--------|----------------|
|
|
| **#115** | Rattachement parent — **backend** | API \`POST/DELETE …/enfants/:enfantId\` |
|
|
| **#116** | Rattachement parent — **frontend** | UI rattacher / détacher depuis la fiche parent |
|
|
| **#130** | \`UserService\` — APIs admin | Appels \`getParents\`, \`getParent\`, \`getEnfants\`, \`updateParentFiche\`, etc. |
|
|
| **#131** | Fiche parent éditable | Modale parent (dashboard) — *hors fiche AM* |
|
|
| **#137** | Onglet **Enfants** | Liste globale admin + accès fiche enfant |
|
|
| **#138** | Fiche enfant + liste dans fiche parent | \`AdminChildDetailModal\` + liste enfants en bas de fiche parent |
|
|
|
|
> **Note :** fermer #140 peut entraîner la fermeture **partielle ou totale** de ces tickets selon ce qui est réellement livré et recetté dans la PR.
|
|
|
|
---
|
|
|
|
## Hors scope #140
|
|
|
|
- **§6.3** — Création dossier admin sans numéro → **#129**
|
|
- Fiche **AM** éditable (dashboard) → reste **#131** (partie AM)
|
|
- Parcours gestionnaire « famille complexe » → **#139**
|
|
- Qualification responsable légal (combobox sur lien) → ticket à créer
|
|
|
|
---
|
|
|
|
## Backend (attendu / livré)
|
|
|
|
- [x] \`PATCH /parents/:id/fiche\` — édition fiche parent (admin/gestionnaire)
|
|
- [x] \`POST /parents/:id/enfants/:enfantId\` — rattacher un enfant existant
|
|
- [x] \`DELETE /parents/:id/enfants/:enfantId\` — détacher (garde-fou : ≥1 responsable / enfant)
|
|
- [x] \`GET /enfants\` enrichi ; \`PATCH /enfants/:id\` pour gestionnaire
|
|
|
|
---
|
|
|
|
## Frontend — fait
|
|
|
|
- [x] Modale **fiche parent** éditable (shell aligné validation, statut gélule, téléphone formaté, \`IdentityBlock\`)
|
|
- [x] Onglet **Enfants** — liste globale (\`EnfantManagementWidget\`)
|
|
- [x] Liste enfants dans fiche parent — cartes (photo, nom, âge ans/mois, statut), cadre blanc, scroll 2,5 lignes
|
|
- [x] Rattacher / détacher un enfant **existant** (API branchée)
|
|
- [x] Parsing robuste \`parentChildren\` + URLs médias \`/uploads\` en Flutter web
|
|
- [x] \`UserService\` — APIs parents / enfants / affiliation
|
|
|
|
---
|
|
|
|
## Frontend — reste à faire (bloquant clôture)
|
|
|
|
### Fiche enfant — #138 (UI)
|
|
- [ ] Reprendre \`AdminChildDetailModal\` : même **look & feel** que fiche parent / modales validation (largeur ~930 px, grille champs, photo enfant)
|
|
- [ ] Aligner dates, genre, statut sur les wizards validation famille
|
|
|
|
### Modale **rattacher** un enfant — #116 (UI)
|
|
- [ ] Remplacer le \`SimpleDialog\` actuel par une modale cohérente : liste type \`AdminEnfantUserCard\` (photo, nom, âge), recherche éventuelle
|
|
|
|
### Création d'un **nouvel** enfant depuis la fiche parent — doc §6.2
|
|
- [ ] **Non implémenté** aujourd'hui (seul le rattachement d'un enfant déjà en base existe)
|
|
- [ ] À trancher : inclus dans #140 si le back expose un \`POST\` admin depuis le contexte parent, sinon ticket dédié / extension #129
|
|
|
|
---
|
|
|
|
## Recette avant merge
|
|
|
|
1. Parent avec 0 / 1 / 3+ enfants — liste, scroll, compteur
|
|
2. Rattacher puis détacher (message si dernier responsable)
|
|
3. Clic enfant → fiche enfant (après refonte UI)
|
|
4. Onglet Enfants — même rendu cartes
|
|
5. Avatars photos (URLs absolues web)
|
|
|
|
---
|
|
|
|
## Branche
|
|
|
|
\`feature/140-dashboard-admin-ch6-famille\`
|
|
|
|
## Références
|
|
|
|
- Doc produit : \`docs/28_EVOLUTION-FAMILLE-ET-RESPONSABLES.md\` §6.1, §6.2`;
|
|
|
|
const payload = JSON.stringify({ body });
|
|
|
|
const req = https.request(
|
|
{
|
|
hostname: 'git.ptits-pas.fr',
|
|
path: '/api/v1/repos/jmartin/petitspas/issues/140',
|
|
method: 'PATCH',
|
|
headers: {
|
|
Authorization: `token ${token}`,
|
|
'Content-Type': 'application/json',
|
|
'Content-Length': Buffer.byteLength(payload),
|
|
},
|
|
},
|
|
(res) => {
|
|
let data = '';
|
|
res.on('data', (chunk) => {
|
|
data += chunk;
|
|
});
|
|
res.on('end', () => {
|
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
const json = JSON.parse(data);
|
|
console.log('Issue #140 mise à jour :', json.html_url);
|
|
console.log('updated_at:', json.updated_at);
|
|
} else {
|
|
console.error('Erreur', res.statusCode, data);
|
|
process.exit(1);
|
|
}
|
|
});
|
|
},
|
|
);
|
|
req.on('error', (err) => {
|
|
console.error(err);
|
|
process.exit(1);
|
|
});
|
|
req.write(payload);
|
|
req.end();
|