Manuel pour prestataires informatiques
🖥️ Pour les prestataires informatiques
Comptoir d’accueil vide le soir
Manuel 3 sur 5 · manuel pour prestataires informatiques · état r396

Rosie — architecture, sécurité, exploitation

La référence technique pour les prestataires informatiques et les responsables informatiques chez le client. Instance suisse, en-têtes de sécurité, cache de l’application, notifications web, migrations de base de données, sauvegarde, observabilité et escalade — le tout traçable. Les noms des fournisseurs figurent ici volontairement, parce que vous devez ouvrir des règles de pare-feu et documenter l’externalisation.

🖥️ IT 🇨🇭 Infomaniak (CH) 🔒 HSTS preload 📡 Web Vitals État r396
🏗️

Architecture du système

Application web en JavaScript natif sur une instance suisse

Rosie est une application web progressive en JavaScript natif. L’application tourne comme processus Node sur une instance Debian chez Infomaniak, en Suisse, précédée de Caddy comme proxy inverse avec gestion automatique des certificats. La persistance passe par libSQL/SQLite sur la même instance (mode WAL), le stockage d’objets par le stockage d’objets compatible S3 d’Infomaniak. Le service worker utilise un CACHE_PREFIX par version. Un service de protection est placé devant le site public — il ne conserve aucune donnée ; l’interface s’adresse directement à l’instance suisse.

🖥️
Calcul
Node sur Debian chez Infomaniak (CH), Caddy comme proxy inverse. Aucun serveur ni machine virtuelle chez le client.
🗄️
libSQL / SQLite
Sur la même instance, mode WAL, sauvegardes chiffrées hors site. Données hébergées en Suisse.
📦
Stockage d’objets
Pièces jointes et documents dans le stockage d’objets compatible S3 d’Infomaniak (Suisse).
🤖
IA en option
Activable par mandant. Le fournisseur d’IA utilisé figure dans la liste des sous-traitants ultérieurs du contrat de sous-traitance — pas dans ce manuel, afin qu’il ne devienne pas faux en cas de changement.
ℹ️
La pile en un coup d’œil : JavaScript natif · Node sur Debian (Infomaniak CH) · Caddy · libSQL/SQLite · stockage d’objets compatible S3 · service worker avec préfixe de version · notifications web. Rien à installer chez le client.
🌍

Compatibilité des navigateurs

Quels navigateurs sont pris en charge
🟢
Chrome ≥ 90
Entièrement pris en charge, installation de l’application comprise.
🦊
Firefox ≥ 88
Entièrement pris en charge.
🔷
Edge ≥ 90
Entièrement pris en charge, installation de l’application comprise.
🧭
Safari ≥ 14.1
Installation via « Sur l’écran d’accueil ».
⚠️
Internet Explorer : non pris en charge. Écran de démarrage iOS en PNG obligatoire : le format WebP n’est plus accepté depuis la version r168 — les images de démarrage iOS DOIVENT être en PNG.
🌐

DNS et domaines

Domaine principal, alias et sous-domaine de l’application
  • Domaine principal : rosie-app.ch (y compris www).
  • Alias / miroir : rosie-planer.com — sous forme de redirection 301. Tenir compte d’une fenêtre de cache d’environ deux minutes, qui se résorbe d’elle-même. Vérification immédiate de l’origine via ?cb=<random>.
  • Sous-domaine de l’application : l’application tourne sous un nom propre qui pointe directement sur l’instance suisse (« DNS seulement », sans service intermédiaire).
  • Aucune entrée générique. *.rosie-app.ch n’existe pas — un nom inventé ne se résout pas. C’est voulu et cela exclut la prise de contrôle d’un sous-domaine.
  • Service de protection en amont uniquement pour le site public ; il ne conserve aucune donnée client.
💡
Fenêtre de cache du domaine alias : Après une mise en production, la redirection 301 vers rosie-planer.com peut brièvement provenir du cache du service en amont. Cela se résorbe seul. Pour l’analyse : requête vers l’origine avec un paramètre anti-cache.
🛡️

En-têtes de sécurité

HSTS preload, CSP, SRI, traçabilité des versions
🔒
HSTS (preload)
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload — posé par l’application elle-même, afin que l’en-tête s’applique indépendamment du service en amont. La soumission sur hstspreload.org se fait manuellement.
🧱
CSP stricte
Politique de sécurité du contenu stricte, en production.
🧾
SRI
Contrôle d’intégrité des scripts externes.
🔖
X-Worker-Version / X-Request-Id
Dans chaque réponse. WORKER_VERSION = RELEASE, importé depuis shared/version.mjs (source unique).
ℹ️
Vérifiable en une commande : curl -I https://rosie-app.ch affiche tous les en-têtes posés, y compris HSTS, CSP, X-Worker-Version et X-Request-Id.
⚠️
Piège : includeSubDomains s’applique à chaque sous-domaine, y compris les noms de test et de préproduction. Et un en-tête HSTS déjà livré reste valable jusqu’à deux ans dans le navigateur — il ne peut pas être retiré à court terme.
📦

Service worker, cache des ressources

Préfixe de cache, cache en amont, chargement différé, écran iOS, resynchronisation
  • sw.js avec CACHE_PREFIX, estampillé depuis shared/version.mjs (scripts/sync-version.mjs).
  • Cache en amont : environ deux minutes de décalage après une mise en production, qui se résorbe seul.
  • immutableen-tête de cache pour les ressources versionnées.
  • Bibliothèques chargées à la demande via _loadVendor — XLSX, html2canvas.
  • Écran de démarrage iOS en PNG obligatoire — WebP abandonné depuis la version r168.
  • Pas de synchronisation en arrière-plan — volontairement : un rejeu sans onglet ouvert n’aurait pas de jeton valide et risquerait des doubles écritures faute de clés d’idempotence. La file d’attente du chat ne se vide qu’avec l’application ouverte (voir docs/OFFLINE.md).
  • Notifications web sur iOS uniquement dans l’application installée — imposer l’ajout à l’écran d’accueil.
💡
Mise en production : RELEASE dans shared/version.mjs puis npm run version:sync — CACHE_PREFIX dans sw.js / src/constants.js sont estampillés automatiquement ; rien à reprendre à la main.
📡

Notifications web (RFC 8291)

VAPID, idempotence, heures de silence, catégories
  • Clés VAPID (publique et privée) stockées comme secrets sur l’instance, sous /etc/rosie/env.
  • subscribeToPushNotifications est un UPSERT idempotent.
  • Les heures de silence sont respectées.
  • Activation par catégorie d’alerte: bounty · planPublished · adminAlert · messages · absenceResult.
⚠️
La rotation des clés VAPID invalide tous les abonnements aux notifications (limitation connue) — à planifier avec soin.
🔥

Pare-feu / réseau

Autorisations, ports, interrogation
  • Uniquement HTTPS sortant sur le port 443.
  • Autorisation pour rosie-app.ch et le sous-domaine de l’application. Aucune autre destination n’est nécessaire — l’application n’appelle d’elle-même aucun service chez le client.
  • Aucun port entrant.
  • Pas de WebSocket nécessaire — l’application interroge le serveur toutes les 60 secondes.
📧

Système de courriel

SMTP via une boîte suisse, SPF/DKIM/DMARC

Envoi par SMTP vers une boîte suisse chez Hostpoint. L’expéditeur de tous les courriels du système est support@rosie-app.ch — une adresse à laquelle on peut répondre, pas une impasse. SPF, DKIM et DMARC sont configurés ; nous recommandons de tester une fois la remise contre le filtre antispam du client après la mise en place.

💡
Si les courriels d’invitation n’arrivent pas : vérifier d’abord la quarantaine et le filtre antispam chez le client, puis consulter SPF/DKIM/DMARC pour rosie-app.ch . Ajouter l’adresse support@rosie-app.ch à la liste blanche résout la plupart des cas.
📱

Mobile & MDM

iOS / Android, raccourcis web, installation
  • iOS 14.5+, Android 8.0+.
  • Application web — aucun paquet de magasin d’applications.
  • Le MDM peut configurer le navigateur préféré, les raccourcis sur l’écran d’accueil et les sites de confiance .
  • À noter : Notifications web sur iOS exige l’application installée ; écran de démarrage iOS en PNG (pas de WebP).
🗃️

Migrations et versions du schéma

Versionnées, en avant seulement, vérifiées après chaque passage

Les migrations se trouvent sous database/migrations/ , numérotées à la suite, et ne s’appliquent que vers l’avant. L’état actuel figure dans le répertoire lui-même — cette page ne cite volontairement aucun numéro, qui serait faux dès la version suivante. Chaque passage est suivi d’une vérification du schéma. Les migrations sont construites de manière à pouvoir reconstituer entièrement une base vide.

ℹ️
Les migrations s’exécutent lors de la mise en production et ne demandent aucune intervention chez le client. Aucun retour en arrière n’est prévu — le chemin de retour passe par la restauration (voir Sauvegarde & Restauration).
💾

Sauvegarde & Restauration

Sauvegardes chiffrées, points de restauration, export
  • Sauvegardes automatiques de la base de données, chiffrées et déposées hors site.
  • Fenêtre de restauration de 30 jours avec des points de restauration horaires (perte de données maximale : une heure).
  • Stockage d’objets est sauvegardé séparément.
  • Export complet des données par mandant, à tout moment depuis l’interface d’administration.
  • Pas de redondance géographique. Une seule instance de production est exploitée volontairement — un redémarrage ou une mise à jour entraîne une brève interruption. C’est un compromis connu et assumé, rattrapable sans changer l’architecture.
⚠️
Les délais de restauration ne font pas partie de ce manuel. Seul le contrat de service fait foi.
↩️

Retour arrière / versions

Étiquettes de version, procédure d’urgence

À chaque version correspond une étiquette checkpoint-rNNN-deployed dans le système de gestion du code source. On peut ainsi prouver à tout moment quelle version était en production et quand.

ℹ️
Retour arrière : La version précédente est conservée sur l’instance et peut être réactivée en quelques minutes. Une migration de base de données ne revient pas en arrière — pour aller plus loin, il faut passer par la restauration.
Procédure d’urgence
1
Annoncer au fournisseur
Les retours arrière sur l’instance sont effectués par le fournisseur — avec le numéro de version et l’heure tirés du symptôme.
2
Vider le cache du navigateur
Rechargement forcé, mise à jour du service worker si nécessaire.
3
Vérifier les en-têtes
curl -I → X-Worker-Version à contrôler.
🏢

Isolation des mandants

Filtrage côté serveur, réinitialisation à la déconnexion
  • Filtrage des mandants côté serveur — tenant_id dans chaque requête.
  • Les variables globales du mandant en mémoire sont vidées à la déconnexion par _resetTenantCalendarData() (six variables de calendrier).
  • Les tests de fuite entre mandants sont figés par des cas de régression.
  • Déclencheur d’enregistrement par marqueur de mandant companySettingsDirty.
📊

Observabilité & Journaux

Version, identifiant de requête, Web Vitals, filtrage des données personnelles
  • X-Worker-Version (r166 A10), X-Request-Id dans chaque réponse.
  • Web Vitals → /api/analytics, envoi en keepalive, signal « Do Not Track » respecté.
  • Filtre des données personnelles avant toute analyse.
  • k-anonymat ≥ 4 pour les graphiques agrégés.
  • Journaux se trouvent sur l’instance (systemd/journald) et sont exploités par le fournisseur ; une surveillance externe contrôle la disponibilité et alerte.
⚠️
Correction par rapport à l’ancien manuel : l’observabilité n’est PAS désactivée — elle est active, avec filtrage des données personnelles et respect du signal « Do Not Track ».
⚡

Budget de performance

LCP / CLS / INP, chargement différé, économie de batterie
  • Objectifs LCP / CLS / INP comme budget de performance.
  • Correction du décalage visuel: width / height sur les balises <img>.
  • Bibliothèques chargées à la demande via _loadVendor — XLSX / html2canvas.
  • Économie de batterie : l’interrogation s’interrompt lorsque document.hidden (pause à la perte de visibilité).
🔌

Principaux points d’API

Routes avec en-tête de version
👥
Données de base & Plan
/api/staff · /api/shift-assignments · /api/vacations
🤒
Absences
/api/absences · /api/absences/:id/{approve,reject,cancel} · /api/absence-approval-config
💬
Communication
/api/messages · /api/suggestions
📄
QMS
/api/qms/documents
📋
Tâches
/api/tasks · /api/tasks/templates · /api/tasks/:id/qms-links (PATCH) · /api/tasks/audit
🔄
Mutations / mise en route
/api/mutations · /api/onboarding/:step
📊
Analyses / journal
/api/analytics · /api/log
👤
Profil
/api/profile
🔐
Clôture mensuelle
/r163-monatsabschluss · /r163-monatsabschluss/:year_month (POST / DELETE)
📰
Proxy de flux
/api/feed-proxy
ℹ️
Chaque réponse porte un en-tête de version (X-Worker-Version) et un identifiant de requête (X-Request-Id).
🤖

Système d’IA & Pare-feu de protection des données

Limitation de débit, filtrage des données personnelles, reconnaissance vocale dans le navigateur
  • Fournisseur d’IA : activable par mandant ; un service fixe par usage, sans service de repli automatique. Le fournisseur utilisé figure dans la liste des sous-traitants ultérieurs du contrat de sous-traitance — pas ici, afin que cette page ne devienne pas fausse en cas de changement.
  • Limitation de débit : 30 requêtes par heure et par utilisateur.
  • Le filtre de données personnelles retire adresse électronique, numéro AVS, IBAN, téléphone et date avant chaque appel au service d’IA.
  • Tâches planifiées de l’IA 0 2 / 0 4 pour l’apprentissage des motifs de tâches — requêtes sans staff.id.
  • Reconnaissance vocale : assurée par le navigateur (Web Speech API) ; selon le navigateur ou le système d’exploitation, l’enregistrement est envoyé à son propre service de reconnaissance vocale — ROSIE ne reçoit ni ne conserve aucun enregistrement audio. Pour la reconnaissance de la commande, seul le texte reconnu est envoyé au service d’IA, avec consentement (art. 6 al. 6 nLPD).
💡
Pare-feu de protection des données : requêtes anonymisées sans identifiant ; numéro de téléphone, numéro AVS, IBAN, adresse électronique et date sont retirés avant l’envoi, les noms non. Pour les règles de pare-feu du client : les appels au service d’IA partent de l’instance, pas du poste de travail. La reconnaissance vocale, en revanche, est appelée par le navigateur depuis le poste de travail, auprès du service de son fournisseur.
🧩

Système de modules

Modules optionnels par mandant

Modules optionnels : Gestion de la qualité (QMS), Voice-to-Schedule, Préparation des salaires & finances, Smart Matchmaker, Radar de charge, Réseau régional. Activation par mandant via Administration → Outils.

♿

Accessibilité & Langues

Échap et piège de focus, ARIA, quatre langues d’interface
  • Touche Échap globale et piège de focus .
  • Barre de progression ARIA .
  • Quatre langues d’interface : DE / FR / IT / EN.
  • 14 langues de chat pour la communication interne — la traduction s’effectue sur l’appareil.
🔑

Gestion des secrets

Secrets sur l’instance · rotation · hachage des mots de passe
  • Les secrets se trouvent dans /etc/rosie/env sur l’instance, lisibles uniquement par le compte de service : clé de signature des sessions, paire de clés VAPID, identifiants pour le stockage d’objets, le SMTP et le service d’IA.
  • Renouveler la clé de signature chaque année.
  • La rotation des clés VAPID invalide les abonnements aux notifications (limitation connue).
  • Hachage des mots de passe : PBKDF2-SHA-256 avec sel, en quatre passes chaînées de 100 000 itérations chacune (400 000 au total).
🚀

Première mise en place côté informatique

Ce qu’il y a à faire chez le client — et ce qu’il n’y a pas à faire

La création d’un mandant se fait chez le fournisseur, sur l’instance suisse. Aucune installation n’est nécessaire chez le client — pas de serveur, pas d’agent, pas de port entrant. Ce qui suit est la liste des points qui incombent réellement au client.

Après la mise en route
1
Vérifier l’accessibilité
curl -I sur l’adresse de l’application — en-têtes, dont X-Worker-Version à contrôler.
2
Tester la remise des courriels
Envoyer une invitation à une adresse du client et contrôler la quarantaine ; support@rosie-app.ch à autoriser.
3
Signer le contrat de sous-traitance
Conclure le contrat de sous-traitance avec Digital Passion GmbH — elle est à la fois fournisseur et sous-traitant.
4
Créer le compte d’administration
Premier administrateur du mandant.
🛠️

Dépannage & Assistance

Procédures, niveaux d’escalade

Des procédures existent pour : erreurs de connexion · erreurs de base de données · erreurs de mise en production · remise des courriels · panne de l’IA · remise des notifications · erreurs de migration.

ℹ️
Assistance : support@rosie-app.ch. Les délais de réaction sont réglés par le contrat de service, pas par ce manuel. Pour les annonces de sécurité, la voie de signalement figure sous /.well-known/security.txt.
Niveaux d’escalade
1️⃣
1er niveau
Navigateur / cache / application.
2️⃣
2e niveau
Réseau, remise des courriels, MDM — tout ce qui relève du client.
3️⃣
3e niveau
Fournisseur : journaux du serveur, base de données, version. Merci d’annoncer avec X-Request-Id et l’heure.
🔒

Vérification de la protection des données

TLS / AES / hébergement / contrat / authentification unique
  • TLS 1.3.
  • AES-256 au repos. Les champs de texte libre particulièrement sensibles sont en outre chiffrés individuellement.
  • Hébergement des données en Suisse (Infomaniak) : puissance de calcul, base de données, stockage d’objets et sauvegardes. Le service de protection placé devant le site public et le prestataire de paiement sont nommés dans la liste des sous-traitants ultérieurs du contrat de sous-traitance.
  • Contrat de sous-traitance disponible.
  • Aucun cookie, aucun pistage — le signal « Do Not Track » est respecté.
  • Destruction des clés comme révocation opérationnelle ; effacement dans les 30 jours suivant la fin du contrat, avec attestation écrite.
  • Le SSO (SAML/OIDC) est indisponible et en cours d’évaluation ; aucune date ferme n’est fixée. Connexion par courriel et mot de passe, avec TOTP en option.
❓

Questions fréquentes pour l’informatique

Les questions informatiques les plus fréquentes, brièvement
Où les données sont-elles stockées ?▶
En Suisse, chez Infomaniak : base de données (libSQL/SQLite) et stockage d’objets compatible S3. Chiffrées en transit (TLS 1.3) et au repos (AES-256). Le cadre contractuel est réglé par le contrat de sous-traitance ; la liste des sous-traitants ultérieurs y nomme tous les intervenants.
Quelles règles de pare-feu faut-il ?▶
Uniquement HTTPS sortant sur le port 443. Aucun port entrant. Une autorisation pour rosie-app.ch et le sous-domaine de l’application suffit — les appels au service d’IA partent de l’instance, pas du poste de travail.
L’authentification unique (SSO) existe-t-elle ?▶
Non. Le SSO (SAML/OIDC) n’est pas disponible et se trouve en évaluation ; aucune date ferme n’est fixée. Connexion par courriel et mot de passe, avec TOTP comme deuxième facteur en option.
L’observabilité est-elle désactivée ?▶
Correction : l’observabilité est ACTIVE — avec filtrage des données personnelles et respect du signal « Do Not Track ». Seules des données agrégées et anonymisées sont collectées.
Comment les mots de passe sont-ils hachés ?▶
PBKDF2-SHA-256 avec sel, en quatre passes chaînées de 100 000 itérations — 400 000 au total.
Pourquoi le WebP n’est-il pas admis pour l’écran de démarrage iOS ?▶
iOS n’accepte que le PNG pour les écrans de démarrage. Depuis la version r168, le WebP a été abandonné pour ces images — l’écran de démarrage iOS DOIT être en PNG.
Comment fonctionnent les notifications sur iOS ?▶
Les notifications web sur iOS ne fonctionnent que dans l’application installée. Recommandation MDM : imposer un raccourci sur l’écran d’accueil.
Pourquoi rosie-planer.com est-il brièvement obsolète après une mise en production ?▶
La redirection 301 du domaine alias se trouve derrière le service de protection et peut brièvement provenir du cache. Cela se résorbe seul. Analyse : requête vers l’origine avec un paramètre anti-cache (?cb=<random>).
Comment identifier la version en cours lors d’un incident ?▶
curl -I sur le domaine — l’en-tête X-Worker-Version indique le numéro de version actif, X-Request-Id la requête précise, pour la corrélation dans les journaux du serveur.

Rosie — manuel pour prestataires informatiques · version 9.9 · r396
Fournisseur et sous-traitant : Digital Passion GmbH, Haldenstrasse 16, 4600 Olten · CHE-154.512.796
Des questions ? support@rosie-app.ch · rosie-app.ch
← Retour à la vue d’ensemble