Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4d02f8f
add multiple airplanes to schema context and types
abdratsd Mar 14, 2025
9ce57b4
Minor changes:
ahmerique May 27, 2025
ca35f9d
Issue #2: Improve line name readability by formatting the displayed l…
ahmerique Jul 1, 2025
f846f8e
Issue #5: Send grid state after line disconnection in Anticipation cards
ahmerique Jul 3, 2025
9ca70f5
Merge pull request #2 from ahmerique/fix/5-2-and-minors
abdratsd Jul 29, 2025
05d414f
resources/checkPorts.sh to check if all needed ports are available
obretteville Jun 20, 2025
5e448a7
Troubleshooting documentation updated
obretteville Jun 20, 2025
8a7fcff
Update scripts to use docker compose V2 instead of old docker-compose
ahmerique Jul 28, 2025
9f316e0
Update scripts to use docker compose V2 instead of old docker-compose
ahmerique Jul 28, 2025
1fbd64e
Handle alert notifications (different than alarm)
ahmerique Sep 25, 2025
1057612
added nocontext var to locales
abdratsd Oct 2, 2025
e6d5e94
plane id is now a string
abdratsd Oct 2, 2025
ff7e0d5
replace old usecase name in filename
abdratsd Oct 2, 2025
d6ddb33
feat(map): add autoFit prop; auto-fit on contextWaypoints only when e…
abdratsd Oct 2, 2025
d775068
fix(ATM): clear previous ROUTE markers before rebuild; stop removing …
abdratsd Oct 2, 2025
613ebfc
i18n(railway): change primary button label to “Get recommendation fro…
abdratsd Oct 2, 2025
edd67b1
fix: rename map markers of old usecases
abdratsd Oct 2, 2025
5958797
Merge pull request #9 from AI4REALNET/fix-context-existence-lang
abdratsd Oct 2, 2025
deeb85b
Merge pull request #3 from ahmerique/update-installation
abdratsd Oct 2, 2025
8d09bc1
Merge pull request #7 from ahmerique/feature/alert_notification
abdratsd Oct 2, 2025
7d8e13b
Merge pull request #10 from AI4REALNET/900-multiple-airplanes-context
abdratsd Oct 2, 2025
5840bf0
Update KPI name
MarouaMed Oct 15, 2025
4b96fb7
Update recommendations titles and description in english
MarouaMed Oct 15, 2025
e8690b9
Update Events title and description in english
MarouaMed Oct 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* text=auto
*.sh text eol=lf
*.conf text eol=lf
*.bash text eol=lf
*.yml text eol=lf
33 changes: 18 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ The platform uses the project **OperatorFabric** for notification management.
### Prerequisites

- [Git (version 2.40.1)](https://git-scm.com/)
- [Docker (version 24.0.2)](https://www.docker.com/)
- [Docker Compose (version 1.25.0 or later)](https://www.docker.com/)
- [Docker Engine (version 27)](https://www.docker.com/)
- [Docker Compose V2](https://www.docker.com/)


### Setting Up the Environment
Expand All @@ -63,7 +63,7 @@ Below are the steps to start all services. For other methods, please consult the

### Running All Services (Dev Mode)

1. Set-up environement variables
1. **Set-up environement variables**


`VITE_POWERGRID_SIMU`, `VITE_RAILWAY_SIMU` , `VITE_ATM_SIMU` are the simulators' endpoints.
Expand All @@ -79,31 +79,34 @@ export VITE_ATM_SIMU=http://[Service url]:[Service port]
> **_NOTE:_** For this step, you should already have a running simulator. If not, you can use the simulator we provided as an example. For this, please follow the tutorial provided in InteractiveAI/usecases_examples/PowerGrid/ then set the VITE_POWERGRID_SIMU variable to http://YOUR_SERVER_ADDRESS:5100/
>
>
2. Run InteractiveAI assistant
2. **Run InteractiveAI assistant**
```sh
cd config/dev/cab-standalone
./docker-compose.sh
```
> **_NOTE:_** You will see the word cab (Cockpit Assistant Bidirectionnel) on most files in the project. Note that it was the initial project name of InteractiveAI. Might be updated later.

3. Setting up Keycloak `Frontend URL`
* **Access Keycloak Interface**:
3. **Setting up Keycloak `Frontend URL`**
* Access Keycloak Interface:
- Ensure that your Keycloak instance is running and accessible.
- Open a web browser and navigate to the Keycloak admin console, typically available at `http://localhost:89/auth/admin`.
* **Login to Keycloak Admin Console**:
* Login to Keycloak Admin Console:
- Log in to the Keycloak admin console using your administrator credentials (`admin:admin` by default)
* **Navigate to Client Settings**:
* Configure frontendUrl:
- On the Keycloak admin console, locate and click on the "Realm Settings" section.
- In the Frontend URL setting, add the URL of your Assistant Platform frontend as a valid redirect URI. This URL is typically where your frontend application is hosted. For example, if your frontend is hosted locally for development purposes, you might add `http://localhost:3200/*`.
- After adding the frontend URL, save the changes to update the client settings.
* Configure Valid Redirect URIs:
- On the Keycloak admin console, locate and click on the "Clients" section.
- Select the client representing your Assistant Platform application.
* **Configure FrontendUrl**:
- Within the client settings, look for the "Valid Redirect URIs" or similar configuration field.
- Add the URL of your Assistant Platform frontend as a valid redirect URI. This URL is typically where your frontend application is hosted. For example, if your frontend is hosted locally for development purposes, you might add `http://localhost:3200/*`.
- Ensure that the frontend URL you specify matches the actual URL where your frontend application is accessible.
* **Save Changes**:
- After adding the frontend URL, save the changes to update the client settings.
- Add the URL of your Assistant Platform frontend, it should match the one used in the frontendUrl setting.
- After adding the Valid Redirect URIs, save the changes to update the client settings.


4. **Load resources**

4. Load resources
**WARINING:** You need to restart the frontend after updating the URL on keycloak do it before loading the resources.
**WARNING:** You need to restart the frontend after updating the URL on keycloak do it before loading the resources.
```sh
docker restart frontend
```
Expand Down
Empty file modified backend/capitalization-service/entrypoint.sh
100755 → 100644
Empty file.
Empty file modified backend/context-service/entrypoint.sh
100755 → 100644
Empty file.
29 changes: 27 additions & 2 deletions backend/context-service/resources/ATM/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,35 @@

from api.schemas import MetadataSchema
from apiflask.fields import Dict, String, Float, List, Integer
class MetadataSchemaATM(MetadataSchema):
from apiflask import Schema, fields
from marshmallow import pre_load
class PlaneMetadataSchemaATM(MetadataSchema):
id_plane = String()
ApDest = Dict()
Current_airspeed = Float()
Latitude = Float()
Longitude = Float()
wpList = List(Dict())
id_plane = Integer()

class MetadataSchemaATM(MetadataSchema):
airplanes = List(fields.Nested(PlaneMetadataSchemaATM), required=True)

# Backward compatibility: optional fields for the single airplane case
ApDest = Dict(required=False)
Current_airspeed = Float(required=False)
Latitude = Float(required=False)
Longitude = Float(required=False)
wpList = List(Dict(), required=False)

@pre_load
def handle_backward_compatibility(self, data, **kwargs):
# If the new 'airplanes' field is not provided, assume the old format.
if 'airplanes' not in data:
airplane = {}
for field in ['ApDest', 'Current_airspeed', 'Latitude', 'Longitude', 'wpList']:
if field in data:
airplane[field] = data[field]
# Provide a default id_plane if not present.
airplane.setdefault('id_plane', "X")
data['airplanes'] = [airplane]
return data
Empty file modified backend/event-service/entrypoint.sh
100755 → 100644
Empty file.
Empty file modified backend/historic-service/entrypoint.sh
100755 → 100644
Empty file.
Empty file modified backend/recommendation-service/entrypoint.sh
100755 → 100644
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def get_parade_info(self, act):
"Redispatch" # pour renvoyer le kpi type_of_the_reco
)
title.append(
"Parade injection: redispatch de source de production"
"Injection recommendation: production source redispatch"
)
cpt = 0
for gen_idx in range(act.n_gen):
Expand All @@ -213,9 +213,9 @@ def get_parade_info(self, act):
# storage
if act._modif_storage:
kpis["type_of_the_reco"] = (
"Stockage" # pour renvoyer le kpi type_of_the_reco
"Storage" # pour renvoyer le kpi type_of_the_reco
)
title.append("Parade stockage")
title.append("Storage recommendation")
cpt = 0
for stor_idx in range(act.n_storage):
amount_ = act._storage_power[stor_idx]
Expand All @@ -225,8 +225,8 @@ def get_parade_info(self, act):
description.append(", ")
cpt = 1
description.append(
f'Demande à l\'unité "{name_}" de '
f'{"charger" if amount_ > 0.0 else "decharger"} '
f'Ask unit "{name_}" to '
f'{"charge" if amount_ > 0.0 else "discharge"} '
f'{abs(amount_):.2f} MW (setpoint: {amount_:.2f} MW)'
)

Expand All @@ -235,7 +235,7 @@ def get_parade_info(self, act):
kpis["type_of_the_reco"] = (
"Injection" # pour renvoyer le kpi type_of_the_reco
)
title.append("Parade injection")
title.append("Injection recommendation")
cpt = 0
for gen_idx in range(act.n_gen):
amount_ = act._curtail[gen_idx]
Expand All @@ -245,71 +245,71 @@ def get_parade_info(self, act):
description.append(", ")
cpt = 1
description.append(
f'Limiter l\'unité "{name_}" à '
f'{100.0 * amount_:.1f}% de sa capacité max '
f'Limit unit "{name_}" to '
f'{100.0 * amount_:.1f}% of its maximum capacity '
f'(setpoint: {amount_:.3f})'
)

# force line status
force_line_impact = impact["force_line"]
if force_line_impact["changed"]:
kpis["type_of_the_reco"] = (
"Topologique" # pour renvoyer le kpi type_of_the_reco
"Topological" # pour renvoyer le kpi type_of_the_reco
)
title.append(
"Parade topologique: connection/deconnection de ligne"
"Topological recommendation: connection/disconnection of line"
)
reconnections = force_line_impact["reconnections"]
if reconnections["count"] > 0:
description.append(
f"Reconnection de {reconnections['count']} lignes "
f"Reconnection of {reconnections['count']} lines "
f"({reconnections['powerlines']})"
)

disconnections = force_line_impact["disconnections"]
if disconnections["count"] > 0:
description.append(
f"Déconnection de {disconnections['count']} lignes "
f"Disconnection of {disconnections['count']} lines "
f"({disconnections['powerlines']})"
)

# swtich line status
swith_line_impact = impact["switch_line"]
if swith_line_impact["changed"]:
kpis["type_of_the_reco"] = (
"Topologique" # pour renvoyer le kpi type_of_the_reco
"Topological" # pour renvoyer le kpi type_of_the_reco
)
title.append("Parade topologique: changer l'état d'une ligne")
title.append("Topological: change a line state")
description.append(
f"Changer le statut de {swith_line_impact['count']} lignes "
f"Change the state of {swith_line_impact['count']} lines "
f"({swith_line_impact['powerlines']})"
)

# topology
bus_switch_impact = impact["topology"]["bus_switch"]
if len(bus_switch_impact) > 0:
kpis["type_of_the_reco"] = (
"Topologique" # pour renvoyer le kpi type_of_the_reco
"Topological" # pour renvoyer le kpi type_of_the_reco
)
title.append(
"Parade topologique: prise de schéma au poste "
"Topological recommendation: Schematic acquisition at substation "
+ str(bus_switch_impact["substation"])
)
description.append("Changement de bus:")
description.append("Busbar change:")
for switch in bus_switch_impact:
description.append(
f"\t \t - Switch bus de {switch['object_type']} id "
f"{switch['object_id']} [au poste {switch['substation']}]"
f"\t \t - Switch bus of {switch['object_type']} id "
f"{switch['object_id']} [at station {switch['substation']}]"
)

assigned_bus_impact = impact["topology"]["assigned_bus"]
disconnect_bus_impact = impact["topology"]["disconnect_bus"]
if len(assigned_bus_impact) > 0 or len(disconnect_bus_impact) > 0:
kpis["type_of_the_reco"] = (
"Topologique" # pour renvoyer le kpi type_of_the_reco
"Topological" # pour renvoyer le kpi type_of_the_reco
)
title.append(
"Parade topologique: prise de schéma au poste "
"Topological recommendation: Schematic acquisition at substation "
+ str(assigned_bus_impact[0]["substation"])
)
if assigned_bus_impact:
Expand All @@ -320,7 +320,7 @@ def get_parade_info(self, act):
description.append(", ")
cpt = 1
description.append(
f" Assigner le bus {assigned['bus']} à "
f" Assign bus {assigned['bus']} to "
f"{assigned['object_type']} id {assigned['object_id']}"
)
if disconnect_bus_impact:
Expand All @@ -331,20 +331,20 @@ def get_parade_info(self, act):
description.append(", ")
cpt = 1
description.append(
f"Déconnecter {disconnected['object_type']} avec l'id "
f"{disconnected['object_id']} [au niveau du poste "
f"Disconnect {disconnected['object_type']} with id "
f"{disconnected['object_id']} [at the substation level "
f"{disconnected['substation']}]"
)

# Any of the above cases,
# then the recommendation is most likely "Do nothing"
if not title and act == self.action_do_nothing:
kpis["type_of_the_reco"] = (
"Ne rien faire" # pour renvoyer le kpi type_of_the_reco
"Do nothing" # pour renvoyer le kpi type_of_the_reco
)
title.append("Poursuivre")
description.append(
"Poursuite du scénario sans intervention extérieur"
"Continuation of the scenario without operator action"
)

title = "".join(title)
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# backend/recommendation-service/resources/RTE/manager.py
# backend/recommendation-service/resources/Railway/manager.py

from api.manager.base_manager import BaseRecommendationManager

Expand Down
Empty file modified backend/recommendation-service/start_service.bash
100755 → 100644
Empty file.
Empty file modified config/dev/cab-keycloak/export/dev-realm.json
100755 → 100644
Empty file.
Empty file modified config/dev/cab-keycloak/export/dev-users-0.json
100755 → 100644
Empty file.
Empty file modified config/dev/cab-standalone/config_host_ip.bash
100755 → 100644
Empty file.
2 changes: 1 addition & 1 deletion config/dev/cab-standalone/docker-compose.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ fi
echo "HOST_IP=${HOST_IP}" >> .env

cat .env
docker-compose up -d
docker compose up -d
2 changes: 1 addition & 1 deletion config/dev/cab-standalone/nginx-cors-permissive.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# docker-compose DNS used to resolved keycloak services
# docker compose DNS used to resolved keycloak services
resolver 127.0.0.11 ipv6=off;
server {
listen 80;
Expand Down
2 changes: 1 addition & 1 deletion config/dev/cab-standalone/nginx-kubernetes.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# docker-compose DNS used to resolved users service
# docker compose DNS used to resolved users service
# resolver 127.0.0.11 ipv6=off;

# Log format to have msec in time + request processing time
Expand Down
2 changes: 1 addition & 1 deletion config/dev/cab-standalone/nginx.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# docker-compose DNS used to resolved users service
# docker compose DNS used to resolved users service
resolver 127.0.0.11 ipv6=off;

# Log format to have msec in time + request processing time
Expand Down
2 changes: 1 addition & 1 deletion config/dev/cab-standalone/stopOpfab.sh
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/bash

docker-compose down -v
docker compose down -v
2 changes: 1 addition & 1 deletion config/dev/recommendation-service/docker-compose.bash
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ fi

echo "HOST_IP=${HOST_IP}" > .env

docker-compose -f "docker-compose-recommendation-service.yml" up --build
docker compose -f "docker-compose-recommendation-service.yml" up --build
2 changes: 1 addition & 1 deletion config/dev/recommendation-service/nginx.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# docker-compose DNS used to resolved keycloak services
# docker compose DNS used to resolved keycloak services
resolver 127.0.0.11 ipv6=off;
server {
listen 80;
Expand Down
35 changes: 34 additions & 1 deletion docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,39 @@

Are you having issues with setting up your environment? Here are some tips that might help.

## Ports already in use

InteractiveAI uses about twenty ports on server. If a port needed for InteractiveAI is already in use, InteractiveAI will fail (with messages in logs but the can be missed).
The script `resources/checkPorts.sh` tests the availability of each port specified in `config/dev/cab-standalone/docker-compose.yml` and write a diagnosis on console.

It it succeeds:
```
brettevi@PCAlien:~/Projets/InteractiveAI$ ./resources/checkPorts.sh
Ports used for InteractiveAI: 89 3200 5000 5100 5200 5400 5433 5434 5436 5437 5438 5500 12002 12100 12102 12103 12104 27017
All is fine: all ports used by InteractiveAI are available
```

If it fails:
```
brettevi@PCAlien:~/Projets/InteractiveAI$ ./resources/checkPorts.sh
Ports used for InteractiveAI: 89 3200 5000 5100 5200 5400 5433 5434 5436 5437 5438 5500 12002 12100 12102 12103 12104 27017
docker: Error response from daemon: driver failed programming external connectivity on endpoint stoic_williams (b69f8285b2ec63145267ad7ea04969cf58dc423528729c7c3f07b5d5c3ccc342): Bind for 0.0.0.0:89 failed: port is already allocated.
...
docker: Error response from daemon: driver failed programming external connectivity on endpoint zen_feistel (f3047f6ae4ebf5e78dc034137d24a832e2ff60490424ba8ba4ae2531d2222142): Bind for 0.0.0.0:12104 failed: port is already allocated.
docker: Error response from daemon: driver failed programming external connectivity on endpoint keen_swanson (82f2ac17d11057767379dc0f492b5a9b8fd7620fb562e8107e9ce1453e548052): Bind for 0.0.0.0:27017 failed: port is already allocated.
Check your counfiguration: 18 port(s) used by InteractiveAI are already used
InteractiveAI can't run on this platform with this /home/brettevi/Projets/InteractiveAI/config/dev/cab-standalone/docker-compose.yml ports configuration
```

This command may also be used with a specific docker-compose.yml file. For example, to test Powergrid simulator ports availability, one can use:
```
brettevi@PCAlien:~/Projets/InteractiveAI$ ./resources/checkPorts.sh usecases_examples/PowerGrid/docker-compose.yml
Ports used for InteractiveAI: 5150
docker: Error response from daemon: driver failed programming external connectivity on endpoint funny_rhodes (6291f43617a7798a833fdeee05c32c75c2d0bf765eac5dc3b8fe08b7255e57a1): Bind for 0.0.0.0:5150 failed: port is already allocated.
Check your counfiguration: 1 port(s) used by InteractiveAI are already used
InteractiveAI can't run on this platform with this usecases_examples/PowerGrid/docker-compose.yml ports configuration
```

## EoL Sequence Configuration errors.

Some users may encounter issues if their system is automatically converting end of line sequence from LF to CRLF.
Expand All @@ -18,6 +51,6 @@ The .env should contain:
HOST_IP=<IP_Address>
```

If the IP_Address is not your network IP address, please set it manually and run the system using native docker-compose commands.
If the IP_Address is not your network IP address, please set it manually and run the system using native docker compose commands.

> **_NOTE:_** You are welcome to contribute with any issue that you encounter during setup.
1 change: 0 additions & 1 deletion frontend/.dockerignore

This file was deleted.

1 change: 1 addition & 0 deletions frontend/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.gitignore
Empty file modified frontend/.husky/commit-msg
100755 → 100644
Empty file.
Empty file modified frontend/.husky/pre-commit
100755 → 100644
Empty file.
Empty file modified frontend/.husky/pre-push
100755 → 100644
Empty file.
Loading