Présence par QR code (QRCONTR) — Hybride PRD+FSD¶
Code du module : QRCONTR Produit : (Papillon HR Suite + ALTARYS ENTERPRISE HR Suite) Pays concerné : CI (Côte d'Ivoire) — MVP Version : 1.0 Date : 01/03/2026 Auteur : ANALYST (Emmanuel & Claude Code) Documents d'entrée : - docs/specs/qr-attendance.md (spécification de niveau 1 rédigée par un humain) - docs/prd/platform-vision-prd.md (Vision de la plateforme PRD v1.0) - docs/research/3_validated/qr-attendance-legal-validated.md (recherche juridique) - docs/research/2_audit/qr-attendance-legal-audit.md (lacunes de l'audit juridique)
PARTIE A — Exigences du produit (PRD)¶
A.1 Résumé¶
Le problème¶
Dans la zone OHADA, le suivi des présences s'effectue généralement sur des feuilles de présence papier, voire pas du tout. Cela engendre trois risques cumulés pour les employeurs :
- Inexactitude de la paie : les heures supplémentaires et les retenues pour retard sont estimées, et non calculées à partir des données horaires réelles. Cela conduit à des trop perçus ou à des paiement insuffisants — deux situations coûteuses.
- Position indéfendable en cas de litige : Lorsqu'un salarié conteste le paiement d'heures supplémentaires ou des retenues sur salaire, les employeurs ne disposant pas de registres fiables sont désavantagés. Les tribunaux de Côte d'Ivoire, suivant la tradition francophone issue de l'article L.3171-4 du Code du travail français, ont tendance à donner raison au salarié lorsque l'employeur ne peut pas produire de registres de suivi du temps de travail.
- Falsification des pointages par un collègue et présences fantômes : les feuilles de présence papier n'offrent aucune garantie de responsabilité — les salariés peuvent pointer à la place de collègues absents sans qu'aucun mécanisme de détection ne le permette.
De plus, les systèmes de pointage biométriques (empreintes digitales, reconnaissance faciale), que certains employeurs ont adoptés, sont désormais effectivement interdits en Côte d'Ivoire par l'ARTCI (l'autorité de protection des données), qui les a jugés disproportionnés à des fins de contrôle des présences (communiqués de 2019, réitérés en juin 2024). Les entreprises utilisant des systèmes biométriques s'exposent à un risque réglementaire.
La solution¶
Le module QR Attendance (QRCONTR) remplace les registres papier et les systèmes biométriques non conformes par un système de pointage (arrivée/départ) respectueux de la vie privée, compatible avec les appareils mobiles et fonctionnant hors ligne, basé sur la lecture de codes QR.
Positionnement du module : atténuation des risques + efficacité opérationnelle. Le module : - Protège les employeurs en cas de litiges sociaux en produisant des registres de présence inviolables et horodatés, accompagnés d'une piste d'audit complète - Transmet des données précises sur les heures supplémentaires au service de la paie — heures classées par tranche d'heures supplémentaires, prêtes pour le calcul monétaire - Remplace les feuilles de présence papier par un système numérique fonctionnant sur n'importe quel smartphone, même hors ligne - Respecte la loi sur la protection des données CI — les codes QR sont explicitement approuvés par l'ARTCI comme une alternative proportionnée à la biométrie
Code du module : QRCONTR Commercialisable : Oui Sprint : 2b (en parallèle avec la gestion des absences) Objectif commercial : mars 2026
A.2 Profils d'utilisateurs¶
P1 : Directeur général (DG) —¶
- Dans QR Attendance : consulte le tableau de bord des présences à l'échelle de l'entreprise (statistiques récapitulatives). Ne configure ni n'utilise le module.
- Besoin principal : « Mon équipe est-elle présente ? Combien d'heures supplémentaires payons-nous ? »
- Contexte Papillon : Souvent le propriétaire de l'entreprise (gérant SARL). Dans les très petites entreprises (S1-S2, 2 à 10 employés), il peut également s'agir du responsable RH qui configure le module.
P2 : Responsable RH / HR Manager —¶
- Dans QR Attendance : Opérateur principal. Configure les sites, les codes QR, les plannings de travail. Consulte le tableau de bord quotidien des présences. Crée/approuve les régularisations. Génère des rapports. Exporte des données. Gère les demandes de télétravail.
- Besoin clé : « Qui est présent aujourd’hui ? Qui est en retard ? Mes relevés d’heures supplémentaires sont-ils exacts pour la paie ? »
- Contexte Papillon : Souvent un employé de confiance assumant plusieurs rôles. A besoin d’être guidé — étiquettes claires, formulaires simples, sauvegarde automatique. En transition depuis des feuilles de présence papier ou Excel.
- Contexte Entreprise (V2) : Directeur RH professionnel. A besoin d’attribuer des horaires en masse, de régulariser par lots, d’analyses avancées.
P4 : Employé / Employee —¶
- Dans QR Attendance : Scanne le code QR pour pointer à l’arrivée/au départ. Consulte son historique de présence. Demande des régularisations lorsqu’il a oublié de scanner. Demande des jours de télétravail.
- Besoin clé : « Pointer rapidement, vérifier mes heures, demander une correction si j’ai oublié. »
- Contexte Papillon : Faible maîtrise du numérique. Téléphone Android (souvent d’entrée de gamme). Connexion intermittente. A besoin d’une simplicité absolue — scanner, voir la confirmation, c’est fait.
N+1 : Manager —¶
- Dans QR Attendance : consulte les présences de l'équipe. Approuve les demandes de régularisation pour ses subordonnés directs. Approuve les demandes de télétravail. Consulte les rapports de l'équipe.
- Besoin clé : « Qui, dans mon équipe, est en retard ou absent ? Approuver rapidement les corrections. »
- Contexte Papillon : peut être un employé senior ayant une expérience limitée des outils de gestion. A besoin d'actions d'approbation claires.
P3 : Comptable / Accountant —¶
- Dans QR Attendance : accès en lecture seule aux données de présence pour le rapprochement de la paie. Consulte les rapports d’heures supplémentaires.
- Besoin clé : « Vérifier les heures supplémentaires avant le traitement de la paie. »
A.3 UIS¶
US-QR-001 : Pointage de l’employé¶
En tant qu’employé, je souhaite scanner le code QR du site lorsque j’arrive au travail, afin que ma présence soit enregistrée avec précision.
Critères d'acceptation : - Étant donné que je suis connecté à l'application Papillon et que je me trouve sur un site où un code QR est affiché, lorsque je scanne le code QR, un événement de pointage est enregistré avec mon identifiant d'employé, l'identifiant du site et l'horodatage de l'appareil. - Étant donné que je scanne le code QR, lorsque le scan est réussi, je vois un message de confirmation : « Pointage enregistré — [HH:MM] ». - Si je suis hors ligne, lorsque je scanne le code QR, l'événement de pointage est stocké localement et mis en file d'attente pour la synchronisation. - Si je scanne le même code QR deux fois en moins de 15 minutes, lorsque le système traite les scans, le deuxième scan est rejeté car il s'agit d'un doublon. - Si je suis un employé dont le contrat a pris fin, lorsque j'essaie de scanner, le scan est rejeté avec le message « Compte désactivé — contactez les RH ».
US-QR-002 : Point de sortie des employés¶
En tant qu'employé, je souhaite scanner le code QR du site lorsque je quitte le travail, afin que mon heure de départ soit enregistrée et mes heures travaillées calculées.
Critères d'acceptation : - Étant donné que j'ai une pointe d'arrivée enregistrée pour aujourd'hui, lorsque je scanne le code QR, un événement de pointage de sortie est enregistré. - Étant donné que j'oublie de pointer ma sortie, lorsque mon heure de fin prévue est dépassée, le système clôt automatiquement mon enregistrement à l'heure de fin prévue, le marque comme généré par le SYSTÈME et ne crédite PAS d'heures supplémentaires. - Étant donné que je pointe avant l'heure de fin prévue, lorsque le système traite l'événement, un départ anticipé est signalé.
US-QR-003 : Consulter son historique de présence¶
En tant qu'employé, je souhaite consulter mon historique de présence (heures de pointage, signalements de retard, régularisations), afin de pouvoir vérifier mes enregistrements et contester les inexactitudes.
Critères d'acceptation : - Étant donné que je suis connecté, lorsque je navigue vers mon historique de présence, je vois alors une liste de mes événements de pointage pour le mois en cours (par défaut), filtrable par plage de dates. - Étant donné que je suis hors ligne, lorsque je consulte mon historique, je vois alors les données mises en cache lors de la dernière synchronisation.
US-QR-004 : Demander une régularisation¶
En tant qu'employé ou responsable, je souhaite soumettre une demande de régularisation lorsqu'un événement de pointage est manquant ou incorrect, afin que mon relevé de présence puisse être corrigé avec une piste d'audit.
Critères d'acceptation : - Étant donné que j'ai oublié de pointer à l'arrivée/au départ, lorsque je soumets une demande de régularisation, je dois sélectionner un motif dans la liste prédéfinie et préciser l'heure ou les heures corrigées. - Étant donné que je soumets une demande, lorsqu'elle est enregistrée, elle passe alors au statut EN ATTENTE et mon responsable et les RH en sont informés. - Étant donné que je suis hors ligne, lorsque je soumets une demande, celle-ci est alors mise en file d'attente pour la synchronisation.
US-QR-005 : Approuver une régularisation¶
En tant que responsable ou membre des RH, je souhaite examiner et approuver/rejeter les demandes de régularisation, afin que les relevés de présence soient corrigés avec l'autorisation appropriée.
Critères d'acceptation : - Étant donné que je suis un responsable, lorsque je consulte les régularisations en attente, je ne vois que les demandes de mes subordonnés directs. - Étant donné que je suis aux RH, lorsque je consulte les régularisations en attente, je vois toutes les demandes en attente dans l'ensemble de l'entreprise. - Étant donné que j'approuve une régularisation, lorsque le système la traite, l'enregistrement de présence pour ce jour-là est mis à jour à l'affichage/dans le calcul (l'enregistrement d'origine est conservé à des fins d'audit). - Étant donné que je suis un membre des RH, lorsque je constate qu'une régularisation approuvée par un responsable est incorrecte, je peux alors la remplacer ou la rejeter.
US-QR-006 : Régularisation directe par les RH¶
En tant que membre des RH, je souhaite créer une régularisation directement (sans demande), afin de pouvoir corriger les enregistrements que je remarque lors de ma revue quotidienne sans attendre une demande.
Critères d'acceptation : - Étant donné que je suis aux RH, lorsque je crée une régularisation directe, celle-ci est automatiquement approuvée (sans étape en attente) et enregistrée avec les RH à la fois comme créateur et approbateur. - Étant donné que je crée une régularisation directe, lorsqu'elle est enregistrée, l'employé est informé que son enregistrement a été corrigé.
US-QR-007 : Demande de télétravail¶
En tant qu'employé, je souhaite demander une journée de télétravail, afin que le système sache que je travaille à distance et ne m'enregistre pas comme absent.
Critères d'acceptation : - Étant donné que je demande un télétravail pour une date future, lorsque cette date est postérieure au délai de préavis configuré (par défaut 2 jours), la demande est soumise sans motif obligatoire. - Étant donné que je demande du télétravail le jour même ou à court terme, lorsque je soumets la demande, le champ « motif » est obligatoire (par exemple, « Enfant malade », « Problème de transport »). - Étant donné que mon entreprise a défini un nombre maximal de jours de télétravail par semaine, lorsque j'ai déjà atteint le maximum approuvé pour cette semaine, je reçois un avertissement avant de soumettre la demande (elle n'est pas bloquée — les RH peuvent toujours l'approuver). - Étant donné que ma demande est approuvée, lorsque le jour arrive, mon statut sur le tableau de bord est « Télétravail », aucun scan de QR code n'est requis et les heures prévues sont créditées automatiquement. - Étant donné que ma demande est toujours EN ATTENTE lorsque le jour arrive, lorsque le système évalue mon statut, je suis marqué comme « Absent en attente de validation » (approche prudente).
US-QR-008 : Configurer les sites et les codes QR¶
En tant que RH, je souhaite créer des sites de travail et générer des codes QR pour chaque site, afin que les employés puissent pointer à l'arrivée et au départ au bon endroit.
Critères d'acceptation : - Si je crée un nouveau site, lorsque je l'enregistre, un code QR est généré contenant l'ID du site, l'ID du tenant et un token statique signé HMAC. - Si je soupçonne une fraude au code QR (par exemple, partage de capture d'écran), lorsque je régénère le code QR d'un site, le code QR précédent est immédiatement invalidé. - Une fois le code QR généré, lorsque je le consulte, je peux le télécharger ou l'imprimer.
US-QR-009 : Configurer les horaires de travail¶
En tant que responsable des ressources humaines, je souhaite définir des horaires de travail avec des heures de début et de fin quotidiennes et des plages horaires pour le déjeuner, afin que le système puisse détecter les retards, les départs anticipés et les heures supplémentaires.
Critères d'acceptation : - Étant donné que je crée un horaire, lorsque je le configure, je peux définir des heures de début et de fin différentes pour chaque jour (du lundi au samedi). Le dimanche est un jour de congé par défaut. - Si je crée un horaire, lorsque je le configure, je peux définir une plage horaire pour la pause déjeuner (heures de début et de fin) à des fins de calcul. - Si je crée un horaire, lorsque je le configure, je peux activer ou désactiver le suivi des pauses pour cet horaire. - Si je crée un horaire, lorsque je l'attribue, je peux l'attribuer à des employés individuels ou à un service (tous les employés de ce service en héritent).
US-QR-010 : Tableau de bord des présences quotidiennes¶
En tant que responsable RH ou manager, je souhaite consulter en temps réel les présences du jour, afin de pouvoir réagir en cas de retards, d'absences et d'anomalies.
Critères d'acceptation : - Si j'ouvre le tableau de bord, lorsque les données se chargent, je vois alors les totaux récapitulatifs : Présents, En retard, Absents, Télétravail, En congé. - Si j'ouvre le tableau de bord, lorsque je consulte la liste des employés, je peux alors filtrer par service, site ou statut. - S'il existe une anomalie (enregistrement incomplet, alerte d'appareil partagé), lorsque je consulte le tableau de bord, l'anomalie est alors signalée visuellement. - Si je suis responsable, lorsque je consulte le tableau de bord, je ne vois alors que les données de mon équipe. - Étant donné que je travaille aux RH, lorsque je consulte le tableau de bord, je vois tous les employés.
US-QR-011 : Rapport mensuel de présence¶
En tant que responsable RH, je souhaite générer une feuille de présence mensuelle par employé et par service, afin de disposer d'un enregistrement complet pour la saisie de la paie et l'examen par la direction.
Critères d'acceptation : - Étant donné que je sélectionne un employé et un mois, lorsque je génère le rapport, je vois alors : pour chaque jour : heures prévues, heure d'arrivée effective, heure de départ effective, heures travaillées, statut, heures supplémentaires, départs anticipés, anomalies, régularisations appliquées. Ligne de résumé : total des heures travaillées, total des heures supplémentaires (par tranche), total des retards (nombre + minutes), total des départs anticipés, total des absences, total des jours de télétravail. - Si je sélectionne un service et un mois, lorsque je génère un récapitulatif du service, je vois alors les statistiques agrégées pour tous les employés de ce service. - Si je génère un rapport, lorsque je clique sur « Exporter », je peux alors le télécharger au format Excel ou CSV.
US-QR-012 : Rapport sur les heures supplémentaires pour la paie¶
En tant que responsable RH ou comptable, je souhaite générer un rapport sur les heures supplémentaires classées par catégorie, afin que le service de paie puisse appliquer les taux horaires corrects.
Critères d'acceptation : - Si je génère le rapport sur les heures supplémentaires, lorsque je le consulte, je vois alors, par employé et par semaine : heures de catégorie 1, heures de catégorie 2, heures de catégorie 3, heures de nuit, heures du dimanche/jours fériés, total des heures supplémentaires. - Étant donné que j'exporte le rapport, lorsque le service de paie le reçoit, les données sont structurées pour une importation directe.
US-QR-013 : Rappel de conformité à l'activation du module¶
En tant que responsable RH activant le module QR Attendance, je souhaite recevoir un rappel de l'obligation légale de consulter les délégués du personnel, afin que mon entreprise soit en conformité avant de passer au suivi électronique des présences.
Critères d'acceptation : - Si j'active le module QR Attendance, lorsque l'écran d'activation s'affiche, je vois alors un avis de conformité faisant référence à l'art. 16.1 du Code du travail et à l'obligation de consultation des délégués du personnel. - Si je vois l'avis, lorsque je l'accepte, je peux alors cocher « Oui, consultation effectuée », saisir éventuellement la date de la consultation et télécharger éventuellement le PV (procès-verbal). - Si je ne coche PAS la case, lorsque je continue, le module s'active quand même (ce n'est pas un blocage), mais le système enregistre que le rappel a été affiché et n'a pas été accepté.
A.4 Exigences non fonctionnelles¶
| Requirement | Target | Notes |
|---|---|---|
| Clock-in response time | < 1 second from scan to confirmation on-screen | Critical UX — employee is standing at the entrance |
| Offline clock-in | Works fully offline; queues and syncs within 30s of reconnection | Primary use case for factory/construction/rural sites |
| Dashboard refresh | Near-real-time for online scans (≤ 5s latency via WebSocket or polling) | Offline scans appear on dashboard once synced |
| Report generation | < 5 seconds for monthly attendance sheet (single employee) | For department-level: < 15 seconds for departments up to 100 employees |
| QR code scan accuracy | ≥ 99% successful decode on first attempt in normal lighting | Entry-level Android phones with basic cameras |
| Data retention | 10 years, then anonymize personal data | Aligned with OHADA general document retention (see §A.7 Temporarily Validated) |
| Concurrent clock-ins | Support 500 simultaneous clock-in events per tenant | Large SME shift change scenario (S5-S6 segments, 100-350 employees all arriving within 15 minutes) |
| Scale target | 100,000+ tenant companies × average 20 employees × 2 scans/day = 4M daily clock events platform-wide | Shared DB profile must handle this volume |
| Uptime | 99.5% (Papillon), 99.9% (Enterprise, contractual) | Inherited from Platform Vision |
| Offline storage | Up to 30 days of queued clock events per device | Covers extended connectivity outages in rural areas |
| Export performance | < 10 seconds for Excel export of 1 month × 350 employees | Largest Papillon tenant scenario |
| --- |
A.5 Portée du MVP¶
Dans le MVP (V1)¶
| Feature | Description |
|---|---|
| Site management | CRUD sites, generate/regenerate QR codes per site |
| QR code scanning | Built-in camera scanner in Papillon app |
| Clock-in / clock-out | Record with timestamp, employee ID, site ID, hashed device ID |
| Work schedule configuration | Per-day start/end times (Mon-Sat), lunch break window, assignable to employee or department |
| Optional break tracking | HR enables per site/department. When enabled: 4 scans/day. When disabled: scheduled break window used |
| Late arrival detection | Configurable tolerance: company default (5 min) + department override |
| Early departure detection | Flagged when clock-out before scheduled end |
| Missed clock-out handling | Auto-close at scheduled end, flagged SYSTEM, no overtime |
| Overtime hour classification | Classify into configurable bands (Band 1/2/3 + Night + Sunday/Holiday). CI defaults pre-loaded |
| Weekly overtime tracking | Configurable week start (default Monday). 40h/week legal duration |
| Regularization workflow | Employee/manager request → Manager (team) or HR (all) approves. HR direct-create. Additive records |
| Télétravail workflow | Request → approval (Manager N+1 or HR). Configurable advance notice + max days. Same-day with reason |
| Daily attendance dashboard | Summary counts + employee list + anomaly flags + actions |
| Monthly attendance sheet | Per employee + department summary. Export Excel/CSV |
| Overtime report | Per employee/week, classified by band. Export Excel/CSV |
| Early departure report | Track and report départs anticipés |
| Public holiday calendar | Pre-loaded, ALTARYS-maintained. HR can add company-specific non-working days |
| Anti-fraud: device ID | Hashed device UUID captured. Anomaly detection for shared devices |
| Anti-fraud: auth session | Scan requires authenticated Papillon app session |
| Compliance reminder | Délégués du personnel consultation notice on module activation |
| Offline clock-in/out | Queued in IndexedDB, synced on reconnect |
| Offline regularization | Draft offline, queue for sync |
| Offline télétravail request | Draft offline, queue for sync |
| Offline attendance view | Cached own history |
| Audit trail | All actions logged: clock events, regularizations, config changes, QR regenerations |
| Flexible site scanning | Employee has primary site but can scan at any tenant site. Non-primary flagged |
| Standalone mode | Works without Absence module. Non-holiday non-scan days = "Absent". Graceful integration when Absence events available |
| Tenant-configurable overtime bands | Band thresholds configurable per tenant. CI defaults shipped |
| ### Hors MVP (V2+) |
| Feature | Target |
|---|---|
| GPS coordinate capture at scan | V2 — anti-fraud, single point per scan, privacy review needed |
| QR code token rotation | V2 — daily/hourly rotation for anti-screenshot |
| Shift management | V2 — morning/afternoon/night shifts with rotation |
| Kiosk mode | V2 — shared tablet at site entrance |
| Geofencing | V2 — validate scan within X meters of site |
| Absence pattern analytics | V2 — frequent Monday absences, trends |
| Physical access control integration | V2 — turnstiles, gates |
| Team calendar with attendance overlay | V2 |
| Manager mobile notifications | V2 — push notifications for team late arrivals |
| Bulk schedule assignment | V2 — assign schedule to 500+ employees at once |
| Device binding | V2 — optional bind employee to specific device |
| Anomaly detection (impossible travel) | V2 — clock-in at two sites within impossible travel time |
| Remote clock-in (no QR) | V2 — button-based clock-in for formalized telework |
| Per-employee late tolerance | V2 — for special cases (e.g., mobility constraints) |
| Multi-country overtime rates | Month 9 — BJ, CM rate structures |
| Registre d'employeur integration | V2 — dedicated compliance module |
| Collective agreement override rules | V2 — sector-specific working time rules |
| Night work special rules | V2 — CI night worker regulations |
| --- |
A.6 Questions en suspens¶
| ID | Question | Priority | Impact |
|---|---|---|---|
| OQ-QR-001 | ARTCI declaration requirement: Is a prior declaration to ARTCI required before a company can deploy a QR-code-based attendance system? If yes, the module must include an ARTCI filing checklist in the onboarding flow. | CRITICAL | Onboarding UX, compliance |
| OQ-QR-002 | CI overtime band thresholds: The specific CI overtime band structure (which hours fall in Band 1/2/3) needs verification against the Convention Collective Interprofessionnelle and/or implementing decrees of Art. 21.2-21.3 Code du Travail 2015. Currently using configurable thresholds with temporarily-validated CI defaults. | HIGH | Overtime classification correctness |
| OQ-QR-003 | Geolocation single-point proportionality: Does ARTCI's position on proportionality allow a single GPS coordinate capture per clock-in/out, or must location capture be entirely opt-in? Relevant for V2 GPS feature. | MEDIUM | V2 scope |
| OQ-QR-004 | Burden of proof in CI courts: Has CI case law or statute specifically adopted the French L.3171-4 principle (employer bears burden of proof for working time)? Affects product marketing claims. | MEDIUM | Marketing, positioning |
| OQ-QR-005 | Night work special CI rules: Are there additional record-keeping requirements for night workers (21:00-05:00) beyond standard attendance tracking? | MEDIUM | V2 scope |
| OQ-QR-006 | Collective agreement overrides: Do major CI collective agreements (Convention Collective Interprofessionnelle, sector conventions) impose attendance-tracking requirements beyond the Code du Travail? | MEDIUM | V2 scope |
| OQ-QR-007 | Sector-specific working time: Are there sector-specific working-time arrangements (agriculture, hospitality, domestic work) that would affect overtime classification? | MEDIUM | V2 scope |
| OQ-QR-008 | Registre d'employeur size exemption: Does the registre d'employeur obligation apply to ALL employers in CI regardless of size (even 1 employee), or is there a threshold? | LOW | Documentation, positioning |
| OQ-QR-009 | Art. 92.3 citation verification: The legal research cites "Art. 92.3" of Code du Travail 2015 for the 5-year registre retention. OHADA codes typically use integer numbering. Verify this is Article 92, alinéa 3 (Art. 92 al. 3). | LOW | Source credibility |
| --- |
A.7 Validation provisoire¶
Ces éléments sont mis en œuvre tels quels, mais doivent faire l'objet d'une vérification avant la mise en service en production.
| ID | Item | Current Implementation | Validation Needed |
|---|---|---|---|
| TV-QR-001 | Employee consent for QR scanning | Inform-only approach: employee is notified in-app that attendance is tracked via QR. No consent checkbox. Legal basis assumed: employer's legitimate interest + règlement intérieur. | Confirm with CI data protection specialist that non-biometric QR attendance does not require explicit individual consent under Loi 2013-450. |
| TV-QR-002 | CI overtime band defaults | Band 1: 41st-46th hour/week. Band 2: 47th-48th hour/week. Band 3: Beyond 48h/week. Night: 21:00-05:00. Inferred from Convention Collective Interprofessionnelle. | Verify exact thresholds against the CCI text and/or Art. 21.2-21.3 implementing decrees. Thresholds are tenant-configurable, so incorrect defaults can be corrected without code change. |
| TV-QR-003 | 10-year attendance data retention | Applying OHADA 10-year general document retention rule. Attendance data retained 10 years, then anonymized. | Verify whether attendance scan logs specifically fall under the 10-year rule or the 5-year registre d'employeur rule. Using 10 years is the conservative choice since attendance feeds payroll (which is definitely 10-year). |
| --- |
PARTIE B — Spécifications fonctionnelles (FSD)¶
B.1 Règles fonctionnelles¶
B.1.1 — Gestion des sites et des codes QR¶
FR-QR-001
: Création d'un site
- Un site correspond à un lieu de travail physique appartenant à un tenant.
- Champs obligatoires : name (chaîne de caractères, 100 caractères max.), address (chaîne de caractères, facultatif), tenantId (issu du contexte).
- Les noms de site doivent être uniques au sein d'un tenant.
- SI un site portant le même nom existe déjà pour ce tenant, ALORS rejeter avec l'erreur « Un site avec ce nom existe déjà. »
FR-QR-002
: Génération de code QR
- Lorsqu'un site est créé, le système génère automatiquement un code QR.
- Payload du code QR : JSON { "siteId": "<UUID>", "tenantId": "<UUID>", "token": "<STATIC-hmac-token>" }.
- La payload est signée HMAC à l'aide d'une clé secrète spécifique au tenant. Cela empêche toute falsification (un utilisateur ne peut pas créer une payload QR valide sans la clé secrète du serveur).
- L'image du code QR est générée côté serveur et stockée sous forme de ressource téléchargeable/imprimable.
FR-QR-003 : Régénération du code QR - HR (P2) peut régénérer le code QR d'un site à tout moment. - SI les RH demandent la régénération du QR, ALORS : - Générer un nouveau token HMAC. - Invalider le token précédent (tout scan utilisant l'ancien QR échouera à la validation). - Générer une nouvelle image de code QR. - Enregistrer l'événement de régénération dans la piste d'audit avec la raison (facultatif). - L'ancien code QR imprimé sur le site devient invalide. HR doit imprimer et afficher le nouveau.
FR-QR-004
: Validation du code QR
- Lorsqu'un employé scanne un code QR :
1. Décoder le payload JSON.
2. Vérifier la signature HMAC par rapport à la clé secrète du tenant.
3. Vérifier que tenantId correspond au tenant de l'utilisateur authentifié.
4. Vérifier que siteId existe et est actif.
5. Vérifier que token correspond au token valide actuel du site.
- SI une étape de validation échoue, ALORS rejeter la lecture avec le message « Code QR invalide. Contactez les RH. »
- SI la validation réussit, alors procéder à l'enregistrement de l'événement d'horloge.
- Validation hors ligne : l'application met en cache la liste des paires site/token valides pour le tenant de l'utilisateur. SI hors ligne, alors valider par rapport aux données mises en cache. Accepter le dernier token connu.
B.1.2 — Événements d'horloge¶
FR-QR-010
: Enregistrement d'un événement d'horodatage
- Un événement d'horodatage enregistre : employeeId, siteId, tenantId, timestamp (heure locale de l'appareil, ISO 8601 avec fuseau horaire), eventType (IN ou OUT), deviceIdHash (SHA-256 de l'UUID de l'appareil), source (EMPLOYEE_SCAN | SYSTEM | HR_REGULARIZATION), syncTimestamp (server receive time, null until synced).
- Le champ timestamp utilise l'horloge de l'appareil au moment de la lecture. Il s'agit de l'heure de référence pour tous les calculs de présence.
- Le champ syncTimestamp correspond à l'heure à laquelle le serveur a reçu l'événement. Il est utilisé uniquement à des fins d'audit, jamais pour les calculs de présence.
FR-QR-011 : Détermination du type d'événement (Entrée vs Sortie) - Le système détermine automatiquement si un scan correspond à une pointe d'arrivée ou de départ en fonction de l'état actuel de l'employé pour la journée : - SI l'employé n'a pas de pointe d'arrivée ouverte pour aujourd'hui (c'est-à-dire pas d'arrivée sans départ correspondant), ALORS le scan est une arrivée. - SI l'employé a une pointe d'arrivée en cours (c'est-à-dire une arrivée sans départ correspondant), ALORS la lecture est un départ. - Cela prend en charge plusieurs paires d'arrivée/départ par jour (par exemple, arrivée à 08h00, départ à 12h00, arrivée à 14h00, départ à 18h00).
FR-QR-012 : Détection des scans en double - SI deux scans du même type d'événement (tous deux IN ou tous deux OUT) se produisent pour le même employé dans un intervalle de 15 minutes, ALORS : - Conserver le scan le plus ancien. - Ignorer le scan le plus récent. - Enregistrer le scan ignoré dans la piste d'audit avec la raison « Doublon détecté (fenêtre 15 min). » - SI deux scans du même type ont lieu à plus de 15 minutes d'intervalle, ALORS les traiter comme des événements distincts (sessions multiples légitimes).
FR-QR-013 : Rejet de scan d'un employé licencié - SI le statut de l'employé dans le plan de contrôle est TERMINÉ ou HORS SERVICE, ALORS : - Rejeter le scan. - Afficher le message : « Compte désactivé — contactez les RH. » - Enregistrer la tentative de scan rejetée dans la piste d'audit.
FR-QR-014 : Pointage avant l'heure de début prévue - SI un employé pointe avant son heure de début prévue ALORS : - Enregistrer l'heure réelle du scan comme heure de pointage. - Les heures travaillées sont comptabilisées à partir de l'heure de scan effective (la plus proche entre l'heure de scan et l'heure de début prévue). - Exemple : heure de début prévue 08h00, scan à 07h30 → les heures travaillées commencent à 07h30.
FR-QR-015 : Scan le week-end / jour non prévu - SI un employé n'ayant pas de travail prévu un jour donné (par exemple, le samedi pour un horaire du lundi au vendredi) scanne le code QR ALORS : - Autorisez le scan. Enregistrez l'événement de pointage normalement. - La journée est automatiquement classée comme heures supplémentaires non planifiées / travail le week-end. - Les heures sont classées dans la tranche des heures supplémentaires du dimanche/jours fériés si le jour est un dimanche ou un jour férié, ou dans la tranche d'heures supplémentaires appropriée dans le cas contraire.
B.1.3 — Gestion des oublis de pointage de sortie¶
FR-QR-020 : Fermeture automatique à la fin prévue
- Lors du traitement de fin de journée (tâche batch, s'exécute à une heure configurable, par défaut 23h59) :
- POUR CHAQUE employé ayant un pointage d'entrée ouvert (ENTRÉE sans SORTIE) pour la journée :
- SI l'heure de fin prévue de l'employé est dépassée ALORS :
- Générer un événement de pointage de sortie synthétique à l'heure de fin prévue de l'employé.
- Définir source = SYSTEM.
- Définir autoCloseReason = "MISSED_CLOCK_OUT".
- NE PAS générer d'heures supplémentaires pour cette période fermée automatiquement.
- Marquer la journée comme « Pointage incomplet (fermeture automatique) » sur le tableau de bord.
- SI l'employé n'a pas d'horaire (cas particulier) ALORS :
- NE PAS procéder à la fermeture automatique. Marquer comme « Pointage incomplet — pas d'horaire configuré ».
- Exiger une régularisation manuelle.
FR-QR-021 : Visibilité de la fermeture automatique - Les enregistrements fermés automatiquement sont visuellement distincts sur le tableau de bord et dans les rapports (icône/couleur différente). - Les RH consultent chaque matin une liste consolidée de tous les enregistrements fermés automatiquement la veille. - L'employé peut demander une régularisation pour corriger un enregistrement fermé automatiquement (par exemple, s'il est resté en réalité jusqu'à 19h00).
B.1.4 — Détection des retards et des départs anticipés¶
FR-QR-030 : Détection des retards - Un employé est signalé comme « En retard » SI son premier pointage de la journée dépasse son heure de début prévue de PLUS que la tolérance applicable. - Ordre de recherche de la tolérance : 1. Tolérance au niveau du service (si configurée). 2. Tolérance au niveau de l'entreprise (par défaut : 5 minutes). - Durée du retard = heure d'arrivée − heure de début prévue (non ajustée en fonction de la tolérance). Exemple : horaire 08h00, tolérance 5 min, arrivée à 08h07 → signalé comme en retard, durée du retard = 7 minutes. - SI l'arrivée se situe dans la tolérance ALORS : enregistrer l'heure réelle, mais NE PAS signaler comme en retard. - La tolérance n'affecte que le drapeau RETARD. L'heure de pointage réelle est TOUJOURS enregistrée telle quelle et utilisée pour le calcul des heures travaillées.
FR-QR-031 : Détection de départ anticipé - Un employé est signalé comme « Départ anticipé » SI son heure de pointage de sortie de la journée précède son heure de fin prévue. - Durée du départ anticipé = heure de fin prévue − heure de pointage de sortie. - Aucune tolérance n'est appliquée aux départs anticipés (tout départ avant l'heure de fin prévue est signalé).
FR-QR-032 : Détection d'absence
- SI un employé n'a enregistré aucun événement de pointage pour une journée de travail (et que cette journée n'est pas un jour férié, un congé approuvé ou un télétravail approuvé) ALORS :
- Signaler comme « Absent sans justification ».
- SI le module de gestion des absences est connecté et qu'un événement LeaveApproved couvre cette date ALORS :
- Marquer plutôt comme « En congé ».
- SI l'employé a une demande de télétravail approuvée pour cette date ALORS :
- Marquer comme « Télétravail ».
- SI l'employé a une demande de télétravail EN ATTENTE pour cette date ALORS :
- Marquer comme « Absent en attente de validation » (par mesure de prudence).
B.1.5 — Horaires de travail¶
FR-QR-040 : Structure de l'horaire
- Un horaire de travail définit, pour chaque jour de la semaine (du lundi au samedi) :
- isWorkingDay (booléen)
- startTime (HH:MM, obligatoire si isWorkingDay = true)
- endTime (HH:MM, obligatoire si isWorkingDay = true)
- breakStartTime (HH:MM, facultatif — début de la plage horaire de pause déjeuner)
- breakEndTime (HH:MM, facultatif — fin de la plage horaire de pause déjeuner)
- breakTrackingEnabled (booléen, par défaut false)
- Dimanche : isWorkingDay = false par défaut. Peut être défini sur true (pour les entreprises ouvertes le dimanche).
- Un planning possède un name (par exemple, « Bureau », « Entrepôt », « Terrain ») pour faciliter son identification.
FR-QR-041 : Attribution d'un horaire - Un horaire peut être attribué à : - Un employé en particulier (remplace l'horaire du service). - Un service (tous les employés du service en héritent, sauf s'ils ont une dérogation individuelle). - SI un employé n'a pas d'horaire attribué (individuellement ou via son service) ALORS : - Le système ne peut pas calculer les retards, les arrivées en avance ou les heures supplémentaires pour cet employé. - Les événements de pointage sont toujours enregistrés, mais les indicateurs et les calculs sont suspendus. - Les RH voient un avertissement : « Pas d'horaire configuré pour [Nom]. »
FR-QR-042 : Calcul des heures travaillées (suivi des pauses désactivé)
- SI le suivi des pauses est désactivé pour l'horaire de l'employé ALORS :
- Heures travaillées quotidiennes = Σ(sortie − entrée) pour toutes les paires ENTRÉE/SORTIE − durée de pause prévue.
- Durée de pause prévue = breakEndTime − breakStartTime.
- SI aucune plage de pause n'est définie ALORS : heures travaillées quotidiennes = Σ(sortie − entrée) sans déduction de pause.
FR-QR-043 : Calcul des heures travaillées (Suivi des pauses activé) - SI le suivi des pauses est activé ALORS : - Le système attend 4 enregistrements par jour : ENTRÉE (matin), SORTIE (début de pause), ENTRÉE (fin de pause), SORTIE (soir). - Heures travaillées quotidiennes = (sortie-pause − entrée-matin) + (sortie-soir − entrée-pause). - SI les scans de pause manquent ALORS : appliquer automatiquement la fenêtre de pause programmée (FR-QR-044).
FR-QR-044 : Gestion des scans de pause manquants
- SI le suivi des pauses est activé ET qu'un employé n'a que 2 scans (ENTRÉE et SORTIE, pas de scans de pause) ALORS :
- Appliquer automatiquement la plage de pause programmée : insérer un BREAK_OUT synthétique à breakStartTime et un BREAK_IN à breakEndTime.
- Définir source = SYSTEM pour les deux événements synthétiques.
- Marquer la journée comme « Pause non enregistrée (horaire appliqué) ».
- Le service RH voit le drapeau et peut créer une régularisation si la pause réelle était différente.
B.1.6 — Classification des heures supplémentaires¶
FR-QR-050 : Configuration des tranches d'heures supplémentaires
- Les tranches d'heures supplémentaires sont configurables par tenant via une table overtime_config :
- bandCode (BAND_1, BAND_2, BAND_3, NIGHT, SUNDAY_HOLIDAY)
- weeklyThresholdStart (heures, pour BAND_1/2/3 — par ex. 40, 46, 48)
- weeklyThresholdEnd (heures, peut être nul — nul signifie illimité)
- nightStartTime (HH:MM, pour la tranche NIGHT — valeur par défaut 21:00)
- nightEndTime (HH:MM, pour la bande NIGHT — valeur par défaut 05:00)
- countryCode (CI, BJ, CM — pour la version V2 multi-pays)
- Valeurs par défaut CI (validé temporairement — voir TV-QR-002) :
- BAND_1 : 40 h < hebdomadaire ≤ 46 h
- BAND_2 : 46 h < hebdomadaire ≤ 48 h
- BAND_3 : hebdomadaire > 48 h
- NIGHT : 21 h 00–05 h 00
- SUNDAY_HOLIDAY : tout travail effectué un dimanche ou un jour férié
FR-QR-051 : Calcul des heures supplémentaires hebdomadaires - La semaine de calcul des heures supplémentaires s'étend du jour de début configuré (par défaut : lundi 00h00) au jour précédent (par défaut : dimanche 23h59). - Le jour de début de la semaine est configurable par tenant. - Durée hebdomadaire légale : 40 heures (CI). - Lors du traitement de fin de semaine : - Total des heures travaillées hebdomadaires = Σ heures travaillées quotidiennes (du lundi au dimanche). - SI total > 40 h ALORS heures supplémentaires = total − 40 h. - Classer les heures supplémentaires en tranches en fonction des seuils configurés : - Premières N heures au-delà de 40 → TRANCHE_1 (jusqu'à la fin du seuil). - N heures suivantes → BAND_2. - Reste → BAND_3. - Les heures travaillées pendant la plage HORAIRE_NUIT sont en outre classées dans la tranche HORAIRE_NUIT (ces heures sont également comptabilisées dans les tranches BAND_1/2/3 — la nuit est une classification supplémentaire). - Les heures travaillées le dimanche ou un jour férié sont en outre classées dans la tranche SUNDAY_HOLIDAY.
FR-QR-052 : Suivi quotidien des heures supplémentaires - Heures supplémentaires quotidiennes = heures effectivement travaillées chaque jour − heures quotidiennes prévues (selon l'horaire de l'employé). - SI heures supplémentaires quotidiennes > 0 ALORS marquer le jour et enregistrer les heures excédentaires. - Les heures supplémentaires quotidiennes sont fournies à titre informatif pour le tableau de bord. La classification des heures supplémentaires faisant foi pour la paie est le calcul hebdomadaire (FR-QR-051).
B.1.7 — Workflow de régularisation¶
FR-QR-060 : Demande de régularisation
- Un employé ou un responsable peut créer une demande de régularisation.
- Champs obligatoires :
- employeeId (l'employé dont le dossier est en cours de correction)
- date (la date à corriger)
- reason (énumération : OUBLI_POINTAGE | PROBLEME_TECHNIQUE | MISSION_EXTERIEURE | AUTRE)
- reasonDetail (texte libre, obligatoire si reason = AUTRE, facultatif dans le cas contraire)
- correctedClockIn (HH:MM, facultatif)
- correctedClockOut (HH:MM, facultatif)
- Il faut fournir au moins l'une des valeurs correctedClockIn ou correctedClockOut.
- La demande passe à l'état EN ATTENTE.
FR-QR-061 : Approbation de régularisation - Un responsable peut approuver les demandes de régularisation uniquement pour ses subordonnés directs. - Les RH (P2) peuvent approuver les demandes de régularisation pour n'importe quel salarié. - Une seule approbation suffit (soit par le responsable, soit par les RH). - SI approuvée ALORS : - L'enregistrement de régularisation est marqué APPROUVÉ. - Le calcul de la présence pour cette date est recalculé à l'aide des heures corrigées. - Les événements de pointage d'origine sont CONSERVÉS. La régularisation est un enregistrement additif qui remplace l'affichage et le calcul. - Si la régularisation corrige un pointage de sortie manquant clôturé automatiquement (FR-QR-020), les heures supplémentaires peuvent désormais être créditées sur la base de l'heure corrigée.
FR-QR-062 : Régularisation directe par les RH - Les RH peuvent créer une régularisation directement, sans qu'une demande de l'employé soit nécessaire. - La régularisation directe est automatiquement approuvée (statut = APPROUVÉ, approbateur = RH). - L'employé est informé que son enregistrement a été corrigé. - Cas d'utilisation : les RH remarquent un pointage de sortie manquant lors de la revue quotidienne du tableau de bord et effectuent immédiatement la correction.
FR-QR-063 : Remplacement de l'approbation du responsable par les RH - Les RH peuvent rejeter ou remplacer une régularisation précédemment approuvée par le responsable. - SI les RH rejettent une régularisation approuvée par le responsable, ALORS : - Le statut de la régularisation passe à REJETÉ. - Le calcul de la présence revient aux événements de pointage d'origine. - Le responsable et l'employé en sont tous deux informés.
FR-QR-064 : Piste d'audit des régularisations - Chaque action de régularisation (création, approbation, rejet, annulation) est consignée avec l'acteur, l'horodatage et les valeurs avant/après. - Les événements de pointage d'origine ne sont JAMAIS modifiés ni supprimés. Toutes les corrections sont des enregistrements supplémentaires.
B.1.8 — Workflow de télétravail¶
FR-QR-070 : Demande de télétravail
- Un employé peut demander une journée de télétravail pour une date future.
- Champs obligatoires :
- date (la date de télétravail demandée)
- reason (texte libre, obligatoire si le préavis est inférieur au minimum configuré, facultatif dans le cas contraire)
- Configuration du délai de préavis :
- minAdvanceNoticeDays (entier, valeur par défaut 2, configurable par tenant)
- SI la demande concerne une date située à moins de minAdvanceNoticeDays à compter d'aujourd'hui (y compris le jour même), ALORS le champ reason est obligatoire.
- La demande passe à l'état EN ATTENTE.
- L'employé peut ANNULER une demande EN ATTENTE avant la date prévue.
FR-QR-071 : Approbation du télétravail - Le responsable (N+1) ou les RH peuvent approuver/refuser les demandes de télétravail. - SI approuvée ALORS : - Le statut de l'employé pour cette date = « Télétravail ». - Aucun scan QR n'est attendu à cette date. - Les heures prévues sont créditées automatiquement (heures journalières standard, pas d'heures supplémentaires). - SI rejetée ALORS : - L'employé est informé du motif du rejet. - L'employé est tenu de se présenter sur son site à cette date.
FR-QR-072 : Limites journalières de télétravail
- maxTeletravailPerWeek (entier, nullable, configurable par tenant). Par défaut : null (aucune limite).
- maxTeletravailPerMonth (entier, nullable, configurable par tenant). Par défaut : null (aucune limite).
- SI l'employé soumet une demande qui dépasserait la limite hebdomadaire ou mensuelle ALORS :
- La demande est acceptée (non bloquée) mais un avertissement s'affiche pour l'employé : « Limite de X jours/semaine atteinte. Votre demande sera soumise à validation. »
- Le validateur voit l'avertissement de dépassement de limite lorsqu'il examine la demande.
FR-QR-073 : Télétravail en attente le jour même - SI une demande de télétravail est toujours EN ATTENTE lorsque la date demandée arrive ALORS : - Le statut de l'employé pour cette date = « Absent en attente de validation. » - Le système considère l'employé comme absent (approche prudente). - Le validateur est informé qu'une demande est en attente de validation depuis trop longtemps. - SI le validateur approuve par la suite, le statut est rétroactivement modifié en « Télétravail » et les heures de la journée sont créditées.
B.1.9 — Jours fériés¶
FR-QR-080 [CI] : Calendrier des jours fériés - Le système est livré avec un calendrier des jours fériés CI préchargé pour l'année en cours et l'année suivante. - ALTARYS gère et met à jour le calendrier chaque année (mise à jour des données de la plateforme, pas d'action du tenant). - Les jours fériés CI comprennent à la fois des dates fixes (par exemple, le 7 août = Fête de l'Indépendance) et des dates mobiles (par exemple, Tabaski, Maouloud — calendrier islamique).
FR-QR-081 : Jours chômés spécifiques à l'entreprise - Les RH peuvent ajouter des jours chômés spécifiques à l'entreprise (par exemple, anniversaire de l'entreprise, fête locale). - Ces jours sont traités de la même manière que les jours fériés en matière de présence.
FR-QR-082 : Comportement en matière de présence pendant les jours fériés - Lors d'un jour férié ou d'un jour chômé de l'entreprise : - Aucune présence n'est attendue. Les employés ne sont PAS signalés comme absents. - Le jour est affiché comme « Jour férié » ou « Jour non travaillé » sur le tableau de bord et dans les rapports. - SI un employé scanne le code QR un jour férié, ALORS : - Autoriser le scan. Enregistrer l'événement d'horloge. - La journée est classée comme heures supplémentaires du dimanche/jour férié (FR-QR-051). - Les RH voient le travail sur le tableau de bord.
B.1.10 — Lutte contre la fraude¶
FR-QR-090 : Exigence de session authentifiée - Un scan QR n'est valide que si l'appareil de scan dispose d'une session Papillon active et authentifiée. - Le contenu du code QR seul ne suffit PAS pour enregistrer un événement d'horloge. Le scan doit être lancé depuis l'application.
FR-QR-091 : Capture de l'identifiant de l'appareil
- Au moment du scan, l'application capture l'UUID de l'appareil, le hachage (SHA-256) et inclut le deviceIdHash dans la payload de l'événement d'horloge.
- L'UUID brut de l'appareil n'est JAMAIS stocké ni transmis — seul le hachage l'est.
FR-QR-092 : Détection d'anomalie d'appareil partagé
- SI deux employés différents enregistrent des événements de pointage avec le même deviceIdHash le même jour, ALORS :
- Générer une anomalie « Alerte : appareil partagé ».
- Afficher l'anomalie sur le tableau de bord RH, en lien avec les deux employés.
- Les événements de pointage ne sont PAS rejetés ni modifiés — il s'agit uniquement d'un indicateur d'information.
- Le premier scan provenant d'un deviceIdHash inédit pour un employé est enregistré mais PAS signalé (les employés changent de téléphone).
FR-QR-093 : Fraude au code QR (token invalide) - SI un scan contient un token invalide ou expiré (par exemple, provenant d’une capture d’écran d’un code QR régénéré) ALORS : - Rejeter le scan avec le message « Code QR invalide. Contactez les RH. » - Enregistrer la tentative échouée avec l’ID de l’employé, l’ID du site et l’horodatage dans la piste d’audit.
B.1.11 — Comportement hors ligne¶
FR-QR-100 : Stockage des événements de pointage hors ligne
- En mode hors ligne, les événements de pointage sont stockés dans IndexedDB sur l'appareil.
- Chaque événement comprend : tous les champs de FR-QR-010 + isSynced: false.
- Les événements sont mis en file d'attente dans l'ordre FIFO pour la synchronisation.
FR-QR-101 : Synchronisation à la reconnexion - Lorsque la connexion est rétablie, l'application synchronise les événements mis en file d'attente dans les 30 secondes. - Ordre de synchronisation : FIFO (le plus ancien en premier). - Pour chaque événement, le serveur le valide et le traite comme s'il avait été reçu en temps réel. - SI la synchronisation échoue (erreur serveur, échec de validation) ALORS : - Réessayer avec un délai d'attente exponentiel (max. 3 tentatives). - SI toutes les tentatives échouent ALORS : marquer l'événement comme « sync_failed » et notifier l'employé : « La pointage du [date/heure] n'a pas pu être synchronisé. Contactez les RH. »
FR-QR-102 : Validation QR hors ligne - L'application met en cache la liste des tuples {siteId, tenantId, token} valides pour le tenant de l'utilisateur authentifié. - Le cache est actualisé à chaque synchronisation réussie. - SI hors ligne ALORS : valider le QR scanné par rapport à la liste mise en cache. - SI le QR n'est pas dans le cache (nouveau site ajouté pendant la déconnexion) ALORS : rejeter avec le message « Code QR non reconnu hors ligne. Réessayez en ligne. »
FR-QR-103 : Régularisation hors ligne et télétravail
- Les demandes de régularisation et de télétravail peuvent être rédigées hors ligne.
- Elles sont stockées dans IndexedDB et synchronisées lorsque la connexion est rétablie.
- L'horodatage createdAt de la demande utilise l'horloge de l'appareil (moment de la création), et non le moment de la synchronisation.
FR-QR-104 : Historique des présences hors ligne - L'employé peut consulter son propre historique des présences à partir du cache IndexedDB local. - Le cache contient les dernières données synchronisées. Les nouvelles modifications côté serveur (par exemple, une régularisation approuvée par les RH) ne sont visibles qu'à la prochaine synchronisation.
B.1.12 — Rapports et exportation¶
FR-QR-110 : Feuille de présence mensuelle (par employé) - Contenu par ligne (une ligne par jour ouvré) : - Date | Day of week | Scheduled start | Scheduled end | Actual clock-in | Actual clock-out | Worked hours | Status (Présent / Retard / Absent / Télétravail / Congé / Férié / Départ anticipé) | Late duration (min) | Early departure duration (min) | Overtime hours | Anomalies | Regularizations applied - Ligne de récapitulatif : - Total des heures travaillées | Total scheduled hours | Total overtime (by band) | Total late arrivals (count + total minutes) | Total early departures (count + total minutes) | Total absences (count) | Total télétravail days | Total public holidays
FR-QR-111 : Synthèse mensuelle par service - Version agrégée du formulaire FR-QR-110 pour l'ensemble des employés d'un service. - Contenu par ligne (une ligne par employé) : - Nom de l'employé | Total worked hours | Total overtime | Total late (count) | Total early dep. (count) | Total absences | Total télétravail | Attendance rate (%)
FR-QR-112 : Déclaration des heures supplémentaires (pour la paie) - Contenu par ligne (une ligne par salarié et par semaine) : - Numéro d'identification du salarié | Employee name | Week number | Week start date | Band 1 hours | Band 2 hours | Band 3 hours | Night hours | Sunday/Holiday hours | Total overtime hours
FR-QR-113 : Format d'exportation - Tous les rapports peuvent être exportés au format Excel (.xlsx) et CSV (.csv). - Encodage CSV : UTF-8 avec BOM (pour la compatibilité d'Excel avec les caractères français). - Format de date dans les exportations : JJ/MM/AAAA (convention française). - Format d'heure : HH:MM (24 heures). - Séparateur décimal pour les heures : virgule (convention française — par exemple, « 7,5 » pour 7h30).
B.1.13 — Conformité à l'activation du module¶
FR-QR-120 : Rappel de conformité concernant les délégués du personnel - Lorsque le module QR Attendance est activé pour un tenant : - Afficher un avis de conformité : « La mise en place d'un système de pointage électronique doit faire l'objet d'une consultation des délégués du personnel (art. 16.1 du Code du travail). Avez-vous effectué cette consultation ? » - Éléments de l'interface utilisateur : - Case à cocher : « Oui, consultation effectuée » - Champ de date (facultatif) : « Date de la consultation » - Téléchargement de fichier (facultatif) : « PV de la consultation » (procès-verbal) - Il ne s'agit PAS d'un blocage. Les RH peuvent poursuivre sans cocher la case. - Le système enregistre : si le rappel a été affiché, si la case a été cochée, la date (si fournie), l'ID du fichier PV (s'il a été téléchargé). - Cet enregistrement fait partie de la piste d'audit de conformité du tenant.
FR-QR-121 [CI] : Sensibilisation aux seuils - L'obligation relative aux délégués du personnel s'applique aux entreprises de 11 salariés et plus en CI. - SI le tenant compte moins de 11 salariés actifs, ALORS : afficher tout de même le rappel mais ajouter une note : « Cette obligation concerne les entreprises de 11 salariés et plus. »
B.2 Machines à états¶
B.2.1 — Cycle de vie des événements d'horloge¶
stateDiagram-v2
[*] --> RECORDED : Employee scans QR
RECORDED --> REGULARIZED : HR/Manager approves regularization
RECORDED --> AUTO_CLOSED : System auto-close (missed clock-out)
AUTO_CLOSED --> REGULARIZED : HR/Manager approves regularization
REGULARIZED --> OVERRIDDEN : HR overrides previous regularization
OVERRIDDEN --> REGULARIZED : New regularization applied
note right of RECORDED
source: EMPLOYEE_SCAN
Original timestamp preserved
end note
note right of AUTO_CLOSED
source: SYSTEM
No overtime credited
end note
note right of REGULARIZED
source: HR_REGULARIZATION
Additive record, original preserved
end note
B.2.2 — Cycle de vie d'une demande de régularisation¶
stateDiagram-v2
[*] --> PENDING : Employee/Manager creates request
PENDING --> APPROVED : Manager (team) or HR approves
PENDING --> REJECTED : Manager or HR rejects
APPROVED --> OVERRIDDEN_BY_HR : HR overrides manager approval
OVERRIDDEN_BY_HR --> REJECTED : HR rejects
note right of PENDING
Notifies approvers
end note
note right of APPROVED
Recalculates attendance
Preserves original events
end note
Remarque : les régularisations RH directes (FR-QR-062) ne passent pas par l'état « EN ATTENTE » ; elles sont directement créées avec le statut « APPROUVÉ ».
B.2.3 — Cycle de vie d'une demande de télétravail¶
stateDiagram-v2
[*] --> PENDING : Employee submits request
PENDING --> APPROVED : Manager N+1 or HR approves
PENDING --> REJECTED : Manager or HR rejects
PENDING --> CANCELLED : Employee cancels
APPROVED --> [*] : Day passes (consumed)
REJECTED --> [*] : Employee notified
CANCELLED --> [*] : Request withdrawn
note right of PENDING
If day arrives while PENDING:
Status = "Absent en attente de validation"
end note
note right of APPROVED
No QR scan expected
Schedule hours credited
No overtime tracked
end note
B.2.4 — Statut de présence quotidien (par employé et par jour)¶
stateDiagram-v2
[*] --> EXPECTED : Working day starts
EXPECTED --> PRESENT : Clock-in recorded
EXPECTED --> TELETRAVAIL : Télétravail approved for today
EXPECTED --> EN_CONGE : Leave approved (Absence module)
EXPECTED --> FERIE : Public holiday / company non-working day
EXPECTED --> ABSENT : End of day, no clock-in
EXPECTED --> ABSENT_PENDING : Télétravail PENDING on day-of
PRESENT --> RETARD : Clock-in after tolerance
PRESENT --> DEPART_ANTICIPE : Clock-out before scheduled end
PRESENT --> INCOMPLET : Scheduled end passed, no clock-out
INCOMPLET --> AUTO_CLOSED : System auto-close at scheduled end
AUTO_CLOSED --> REGULARIZED : Regularization corrects times
ABSENT --> REGULARIZED : Regularization provides clock times
ABSENT_PENDING --> TELETRAVAIL : Approver approves retroactively
ABSENT_PENDING --> ABSENT : Approver rejects or day closes
B.3 Tableaux de décision¶
B.3.1 — Résolution quotidienne du statut¶
| Has Clock-In? | Has Clock-Out? | Is Holiday? | Is Leave? | Is Télétravail (Approved)? | Is Télétravail (Pending)? | Status |
|---|---|---|---|---|---|---|
| Yes | Yes | No | No | No | — | PRESENT (check late/early flags) |
| Yes | No | No | No | No | — | INCOMPLET → AUTO_CLOSE at scheduled end |
| No | No | Yes | — | — | — | FERIE |
| No | No | No | Yes | — | — | EN_CONGE |
| No | No | No | No | Yes | — | TELETRAVAIL |
| No | No | No | No | No | Yes | ABSENT_PENDING |
| No | No | No | No | No | No | ABSENT |
| Yes | Yes | Yes | No | No | — | FERIE + WORKED (overtime: Sunday/Holiday band) |
| ### B.3.2 — Résolution des retards |
| Department Tolerance Set? | Value | Company Default | Effective Tolerance |
|---|---|---|---|
| Yes | 0 min | 5 min | 0 min (department overrides) |
| Yes | 10 min | 5 min | 10 min (department overrides) |
| No | — | 5 min | 5 min (company default applies) |
| No | — | 0 min | 0 min |
| ### B.3.3 — Autorité chargée d'approuver la régularisation |
| Actor | Scope | Can Create Request? | Can Approve? | Can Direct-Create? | Can Override? |
|---|---|---|---|---|---|
| Employee (P4) | Own records | Yes | No | No | No |
| Manager (N+1) | Team records | Yes | Yes (team only) | No | No |
| HR (P2) | All records | Yes | Yes (all) | Yes (auto-approved) | Yes |
| DG (P1) | — | No | No | No | No |
| Comptable (P3) | — | No | No | No | No |
| ### B.3.4 — Classification des tranches d'heures supplémentaires (paramètres par défaut de CI — validés à titre temporaire) |
| Weekly Hours | Classification |
|---|---|
| ≤ 40h | Normal (no overtime) |
| 40h < hours ≤ 46h | BAND_1 |
| 46h < hours ≤ 48h | BAND_2 |
| > 48h | BAND_3 |
| Any hours between 21:00-05:00 | NIGHT (supplementary flag, added on top of BAND_1/2/3) |
| Any hours on Sunday or public holiday | SUNDAY_HOLIDAY (supplementary flag) |
| --- |
B.4 Exigences en matière de données¶
B.4.1 — Entités clés¶
Site¶
| Field | Type | Required | Notes |
|---|---|---|---|
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant. ALL queries filter by this. |
| name | VARCHAR(100) | Yes | Unique within tenant |
| address | VARCHAR(500) | No | Physical address |
| qr_token | VARCHAR(255) | Yes | Current valid HMAC token |
| qr_generated_at | TIMESTAMP | Yes | When current QR was generated |
| is_active | BOOLEAN | Yes | Default true |
| created_at | TIMESTAMP | Yes | |
| updated_at | TIMESTAMP | Yes | |
| #### Horaires de travail | |||
| Field | Type | Required | Notes |
| ------------ | -------------- | ---------- | ---------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| name | VARCHAR(100) | Yes | e.g., "Bureau", "Entrepôt" |
| is_active | BOOLEAN | Yes | Default true |
| created_at | TIMESTAMP | Yes | |
| updated_at | TIMESTAMP | Yes | |
| #### Jour de travail | |||
| Field | Type | Required | Notes |
| ------------------------ | ---------- | ------------- | ----------------------------------- |
| id | UUID | Yes | PK |
| schedule_id | UUID | Yes | FK → WorkSchedule |
| day_of_week | SMALLINT | Yes | 1=Monday, 7=Sunday |
| is_working_day | BOOLEAN | Yes | |
| start_time | TIME | Conditional | Required if is_working_day = true |
| end_time | TIME | Conditional | Required if is_working_day = true |
| break_start_time | TIME | No | Lunch window start |
| break_end_time | TIME | No | Lunch window end |
| break_tracking_enabled | BOOLEAN | Yes | Default false |
| #### Affectation des horaires des employés | |||
| Field | Type | Required | Notes |
| ---------------- | ------ | ---------- | ------------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| employee_id | UUID | Yes | FK → employee (Control Plane) |
| schedule_id | UUID | Yes | FK → WorkSchedule |
| effective_from | DATE | Yes | |
| effective_to | DATE | No | Null = current |
| #### Emploi du temps du département | |||
| Field | Type | Required | Notes |
| ---------------- | ------ | ---------- | --------------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| department_id | UUID | Yes | FK → department (Control Plane) |
| schedule_id | UUID | Yes | FK → WorkSchedule |
| effective_from | DATE | Yes | |
| effective_to | DATE | No | Null = current |
| #### Affectation des employés | |||
| Field | Type | Required | Notes |
| ---------------- | --------- | ---------- | ------------------------------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| employee_id | UUID | Yes | FK → employee |
| site_id | UUID | Yes | FK → Site |
| is_primary | BOOLEAN | Yes | Default true. At most one primary per employee. |
| effective_from | DATE | Yes | |
| effective_to | DATE | No | |
| #### Événement d'horloge | |||
| Field | Type | Required | Notes |
| ------------------- | ------------------- | ---------- | -------------------------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| employee_id | UUID | Yes | FK → employee |
| site_id | UUID | Yes | FK → Site |
| event_type | VARCHAR(10) | Yes | IN, OUT, BREAK_OUT, BREAK_IN |
| timestamp | TIMESTAMP WITH TZ | Yes | Device clock at scan time |
| sync_timestamp | TIMESTAMP WITH TZ | No | Server receive time (null until synced) |
| device_id_hash | VARCHAR(64) | Yes | SHA-256 of device UUID |
| source | VARCHAR(20) | Yes | EMPLOYEE_SCAN, SYSTEM, HR_REGULARIZATION |
| is_duplicate | BOOLEAN | Yes | Default false. True if discarded by dedup. |
| auto_close_reason | VARCHAR(30) | No | MISSED_CLOCK_OUT (for SYSTEM source) |
| created_at | TIMESTAMP | Yes | |
| #### Présence quotidienne (matérialisée / calculée) | |||
| Field | Type | Required | Notes |
| ------------------------- | ------------------- | ---------- | ------------------------------------------------------------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| employee_id | UUID | Yes | FK → employee |
| date | DATE | Yes | |
| status | VARCHAR(30) | Yes | PRESENT, RETARD, ABSENT, TELETRAVAIL, CONGE, FERIE, INCOMPLET, ABSENT_PENDING |
| first_clock_in | TIMESTAMP WITH TZ | No | |
| last_clock_out | TIMESTAMP WITH TZ | No | |
| worked_minutes | INTEGER | No | Total worked minutes (after break deduction) |
| scheduled_minutes | INTEGER | No | Expected minutes from schedule |
| overtime_minutes | INTEGER | No | Daily excess |
| late_minutes | INTEGER | No | 0 if within tolerance |
| early_departure_minutes | INTEGER | No | |
| is_auto_closed | BOOLEAN | Yes | Default false |
| has_anomaly | BOOLEAN | Yes | Default false |
| anomaly_details | JSONB | No | Array of anomaly codes/descriptions |
| regularization_id | UUID | No | FK if regularized |
| created_at | TIMESTAMP | Yes | |
| updated_at | TIMESTAMP | Yes | |
| #### Demande de régularisation | |||
| Field | Type | Required | Notes |
| --------------------- | ------------- | ------------- | --------------------------------------------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| employee_id | UUID | Yes | Target employee |
| date | DATE | Yes | The day being corrected |
| reason | VARCHAR(30) | Yes | OUBLI_POINTAGE, PROBLEME_TECHNIQUE, MISSION_EXTERIEURE, AUTRE |
| reason_detail | TEXT | Conditional | Required if reason = AUTRE |
| corrected_clock_in | TIME | Conditional | At least one of in/out required |
| corrected_clock_out | TIME | Conditional | |
| status | VARCHAR(20) | Yes | PENDING, APPROVED, REJECTED |
| requested_by | UUID | Yes | Employee or manager who created |
| approved_by | UUID | No | Manager or HR who approved |
| approved_at | TIMESTAMP | No | |
| is_direct_create | BOOLEAN | Yes | Default false. True if HR created directly. |
| override_of | UUID | No | FK → RegularizationRequest if this overrides a previous one |
| created_at | TIMESTAMP | Yes | |
| updated_at | TIMESTAMP | Yes | |
| #### Demande de télétravail | |||
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| employee_id | UUID | Yes | |
| date | DATE | Yes | Requested remote work date |
| reason | TEXT | Conditional | Mandatory if short-notice |
| status | VARCHAR(20) | Yes | PENDING, APPROVED, REJECTED, CANCELLED |
| approved_by | UUID | No | |
| approved_at | TIMESTAMP | No | |
| rejection_reason | TEXT | No | |
| created_at | TIMESTAMP | Yes | |
| updated_at | TIMESTAMP | Yes | |
| #### Jour férié | |||
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| id | UUID | Yes | PK |
| country_code | VARCHAR(2) | Yes | CI, BJ, CM |
| date | DATE | Yes | |
| name | VARCHAR(200) | Yes | e.g., "Fête de l'Indépendance" |
| is_moveable | BOOLEAN | Yes | True for Islamic holidays |
| year | INTEGER | Yes | Calendar year |
| #### Jour férié | |||
| Field | Type | Required | Notes |
| -------------- | -------------- | ---------- | ---------------------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| date | DATE | Yes | |
| name | VARCHAR(200) | Yes | e.g., "Anniversaire entreprise" |
| is_recurring | BOOLEAN | Yes | If true, repeats annually on same date |
| created_at | TIMESTAMP | Yes | |
| #### OvertimeConfig | |||
| Field | Type | Required | Notes |
| ------------------------ | -------------- | ---------- | ----------------------------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| band_code | VARCHAR(20) | Yes | BAND_1, BAND_2, BAND_3, NIGHT, SUNDAY_HOLIDAY |
| weekly_threshold_start | DECIMAL(5,2) | No | Hours (e.g., 40.00) |
| weekly_threshold_end | DECIMAL(5,2) | No | Null = unlimited |
| night_start_time | TIME | No | For NIGHT band |
| night_end_time | TIME | No | For NIGHT band |
| country_code | VARCHAR(2) | Yes | CI (MVP) |
| created_at | TIMESTAMP | Yes | |
| updated_at | TIMESTAMP | Yes | |
| #### Configuration du module de présence | |||
| Field | Type | Required | Notes |
| -------------------------------- | ----------- | ---------- | -------------------------------------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant. One row per tenant. |
| default_late_tolerance_minutes | INTEGER | Yes | Default: 5 |
| overtime_week_start_day | SMALLINT | Yes | 1=Monday (default), 7=Sunday |
| min_teletravail_advance_days | INTEGER | Yes | Default: 2 |
| max_teletravail_per_week | INTEGER | No | Null = no limit |
| max_teletravail_per_month | INTEGER | No | Null = no limit |
| auto_close_time | TIME | Yes | Default: 23:59. When missed clock-out processing runs. |
| delegues_consultation_done | BOOLEAN | No | From compliance reminder |
| delegues_consultation_date | DATE | No | |
| delegues_pv_document_id | UUID | No | FK to document storage |
| created_at | TIMESTAMP | Yes | |
| updated_at | TIMESTAMP | Yes | |
| #### Configuration de la présence par département | |||
| Field | Type | Required | Notes |
| ------------------------ | ----------- | ---------- | ---------------------------------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | FK → tenant |
| department_id | UUID | Yes | FK → department |
| late_tolerance_minutes | INTEGER | No | Overrides company default if set |
| created_at | TIMESTAMP | Yes | |
| updated_at | TIMESTAMP | Yes | |
| #### Récapitulatif hebdomadaire des heures supplémentaires (calculé) | |||
| Field | Type | Required | Notes |
| ------------------------ | ----------- | ---------- | ----------- |
| id | UUID | Yes | PK |
| tenant_id | UUID | Yes | |
| employee_id | UUID | Yes | |
| week_start_date | DATE | Yes | |
| week_end_date | DATE | Yes | |
| total_worked_minutes | INTEGER | Yes | |
| band_1_minutes | INTEGER | Yes | Default 0 |
| band_2_minutes | INTEGER | Yes | Default 0 |
| band_3_minutes | INTEGER | Yes | Default 0 |
| night_minutes | INTEGER | Yes | Default 0 |
| sunday_holiday_minutes | INTEGER | Yes | Default 0 |
| total_overtime_minutes | INTEGER | Yes | |
| created_at | TIMESTAMP | Yes | |
| updated_at | TIMESTAMP | Yes | |
| --- |
B.5 Conséquences en matière de multi-tenant¶
Le module QR Attendance suit les modèles standard de multi-tenant définis dans le document de spécification fonctionnelle (PRD) de Platform Vision (FR-PV-040 à FR-PV-047). Conséquences spécifiques :
| Concern | Implementation |
|---|---|
| QR code tenant isolation | QR payload includes tenantId. Scans are validated against the authenticated user's tenant. A Tenant A employee scanning a Tenant B QR code is rejected at validation step 3 (FR-QR-004). |
| Site uniqueness | Site names unique within tenant (not globally). tenant_id column on all site-related tables. |
| Clock event storage | Shared DB: all events in one clock_event table with tenant_id. Every query includes WHERE tenant_id = ?. |
| Offline cache isolation | The app caches only the authenticated user's tenant data. Switching tenants (for multi-tenant users like P3/Comptable) clears and reloads the cache. |
| Overtime config | Per-tenant configuration. Each tenant can have different overtime bands, even on the same DB. |
| Public holidays | PublicHoliday table is system-wide (not tenant-scoped) — same holidays for all CI tenants. CompanyNonWorkingDay is tenant-scoped. |
| BYO-DB | No special considerations. All entities include tenant_id even in single-tenant databases (for consistency and future migration). |
| --- |
B.6 Dépendances entre modules¶
B.6.1 — Dépend de (forte)¶
| Module | Dependency | What QR Attendance Needs |
|---|---|---|
| Control Plane | Employee data | Active employees (ID, name, department, site assignment). Used for dashboard, reports, schedule assignment, validation. |
| Control Plane | Authentication | User authentication, session management. Required for QR scan validation (FR-QR-090). |
| Control Plane | Organization structure | Departments, sites (if managed centrally). Department hierarchy for manager→team relationships. |
| Control Plane | Module gating | FR-PV-034: every API endpoint checks QRCONTR is ACTIVE for the tenant. |
| ### B.6.2 — Publication d'événements |
| Event Name | Payload | Consumer | Trigger |
|---|---|---|---|
AttendanceRecorded |
{ tenantId, employeeId, date, firstClockIn, lastClockOut, workedMinutes, overtimeMinutes, band1Minutes, band2Minutes, band3Minutes, nightMinutes, sundayHolidayMinutes, lateMinutes, earlyDepartureMinutes, status, isAutoClose } |
Payroll | End-of-day or after regularization that changes a day's calculations |
WeeklyOvertimeComputed |
{ tenantId, employeeId, weekStartDate, weekEndDate, totalOvertimeMinutes, band1Minutes, band2Minutes, band3Minutes, nightMinutes, sundayHolidayMinutes } |
Payroll | End-of-week processing |
Remarque : le payload de l'événement AttendanceRecorded a été enrichi par rapport à la définition initiale du PRD de Platform Vision. Platform Vision ne mentionnait que les overtimeMinutes ; nous incluons désormais une classification par tranche horaire. Le PRD du module Paie doit être mis à jour pour pouvoir exploiter ce payload enrichi. |
B.6.3 — Exploitation des événements¶
| Event Name | Source | How QR Attendance Uses It |
|---|---|---|
EmployeeCreated |
Control Plane | Add employee to expected attendance list. No schedule yet — HR must assign one. |
EmployeeUpdated |
Control Plane | Update employee metadata (name, department). Reassignment may change schedule inheritance. |
EmployeeTerminated |
Control Plane | Stop expecting attendance. Reject future scans (FR-QR-013). |
EmployeeOffboarded |
Control Plane | Same as Terminated. |
LeaveApproved |
Absence Mgmt | Suppress attendance expectation for leave dates. Show "En congé" status. IF Absence module not connected: this event is simply never received, and standalone behavior (FR-QR-032) applies. |
LeaveCancelled |
Absence Mgmt | Re-enable attendance expectation for cancelled leave dates. |
| ### B.6.4 — Expose l'API interne (pour les futurs modules) |
| Endpoint Pattern | Purpose | Consumer |
|---|---|---|
GET /api/v1/qrcontr/employees/{id}/attendance-summary?month=YYYY-MM |
Monthly attendance summary for an employee | Future Registre/Compliance module |
GET /api/v1/qrcontr/overtime-report?week=YYYY-Wnn |
Weekly overtime data | Payroll module (if event-based delivery is insufficient) |
| --- |
PARTIE C — Contraintes et limites¶
C.1 Conformité réglementaire (CI — Côte d'Ivoire)¶
C.1.1 — Protection des données (Loi n° 2013-450)¶
| Rule | Description | Source |
|---|---|---|
| RC-QR-001 | QR code attendance scanning collects non-biometric personal data (employee ID + timestamp + site + device hash). This falls under the general data processing regime, not the stricter biometric regime. | Loi 2013-450, Art. 1-5; ARTCI communiqués 2019, 2024 |
| RC-QR-002 | Biometric attendance systems (fingerprint, facial recognition) are declared disproportionate by ARTCI and are effectively prohibited for attendance purposes in CI without specific ARTCI authorization. QR code is the explicitly endorsed compliant alternative. | ARTCI communiqué June 2024 |
| RC-QR-003 | Data minimization: the system collects only what is necessary for attendance tracking. No continuous GPS tracking. Device ID is hashed before storage. | Loi 2013-450, proportionality principle |
| RC-QR-004 | Storage limitation: attendance records retained for 10 years (aligned with OHADA general retention), then anonymized. [See TV-QR-003 for validation status.] | OHADA general retention rules |
| RC-QR-005 | OPEN: Whether prior declaration to ARTCI is required for a non-biometric QR attendance system. [See OQ-QR-001.] | Loi 2013-450, declaration requirements |
| ### C.1.2 — Droit du travail (Code du travail de 2015, loi n° 2015-532) |
| Rule | Description | Source |
|---|---|---|
| RC-QR-010 | The registre d'employeur is mandatory for all employers. Its 2nd fascicule covers "work performed, salary, leave." Attendance data is directly relevant to this obligation. | Art. 92 (al. 3), Code du Travail 2015 |
| RC-QR-011 | Legal weekly working duration: 40 hours. Overtime beyond 40h/week must be compensated with legal majorations (rates determined by implementing decrees and collective agreements). | Art. 21.2-21.3, Code du Travail 2015 |
| RC-QR-012 | The règlement intérieur (internal rules) must be submitted for opinion (avis) to the délégués du personnel before being filed with the labour inspectorate. An electronic attendance system is a work organization measure that should be referenced in the règlement intérieur. | Art. 16.1, Code du Travail 2015 |
| RC-QR-013 | Enterprises with 11+ employees must have délégués du personnel. The system includes a compliance reminder for this consultation (FR-QR-120). | Code du Travail 2015, délégués threshold |
| RC-QR-014 | In overtime disputes, employers who cannot produce attendance records are at a disadvantage. While no CI statute explicitly codifies the French L.3171-4 burden-of-proof principle, francophone court practice follows this tradition. QR attendance records serve as reliable electronic proof. | Francophone jurisprudential tradition; [See OQ-QR-004 for CI-specific validation] |
| ### C.1.3 — Jours fériés (CI) |
| Rule | Description |
|---|---|
| RC-QR-020 | CI has approximately 14 public holidays per year, including moveable Islamic holidays (Tabaski, Maouloud, etc.) determined annually. |
| RC-QR-021 | Public holidays are paid non-working days. Employees are not required to work. If they do work, they are entitled to Sunday/holiday overtime compensation. |
| RC-QR-022 | The system must not classify employees as "absent" on public holidays where no work is required. |
| --- |
C.2 Exigences en matière de localisation¶
| Dimension | Requirement |
|---|---|
| Language | French (fr-CI). All UI labels, error messages, reports, notifications in French. |
| Currency | XOF (FCFA). Zero decimal places. Formatted: 15 000 FCFA. (Not directly used in this module — monetary calculation is Payroll's responsibility. But if indicative amounts are ever shown, use this format.) |
| Date format | DD/MM/YYYY (e.g., 01/03/2026). In reports and exports. |
| Time format | HH:MM (24-hour). E.g., 08:02, 17:30. |
| Decimal separator | Comma for hours in reports (e.g., 7,5 for 7h30). |
| Week start | Monday (default, configurable). |
| Timezone | Africa/Abidjan (UTC+0, no daylight saving). All timestamps stored with timezone. |
| Name conventions | Last name first, then first name (NOM Prénom). E.g., "KONÉ Aminata." |
| Phone numbers | Not directly used in this module, but if employee contact is needed: +225 XX XX XX XX XX (10-digit CI format). |
| --- |
C.3 Exigences en matière de sécurité¶
| Requirement | Description |
|---|---|
| Tenant isolation | EVERY database query includes tenant_id filter. No cross-tenant data access. Zero-tolerance policy per Platform Vision FR-PV-041. |
| Role-based access | Employee: own data only. Manager: team data. HR: all employees. DG: dashboards. Comptable: read-only attendance. Per FR-QR decision table B.3.3. |
| Authenticated scanning | QR scans only valid from authenticated Papillon app sessions. The QR code content alone cannot record an event. |
| Device ID hashing | Device UUID is SHA-256 hashed before storage or transmission. Raw UUID never stored. |
| QR token security | QR payloads are HMAC-signed with a tenant-specific secret. Tokens are validated server-side (or against cached data offline). |
| Audit trail | All mutations logged: clock events, regularizations, config changes, QR regenerations, approval actions, compliance acknowledgements. Audit records are immutable (append-only). |
| Data export controls | Excel/CSV exports available only to HR (P2) and Comptable (P3). Exports are logged in audit trail. |
| Offline data protection | IndexedDB data is accessible only to the Papillon app (origin-scoped). Data is encrypted at rest if the device supports it (WebCrypto API). |
| Session timeout | Inherited from Control Plane session management. Expired sessions cannot scan. |
| --- |
C.4 Hors du champ d'application¶
Ce module NE prend PAS en charge :
| Item | Responsible Module | Timeline |
|---|---|---|
| Payroll salary calculation (overtime pay amounts) | Payroll (PAYROL) | Sprint 4 |
| Leave management (congé annuel, maladie, maternité) | Absence Management (ABSMGT) | Sprint 2a (parallel) |
| Employee lifecycle (hiring, termination, onboarding) | Control Plane / Employee Management | Sprint 1 / Post-MVP |
| Time & Activities tracking (project-based time allocation) | Time & Activities (TIMACT) | Post-MVP |
| Registre d'employeur generation | Future Compliance module | V2 |
| Advanced analytics (absence patterns, predictive) | Analytics (ENTERPRISE ONLY) | V2 |
| Complex shift rotation management | QR Attendance V2 (ENTERPRISE ONLY) | V2 |
| Physical access control integration | QR Attendance V2 (ENTERPRISE ONLY) | V2 |
| Kiosk mode (shared tablet at site entrance) | QR Attendance V2 (ENTERPRISE ONLY) | V2 |
| GPS coordinate capture at scan time | QR Attendance V2 | V2 |
| QR code token rotation | QR Attendance V2 | V2 |
| BJ and CM overtime rate configurations | QR Attendance V2 | Month 9 |
| Country-specific adaptations beyond CI | QR Attendance V2 | Month 9+ |
| Multi-entity consolidation (Enterprise) | ALTARYS ENTERPRISE V2 | Month 18+ |
| SSO/SAML integration | Control Plane V2 | Month 18+ |
| Collective agreement override rules | QR Attendance V2 | V2 |
| Night work special regulations | QR Attendance V2 | V2 |
| Sector-specific working time rules | QR Attendance V2 | V2 |
| --- |
Fin du PRD+FSD — Présence QR (QRCONTR) v1.0