diff --git a/VigilCareClinicalAPI.Tests/EncountersListTests.cs b/VigilCareClinicalAPI.Tests/EncountersListTests.cs index 37c7a83..a038b6e 100644 --- a/VigilCareClinicalAPI.Tests/EncountersListTests.cs +++ b/VigilCareClinicalAPI.Tests/EncountersListTests.cs @@ -142,6 +142,7 @@ public class EncountersListTests : IAsyncLifetime icu.GetProperty("gcsClassification").GetString().Should().Be("MODERATE"); icu.GetProperty("attendingPhysician").GetString().Should().Be("Dr. Ward"); icu.GetProperty("lastObservationAt").GetDateTimeOffset().Should().NotBe(default); + icu.GetProperty("isSimulated").GetBoolean().Should().BeFalse(); } [Fact] diff --git a/VigilCareClinicalAPI/Models/Records/Encounter/WardEncounterSummary.cs b/VigilCareClinicalAPI/Models/Records/Encounter/WardEncounterSummary.cs index fdc6403..2b638e9 100644 --- a/VigilCareClinicalAPI/Models/Records/Encounter/WardEncounterSummary.cs +++ b/VigilCareClinicalAPI/Models/Records/Encounter/WardEncounterSummary.cs @@ -19,4 +19,5 @@ public record WardEncounterSummary( string? GcsClassification, DateTimeOffset? LastObservationAt, string AttendingPhysician, - DateTimeOffset AdmittedAt); + DateTimeOffset AdmittedAt, + bool IsSimulated = false); diff --git a/VigilCareClinicalAPI/Services/EncounterService.cs b/VigilCareClinicalAPI/Services/EncounterService.cs index a976f6d..4e7133e 100644 --- a/VigilCareClinicalAPI/Services/EncounterService.cs +++ b/VigilCareClinicalAPI/Services/EncounterService.cs @@ -153,7 +153,8 @@ public class EncounterService : IEncounterService gcs?.Classification, lastObservationAt, encounter.AttendingPhysician, - encounter.AdmittedAt)); + encounter.AdmittedAt, + encounter.Patient.IsSimulated)); } return new PagedResult(summaries, page, pageSize, total); diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/00/2f/fb2687c9bd91abae779635a12725e38b531f89946b7bb4d6b4c198913d3e0c635c267ca8eddbee8eda9daecf6fac92597c39966624c36a7a47bb90a6cd81 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/00/2f/fb2687c9bd91abae779635a12725e38b531f89946b7bb4d6b4c198913d3e0c635c267ca8eddbee8eda9daecf6fac92597c39966624c36a7a47bb90a6cd81 new file mode 100644 index 0000000..87b8ad7 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/00/2f/fb2687c9bd91abae779635a12725e38b531f89946b7bb4d6b4c198913d3e0c635c267ca8eddbee8eda9daecf6fac92597c39966624c36a7a47bb90a6cd81 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/02/6a/bd07f4a86587438b5905ae88e7a2a3cbc58850e16a395e22fc11526b56c07c011a02d4f596e951ad4f458a09e9a3cbc682fa5a2e2678d2ed4d7cc776f4e9 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/02/6a/bd07f4a86587438b5905ae88e7a2a3cbc58850e16a395e22fc11526b56c07c011a02d4f596e951ad4f458a09e9a3cbc682fa5a2e2678d2ed4d7cc776f4e9 new file mode 100644 index 0000000..ba0e42d Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/02/6a/bd07f4a86587438b5905ae88e7a2a3cbc58850e16a395e22fc11526b56c07c011a02d4f596e951ad4f458a09e9a3cbc682fa5a2e2678d2ed4d7cc776f4e9 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/04/b2/374e5d535b73ef97bd25df2ab763ae22f9ac29c17aac181616924a8cb676d782b303fb28fbae15b492e103c7325a6171a3116e6881aa4a34c10a34c8e26c b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/04/b2/374e5d535b73ef97bd25df2ab763ae22f9ac29c17aac181616924a8cb676d782b303fb28fbae15b492e103c7325a6171a3116e6881aa4a34c10a34c8e26c new file mode 100644 index 0000000..865d6b6 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/04/b2/374e5d535b73ef97bd25df2ab763ae22f9ac29c17aac181616924a8cb676d782b303fb28fbae15b492e103c7325a6171a3116e6881aa4a34c10a34c8e26c differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/0d/f5/cdf037e127b347dce7bb7059aedcd0aed7029b911789f13a2bcd20056d22ab94d69048a7c8cea62a558f3395bb3634b05b5a9462539d865f63db68154d92 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/0d/f5/cdf037e127b347dce7bb7059aedcd0aed7029b911789f13a2bcd20056d22ab94d69048a7c8cea62a558f3395bb3634b05b5a9462539d865f63db68154d92 new file mode 100644 index 0000000..ee15346 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/0d/f5/cdf037e127b347dce7bb7059aedcd0aed7029b911789f13a2bcd20056d22ab94d69048a7c8cea62a558f3395bb3634b05b5a9462539d865f63db68154d92 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/11/93/aba436e42a8b4500fef03c0415d54232a063a4e285fbca75a10612c1eeffa678c1db421535ea83e92181934dee28165869af21a98297193ffb229f7858bb b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/11/93/aba436e42a8b4500fef03c0415d54232a063a4e285fbca75a10612c1eeffa678c1db421535ea83e92181934dee28165869af21a98297193ffb229f7858bb new file mode 100644 index 0000000..a110742 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/11/93/aba436e42a8b4500fef03c0415d54232a063a4e285fbca75a10612c1eeffa678c1db421535ea83e92181934dee28165869af21a98297193ffb229f7858bb differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/11/b2/922a1f9b875135205c5e3b4a60d67e1dbe8393b7450389731dfea9fefabf7cfa33ced71b498a5bd795d7ae43c822201e489298c280c95e1cc344b061faa6 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/11/b2/922a1f9b875135205c5e3b4a60d67e1dbe8393b7450389731dfea9fefabf7cfa33ced71b498a5bd795d7ae43c822201e489298c280c95e1cc344b061faa6 new file mode 100644 index 0000000..704ded5 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/11/b2/922a1f9b875135205c5e3b4a60d67e1dbe8393b7450389731dfea9fefabf7cfa33ced71b498a5bd795d7ae43c822201e489298c280c95e1cc344b061faa6 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/14/c8/4ea19578faa47a6935002ca5f6ac4a861bea32013bf006df48233551e6b31ad874563e4c5ff8ff8f0092c3d48fc7e7f208f87b99701258105069ab7f689e b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/14/c8/4ea19578faa47a6935002ca5f6ac4a861bea32013bf006df48233551e6b31ad874563e4c5ff8ff8f0092c3d48fc7e7f208f87b99701258105069ab7f689e new file mode 100644 index 0000000..4bd1a68 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/14/c8/4ea19578faa47a6935002ca5f6ac4a861bea32013bf006df48233551e6b31ad874563e4c5ff8ff8f0092c3d48fc7e7f208f87b99701258105069ab7f689e differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/23/1a/626d38f25679ab210a396aa3690a0a00080fdd4ca2d39613078a154785d9312b23ced6e041b61ba64f4add1e672c93db8ca272164b49b81658d6cc82e1df b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/23/1a/626d38f25679ab210a396aa3690a0a00080fdd4ca2d39613078a154785d9312b23ced6e041b61ba64f4add1e672c93db8ca272164b49b81658d6cc82e1df new file mode 100644 index 0000000..e5f69ee Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/23/1a/626d38f25679ab210a396aa3690a0a00080fdd4ca2d39613078a154785d9312b23ced6e041b61ba64f4add1e672c93db8ca272164b49b81658d6cc82e1df differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/26/cd/26f5cc7ea8e803c68d1e32214612e796cedcfe778f8cdeb1a598a3d3f93e084bf8cfe32970dcdc29bba7294d33fc4753000b5905e156dd2eddc045fdb4f7 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/26/cd/26f5cc7ea8e803c68d1e32214612e796cedcfe778f8cdeb1a598a3d3f93e084bf8cfe32970dcdc29bba7294d33fc4753000b5905e156dd2eddc045fdb4f7 new file mode 100644 index 0000000..a16afc3 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/26/cd/26f5cc7ea8e803c68d1e32214612e796cedcfe778f8cdeb1a598a3d3f93e084bf8cfe32970dcdc29bba7294d33fc4753000b5905e156dd2eddc045fdb4f7 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/2a/e3/9a361727185376cc83c603bc119b317e949035b1e6bbac7ab5eda889fbef65cd8d56586e89a70ab07b528d6d154f22a1e6afc18b631ee36eb41c37feffc3 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/2a/e3/9a361727185376cc83c603bc119b317e949035b1e6bbac7ab5eda889fbef65cd8d56586e89a70ab07b528d6d154f22a1e6afc18b631ee36eb41c37feffc3 new file mode 100644 index 0000000..7b9e5b0 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/2a/e3/9a361727185376cc83c603bc119b317e949035b1e6bbac7ab5eda889fbef65cd8d56586e89a70ab07b528d6d154f22a1e6afc18b631ee36eb41c37feffc3 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/4a/84/dbea53e0db9c59940da26f043ef9a8420a71fe14fd2a984b9a7cc2788339d928e9578a828401e24b802aea8ccf7c002ce25ccf55d5a9858c80952f8205a0 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/4a/84/dbea53e0db9c59940da26f043ef9a8420a71fe14fd2a984b9a7cc2788339d928e9578a828401e24b802aea8ccf7c002ce25ccf55d5a9858c80952f8205a0 new file mode 100644 index 0000000..f912b3b Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/4a/84/dbea53e0db9c59940da26f043ef9a8420a71fe14fd2a984b9a7cc2788339d928e9578a828401e24b802aea8ccf7c002ce25ccf55d5a9858c80952f8205a0 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/58/c8/bf390d9ac554dfff292a09081788872dfa64900c5747d9f93084fc20130bc9d644b36518a29dbd331765dbf2ee3e3aa3c2866c88e8c12ee047b3349cfe15 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/58/c8/bf390d9ac554dfff292a09081788872dfa64900c5747d9f93084fc20130bc9d644b36518a29dbd331765dbf2ee3e3aa3c2866c88e8c12ee047b3349cfe15 new file mode 100644 index 0000000..4503808 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/58/c8/bf390d9ac554dfff292a09081788872dfa64900c5747d9f93084fc20130bc9d644b36518a29dbd331765dbf2ee3e3aa3c2866c88e8c12ee047b3349cfe15 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/79/70/7b087b9a41daa625c73792808db4d3e64ff6e3da073df7d9141600711bc01cd0d7605dce2b9021e1aab82b84ddf375dbefbeb8338f57bdd12b927e6c885c b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/79/70/7b087b9a41daa625c73792808db4d3e64ff6e3da073df7d9141600711bc01cd0d7605dce2b9021e1aab82b84ddf375dbefbeb8338f57bdd12b927e6c885c new file mode 100644 index 0000000..ffae323 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/79/70/7b087b9a41daa625c73792808db4d3e64ff6e3da073df7d9141600711bc01cd0d7605dce2b9021e1aab82b84ddf375dbefbeb8338f57bdd12b927e6c885c differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/7b/41/8eb6afda4d085574dc8353d7b4dbec33f680c333e488390c56304d90463cd15f9cb22c0b870c4fb4684f2f1dbf57442f170f7ede3b6bb9efe174f49a8587 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/7b/41/8eb6afda4d085574dc8353d7b4dbec33f680c333e488390c56304d90463cd15f9cb22c0b870c4fb4684f2f1dbf57442f170f7ede3b6bb9efe174f49a8587 new file mode 100644 index 0000000..95f7d15 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/7b/41/8eb6afda4d085574dc8353d7b4dbec33f680c333e488390c56304d90463cd15f9cb22c0b870c4fb4684f2f1dbf57442f170f7ede3b6bb9efe174f49a8587 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/85/4a/e669605d543731bd8aa7ca1d3dcee9cacd13968db65388dcbc741123912ede8440d089b5c9ed7be59ad6f0b9372552223237e0b25d00f8566928f1f366f3 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/85/4a/e669605d543731bd8aa7ca1d3dcee9cacd13968db65388dcbc741123912ede8440d089b5c9ed7be59ad6f0b9372552223237e0b25d00f8566928f1f366f3 new file mode 100644 index 0000000..98a6b8d Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/85/4a/e669605d543731bd8aa7ca1d3dcee9cacd13968db65388dcbc741123912ede8440d089b5c9ed7be59ad6f0b9372552223237e0b25d00f8566928f1f366f3 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/86/73/919e33ffd4fff31449dda1e5fe9feb7547059126226933f8ceec55b7d8a9fdaf9fac241d8958e758a382fa93bf23d79782c18dc69bfef7eb807510cc2d36 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/86/73/919e33ffd4fff31449dda1e5fe9feb7547059126226933f8ceec55b7d8a9fdaf9fac241d8958e758a382fa93bf23d79782c18dc69bfef7eb807510cc2d36 new file mode 100644 index 0000000..987110a Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/86/73/919e33ffd4fff31449dda1e5fe9feb7547059126226933f8ceec55b7d8a9fdaf9fac241d8958e758a382fa93bf23d79782c18dc69bfef7eb807510cc2d36 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/87/d6/d73e62627213f97cb995428dcfc9a1920c4da7dda3eea26780955466d092e6b78ad8eb398f29de7d1d82382cd5bca132bbb654ecb82ee5fe6edac31f4973 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/87/d6/d73e62627213f97cb995428dcfc9a1920c4da7dda3eea26780955466d092e6b78ad8eb398f29de7d1d82382cd5bca132bbb654ecb82ee5fe6edac31f4973 new file mode 100644 index 0000000..5fc352a Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/87/d6/d73e62627213f97cb995428dcfc9a1920c4da7dda3eea26780955466d092e6b78ad8eb398f29de7d1d82382cd5bca132bbb654ecb82ee5fe6edac31f4973 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/8b/4d/25009da4b35058afbae3363282ec172a012ee755f893dd05f5488e5a63e0051db94299a51ff4e13d75b7730ef5ba749c5b8b6642662cbdbf709cc0e897de b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/8b/4d/25009da4b35058afbae3363282ec172a012ee755f893dd05f5488e5a63e0051db94299a51ff4e13d75b7730ef5ba749c5b8b6642662cbdbf709cc0e897de new file mode 100644 index 0000000..a9192e6 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/8b/4d/25009da4b35058afbae3363282ec172a012ee755f893dd05f5488e5a63e0051db94299a51ff4e13d75b7730ef5ba749c5b8b6642662cbdbf709cc0e897de differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/9d/ce/f65a0abad88eebb435788b34f9fda692d33c72de4b6d9229dff79f3a0299276378d93bd358b26b5cdb87d47240345fb436bfe30be1ad79a5d52557957f8c b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/9d/ce/f65a0abad88eebb435788b34f9fda692d33c72de4b6d9229dff79f3a0299276378d93bd358b26b5cdb87d47240345fb436bfe30be1ad79a5d52557957f8c new file mode 100644 index 0000000..ca234e2 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/9d/ce/f65a0abad88eebb435788b34f9fda692d33c72de4b6d9229dff79f3a0299276378d93bd358b26b5cdb87d47240345fb436bfe30be1ad79a5d52557957f8c differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/ad/40/8e6d39cfdf6434f11daeb88aedeebf4f944a27b939adb9761c5bab399237658f7c5b9f07bedb5c97a6d01461c3000012e46184ed9e6cdbdf0dc40d97ee78 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/ad/40/8e6d39cfdf6434f11daeb88aedeebf4f944a27b939adb9761c5bab399237658f7c5b9f07bedb5c97a6d01461c3000012e46184ed9e6cdbdf0dc40d97ee78 new file mode 100644 index 0000000..ae72995 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/ad/40/8e6d39cfdf6434f11daeb88aedeebf4f944a27b939adb9761c5bab399237658f7c5b9f07bedb5c97a6d01461c3000012e46184ed9e6cdbdf0dc40d97ee78 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/b0/f7/6a0ba072315546bc5d729efbcca34fe8fa80f5557ec36878628edd5b1608ef0641c189be2de3d1a834385fd8d0ed6b8a1e50d95a19b4ade4aeea8d9f79e5 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/b0/f7/6a0ba072315546bc5d729efbcca34fe8fa80f5557ec36878628edd5b1608ef0641c189be2de3d1a834385fd8d0ed6b8a1e50d95a19b4ade4aeea8d9f79e5 new file mode 100644 index 0000000..eba7d27 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/b0/f7/6a0ba072315546bc5d729efbcca34fe8fa80f5557ec36878628edd5b1608ef0641c189be2de3d1a834385fd8d0ed6b8a1e50d95a19b4ade4aeea8d9f79e5 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/b5/a3/36e158a28a64ff5e7b716cfc89433086fa9e0428ea600f79b11705b7f261a3554adf11140e798e040c78dd9e9b6db5f1ee1d05c5c7e9533f4f10fa62daff b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/b5/a3/36e158a28a64ff5e7b716cfc89433086fa9e0428ea600f79b11705b7f261a3554adf11140e798e040c78dd9e9b6db5f1ee1d05c5c7e9533f4f10fa62daff new file mode 100644 index 0000000..4702300 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/b5/a3/36e158a28a64ff5e7b716cfc89433086fa9e0428ea600f79b11705b7f261a3554adf11140e798e040c78dd9e9b6db5f1ee1d05c5c7e9533f4f10fa62daff differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/c4/31/32bb5ae0dbdd38ef614419a2879f3c83ca1e501fe0255afb14e6132832d3e9ce62a5448d236982828121c362d6905993986cc69db92c82c05c18e27d4798 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/c4/31/32bb5ae0dbdd38ef614419a2879f3c83ca1e501fe0255afb14e6132832d3e9ce62a5448d236982828121c362d6905993986cc69db92c82c05c18e27d4798 new file mode 100644 index 0000000..74b6106 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/c4/31/32bb5ae0dbdd38ef614419a2879f3c83ca1e501fe0255afb14e6132832d3e9ce62a5448d236982828121c362d6905993986cc69db92c82c05c18e27d4798 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/c5/e8/f26be6d3fe3ffe47f0066b55ce7d1c4b98d5252ed9708d1b055082c5fb11dfcc496619c985c9dcb682aa88addeb6a6d2047f054ca1f775f6e3560fd2fb37 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/c5/e8/f26be6d3fe3ffe47f0066b55ce7d1c4b98d5252ed9708d1b055082c5fb11dfcc496619c985c9dcb682aa88addeb6a6d2047f054ca1f775f6e3560fd2fb37 new file mode 100644 index 0000000..32f5938 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/c5/e8/f26be6d3fe3ffe47f0066b55ce7d1c4b98d5252ed9708d1b055082c5fb11dfcc496619c985c9dcb682aa88addeb6a6d2047f054ca1f775f6e3560fd2fb37 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/df/5f/f4da6541e32b9053a69d2a4e52958ea6fa6c43c14ab92999326209cbaeb2a5ed3126d7edcfc83b43073da43afff0c59cf8d461ecbd5d40feee919a2c81bf b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/df/5f/f4da6541e32b9053a69d2a4e52958ea6fa6c43c14ab92999326209cbaeb2a5ed3126d7edcfc83b43073da43afff0c59cf8d461ecbd5d40feee919a2c81bf new file mode 100644 index 0000000..9a68800 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/df/5f/f4da6541e32b9053a69d2a4e52958ea6fa6c43c14ab92999326209cbaeb2a5ed3126d7edcfc83b43073da43afff0c59cf8d461ecbd5d40feee919a2c81bf differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/e3/cc/52ae2658620fbca979daf64c2a8c8573b90c62f8a616a76fb99c262760a3d3af42ef0fcf49aa4d8eaf9a20c73d0d50c7c88e1876948517fcbc97f41e2822 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/e3/cc/52ae2658620fbca979daf64c2a8c8573b90c62f8a616a76fb99c262760a3d3af42ef0fcf49aa4d8eaf9a20c73d0d50c7c88e1876948517fcbc97f41e2822 new file mode 100644 index 0000000..a5d3db0 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/e3/cc/52ae2658620fbca979daf64c2a8c8573b90c62f8a616a76fb99c262760a3d3af42ef0fcf49aa4d8eaf9a20c73d0d50c7c88e1876948517fcbc97f41e2822 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/e4/bf/93d5f317e112040686734f4fac4343e14d2dfa3542c598c5ed9754d9a38e1330044e20c1db66e7d23a3556b7f63adb606dc60c6d68d3a891b4c3bdfb2b64 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/e4/bf/93d5f317e112040686734f4fac4343e14d2dfa3542c598c5ed9754d9a38e1330044e20c1db66e7d23a3556b7f63adb606dc60c6d68d3a891b4c3bdfb2b64 new file mode 100644 index 0000000..b5ba31c Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/e4/bf/93d5f317e112040686734f4fac4343e14d2dfa3542c598c5ed9754d9a38e1330044e20c1db66e7d23a3556b7f63adb606dc60c6d68d3a891b4c3bdfb2b64 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/e7/a8/620093e1c10d51e22fb6d45545ed5f24483e73653747715b9114c5b4867ef9def55f40df31971e2e38f4f8c68187d19fe85404ee47cd808aa4930c8a5a1e b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/e7/a8/620093e1c10d51e22fb6d45545ed5f24483e73653747715b9114c5b4867ef9def55f40df31971e2e38f4f8c68187d19fe85404ee47cd808aa4930c8a5a1e new file mode 100644 index 0000000..ff1ab50 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/e7/a8/620093e1c10d51e22fb6d45545ed5f24483e73653747715b9114c5b4867ef9def55f40df31971e2e38f4f8c68187d19fe85404ee47cd808aa4930c8a5a1e differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/ed/15/0a7d781230c933b7a66e5e6a9aa4ebab2c63cf7e08fa97db9167b9511a896f934cb6ca871cdf92dd731282e4f419767d8332a8a8010d8da1672b4ca9a6ea b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/ed/15/0a7d781230c933b7a66e5e6a9aa4ebab2c63cf7e08fa97db9167b9511a896f934cb6ca871cdf92dd731282e4f419767d8332a8a8010d8da1672b4ca9a6ea new file mode 100644 index 0000000..bcf57c0 Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/ed/15/0a7d781230c933b7a66e5e6a9aa4ebab2c63cf7e08fa97db9167b9511a896f934cb6ca871cdf92dd731282e4f419767d8332a8a8010d8da1672b4ca9a6ea differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/f7/f2/9779950a289c2a09751d071149def3e1e3aece09c912066603c122bf12d574f742be88c27bcf1d92dc72d50c858541da8c22c6566e768689b6b5f1a5a168 b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/f7/f2/9779950a289c2a09751d071149def3e1e3aece09c912066603c122bf12d574f742be88c27bcf1d92dc72d50c858541da8c22c6566e768689b6b5f1a5a168 new file mode 100644 index 0000000..e773ceb Binary files /dev/null and b/vigilcare-dashboard/.npm-cache/_cacache/content-v2/sha512/f7/f2/9779950a289c2a09751d071149def3e1e3aece09c912066603c122bf12d574f742be88c27bcf1d92dc72d50c858541da8c22c6566e768689b6b5f1a5a168 differ diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/04/36/e69583c26351b3de961e0aba7df34c901276dea9a2b856e4fa00926e8854 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/04/36/e69583c26351b3de961e0aba7df34c901276dea9a2b856e4fa00926e8854 new file mode 100644 index 0000000..ca203c3 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/04/36/e69583c26351b3de961e0aba7df34c901276dea9a2b856e4fa00926e8854 @@ -0,0 +1,2 @@ + +2dcd301eaabc7f81c1959c1adbb82b85204e1298 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/rollup/-/rollup-4.62.0.tgz","integrity":"sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==","time":1785953912200,"size":571304,"metadata":{"time":1785953910664,"url":"https://registry.npmjs.org/rollup/-/rollup-4.62.0.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"ed80e4dd0876eb8251989b454a19ded6\"","last-modified":"Sat, 13 Jun 2026 08:32:26 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/04/df/36a31469755822907b76124883319ec864aa60a1986ce8d69e13b5c62701 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/04/df/36a31469755822907b76124883319ec864aa60a1986ce8d69e13b5c62701 new file mode 100644 index 0000000..9c65da8 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/04/df/36a31469755822907b76124883319ec864aa60a1986ce8d69e13b5c62701 @@ -0,0 +1,2 @@ + +a685b54110c7e12febc5aa1baf5334b7fbb9bd5d {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz","integrity":"sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==","time":1785953911384,"size":32601,"metadata":{"time":1785953910992,"url":"https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:32 GMT","etag":"\"09853320d153c1e10f72563196274767\"","last-modified":"Thu, 02 Apr 2026 16:43:47 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/0a/e8/1fd50b16b7a81f42b0cf8dc4e505e85a585cb357a015a4d963d1113c65f7 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/0a/e8/1fd50b16b7a81f42b0cf8dc4e505e85a585cb357a015a4d963d1113c65f7 new file mode 100644 index 0000000..9a4f118 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/0a/e8/1fd50b16b7a81f42b0cf8dc4e505e85a585cb357a015a4d963d1113c65f7 @@ -0,0 +1,2 @@ + +4e2fb49cf08db34c1a637a9f636d1d27ce4dd609 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.1.tgz","integrity":"sha512-xDEyu1rg290472FEGaKHnzyDyh5QH+AlWvsU5hMoMtPpzmKlRI0jaYKCgSHDYtaQWZOYbMaduSyCwFwY4n1HmA==","time":1785953912063,"size":1277372,"metadata":{"time":1785953910791,"url":"https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.1.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, must-revalidate, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"6ffe96a217c6bef180cec697051b79d6\"","last-modified":"Fri, 12 Jun 2026 17:59:12 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/0d/35/9e1f98072240b36b23bd4b0c2851d77c503e802626ed480a926932785b6c b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/0d/35/9e1f98072240b36b23bd4b0c2851d77c503e802626ed480a926932785b6c new file mode 100644 index 0000000..571bef2 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/0d/35/9e1f98072240b36b23bd4b0c2851d77c503e802626ed480a926932785b6c @@ -0,0 +1,2 @@ + +dc3f116e2fc0e24497fb31ef9dcf885e7783c990 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz","integrity":"sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==","time":1785953911295,"size":46389,"metadata":{"time":1785953911062,"url":"https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:32 GMT","etag":"\"62617ff0f132aa342fc74aa08d2d0d2e\"","last-modified":"Mon, 13 Apr 2026 20:41:46 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/24/53/ea4dd358e11afe9ef68c643b6a7f643c748872d2b708f7af6649062338da b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/24/53/ea4dd358e11afe9ef68c643b6a7f643c748872d2b708f7af6649062338da new file mode 100644 index 0000000..db62ccb --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/24/53/ea4dd358e11afe9ef68c643b6a7f643c748872d2b708f7af6649062338da @@ -0,0 +1,2 @@ + +93797821fbaaac28556311c548104081b86f3518 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz","integrity":"sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==","time":1785953911772,"size":427320,"metadata":{"time":1785953910956,"url":"https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"758a7d062fc209b0090ab072f4eee573\"","last-modified":"Tue, 05 May 2026 21:02:49 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/29/17/12ae86673945f9cfeb897f2a79022fad0402a9604325792a7b881bbc73a3 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/29/17/12ae86673945f9cfeb897f2a79022fad0402a9604325792a7b881bbc73a3 new file mode 100644 index 0000000..f9c4330 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/29/17/12ae86673945f9cfeb897f2a79022fad0402a9604325792a7b881bbc73a3 @@ -0,0 +1,2 @@ + +e67aed607cd01e02c6ebedcf28d21279491314cb {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/semver/-/semver-7.8.4.tgz","integrity":"sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==","time":1785953911977,"size":29325,"metadata":{"time":1785953910571,"url":"https://registry.npmjs.org/semver/-/semver-7.8.4.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"715397a31bd5c36494a3ed2a26bb88cb\"","last-modified":"Tue, 09 Jun 2026 23:50:05 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/2c/ee/3487b16022ae8a3a2b945a2f8567ecb5aeb0e2c5fef286e38d68203b25b2 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/2c/ee/3487b16022ae8a3a2b945a2f8567ecb5aeb0e2c5fef286e38d68203b25b2 new file mode 100644 index 0000000..de89084 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/2c/ee/3487b16022ae8a3a2b945a2f8567ecb5aeb0e2c5fef286e38d68203b25b2 @@ -0,0 +1,2 @@ + +6f1e2f039374ccb6ac28b858ec5c5618f121e92c {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz","integrity":"sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==","time":1785953911816,"size":67009,"metadata":{"time":1785953910583,"url":"https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"0b30e6ab9d64834c6bb441d62e617709\"","last-modified":"Tue, 17 Jun 2025 17:54:01 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/2d/23/9cb0f89da793aead50eab9755999e16b9b43e70c8a65007a0ad40e0033b3 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/2d/23/9cb0f89da793aead50eab9755999e16b9b43e70c8a65007a0ad40e0033b3 new file mode 100644 index 0000000..79dc2d7 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/2d/23/9cb0f89da793aead50eab9755999e16b9b43e70c8a65007a0ad40e0033b3 @@ -0,0 +1,2 @@ + +673d2f7f8226db25658360b0bb849a5ee603316c {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/glob/-/glob-10.5.0.tgz","integrity":"sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==","time":1785953912026,"size":74227,"metadata":{"time":1785953910963,"url":"https://registry.npmjs.org/glob/-/glob-10.5.0.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"35a8b606f227a3c84a8af5f3ebc03679\"","last-modified":"Tue, 18 Nov 2025 01:34:52 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/33/20/e86df570f0d5ccf74a9194726045695ee4a45581453c0cd08f3a32bf968b b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/33/20/e86df570f0d5ccf74a9194726045695ee4a45581453c0cd08f3a32bf968b new file mode 100644 index 0000000..b4aee30 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/33/20/e86df570f0d5ccf74a9194726045695ee4a45581453c0cd08f3a32bf968b @@ -0,0 +1,2 @@ + +d1d5fe102df1c35571fbb714c7ab02a01cec6ba5 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz","integrity":"sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==","time":1785953912465,"size":3699964,"metadata":{"time":1785953910818,"url":"https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"cd82608915af34d4260109fc1ad6f7b8\"","last-modified":"Mon, 09 Mar 2026 04:23:34 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/3b/17/f45e412c29aacbb328f9d4d864101d74f4ed118dfdb7fbf9054ad9586eac b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/3b/17/f45e412c29aacbb328f9d4d864101d74f4ed118dfdb7fbf9054ad9586eac new file mode 100644 index 0000000..1e55b9a --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/3b/17/f45e412c29aacbb328f9d4d864101d74f4ed118dfdb7fbf9054ad9586eac @@ -0,0 +1,2 @@ + +c011da6f5a5f0bfe35f00a5177c4326ee481cfaa {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz","integrity":"sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==","time":1785953911307,"size":17360,"metadata":{"time":1785953911069,"url":"https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:32 GMT","etag":"\"8926ea0bf6fa92f4c76f5a9f8c801a3f\"","last-modified":"Tue, 31 Mar 2026 10:24:54 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/3d/3c/62cff5b36a29da1b9565508f580da10fb6fc33759a55d38d31f3f698e7c4 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/3d/3c/62cff5b36a29da1b9565508f580da10fb6fc33759a55d38d31f3f698e7c4 new file mode 100644 index 0000000..594e4ff --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/3d/3c/62cff5b36a29da1b9565508f580da10fb6fc33759a55d38d31f3f698e7c4 @@ -0,0 +1,3 @@ + +497b3f086f894cbc8d2c76bb974449be9e3c2ff4 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/vite/-/vite-7.3.5.tgz","integrity":"sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==","time":1785953912118,"size":543193,"metadata":{"time":1785953911134,"url":"https://registry.npmjs.org/vite/-/vite-7.3.5.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:32 GMT","etag":"\"366ac74512ac7cdc06673bd7362a157f\"","last-modified":"Mon, 01 Jun 2026 10:19:33 GMT"},"options":{"compress":true}}} +ee9f9593cef8c446efbf7c8aa2c1b6c271b08575 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/vite/-/vite-7.3.5.tgz","integrity":"sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==","time":1785953912122,"size":543193,"metadata":{"time":1785953911109,"url":"https://registry.npmjs.org/vite/-/vite-7.3.5.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:32 GMT","etag":"\"366ac74512ac7cdc06673bd7362a157f\"","last-modified":"Mon, 01 Jun 2026 10:19:33 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/3d/6a/255369c8b2fd2d70cd81c0bb1447f8596a8adfc933bcfd43aa4d5427bd72 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/3d/6a/255369c8b2fd2d70cd81c0bb1447f8596a8adfc933bcfd43aa4d5427bd72 new file mode 100644 index 0000000..4329d8c --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/3d/6a/255369c8b2fd2d70cd81c0bb1447f8596a8adfc933bcfd43aa4d5427bd72 @@ -0,0 +1,2 @@ + +ea25a12abc7092163c99cc73e4168e53f741e14b {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz","integrity":"sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==","time":1785953911429,"size":9355,"metadata":{"time":1785953910761,"url":"https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"e0aae139db7a2b9ce9182e755fb7e054\"","last-modified":"Sat, 04 May 2024 01:10:39 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/44/f0/bd58606e6a186e23336fae0ee8f42b3ea46b68e030fd73238295bb0eab05 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/44/f0/bd58606e6a186e23336fae0ee8f42b3ea46b68e030fd73238295bb0eab05 new file mode 100644 index 0000000..fde0dc0 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/44/f0/bd58606e6a186e23336fae0ee8f42b3ea46b68e030fd73238295bb0eab05 @@ -0,0 +1,2 @@ + +2c5baf041c1d5cb99a633042b26ba55b2d984ab3 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/vitest/-/vitest-3.2.6.tgz","integrity":"sha512-xejya+bT/j/+R/AGa1XOfRxLmNUlLtlwjRsFUILF+xHfzElmGcmFydy2gqqIrd62ptIEfwVMofd19uNWD9L7Nw==","time":1785953912409,"size":335129,"metadata":{"time":1785953910626,"url":"https://registry.npmjs.org/vitest/-/vitest-3.2.6.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"d56e8d61c0afbadb89f9ab8f60870573\"","last-modified":"Mon, 01 Jun 2026 09:39:05 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/4d/f4/09762996a103ca714750b2b00bee2a9b74f61dce909942f7acb302407e75 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/4d/f4/09762996a103ca714750b2b00bee2a9b74f61dce909942f7acb302407e75 new file mode 100644 index 0000000..aca66d3 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/4d/f4/09762996a103ca714750b2b00bee2a9b74f61dce909942f7acb302407e75 @@ -0,0 +1,2 @@ + +28e162e7303833ccf27101cccde30bdb0bffdf10 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz","integrity":"sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==","time":1785953911896,"size":438527,"metadata":{"time":1785953910674,"url":"https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, must-revalidate, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"3581d99c820bf686b8c59131895ac7cf\"","last-modified":"Mon, 25 May 2026 11:16:21 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/59/c6/88f16af6bb6d5997afb1e2a18a8d3daae76ba8fb6b2f4160b885851fbe02 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/59/c6/88f16af6bb6d5997afb1e2a18a8d3daae76ba8fb6b2f4160b885851fbe02 new file mode 100644 index 0000000..f8d7151 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/59/c6/88f16af6bb6d5997afb1e2a18a8d3daae76ba8fb6b2f4160b885851fbe02 @@ -0,0 +1,2 @@ + +19838e61dfa5067eb59d05b305614d96bbd1cf89 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz","integrity":"sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==","time":1785953912512,"size":4746453,"metadata":{"time":1785953910925,"url":"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, must-revalidate, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"0cb4b5c1243dce10cc2efa4dd4c5bc59\"","last-modified":"Thu, 02 Apr 2026 16:43:43 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/6c/d1/eacf1bc6656c90469010990afa8d3eea7e8c2154b0ee8b7217123eb2ac45 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/6c/d1/eacf1bc6656c90469010990afa8d3eea7e8c2154b0ee8b7217123eb2ac45 new file mode 100644 index 0000000..3eed9c5 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/6c/d1/eacf1bc6656c90469010990afa8d3eea7e8c2154b0ee8b7217123eb2ac45 @@ -0,0 +1,2 @@ + +be1ff74de135f502f26d7a49bda384aa28ff8776 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz","integrity":"sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==","time":1785953911322,"size":3205,"metadata":{"time":1785953910747,"url":"https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"966c194bda253ce0a4f6a8301b6828ee\"","last-modified":"Mon, 08 Jul 2024 12:57:25 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/7c/16/27195d31f9c183881aff1ea0bb5720627c476c496921d907188baebc0799 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/7c/16/27195d31f9c183881aff1ea0bb5720627c476c496921d907188baebc0799 new file mode 100644 index 0000000..81d714c --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/7c/16/27195d31f9c183881aff1ea0bb5720627c476c496921d907188baebc0799 @@ -0,0 +1,2 @@ + +05fe4f0bf572f7d20fdc303b6b064bccabbc6c3c {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz","integrity":"sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==","time":1785953912687,"size":8873207,"metadata":{"time":1785953910656,"url":"https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, must-revalidate, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"76d28d6bf8f31554d587cd494cd8045e\"","last-modified":"Wed, 27 May 2026 11:47:02 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/7e/fa/a49b2021b90f1f455032926e78758755c16a75b38b6842f87405d8502cf6 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/7e/fa/a49b2021b90f1f455032926e78758755c16a75b38b6842f87405d8502cf6 new file mode 100644 index 0000000..7519274 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/7e/fa/a49b2021b90f1f455032926e78758755c16a75b38b6842f87405d8502cf6 @@ -0,0 +1,2 @@ + +7c3a3473b73bd8f3dfb90d58b6bd3e27c8d1ec32 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.0.tgz","integrity":"sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA==","time":1785953911912,"size":881262,"metadata":{"time":1785953910876,"url":"https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.0.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, must-revalidate, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"a806648ad3d705c9f54816b2f4771223\"","last-modified":"Sat, 13 Jun 2026 08:31:58 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/8a/55/c86f96b7fdfc644772a1a7ec61a9b90db4ebc2bbdfad9b60c018adea74f1 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/8a/55/c86f96b7fdfc644772a1a7ec61a9b90db4ebc2bbdfad9b60c018adea74f1 new file mode 100644 index 0000000..aaad849 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/8a/55/c86f96b7fdfc644772a1a7ec61a9b90db4ebc2bbdfad9b60c018adea74f1 @@ -0,0 +1,2 @@ + +94da227b56946879a36cc2227fd492f384ea94d0 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz","integrity":"sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==","time":1785953912291,"size":728769,"metadata":{"time":1785953910555,"url":"https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"2b85be9f8c2af7046d1181f3d873eda4\"","last-modified":"Sat, 12 Apr 2025 07:09:23 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/8f/0f/99f309ce8c4c0d5e3f9ab31110838e19593c5c5c8eea99e413cbf26bdfad b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/8f/0f/99f309ce8c4c0d5e3f9ab31110838e19593c5c5c8eea99e413cbf26bdfad new file mode 100644 index 0000000..434deb4 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/8f/0f/99f309ce8c4c0d5e3f9ab31110838e19593c5c5c8eea99e413cbf26bdfad @@ -0,0 +1,2 @@ + +06f0683b26e0225edaae1d86d37467b03088b647 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz","integrity":"sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==","time":1785953912001,"size":174936,"metadata":{"time":1785953910523,"url":"https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"dd35902285a469bef4b6341d2d899174\"","last-modified":"Wed, 27 May 2026 11:49:17 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/91/b3/e299c26ffedb197f51cc9e02ad3aa7e99a4423c7017bc34eb3c7a05bbe7f b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/91/b3/e299c26ffedb197f51cc9e02ad3aa7e99a4423c7017bc34eb3c7a05bbe7f new file mode 100644 index 0000000..e249d1a --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/91/b3/e299c26ffedb197f51cc9e02ad3aa7e99a4423c7017bc34eb3c7a05bbe7f @@ -0,0 +1,2 @@ + +f2c512257fcfeae452af0e1a76c161ac93881296 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/vite/-/vite-8.0.16.tgz","integrity":"sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==","time":1785953912135,"size":538260,"metadata":{"time":1785953910603,"url":"https://registry.npmjs.org/vite/-/vite-8.0.16.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"1c1ff0e0d13d58d1692d08a5ecc097e2\"","last-modified":"Mon, 01 Jun 2026 09:50:47 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/a6/b9/b6145de4e32c2a4dfa687b1fa6294d260c35099572a12bed794383d2e3b0 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/a6/b9/b6145de4e32c2a4dfa687b1fa6294d260c35099572a12bed794383d2e3b0 new file mode 100644 index 0000000..887f565 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/a6/b9/b6145de4e32c2a4dfa687b1fa6294d260c35099572a12bed794383d2e3b0 @@ -0,0 +1,2 @@ + +95545cc9f8501d418b345c7683775f3ff8c1a1c1 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.7.tgz","integrity":"sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw==","time":1785953911310,"size":9681,"metadata":{"time":1785953910996,"url":"https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.7.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:32 GMT","etag":"\"ab7e2817e97f21770839622bfc33fc36\"","last-modified":"Fri, 27 Feb 2026 23:16:49 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/a9/9d/0c48189d2f5f50efd633df6a1da383bb27ec954d9369483ad8b0069537d5 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/a9/9d/0c48189d2f5f50efd633df6a1da383bb27ec954d9369483ad8b0069537d5 new file mode 100644 index 0000000..3f1e217 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/a9/9d/0c48189d2f5f50efd633df6a1da383bb27ec954d9369483ad8b0069537d5 @@ -0,0 +1,2 @@ + +309290abb0f4672b228fcc24f5000f83b4b09379 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.0.tgz","integrity":"sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA==","time":1785953911966,"size":982610,"metadata":{"time":1785953910836,"url":"https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.0.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, must-revalidate, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"ef2a6aa27e252652e8e20b9df1f5c864\"","last-modified":"Sat, 13 Jun 2026 08:32:02 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/ab/42/0be128f60ae6e3ec0d73e8305a1cec88343e390b113f7697031fc1904501 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/ab/42/0be128f60ae6e3ec0d73e8305a1cec88343e390b113f7697031fc1904501 new file mode 100644 index 0000000..9425753 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/ab/42/0be128f60ae6e3ec0d73e8305a1cec88343e390b113f7697031fc1904501 @@ -0,0 +1,2 @@ + +86545026ef44375b1a05070f481eb2f0e28927ea {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz","integrity":"sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==","time":1785953912158,"size":196338,"metadata":{"time":1785953910951,"url":"https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"25ec268915df89e2c9147cc847cfa0ae\"","last-modified":"Thu, 27 Feb 2025 17:54:02 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/b1/90/b179097bf33c30fcd5322583f45c0ffe91cb5b4b04eba298df4fb2468743 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/b1/90/b179097bf33c30fcd5322583f45c0ffe91cb5b4b04eba298df4fb2468743 new file mode 100644 index 0000000..e2a46e9 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/b1/90/b179097bf33c30fcd5322583f45c0ffe91cb5b4b04eba298df4fb2468743 @@ -0,0 +1,2 @@ + +fcdf5dec3ff20265222963c02402cccf93cb436e {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz","integrity":"sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==","time":1785953911336,"size":5240,"metadata":{"time":1785953910578,"url":"https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"525ca79ade2ccfef596412f4ffa432c3\"","last-modified":"Tue, 16 Dec 2025 15:17:59 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/b4/9d/5a271b1898a503a6f8a6b2361235fd7539e9ae1aa5622d3e78124d1a0c34 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/b4/9d/5a271b1898a503a6f8a6b2361235fd7539e9ae1aa5622d3e78124d1a0c34 new file mode 100644 index 0000000..18c8fbc --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/b4/9d/5a271b1898a503a6f8a6b2361235fd7539e9ae1aa5622d3e78124d1a0c34 @@ -0,0 +1,2 @@ + +a631269bc2d1a106a8dccf568adece63694153ef {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/which/-/which-2.0.2.tgz","integrity":"sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==","time":1785953911289,"size":4496,"metadata":{"time":1785953910542,"url":"https://registry.npmjs.org/which/-/which-2.0.2.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"9556a736013ff5223cc9731d9f32b55f\"","last-modified":"Mon, 18 Nov 2019 22:26:18 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/c2/86/aacea7c15f9ed9463493c08ab280a61392c2ac3dd7a91d50eb808574e493 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/c2/86/aacea7c15f9ed9463493c08ab280a61392c2ac3dd7a91d50eb808574e493 new file mode 100644 index 0000000..3936a65 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/c2/86/aacea7c15f9ed9463493c08ab280a61392c2ac3dd7a91d50eb808574e493 @@ -0,0 +1,2 @@ + +24be7f0adf6dd77562f46dea0028063dd47e1c3e {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.38.tgz","integrity":"sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==","time":1785953911308,"size":53370,"metadata":{"time":1785953911059,"url":"https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.38.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:32 GMT","etag":"\"49edc750f1e546f945131df311d72e52\"","last-modified":"Wed, 17 Jun 2026 16:56:26 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/c5/e5/cee8daa2b5fad734d6884846ab0d74154b58356f36fb74808e539d26ce7d b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/c5/e5/cee8daa2b5fad734d6884846ab0d74154b58356f36fb74808e539d26ce7d new file mode 100644 index 0000000..ac502e3 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/c5/e5/cee8daa2b5fad734d6884846ab0d74154b58356f36fb74808e539d26ce7d @@ -0,0 +1,2 @@ + +b1906c92556ec267f05fac0dbe5dfc0eced263de {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.6.tgz","integrity":"sha512-EZOrpDbkKotFAP7wPAQV1UIyoGOk4oX7ynWhBhLB7v+meMHbQhU16oPpIYGTTe4oFlhpryGpgpcZP/sin3hYuw==","time":1785953911308,"size":39414,"metadata":{"time":1785953911103,"url":"https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.6.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, must-revalidate, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:32 GMT","etag":"\"31c7953660299e731ee70e98354f398f\"","last-modified":"Mon, 01 Jun 2026 09:38:48 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/c8/8c/f1df25ed2ad401a66308109087186d07c656cc81d81226779e4fef82dc37 b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/c8/8c/f1df25ed2ad401a66308109087186d07c656cc81d81226779e4fef82dc37 new file mode 100644 index 0000000..92efb8f --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/c8/8c/f1df25ed2ad401a66308109087186d07c656cc81d81226779e4fef82dc37 @@ -0,0 +1,2 @@ + +e88d176a08778649375e12b00ae8e4c22c0a8f0c {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/nanoid/-/nanoid-3.3.13.tgz","integrity":"sha512-sPdqC6ByMVVGvF1ynvvMo0/o+oD1VX7DaHhijt1bFgjvBkHBib4t49GoNDhf2NDta4oeUNlaGbSt5K7qjZ955Q==","time":1785953911305,"size":7167,"metadata":{"time":1785953910846,"url":"https://registry.npmjs.org/nanoid/-/nanoid-3.3.13.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:31 GMT","etag":"\"cac9bb6bc6055fc1fcf99c3135dfa5f3\"","last-modified":"Thu, 18 Jun 2026 17:29:54 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_cacache/index-v5/d9/83/5f0f5600d4f6c8cd5287991a72adc9ee514c0139a77a26e8dd6e3ef107fe b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/d9/83/5f0f5600d4f6c8cd5287991a72adc9ee514c0139a77a26e8dd6e3ef107fe new file mode 100644 index 0000000..f4a7ce1 --- /dev/null +++ b/vigilcare-dashboard/.npm-cache/_cacache/index-v5/d9/83/5f0f5600d4f6c8cd5287991a72adc9ee514c0139a77a26e8dd6e3ef107fe @@ -0,0 +1,2 @@ + +bb6ac3a8e022d5572d54b2f5d3932c2d21af0188 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz","integrity":"sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==","time":1785953911308,"size":3965,"metadata":{"time":1785953911137,"url":"https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, immutable, max-age=31557600","content-type":"application/octet-stream","date":"Wed, 05 Aug 2026 18:18:32 GMT","etag":"\"5d5a51f9670467a8edaef4269b413647\"","last-modified":"Fri, 20 Jan 2023 02:27:13 GMT"},"options":{"compress":true}}} \ No newline at end of file diff --git a/vigilcare-dashboard/.npm-cache/_update-notifier-last-checked b/vigilcare-dashboard/.npm-cache/_update-notifier-last-checked new file mode 100644 index 0000000..e69de29 diff --git a/vigilcare-dashboard/package-lock.json b/vigilcare-dashboard/package-lock.json index a68d5b1..c005ab7 100644 --- a/vigilcare-dashboard/package-lock.json +++ b/vigilcare-dashboard/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "vigilcare-dashboard", "version": "0.0.0", + "license": "SEE LICENSE IN LICENSE", "dependencies": { "@vueuse/core": "^14.3.0", "chart.js": "^4.5.1", diff --git a/vigilcare-dashboard/package.json b/vigilcare-dashboard/package.json index a1b0a61..083d68f 100644 --- a/vigilcare-dashboard/package.json +++ b/vigilcare-dashboard/package.json @@ -10,6 +10,7 @@ "build": "vite build", "preview": "vite preview", "test": "vitest run", + "test:unit": "vitest run", "test:watch": "vitest" }, "dependencies": { diff --git a/vigilcare-dashboard/src/__tests__/PatientBanner.test.js b/vigilcare-dashboard/src/__tests__/PatientBanner.test.js index f95969a..d92683f 100644 --- a/vigilcare-dashboard/src/__tests__/PatientBanner.test.js +++ b/vigilcare-dashboard/src/__tests__/PatientBanner.test.js @@ -40,17 +40,15 @@ describe('PatientBanner', () => { expect(strip.classes().join(' ')).toMatch(/bg-red-600/) }) - it('showsNkdaWhenNoAllergies', () => { + it('showsSimChipWhenPatientIsSimulated', () => { const wrapper = mount(PatientBanner, { props: { encounter: { ...encounter, - patient: { ...encounter.patient, allergies: null }, + patient: { ...encounter.patient, isSimulated: true }, }, }, }) - expect(wrapper.text()).toContain('NKDA') - const strip = wrapper.find('[role="status"]') - expect(strip.classes().join(' ')).not.toMatch(/bg-red-600/) + expect(wrapper.text()).toContain('SIM') }) }) diff --git a/vigilcare-dashboard/src/__tests__/ScenarioCard.test.js b/vigilcare-dashboard/src/__tests__/ScenarioCard.test.js new file mode 100644 index 0000000..dc44f96 --- /dev/null +++ b/vigilcare-dashboard/src/__tests__/ScenarioCard.test.js @@ -0,0 +1,73 @@ +import { describe, it, expect } from 'vitest' +import { mount } from '@vue/test-utils' +import ScenarioCard from '@/components/simulation/ScenarioCard.vue' + +const baseScenario = { + id: 'stable-baseline-01', + name: 'Stable Baseline — Routine Inpatient Monitoring', + description: '52-year-old female admitted for elective cholecystectomy. Completely uneventful 8-hour post-op monitoring period with all vitals remaining normal throughout. This is a CONTROL scenario that validates the system does NOT generate false alerts on a stable patient.', + durationMinutes: 480, + tags: ['stable', 'baseline', 'control', 'surgery'], + department: 'Surgery', + eventCount: 312, +} + +describe('ScenarioCard', () => { + it('rendersMetadata', () => { + const wrapper = mount(ScenarioCard, { + props: { scenario: baseScenario }, + }) + + expect(wrapper.text()).toContain(baseScenario.name) + expect(wrapper.text()).toContain('8 hours of monitoring') + expect(wrapper.text()).toContain('Surgery') + expect(wrapper.text()).toContain('312 events') + expect(wrapper.text()).toContain('control') + }) + + it('labelsControlScenario', () => { + const wrapper = mount(ScenarioCard, { + props: { scenario: baseScenario }, + }) + expect(wrapper.text()).toContain('Control scenario — should stay quiet') + }) + + it('labelsRealDataScenario', () => { + const wrapper = mount(ScenarioCard, { + props: { + scenario: { + ...baseScenario, + id: 'mimic-case-01', + tags: ['mimic-iv', 'real-data', 'sepsis'], + }, + }, + }) + expect(wrapper.text()).toContain('Real de-identified ICU record') + }) + + it('disablesStartAtConcurrencyLimit', async () => { + const wrapper = mount(ScenarioCard, { + props: { + scenario: baseScenario, + atConcurrencyLimit: true, + maxConcurrentRuns: 2, + }, + }) + + const startBtn = wrapper.findAll('button').find(b => b.text() === 'Start') + expect(startBtn.attributes('disabled')).toBeDefined() + expect(startBtn.attributes('title')).toMatch(/Concurrency limit reached/) + + await startBtn.trigger('click') + expect(wrapper.emitted('start')).toBeUndefined() + }) + + it('emitsStartWithScenarioId', async () => { + const wrapper = mount(ScenarioCard, { + props: { scenario: baseScenario }, + }) + const startBtn = wrapper.findAll('button').find(b => b.text() === 'Start') + await startBtn.trigger('click') + expect(wrapper.emitted('start')).toEqual([['stable-baseline-01']]) + }) +}) diff --git a/vigilcare-dashboard/src/__tests__/SimulationControlView.test.js b/vigilcare-dashboard/src/__tests__/SimulationControlView.test.js new file mode 100644 index 0000000..97ed9e2 --- /dev/null +++ b/vigilcare-dashboard/src/__tests__/SimulationControlView.test.js @@ -0,0 +1,100 @@ +import { describe, it, expect, beforeEach, vi } from 'vitest' +import { mount } from '@vue/test-utils' +import { createPinia, setActivePinia } from 'pinia' +import SimulationControlView from '@/views/SimulationControlView.vue' + +const { + fetchScenarios, + fetchRuns, + fetchSimulationConfig, + startRun, + stopRun, +} = vi.hoisted(() => ({ + fetchScenarios: vi.fn(), + fetchRuns: vi.fn(), + fetchSimulationConfig: vi.fn(), + startRun: vi.fn(), + stopRun: vi.fn(), +})) + +vi.mock('@/api/simulation', () => ({ + fetchScenarios, + fetchRuns, + fetchSimulationConfig, + startRun, + stopRun, + fetchRun: vi.fn(), +})) + +vi.mock('@/stores/ward', () => ({ + useWardStore: () => ({ loadEncounters: vi.fn() }), +})) + +const scenarios = [ + { + id: 'uti-sepsis-elderly-01', + name: 'UTI Sepsis Elderly', + description: 'Elderly patient with UTI progressing to sepsis.', + durationMinutes: 480, + tags: ['sepsis', 'uti'], + department: 'GeneralMedicine', + eventCount: 200, + }, + { + id: 'stable-baseline-01', + name: 'Stable Baseline', + description: 'Control scenario.', + durationMinutes: 480, + tags: ['control', 'stable'], + department: 'Surgery', + eventCount: 312, + }, +] + +describe('SimulationControlView', () => { + beforeEach(() => { + vi.clearAllMocks() + setActivePinia(createPinia()) + fetchScenarios.mockResolvedValue(scenarios) + fetchRuns.mockResolvedValue([]) + fetchSimulationConfig.mockResolvedValue({ + enabled: true, + maxSpeed: 600, + maxConcurrentRuns: 2, + }) + }) + + it('showsWallClockDurationForSelectedScenarioSpeed', async () => { + const wrapper = mount(SimulationControlView) + await vi.waitFor(() => expect(wrapper.text()).toContain('UTI Sepsis Elderly')) + + // Default Fast (60×): 480 sim minutes → 8 wall-clock minutes + expect(wrapper.text()).toMatch(/8 minutes for selected scenario/) + + const realTime = wrapper.findAll('button').find(b => b.text().includes('Real time')) + expect(realTime.text()).toMatch(/8 hours for selected scenario/) + + const instant = wrapper.findAll('button').find(b => b.text().includes('Instant')) + expect(instant.text()).toMatch(/1 minute for selected scenario/) + }) + + + it('filtersCatalogueByTag', async () => { + const wrapper = mount(SimulationControlView) + await vi.waitFor(() => expect(wrapper.text()).toContain('Stable Baseline')) + + const sepsisChip = wrapper.findAll('button').find(b => b.text() === 'sepsis') + await sepsisChip.trigger('click') + + expect(wrapper.text()).toContain('UTI Sepsis Elderly') + expect(wrapper.text()).not.toContain('Stable Baseline') + }) + + it('showsEmptyStateWhenCatalogueMissing', async () => { + fetchScenarios.mockResolvedValue([]) + const wrapper = mount(SimulationControlView) + await vi.waitFor(() => + expect(wrapper.text()).toContain('Simulation:ScenarioDirectory'), + ) + }) +}) diff --git a/vigilcare-dashboard/src/__tests__/SimulationModeBanner.test.js b/vigilcare-dashboard/src/__tests__/SimulationModeBanner.test.js new file mode 100644 index 0000000..36b9ac8 --- /dev/null +++ b/vigilcare-dashboard/src/__tests__/SimulationModeBanner.test.js @@ -0,0 +1,25 @@ +import { describe, it, expect, beforeEach } from 'vitest' +import { mount } from '@vue/test-utils' +import { createPinia, setActivePinia } from 'pinia' +import SimulationModeBanner from '@/components/simulation/SimulationModeBanner.vue' +import { useSimulationStore } from '@/stores/simulation' + +describe('SimulationModeBanner', () => { + beforeEach(() => { + setActivePinia(createPinia()) + }) + + it('rendersWhenEnabled', () => { + useSimulationStore().enabled = true + const wrapper = mount(SimulationModeBanner) + expect(wrapper.text()).toContain('SIMULATION MODE') + expect(wrapper.find('[role="status"]').exists()).toBe(true) + }) + + it('isAbsentWhenDisabled', () => { + useSimulationStore().enabled = false + const wrapper = mount(SimulationModeBanner) + expect(wrapper.find('[role="status"]').exists()).toBe(false) + expect(wrapper.text()).toBe('') + }) +}) diff --git a/vigilcare-dashboard/src/__tests__/SimulationRunPanel.test.js b/vigilcare-dashboard/src/__tests__/SimulationRunPanel.test.js new file mode 100644 index 0000000..d300bab --- /dev/null +++ b/vigilcare-dashboard/src/__tests__/SimulationRunPanel.test.js @@ -0,0 +1,75 @@ +import { describe, it, expect } from 'vitest' +import { mount } from '@vue/test-utils' +import SimulationRunPanel from '@/components/simulation/SimulationRunPanel.vue' + +const RouterLinkStub = { + props: ['to'], + template: '', +} + +const activeRun = { + runId: 'run-1', + scenarioId: 'uti-sepsis-elderly-01', + scenarioName: 'UTI Sepsis Elderly', + status: 'RUNNING', + speed: 60, + encounterId: 'enc-99', + patientDisplayName: 'Mary Chen', + startedAt: '2026-08-05T10:00:00Z', + elapsedRealSeconds: 125, + lastOffsetMinutes: 200, + totalOffsetMinutes: 480, + progressPercent: 41.6, + observationsSent: 40, + medicationsSent: 2, + ordersPlaced: 1, + failureReason: null, +} + +function mountPanel(props) { + return mount(SimulationRunPanel, { + props, + global: { stubs: { RouterLink: RouterLinkStub } }, + }) +} + +describe('SimulationRunPanel', () => { + it('showsProgressAndSimClock', () => { + const wrapper = mountPanel({ activeRuns: [activeRun], recentRuns: [] }) + expect(wrapper.text()).toContain('03:20 of 08:00 elapsed') + expect(wrapper.text()).toContain('42%') + expect(wrapper.text()).toContain('60×') + expect(wrapper.find('[role="progressbar"]').attributes('aria-valuenow')).toBe('42') + }) + + it('linksToPatientEncounter', () => { + const wrapper = mountPanel({ activeRuns: [activeRun], recentRuns: [] }) + const link = wrapper.find('a[href="/patients/enc-99"]') + expect(link.exists()).toBe(true) + expect(link.text()).toContain('Mary Chen') + }) + + it('requiresStopConfirmBeforeEmitting', async () => { + const wrapper = mountPanel({ activeRuns: [activeRun], recentRuns: [] }) + + await wrapper.findAll('button').find(b => b.text() === 'Stop').trigger('click') + expect(wrapper.emitted('stop')).toBeUndefined() + expect(wrapper.text()).toContain('Stopping leaves the patient on the ward') + + await wrapper.findAll('button').find(b => b.text() === 'Confirm stop').trigger('click') + expect(wrapper.emitted('stop')).toEqual([['run-1']]) + }) + + it('showsFailureReasonForFailedRecentRun', () => { + const wrapper = mountPanel({ + activeRuns: [], + recentRuns: [{ + ...activeRun, + status: 'FAILED', + failureReason: 'Loopback authentication failed', + }], + }) + expect(wrapper.text()).toContain('Failed') + expect(wrapper.text()).toContain('Loopback authentication failed') + }) +}) diff --git a/vigilcare-dashboard/src/__tests__/roleAccess.test.js b/vigilcare-dashboard/src/__tests__/roleAccess.test.js index 0f086b5..d1e7fa7 100644 --- a/vigilcare-dashboard/src/__tests__/roleAccess.test.js +++ b/vigilcare-dashboard/src/__tests__/roleAccess.test.js @@ -1,5 +1,15 @@ -import { describe, it, expect } from 'vitest' -import { canAccessOps, filterNavLinks, isDashboardRole, roleCanAccessRoute, MAIN_NAV_LINKS } from '@/composables/roleAccess' +import { describe, it, expect, beforeEach } from 'vitest' +import { createPinia, setActivePinia } from 'pinia' +import { + canAccessOps, + filterNavLinks, + isDashboardRole, + roleCanAccessRoute, + MAIN_NAV_LINKS, + useRoleAccess, +} from '@/composables/roleAccess' +import { useAuthStore } from '@/stores/auth' +import { useSimulationStore } from '@/stores/simulation' describe('roleAccess', () => { it('filtersNavLinksByRole', () => { @@ -29,3 +39,50 @@ describe('roleAccess', () => { expect(canAccessOps('INTEGRATION')).toBe(false) }) }) + +describe('useRoleAccess simulation nav', () => { + beforeEach(() => { + setActivePinia(createPinia()) + const auth = useAuthStore() + auth.token = 'tok' + auth.user = { + userId: '1', + username: 'nurse', + displayName: 'Nurse', + role: 'NURSE', + } + }) + + it('includesSimulationLinkOnlyWhenEnabled', () => { + const sim = useSimulationStore() + const { mainNavLinks } = useRoleAccess() + + sim.enabled = false + expect(mainNavLinks.value.some(l => l.to === '/simulation')).toBe(false) + + sim.enabled = true + expect(mainNavLinks.value.some(l => l.to === '/simulation')).toBe(true) + }) + + it('omitsSimulationLinkWhenDisabledRegardlessOfRole', () => { + const auth = useAuthStore() + const sim = useSimulationStore() + sim.enabled = false + + for (const role of ['NURSE', 'PHYSICIAN', 'ADMIN']) { + auth.user = { ...auth.user, role } + const { mainNavLinks } = useRoleAccess() + expect(mainNavLinks.value.some(l => l.to === '/simulation')).toBe(false) + } + }) + + it('movesQualityToOverflowWhenSimulationEnabledOnMobile', () => { + const sim = useSimulationStore() + const { mobileNavLinks, mobileOverflowLinks } = useRoleAccess() + + sim.enabled = true + expect(mobileNavLinks.value.some(l => l.to === '/simulation')).toBe(true) + expect(mobileNavLinks.value.some(l => l.to === '/admin/reconciliation')).toBe(false) + expect(mobileOverflowLinks.value.some(l => l.to === '/admin/reconciliation')).toBe(true) + }) +}) diff --git a/vigilcare-dashboard/src/__tests__/simulationRouter.test.js b/vigilcare-dashboard/src/__tests__/simulationRouter.test.js new file mode 100644 index 0000000..a944e24 --- /dev/null +++ b/vigilcare-dashboard/src/__tests__/simulationRouter.test.js @@ -0,0 +1,61 @@ +import { describe, it, expect, beforeEach, vi } from 'vitest' +import { createPinia, setActivePinia } from 'pinia' +import { useAuthStore } from '@/stores/auth' +import { useSimulationStore } from '@/stores/simulation' + +const { fetchSimulationConfig } = vi.hoisted(() => ({ + fetchSimulationConfig: vi.fn(), +})) + +vi.mock('@/api/simulation', () => ({ + fetchSimulationConfig, + fetchScenarios: vi.fn(), + fetchRuns: vi.fn(), + startRun: vi.fn(), + stopRun: vi.fn(), + fetchRun: vi.fn(), +})) + +describe('simulation router guard', () => { + beforeEach(async () => { + vi.clearAllMocks() + setActivePinia(createPinia()) + + const auth = useAuthStore() + auth.token = 'test-token' + auth.user = { + userId: 'u1', + username: 'nurse', + displayName: 'Test Nurse', + role: 'NURSE', + } + + fetchSimulationConfig.mockResolvedValue({ enabled: false }) + + const { default: router } = await import('@/router') + // Reset to a known route; ignore failures from first load + await router.push('/ward').catch(() => {}) + await router.isReady() + }) + + it('redirectsDirectSimulationNavigationWhenDisabled', async () => { + const sim = useSimulationStore() + sim.enabled = false + + const { default: router } = await import('@/router') + await router.push('/simulation') + + expect(router.currentRoute.value.path).toBe('/ward') + expect(fetchSimulationConfig).toHaveBeenCalled() + }) + + it('allowsSimulationWhenEnabled', async () => { + const sim = useSimulationStore() + sim.enabled = true + + const { default: router } = await import('@/router') + await router.push('/simulation') + + expect(router.currentRoute.value.path).toBe('/simulation') + }) +}) diff --git a/vigilcare-dashboard/src/__tests__/useSimulationStore.test.js b/vigilcare-dashboard/src/__tests__/useSimulationStore.test.js new file mode 100644 index 0000000..baf8392 --- /dev/null +++ b/vigilcare-dashboard/src/__tests__/useSimulationStore.test.js @@ -0,0 +1,171 @@ +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest' +import { createPinia, setActivePinia } from 'pinia' +import { nextTick } from 'vue' +import { useSimulationStore } from '@/stores/simulation' + +const { + fetchSimulationConfig, + fetchScenarios, + fetchRuns, + startRun, + stopRun, + loadEncounters, +} = vi.hoisted(() => ({ + fetchSimulationConfig: vi.fn(), + fetchScenarios: vi.fn(), + fetchRuns: vi.fn(), + startRun: vi.fn(), + stopRun: vi.fn(), + loadEncounters: vi.fn(), +})) + +vi.mock('@/api/simulation', () => ({ + fetchSimulationConfig, + fetchScenarios, + fetchRuns, + startRun, + stopRun, + fetchRun: vi.fn(), +})) + +vi.mock('@/stores/ward', () => ({ + useWardStore: () => ({ loadEncounters }), +})) + +function runningRun(overrides = {}) { + return { + runId: 'run-1', + scenarioId: 'uti-sepsis-elderly-01', + scenarioName: 'UTI Sepsis', + status: 'RUNNING', + speed: 60, + patientId: 'p1', + encounterId: 'e1', + patientDisplayName: 'Test Patient', + startedAt: '2026-08-05T10:00:00Z', + elapsedRealSeconds: 30, + lastOffsetMinutes: 20, + totalOffsetMinutes: 480, + progressPercent: 4, + observationsSent: 3, + medicationsSent: 0, + ordersPlaced: 0, + failureReason: null, + ...overrides, + } +} + +describe('useSimulationStore', () => { + beforeEach(() => { + vi.clearAllMocks() + vi.useFakeTimers() + setActivePinia(createPinia()) + fetchRuns.mockResolvedValue([]) + fetchScenarios.mockResolvedValue([]) + fetchSimulationConfig.mockResolvedValue({ + enabled: true, + maxSpeed: 600, + maxConcurrentRuns: 2, + }) + }) + + afterEach(() => { + const store = useSimulationStore() + store.stopPolling() + vi.useRealTimers() + }) + + it('activeRuns_and_atConcurrencyLimit', () => { + const store = useSimulationStore() + store.maxConcurrentRuns = 2 + store.runs = [ + runningRun({ runId: 'a', status: 'RUNNING' }), + runningRun({ runId: 'b', status: 'PENDING' }), + runningRun({ runId: 'c', status: 'COMPLETED' }), + ] + + expect(store.activeRuns.map(r => r.runId)).toEqual(['a', 'b']) + expect(store.hasActiveRun).toBe(true) + expect(store.atConcurrencyLimit).toBe(true) + expect(store.recentRuns.map(r => r.runId)).toEqual(['c']) + }) + + it('start_pushesOptimisticPlaceholderThenReconciles', async () => { + const store = useSimulationStore() + store.scenarios = [{ id: 's1', name: 'Scenario One', durationMinutes: 480 }] + + let resolveStart + startRun.mockReturnValue(new Promise((resolve) => { + resolveStart = resolve + })) + + const startPromise = store.start('s1', 60) + await nextTick() + + expect(store.activeRuns).toHaveLength(1) + expect(store.activeRuns[0].status).toBe('PENDING') + expect(store.activeRuns[0]._optimistic).toBe(true) + expect(store.starting).toBe(true) + + resolveStart(runningRun({ runId: 'real-1', scenarioId: 's1', scenarioName: 'Scenario One' })) + await startPromise + + expect(store.runs).toHaveLength(1) + expect(store.runs[0].runId).toBe('real-1') + expect(store.runs[0]._optimistic).toBeUndefined() + expect(store.starting).toBe(false) + expect(loadEncounters).toHaveBeenCalled() + }) + + it('start_rollsBackPlaceholderOnFailure', async () => { + const store = useSimulationStore() + startRun.mockRejectedValue(new Error('Maximum concurrent simulation runs (2) reached.')) + + await expect(store.start('s1', 60)).rejects.toThrow(/concurrent/) + expect(store.runs).toEqual([]) + expect(store.error).toMatch(/concurrent/) + expect(store.starting).toBe(false) + }) + + it('stop_updatesRunFromApi', async () => { + const store = useSimulationStore() + store.runs = [runningRun()] + stopRun.mockResolvedValue(runningRun({ status: 'CANCELLED' })) + + await store.stop('run-1') + expect(stopRun).toHaveBeenCalledWith('run-1') + expect(store.runs[0].status).toBe('CANCELLED') + }) + + it('polling_runsOnlyWhileActiveRunExists', async () => { + const store = useSimulationStore() + store.startPolling() + + await vi.advanceTimersByTimeAsync(5_000) + expect(fetchRuns).not.toHaveBeenCalled() + + store.runs = [runningRun()] + await nextTick() + + await vi.advanceTimersByTimeAsync(2_000) + expect(fetchRuns).toHaveBeenCalledTimes(1) + + fetchRuns.mockResolvedValue([runningRun({ status: 'COMPLETED', progressPercent: 100 })]) + await store.refreshRuns() + await nextTick() + + fetchRuns.mockClear() + await vi.advanceTimersByTimeAsync(4_000) + expect(fetchRuns).not.toHaveBeenCalled() + + store.stopPolling() + }) + + it('loadConfig_failsClosedOnError', async () => { + const store = useSimulationStore() + fetchSimulationConfig.mockRejectedValue(new Error('network')) + await store.loadConfig() + expect(store.enabled).toBe(false) + expect(store.maxConcurrentRuns).toBe(0) + }) +}) diff --git a/vigilcare-dashboard/src/api/normalize.js b/vigilcare-dashboard/src/api/normalize.js index 465190c..548e5aa 100644 --- a/vigilcare-dashboard/src/api/normalize.js +++ b/vigilcare-dashboard/src/api/normalize.js @@ -88,4 +88,15 @@ const BUNDLE_ELEMENT_LABELS = { export function bundleElementLabel(elementType) { return BUNDLE_ELEMENT_LABELS[elementType] ?? elementType -} \ No newline at end of file +} + +/** + * True when the ward summary or encounter detail marks the patient as simulated. + * Ward list: top-level `isSimulated`. Patient detail: `patient.isSimulated`. + */ +export function isSimulatedPatient(source) { + if (!source) return false + if (source.isSimulated === true) return true + if (source.patient?.isSimulated === true) return true + return false +} diff --git a/vigilcare-dashboard/src/api/simulation.js b/vigilcare-dashboard/src/api/simulation.js new file mode 100644 index 0000000..e64bc37 --- /dev/null +++ b/vigilcare-dashboard/src/api/simulation.js @@ -0,0 +1,8 @@ +import { api } from './client' + +export const fetchSimulationConfig = () => api.get('/api/v1/simulation/config') +export const fetchScenarios = () => api.get('/api/v1/simulation/scenarios') +export const fetchRuns = () => api.get('/api/v1/simulation/runs') +export const fetchRun = (runId) => api.get(`/api/v1/simulation/runs/${runId}`) +export const startRun = (body) => api.post('/api/v1/simulation/runs', body) +export const stopRun = (runId) => api.post(`/api/v1/simulation/runs/${runId}/stop`) diff --git a/vigilcare-dashboard/src/components/layout/AppShell.vue b/vigilcare-dashboard/src/components/layout/AppShell.vue index 4ab3446..ee21f46 100644 --- a/vigilcare-dashboard/src/components/layout/AppShell.vue +++ b/vigilcare-dashboard/src/components/layout/AppShell.vue @@ -1,13 +1,31 @@