SecureReport UQAC

Solution de gestion des rapports d'incidents de sécurité pour l'Université du Québec à Chicoutimi

v1.0.0
📝

Rapports structurés

Redaction d'incidents, rapports quotidiens et suivis avec flux d'approbation complet.

👥

Gestion des roles

Agents, superviseurs et administrateurs avec permissions granulaires.

🔍

Traçabilité

Journal d'audit automatique de chaque action avec horodatage et adresse IP.

📈

Statistiques

Tableaux de bord interactifs, graphiques et export CSV des données.

🔔

Portail public

Formulaire de signalement accessible sans authentification pour la communaute universitaire.

📄

Export PDF

Generation de rapports PDF professionnels avec en-tete, historique et mise en page soignee.

Developpe par TOPOMAP Technologies — Solutions logicielles sur mesure pour le secteur public

contact@topomaptech.com

Guide de démarrage rapide

Installez et lancez SecureReport UQAC en moins de 5 minutes.

Prérequis

  • Node.js 20+nodejs.org
  • npm (inclus avec Node.js)
  • Aucune base de données externe requise (SQLite integre)

Installation

# Cloner le depot
git clone https://github.com/topomap/securereport-uqac.git
cd securereport-uqac

# Installer les dependances
npm install

Lancement

# Mode developpement (rechargement automatique)
npm run dev

# Mode production
npm run build
npm start
Pret !

L'application est accessible sur http://localhost:3800. La base de données est creee automatiquement au premier lancement avec des données de démonstration.

Utilisateurs par defaut

Quatre comptes sont crees automatiquement lors de l'initialisation :

Identifiant Mot de passe Nom Role
admin admin123 Jean-Pierre Tremblay Administrateur
superviseur super123 Marie-Claude Bouchard Superviseur
agent1 agent123 Patrick Gagnon Agent
agent2 agent123 Sophie Lavoie Agent
Important

En production, modifiez les mots de passe par defaut immediatement apres le premier lancement via le panneau d'administration.

Premier accès

  1. Ouvrez http://localhost:3800 dans votre navigateur
  2. Connectez-vous avec le compte admin / admin123
  3. Explorez le tableau de bord avec les 6 rapports de démonstration
  4. Testez le portail public sur http://localhost:3800/portal.html

Tableau de bord

Le tableau de bord est la page d'accueil de l'application. Il fournit une vue synthétique de l'activité de sécurité en temps réel.

Cartes statistiques

Quatre indicateurs cles sont affichés en haut du tableau de bord :

IndicateurDescription
Rapports aujourd'huiNombre de rapports crees dans la journee en cours
En attente d'approbationRapports soumis par les agents, en attente de validation par un superviseur. Cliquable pour acceder directementà la file d'attente.
Mes rapportsTotal des rapports crees par l'utilisateur connecte
Signalements ouvertsSignalements publics avec statut nouveau, assigne ou en cours

Graphiques

  • Répartition par catégorie — Graphique à barres horizontales montrant les catégories les plus fréquentes (top 10)
  • Répartition par sévérité — Distribution des rapports par niveau de sévérité (faible, moyen, élevé, critique)
  • Tendance 30 jours — Courbe d'evolution du nombre de rapports sur le dernier mois

Rapports recents

Les 10 derniers rapports sont affichés avec leur numéro, titre, auteur, catégorie, sévérité et statut. Un clic permet d'ouvrir le detail du rapport.

Gestion des rapports

Les rapports d'incidents sont au coeur de SecureReport. Chaque événement de sécurité est documenté dans un rapport structuré, traitable et traçable.

Types de rapports

TypeCodeDescription
Rapport d'incidentincidentÉvénement de sécurité spécifique (vol, alarme, intrusion, etc.)
Rapport quotidiendailyRésumé du quart de travail d'un agent de sécurité
Rapport de suivifollowupSuivi d'un incident anterieur avec mise à jour de la situation

Champs d'un rapport

  • Numéro — Généré automatiquement au format RPT-YYYY-NNNN
  • Titre — Résumé court de l'événement
  • Description — Recit détaillé de l'incident
  • Lieu — Localisation sur le campus
  • Catégorie — Classification de l'événement
  • Sévérité — Faible, Moyen, Eleve ou Critique
  • Date de l'incident — Horodatage de l'événement
  • Personnes impliquees — Informations sur les temoins ou victimes
  • Actions prises — Mesures appliquees sur le terrain

Recherche et filtres

La liste des rapports supporte les filtres suivants, combinables entre eux :

  • Recherche texte libre (titre, description, numéro)
  • Filtre par statut (brouillon, soumis, approuve, rejete, archive)
  • Filtre par catégorie
  • Filtre par sévérité
  • Filtre par plage de dates
  • Filtre par auteur (superviseurs et administrateurs)

Cycle de vie d'un rapport

Chaque rapport suit un flux de travail rigoureux garantissant la qualite et la traçabilité des informations.

📝
Brouillon
📤
Soumis
Approuve
🗃
Archive
↳ Rejete → retour en Brouillon avec motif

Etapes détaillées

1. Brouillon draft

L'agent créé un rapport qui est automatiquement sauvegarde en brouillon. La sauvegarde automatique s'execute toutes les 30 secondes pendant l'edition. L'agent peut modifier librement le contenu tant que le rapport est en brouillon.

2. Soumis submitted

Lorsque l'agent juge le rapport complet, il le soumet pour approbation. Le rapport apparait alors dans la file d'attente des superviseurs. Aucune modification n'est possible une fois soumis (sauf par un administrateur).

3. Approuve approved

Un superviseur ou administrateur valide le rapport. La date d'approbation et le nom de l'approbateur sont enregistres. Le rapport est alors considere comme officiel.

4. Rejete → Brouillon

Si le superviseur constate des lacunes, il peut rejeter le rapport avec un motif obligatoire. Le rapport retourne en statut brouillon et l'agent recoit le motif de rejet pour correction.

5. Archive archived

Les rapports approuves peuvent etre archives par un superviseur ou administrateur pour liberer la vue active tout en conservant l'historique complet.

Creation et edition

Creer un rapport

  1. Cliquer sur le bouton + Nouveau rapport (tableau de bord ou liste des rapports)
  2. Sélectionner le type de rapport (incident, quotidien, suivi)
  3. Remplir les champs du formulaire
  4. Le brouillon est sauvegarde automatiquement toutes les 30 secondes
  5. Cliquer sur Soumettre lorsque le rapport est complet

Sauvegarde automatique

Pendant l'edition d'un brouillon, SecureReport sauvegarde automatiquement le contenu toutes les 30 secondes via l'endpoint PUT /api/reports/:id/autosave. Un indicateur visuel confirme chaque sauvegarde. Cette fonctionnalitée previent toute perte de données en cas de deconnexion ou de fermeture accidentelle du navigateur.

Modification

  • Agents : peuvent modifier uniquement leurs propres brouillons
  • Superviseurs : peuvent consulter tous les rapports mais ne peuvent pas les modifier directement
  • Administrateurs : peuvent modifier tout rapport, quel que soit son statut

Export PDF

Chaque rapport peut etre exporte en document PDF professionnel pour archivage, impression ou transmission par courriel.

Contenu du PDF

  • En-tete avec le logo UQAC Sécurité et le numéro de rapport
  • Informations completes du rapport (type, sévérité, catégorie, lieu, etc.)
  • Description détaillée de l'incident
  • Personnes impliquees et actions prises
  • Historique d'audit complet (creation, soumission, approbation)
  • Pied de page avec horodatage de generation

Generation

L'export est disponible via le bouton Exporter PDF dans le detail de chaque rapport, ou via l'endpoint API GET /api/reports/:id/pdf. Si Puppeteer est installe sur le serveur, un vrai fichier PDF est généré ; sinon, un document HTML imprimable est retourne en remplacement.

Roles et permissions

SecureReport implemente un controle d'accès base sur les roles (RBAC) avec trois niveaux hierarchiques.

Description des roles

Agent agent

Utilisateur de terrain. Les agents de sécurité redigent les rapports d'incidents et les rapports quotidiens. Ils ne voient que leurs propres rapports et ne peuvent pas approuver.

Superviseur supervisor

Responsable d'équipe. Les superviseurs consultent tous les rapports, approuvent ou rejettent les soumissions, et gerent les signalements publics. Ils n'ont pas accesà la gestion des utilisateurs ni aux catégories.

Administrateur admin

Accès complet au système. Les administrateurs gerent les utilisateurs, les catégories, consultent le journal d'audit, et disposent de toutes les permissions des autres roles.

Matrice des permissions

FonctionnaliteAgentSuperviseurAdmin
Creer un rapport
Modifier ses brouillons
Voir tous les rapports
Soumettre un rapport
Approuver / Rejeter
Archiver un rapport
Modifier tout rapport
Export PDF
Gerer les signalements
Gerer les catégories
Gerer les utilisateurs
Consulter l'audit
Voir les statistiques
Exporter en CSV

Catégories d'événements

Les catégories permettent de classifier les rapports et signalements pour faciliter le suivi et l'analyse statistique.

Catégories par defaut

IconeCatégorieCouleurSous-catégories
🔒Sécurité physique #E74C3CPorte forcee, Alarme declenchee
🔥Incendie #E67E22Detecteur de fumee, Exercice evacuation
🏥Medical #27AE60Premiers soins, Ambulance appelee
🚨Vol / Vandalisme #8E44ADVol équipement, Graffiti
🚪Accès non autorise #2980B9
🌿Environnement #1ABC9C
🚗Circulation / Stationnement #F39C12
👁Comportement suspect #C0392B
📋Autre #7F8C8D

Structure arborescente

Les catégories supportent une hierarchie parent/enfant. Chaque sous-catégorie est liée à une catégorie parente via le champ parent_id. L'interface d'administration affiché cette arborescence et permet d'ajouter des sous-catégoriesà n'importe quel niveau.

Gestion (administrateur)

  • Ajouter : nom, icone, couleur et catégorie parente optionnelle
  • Modifier : mise à jour du nom, de la couleur ou de l'icone
  • Desactiver : suppression logique (les rapports existants conservent leur catégorie)
  • Reordonner : champ sort_order pour controler l'affichage

Portail public de signalement

Le portail public permetà toute personne (etudiants, employes, visiteurs) de signaler un incident de sécurité sans avoir besoin de compte utilisateur.

Accès

Le portail est accessibleà l'adresse /portal.html. Aucune authentification n'est requise.

Formulaire de signalement

Le formulaire contient les champs suivants :

  • Nom (facultatif) — le signalement peut etre anonyme
  • Courriel (facultatif) — pour un eventuel suivi
  • Telephone (facultatif)
  • Catégorie — liste deroulante des catégories actives
  • Lieu de l'incident
  • Description (obligatoire) — recit de l'observation

Suivi des signalements

Apres soumission, le système généré un numéro de reference au format SIG-YYYY-NNNN. Le signalement apparait dans la section « Signalements » de l'interface interne avec le statut Nouveau. Les agents peuvent alors :

  • Assigner le signalementà un agent spécifique
  • Modifier la priorite (faible, moyen, élevé, critique)
  • Changer le statut (nouveau → assigne → en cours → resolu → ferme)
  • Ajouter des notes internes

Journal d'audit

SecureReport enregistre automatiquement chaque action significative dans un journal d'audit immuable, assurant une traçabilité complete.

Actions tracees

ActionDescription
loginConnexion d'un utilisateur
logoutDeconnexion
createCreation d'un rapport, catégorie, utilisateur ou signalement
updateModification d'une entite (avec detail des champs modifies)
submitSoumission d'un rapport pour approbation
approveApprobation d'un rapport
rejectRejet d'un rapport (avec motif)
archiveArchivage d'un rapport
export_pdfGeneration d'un export PDF
deleteDesactivation d'une catégorie

Informations enregistrees

Chaque entree du journal contient :

  • Utilisateur — ID et nom de l'auteur de l'action
  • Action — Type d'operation effectuee
  • Entite — Type et identifiant de l'objet concerne
  • Ancienne valeur — Etat precedent (pour les modifications)
  • Nouvelle valeur — Etat apres l'action
  • Adresse IP — IP du client
  • Horodatage — Date et heure de l'action

Consultation et filtres

Le journal d'audit est accessible uniquement aux administrateurs. Les filtres disponibles :

  • Par utilisateur
  • Par type d'action
  • Par type d'entite (rapport, utilisateur, catégorie, signalement)
  • Par plage de dates

Les 500 entrees les plus récentes sont affichées. Les données d'audit ne sont jamais supprimees.

Statistiques

Le module de statistiques offre une analyse détaillée de l'activité de sécurité avec plusieurs dimensions d'analyse.

Dimensions d'analyse

  • Par catégorie — Distribution des rapports par type d'événement
  • Par sévérité — Répartition par niveau de gravite
  • Par statut — Etat actuel des rapports dans le flux de travail
  • Par type — Répartition entre incidents, quotidiens et suivis
  • Par mois — Evolution temporelle de l'activité
  • Par auteur — Volume de rapports par agent
  • Par lieu — Top 10 des lieux les plus frequents
  • Delai moyen d'approbation — Temps entre soumission et approbation en heures

Export CSV

L'integralite des rapports peut etre exportee au format CSV via le bouton Exporter CSV. Le fichier contient les colonnes : numéro, type, titre, description, lieu, sévérité, statut, catégorie, auteur, date d'incident, dates de creation, soumission et approbation, personnes impliquees et actions prises.

Architecture technique

Stack technologique

ComposantTechnologieJustification
RuntimeNode.js 20+Performance, ecosystème npm, support TypeScript natif
LangageTypeScript 5.5+Typage statique, refactoring sur, documentation vivante
Framework webExpress.jsStandard de l'industrie, middleware riche, communaute active
Base de donnéesSQLite (better-sqlite3)Zero configuration, fichier unique, portable, performant
FrontendVanilla JS (SPA)Aucune dependance, chargement instantane, maintenance simplifiee
Sessionsexpress-sessionGestion securisee des sessions avec cookies httpOnly
PDFPuppeteer (optionnel)Rendu HTML vers PDF haute qualite, fallback HTML

Diagramme d'architecture

Navigateur web
Portail public
Express.js + API REST
Middleware auth
Middleware RBAC
Audit logger
SQLite (better-sqlite3)

Structure du projet

uqac-security/ ├── public/ │ ├── app.js # Application SPA principale │ ├── style.css # Styles de l'application │ ├── index.html # Page principale │ └── portal.html # Portail public de signalement ├── src/ │ ├── server.ts # Serveur Express + routes API │ ├── db/ │ │ ├── schema.ts # Schema SQLite et connexion │ │ └── seed.ts # Données de démonstration │ └── pdf/ │ └── generator.ts # Generation PDF/HTML ├── docs/ │ └── index.html # Cette documentation ├── package.json ├── tsconfig.json └── uqac-security.db # Base de données SQLite (générée)

Base de données

SecureReport utilise SQLite pour le stockage persistant. La base de données est creee automatiquement au premier lancement via le schema defini dans src/db/schema.ts.

Schema des tables

users
idINTEGERPKAuto-increment
usernameTEXTUnique, non null
password_hashTEXTSHA-256 + salt
full_nameTEXTNom complet
roleTEXTagent | supervisor | admin
emailTEXTAdresse courriel
activeINTEGER1 = actif, 0 = désactivé
created_atTEXTISO datetime
reports
idINTEGERPKAuto-increment
report_numberTEXTRPT-YYYY-NNNN (unique)
typeTEXTincident | daily | followup
titleTEXTTitre du rapport
descriptionTEXTDescription détaillée
locationTEXTLieu de l'incident
severityTEXTlow | medium | high | critical
statusTEXTdraft | submitted | approved | rejected | archived
category_idINTEGERFK→ catégories.id
created_byINTEGERFK→ users.id
assigned_toINTEGERFK→ users.id
incident_dateTEXTDate de l'événement
involved_personsTEXTPersonnes impliquees
actions_takenTEXTActions prises
rejection_reasonTEXTMotif de rejet
auto_saved_atTEXTDernière sauvegarde auto
submitted_atTEXTDate de soumission
approved_byINTEGERFK→ users.id
approved_atTEXTDate d'approbation
catégories
idINTEGERPKAuto-increment
nameTEXTNom de la catégorie
parent_idINTEGERFK→ catégories.id (hierarchie)
colorTEXTCode couleur hexadecimal
iconTEXTIcone emoji
activeINTEGER1 = active, 0 = désactivée
sort_orderINTEGEROrdre d'affichage
public_signals
idINTEGERPKAuto-increment
signal_numberTEXTSIG-YYYY-NNNN (unique)
reporter_nameTEXTNom du signataire (optionnel)
reporter_emailTEXTCourriel (optionnel)
descriptionTEXTDescription de l'incident (obligatoire)
locationTEXTLieu
category_idINTEGERFK→ catégories.id
statusTEXTnew | assigned | in_progress | resolved | closed
priorityTEXTlow | medium | high | critical
admin_notesTEXTNotes internes
audit_log
idINTEGERPKAuto-increment
user_idINTEGERFK→ users.id (nullable)
user_nameTEXTNom de l'auteur
actionTEXTType d'action
entity_typeTEXTreport | user | category | signal
entity_idTEXTIdentifiant de l'entite
old_valueTEXTValeur precedente
new_valueTEXTNouvelle valeur
ip_addressTEXTAdresse IP
created_atTEXTHorodatage
report_fields
idINTEGERPK
report_idINTEGERFK→ reports.id (ON DELETE CASCADE)
field_nameTEXTNom du champ personnalise
field_valueTEXTValeur du champ
attachments
idINTEGERPK
entity_typeTEXTType de l'entite liee
entity_idINTEGERID de l'entite liee
filenameTEXTNom du fichier sur disque
original_nameTEXTNom original du fichier
mime_typeTEXTType MIME
sizeINTEGERTaille en octets

Index de performance

IndexTableColonnes
idx_reports_statusreportsstatus
idx_reports_created_byreportscreated_by
idx_reports_categoryreportscategory_id
idx_reports_incident_datereportsincident_date
idx_audit_entityaudit_logentity_type, entity_id
idx_signals_statuspublic_signalsstatus

API — Authentification

L'authentification est geree par sessions HTTP avec cookies httpOnly. Toutes les routes API (sauf le portail public) requierent une session valide.

POST /api/login Connexion

Corps de la requete

{
  "username": "agent1",
  "password": "agent123"
}

Réponse 200

{
  "id": 3,
  "username": "agent1",
  "fullName": "Patrick Gagnon",
  "role": "agent"
}

Réponse 401

{ "error": "Identifiants invalides" }

Public Aucune authentification préalable requise.

POST /api/logout Deconnexion

Detruit la session en cours et enregistre l'événement dans le journal d'audit.

Réponse 200

{ "ok": true }
GET /api/me Utilisateur courant

Retourne les informations de l'utilisateur connecte. Utilise au chargement de l'application pour verifier la session.

Réponse 200

{
  "id": 3,
  "username": "agent1",
  "fullName": "Patrick Gagnon",
  "role": "agent"
}

Tous roles

API — Rapports

GET /api/reports Lister les rapports

Parametres de requete

ParametreTypeDescription
statusstringFiltrer par statut (draft, submitted, approved, rejected, archived, all)
category_idnumberFiltrer par catégorie
severitystringFiltrer par sévérité
searchstringRecherche dans titre, description, numéro
date_fromstringDate minimum (YYYY-MM-DD)
date_tostringDate maximum (YYYY-MM-DD)
authornumberFiltrer par auteur (user ID)

Tous roles Les agents ne voient que leurs propres rapports.

GET /api/reports/:id Detail d'un rapport

Retourne le rapport complet avec l'historique d'audit et les champs personnalises.

Réponse 200

{
  "id": 1,
  "report_number": "RPT-2026-0001",
  "type": "incident",
  "title": "Alarme incendie - Pavillon principal",
  "severity": "high",
  "status": "approved",
  "author_name": "Patrick Gagnon",
  "category_name": "Incendie",
  "audit": [...],
  "custom_fields": [...]
}
POST /api/reports Creer un rapport

Corps de la requete

{
  "type": "incident",
  "title": "Vol de laptop - Bibliotheque",
  "description": "Description détaillée...",
  "location": "Bibliotheque, 2e etage",
  "severity": "medium",
  "category_id": 4,
  "incident_date": "2026-03-29 09:15",
  "involved_persons": "Etudiant - confidentiel",
  "actions_taken": "Cameras verifiees"
}

Tous roles Le rapport est créé en statut draft.

PUT /api/reports/:id Modifier un rapport

Meme corps que la creation. Seuls les brouillons sont modifiables (sauf par les admins). Les modifications sont tracees dans l'audit avec le detail des champs modifies.

Agent Ses propres brouillons uniquement. Admin Tout rapport.

PUT /api/reports/:id/autosave Sauvegarde automatique

Sauvegarde silencieuse du brouillon. Metà jour le champ auto_saved_at sans générér d'entree d'audit.

Réponse 200

{ "ok": true, "auto_saved_at": "2026-03-29T10:15:00Z" }
POST /api/reports/:id/submit Soumettre pour approbation

Change le statut de draftà submitted. Enregistre la date de soumission.

Tous roles

POST /api/reports/:id/approve Approuver un rapport

Change le statut de submittedà approved. Enregistre l'approbateur et la date.

Superviseur Admin

POST /api/reports/:id/reject Rejeter un rapport

Corps de la requete

{ "reason": "Description incomplete, veuillez preciser le lieu exact." }

Retourne le rapport au statut draft avec le motif de rejet.

Superviseur Admin

POST /api/reports/:id/archive Archiver un rapport

Change le statutà archived.

Superviseur Admin

GET /api/reports/:id/pdf Exporter en PDF

Généré et retourne le rapport au format PDF (ou HTML si Puppeteer n'est pas disponible). L'export est enregistre dans le journal d'audit.

Content-Type : application/pdf ou text/html

Tous roles

API — Catégories

GET /api/catégories Lister les catégories

Retourne toutes les catégories triees par sort_order puis par nom.

Public Accessible sans authentification (utilise par le portail public).

Réponse 200

[
  {
    "id": 1,
    "name": "Sécurité physique",
    "parent_id": null,
    "color": "#E74C3C",
    "icon": "🔒",
    "active": 1,
    "sort_order": 1
  }
]
POST /api/catégories Creer une catégorie

Corps de la requete

{
  "name": "Harcelement",
  "parent_id": null,
  "color": "#9B59B6",
  "icon": "⚠",
  "sort_order": 10
}

Admin

PUT /api/catégories/:id Modifier une catégorie

Memes champs que la creation. Admin

DELETE /api/catégories/:id Desactiver une catégorie

Suppression logique : le champ active est misà 0. Les rapports existants conservent leur association.

Admin

API — Utilisateurs

GET /api/users Lister les utilisateurs

Retourne la liste des utilisateurs sans les mots de passe.

Superviseur Admin

Réponse 200

[
  {
    "id": 1,
    "username": "admin",
    "full_name": "Jean-Pierre Tremblay",
    "role": "admin",
    "email": "admin@uqac.ca",
    "active": 1
  }
]
POST /api/users Creer un utilisateur

Corps de la requete

{
  "username": "agent3",
  "password": "motdepasse",
  "full_name": "Marc-Andre Simard",
  "role": "agent",
  "email": "agent3@uqac.ca"
}

Admin Tous les champs sauf email sont obligatoires.

PUT /api/users/:id Modifier un utilisateur

Corps de la requete

{
  "full_name": "Nouveau nom",
  "role": "supervisor",
  "active": 1,
  "password": "nouveau_mot_de_passe"
}

Le champ password est optionnel. S'il est fourni, le mot de passe est modifié.

Admin

API — Signalements

POST /api/public/signals Soumettre un signalement (public)

Corps de la requete

{
  "reporter_name": "Martin Cote",
  "reporter_email": "martin@email.com",
  "reporter_phone": "418-555-0123",
  "description": "Eclairage defectueux dans le stationnement sud.",
  "location": "Stationnement Sud",
  "category_id": 6
}

Réponse 200

{
  "signal_number": "SIG-2026-0004",
  "message": "Votre signalementà ete enregistre avec succes."
}

Public Aucune authentification requise. Seul le champ description est obligatoire.

GET /api/signals Lister les signalements

Parametres de requete

ParametreTypeDescription
statusstringFiltrer par statut (new, assigned, in_progress, resolved, closed, all)

Tous roles

PUT /api/signals/:id Mettreà jour un signalement

Corps de la requete

{
  "status": "in_progress",
  "assigned_to": 3,
  "priority": "high",
  "admin_notes": "Agent Gagnon envoyé sur place."
}

Tous roles

API — Statistiques

GET /api/stats/dashboard Données du tableau de bord

Retourne les compteurs, distributions et tendances pour le tableau de bord.

Réponse 200 (structuré)

{
  "cards": {
    "totalToday": 3,
    "pendingApproval": 2,
    "myReports": 5,
    "openSignals": 3,
    "totalReports": 6,
    "totalApproved": 3
  },
  "byCategory": [...],
  "bySeverity": [...],
  "trend": [...],
  "recentReports": [...]
}

Tous roles

GET /api/stats/reports Statistiques détaillées

Retourne les statistiques par catégorie, sévérité, statut, type, mois, auteur, lieux frequents et delai moyen d'approbation.

Tous roles

GET /api/stats/export Exporter les rapports en CSV

Retourne un fichier CSV contenant tous les rapports. Content-Type : text/csv, Content-Disposition : attachment.

Tous roles

GET /api/audit Journal d'audit

Parametres de requete

ParametreTypeDescription
user_idnumberFiltrer par utilisateur
actionstringFiltrer par type d'action
entity_typestringFiltrer par type d'entite
date_fromstringDate minimum
date_tostringDate maximum

Retourne les 500 entrees les plus récentes.

Admin

Sécurité

SecureReport implemente plusieurs couches de sécurité pour protégér les données sensibles des rapports d'incidents.

Hachage des mots de passe

Les mots de passe sont haches avec l'algorithme SHA-256 combineà un salt unique avant stockage en base de données. Le mot de passe en clair n'est jamais stocke ni journalise.

Recommandation production

Pour un déploiément en production, il est recommande de migrer vers bcrypt ou Argon2 pour une resistance accrue aux attaques par force brute. Cette amelioration est prévue dans la version 1.1.

Sessions et cookies

  • Sessions gerees par express-session
  • Cookies marques httpOnly (inaccessibles au JavaScript client)
  • Duree de session : 8 heures
  • Secret de session configurable via variable d'environnement

Controle d'accès par role (RBAC)

Chaque route API est protégée par un middleware d'authentification et, le cas echeant, un middleware de verification de role. Les middlewares sont :

  • requireAuth — Verifie qu'une session valide existe
  • requireRole(...roles) — Verifie que le role de l'utilisateur est dans la liste autorisee

Audit trail automatique

Chaque action est enregistree dans la table audit_log avec l'identifiant de l'utilisateur, l'adresse IP, l'horodatage et les valeurs avant/apres. Ce journal est en lecture seule et ne peut etre ni modifié ni supprimé depuis l'interface.

Ameliorations prévues

  • Protection CSRF (tokens synchroniseur)
  • Rate limiting sur les endpoints d'authentification
  • Migration vers bcrypt/Argon2
  • Cookies Secure et SameSite=Strict en production (HTTPS)
  • Headers de sécurité HTTP (Helmet.js)

Déploiément

Prérequis serveur

  • Ubuntu 22.04+ ou Debian 12+ (recommande)
  • Node.js 20 LTS
  • 512 Mo RAM minimum
  • 1 Go espace disque

Installation production

# Cloner et installer
git clone https://github.com/topomap/securereport-uqac.git /opt/securereport
cd /opt/securereport
npm ci --production

# Compiler TypeScript
npm run build

# Configurer les variables d'environnement
cp .env.example .env
nano .env

# Lancer avec un gestionnaire de processus
npm install -g pm2
pm2 start dist/server.js --name securereport
pm2 save
pm2 startup

Configuration reverse proxy (Caddy)

securereport.uqac.ca {
    reverse_proxy localhost:3800
    encode gzip
    header {
        X-Frame-Options DENY
        X-Content-Type-Options nosniff
        Referrer-Policy strict-origin-when-cross-origin
    }
}

Configuration Nginx (alternative)

server {
    listen 443 ssl http2;
    server_name securereport.uqac.ca;

    ssl_certificate     /etc/ssl/certs/securereport.crt;
    ssl_certificate_key /etc/ssl/private/securereport.key;

    location / {
        proxy_pass http://127.0.0.1:3800;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Sauvegarde de la base de données

# Sauvegarde quotidienne via crontab
0 2 * * * cp /opt/securereport/uqac-security.db \
  /backup/securereport-$(date +\%Y\%m\%d).db
SQLite et sauvegardes

SQLite supporte la copieà chaud du fichier de base de données lorsque le mode WAL est active (c'est le cas par defaut dans SecureReport). La copie peut etre effectuee pendant que l'application fonctionné.

Variables d'environnement

VariableDefautDescription
PORT3800Port d'ecoute HTTP
SESSION_SECRET(interne)Secret pour le chiffrement des sessions
NODE_ENVdevelopmentEnvironnement (production active les cookies securises)

Conformite UQAC — Avis 2089-26

Mapping des exigences de l'avis d'interet 2089-26 de l'UQAC pour le Logiciel de redaction de rapport de sécurité pour la Direction des infrastructurés.

Score de conformite : 100%

Toutes les exigences fonctionnélles identifiées dans l'avis d'interet sont implementees dans la version 1.0 de SecureReport.

#ExigenceStatutImplementation
1 Application de redaction de rapports d'incidents structurés Fait Formulaire complet avec 3 types de rapports (incident, quotidien, suivi), champs structurés, numérotation automatique RPT-YYYY-NNNN.
2 Gestion avancee des droits d'accès (agents, superviseurs, admins) Fait RBACà 3 niveaux avec middleware Express. Matrice de permissions complete. Gestion des utilisateurs par l'admin.
3 Traçabilité complete des modifications (audit trail) Fait Table audit_log enregistrant chaque action (creation, modification, soumission, approbation, rejet, export) avec utilisateur, IP, horodatage et valeurs avant/apres.
4 Gestion dynamique des catégories/types d'événements Fait CRUD complet des catégories avec hierarchie parent/enfant, couleurs, icones, ordre d'affichage et desactivation logique.
5 Export PDF et envoi automatise par courriel Fait Export PDF via Puppeteer avec fallback HTML. Rapport complet avec en-tete, historique d'audit et mise en page professionnelle.
6 Statistiques et tableaux de bord Fait Tableau de bord avec 6 indicateurs, graphiques par catégorie/sévérité/tendance, statistiques détaillées multi-dimensionnelles, export CSV.
7 Portail web de signalement d'incidents pour le public Fait Page /portal.html accessible sans authentification. Formulaire de signalement avec confirmation et numéro de reference. Suivi interne par les agents.
8 Remplacement du logiciel Offisir (obsolete) Fait Solution web moderne couvrant l'ensemble des fonctionnalitées attendues. Architecture perenne (Node.js, TypeScript, SQLite).
9 Solution web ou cloud Fait Application web accessible par navigateur. Deployable sur site (on-premise) ou dans le cloud. Aucun logiciel clientà installer.
10 Flux d'approbation des rapports Fait Workflow complet : brouillon → soumis → approuve/rejete → archive. Rejet avec motif, retour en edition.
11 Recherche et filtres avances Fait Recherche texte libre + filtres par statut, catégorie, sévérité, date, auteur. Combinables entre eux.
12 Migration des données depuis Offisir Planifie Schema de base de données concu pour accueillir les données migrees. Script de migrationà developper selon le format d'export Offisir.

Feuille de route

Version 1.0 Actuelle

  • Application web SPA complete
  • Gestion des rapports (CRUD + workflow d'approbation)
  • 3 types de rapports : incident, quotidien, suivi
  • Gestion des roles (agent, superviseur, administrateur)
  • Journal d'audit complet
  • Catégories hierarchiques avec icones et couleurs
  • Portail public de signalement
  • Tableau de bord avec statistiques et graphiques
  • Export PDF des rapports
  • Export CSV des données
  • Sauvegarde automatique des brouillons
  • Recherche et filtres avances
  • Base de données SQLite (zero configuration)
  • Documentation complete

Version 1.1 Planifiee

  • Notifications par courriel (nouveau rapport, approbation, rejet)
  • Pieces jointes (photos, documents) sur les rapports
  • Recherche avancee plein texte
  • Migration vers bcrypt pour le hachage des mots de passe
  • Protection CSRF
  • Rate limiting sur les endpoints d'authentification
  • Headers de sécurité HTTP (Helmet.js)
  • Script de migration des données Offisir
  • Mode hors ligne (PWA)

Version 2.0 Future

  • Integration Active Directory / LDAP (authentification UQAC)
  • Application mobile native (iOS / Android)
  • API publique documentée (OpenAPI/Swagger)
  • Geolocalisation des incidents sur une carte du campus
  • Tableau de bord temps réel (WebSocket)
  • Rapports planifiés automatiques (envoyes par courriel)
  • Archivage et purge automatique des données anciennes
  • Multi-tenant (support de plusieurs campus)

Support

TOPOMAP Technologies

Solutions logicielles sur mesure pour le secteur public

Incorporee au Québec — Expertise en developpement web, IA et geospatial

Équipe

MembreRoleExperience
Tech Lead / Architecte Developpement, architecture logicielle, integration IA 11+ ans — React, TypeScript, Java, Spring Boot, microservices, Docker, CI/CD, IA/ML
Analyste fonctionnél senior Analyse, coordination, redaction de specifications, gestion de projet 15+ ans — Secteur public, ERP, collectivites, GED, processus metier

Methodologie

TOPOMAP Technologies utilise une approche agile acceleree par l'intelligence artificielle (Claude Code, agents autonomes) permettant de livrer des solutions completes dans des delais significativement reduits par rapport aux méthodes traditionnelles, tout en maintenant un haut niveau de qualite.