Web service initiated
|
|
@ -17,9 +17,8 @@ RUN poetry config virtualenvs.create false \
|
||||||
# Copy application code
|
# Copy application code
|
||||||
COPY /ApiServices/AuthService /ApiServices/AuthService
|
COPY /ApiServices/AuthService /ApiServices/AuthService
|
||||||
COPY /Controllers /Controllers
|
COPY /Controllers /Controllers
|
||||||
COPY /Schemas/building /Schemas/building
|
COPY /Modules /Modules
|
||||||
COPY /Schemas/company /Schemas/company
|
COPY /Schemas /Schemas
|
||||||
COPY /Schemas/identity /Schemas/identity
|
|
||||||
|
|
||||||
# Set Python path to include app directory
|
# Set Python path to include app directory
|
||||||
ENV PYTHONPATH=/ PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
|
ENV PYTHONPATH=/ PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,7 @@ class RouteRegisterController:
|
||||||
self.router_list = router_list
|
self.router_list = router_list
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def register_routes(self):
|
def register_routes(self):
|
||||||
for router in self.router_list:
|
for router in self.router_list:
|
||||||
self.app.include_router(router)
|
self.app.include_router(router)
|
||||||
self.add_router_to_database(router)
|
|
||||||
return self.app
|
return self.app
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,12 @@ from ApiServices.AuthService.validations.request.authentication.login_post impor
|
||||||
RequestChangePassword,
|
RequestChangePassword,
|
||||||
RequestForgotPasswordPhone,
|
RequestForgotPasswordPhone,
|
||||||
RequestForgotPasswordEmail,
|
RequestForgotPasswordEmail,
|
||||||
|
RequestVerifyOTP,
|
||||||
)
|
)
|
||||||
|
from ApiServices.AuthService.events.auth.auth import AuthHandlers
|
||||||
|
|
||||||
|
|
||||||
auth_route = APIRouter(
|
auth_route = APIRouter(prefix="/authentication", tags=["Authentication Cluster"])
|
||||||
prefix="/authentication",
|
|
||||||
tags=["Authentication Cluster"],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@auth_route.post(
|
@auth_route.post(
|
||||||
|
|
@ -49,8 +48,12 @@ def authentication_login_post(
|
||||||
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
|
result = AuthHandlers.LoginHandler.authentication_login_with_domain_and_creds(
|
||||||
|
request=request,
|
||||||
|
data=data,
|
||||||
|
)
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
content={**data.model_dump()},
|
content=result,
|
||||||
status_code=status.HTTP_202_ACCEPTED,
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
|
|
@ -84,9 +87,12 @@ def authentication_select_post(
|
||||||
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
|
result = AuthHandlers.LoginHandler.authentication_select_company_or_occupant_type(
|
||||||
|
request=request,
|
||||||
|
data=data,
|
||||||
|
)
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
content=data.model_dump(),
|
content=result,
|
||||||
status_code=status.HTTP_202_ACCEPTED,
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
|
|
@ -107,13 +113,15 @@ def authentication_password_create_post(
|
||||||
"""
|
"""
|
||||||
Authentication create password Route with Post Method
|
Authentication create password Route with Post Method
|
||||||
"""
|
"""
|
||||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
|
||||||
headers = {
|
headers = {
|
||||||
"language": language or "",
|
"language": language or "",
|
||||||
"domain": domain or "",
|
"domain": domain or "",
|
||||||
"eys-ext": f"{str(uuid.uuid4())}",
|
"eys-ext": f"{str(uuid.uuid4())}",
|
||||||
"token": token,
|
|
||||||
}
|
}
|
||||||
|
result = AuthHandlers.PasswordHandler.create_password(
|
||||||
|
password=data.password,
|
||||||
|
password_token=data.password_token,
|
||||||
|
)
|
||||||
if not domain or not language:
|
if not domain or not language:
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
content={"error": "EYS_0001"},
|
content={"error": "EYS_0001"},
|
||||||
|
|
@ -121,7 +129,7 @@ def authentication_password_create_post(
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
content={**data.model_dump()},
|
content={},
|
||||||
status_code=status.HTTP_202_ACCEPTED,
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
|
|
@ -333,3 +341,41 @@ def authentication_token_refresh_post(
|
||||||
status_code=status.HTTP_202_ACCEPTED,
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@auth_route.get(
|
||||||
|
path="/password/verify-otp",
|
||||||
|
summary="Verify OTP for password reset",
|
||||||
|
description="Verify OTP for password reset",
|
||||||
|
)
|
||||||
|
def authentication_password_verify_otp(
|
||||||
|
request: Request,
|
||||||
|
data: RequestVerifyOTP,
|
||||||
|
language: str = Header(None, alias="language"),
|
||||||
|
domain: str = Header(None, alias="domain"),
|
||||||
|
tz: str = Header(None, alias="timezone"),
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Verify OTP for password reset
|
||||||
|
"""
|
||||||
|
|
||||||
|
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||||
|
headers = {
|
||||||
|
"language": language or "",
|
||||||
|
"domain": domain or "",
|
||||||
|
"eys-ext": f"{str(uuid.uuid4())}",
|
||||||
|
"tz": tz or "GMT+3",
|
||||||
|
"token": token,
|
||||||
|
}
|
||||||
|
print('Token&OTP : ', data.otp, data.token)
|
||||||
|
if not domain or not language:
|
||||||
|
return JSONResponse(
|
||||||
|
content={"error": "EYS_0003"},
|
||||||
|
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||||
|
headers=headers,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
headers=headers,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -16,4 +16,7 @@ def get_safe_endpoint_urls() -> list[tuple[str, str]]:
|
||||||
("/auth/login", "POST"),
|
("/auth/login", "POST"),
|
||||||
("/metrics", "GET"),
|
("/metrics", "GET"),
|
||||||
("/authentication/login", "POST"),
|
("/authentication/login", "POST"),
|
||||||
|
("/authentication/password/reset", "POST"),
|
||||||
|
("/authentication/password/create", "POST"),
|
||||||
|
("/authentication/password/verify-otp", "POST"),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
from typing import Any, List, Dict, Optional, Union
|
import arrow
|
||||||
|
|
||||||
|
from typing import Any, Dict, Optional, Union
|
||||||
|
from ApiServices.AuthService.events.auth.model import PasswordHistoryViaUser
|
||||||
from ApiServices.AuthService.validations.custom.token import (
|
from ApiServices.AuthService.validations.custom.token import (
|
||||||
EmployeeTokenObject,
|
EmployeeTokenObject,
|
||||||
OccupantTokenObject,
|
OccupantTokenObject,
|
||||||
|
|
@ -6,7 +9,7 @@ from ApiServices.AuthService.validations.custom.token import (
|
||||||
OccupantToken,
|
OccupantToken,
|
||||||
UserType,
|
UserType,
|
||||||
)
|
)
|
||||||
from ApiServices.TemplateService.config import api_config
|
from ApiServices.AuthService.config import api_config
|
||||||
from Schemas import (
|
from Schemas import (
|
||||||
Users,
|
Users,
|
||||||
People,
|
People,
|
||||||
|
|
@ -25,12 +28,14 @@ from Schemas import (
|
||||||
Event2Employee,
|
Event2Employee,
|
||||||
)
|
)
|
||||||
from Modules.Token.password_module import PasswordModule
|
from Modules.Token.password_module import PasswordModule
|
||||||
from Controllers.Redis.database import RedisActions
|
|
||||||
from Schemas.building.build import RelationshipEmployee2Build
|
from Schemas.building.build import RelationshipEmployee2Build
|
||||||
from Schemas.event.event import Event2Occupant
|
from Schemas.event.event import Event2Occupant
|
||||||
|
from Controllers.Redis.database import RedisActions
|
||||||
|
from Controllers.Mongo.database import mongo_handler
|
||||||
|
|
||||||
TokenDictType = Union[EmployeeTokenObject, OccupantTokenObject]
|
TokenDictType = Union[EmployeeTokenObject, OccupantTokenObject]
|
||||||
|
|
||||||
|
|
||||||
class RedisHandlers:
|
class RedisHandlers:
|
||||||
AUTH_TOKEN: str = "AUTH_TOKEN"
|
AUTH_TOKEN: str = "AUTH_TOKEN"
|
||||||
|
|
||||||
|
|
@ -63,7 +68,7 @@ class RedisHandlers:
|
||||||
result_delete = RedisActions.delete(
|
result_delete = RedisActions.delete(
|
||||||
list_keys=[RedisHandlers.AUTH_TOKEN, "*", str(user.uu_id)]
|
list_keys=[RedisHandlers.AUTH_TOKEN, "*", str(user.uu_id)]
|
||||||
)
|
)
|
||||||
print('result_delete', result_delete)
|
print("result_delete", result_delete)
|
||||||
generated_access_token = PasswordModule.generate_access_token()
|
generated_access_token = PasswordModule.generate_access_token()
|
||||||
keys = [RedisHandlers.AUTH_TOKEN, generated_access_token, str(user.uu_id)]
|
keys = [RedisHandlers.AUTH_TOKEN, generated_access_token, str(user.uu_id)]
|
||||||
RedisActions.set_json(
|
RedisActions.set_json(
|
||||||
|
|
@ -74,20 +79,27 @@ class RedisHandlers:
|
||||||
return generated_access_token
|
return generated_access_token
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_token_at_redis(cls, token: str, add_payload: Union[CompanyToken, OccupantToken]):
|
def update_token_at_redis(
|
||||||
|
cls, token: str, add_payload: Union[CompanyToken, OccupantToken]
|
||||||
|
):
|
||||||
if already_token_data := RedisActions.get_json(
|
if already_token_data := RedisActions.get_json(
|
||||||
list_keys=[RedisHandlers.AUTH_TOKEN, token, "*"]
|
list_keys=[RedisHandlers.AUTH_TOKEN, token, "*"]
|
||||||
).first:
|
).first:
|
||||||
already_token = cls.process_redis_object(**already_token_data)
|
already_token = cls.process_redis_object(already_token_data)
|
||||||
if already_token.is_employee:
|
if already_token.is_employee and isinstance(add_payload, CompanyToken):
|
||||||
already_token.selected_company = add_payload
|
already_token.selected_company = add_payload
|
||||||
elif already_token.is_occupant:
|
elif already_token.is_occupant and isinstance(add_payload, OccupantToken):
|
||||||
already_token.selected_occupant = add_payload
|
already_token.selected_occupant = add_payload
|
||||||
result = RedisActions.set_json(
|
result = RedisActions.set_json(
|
||||||
list_keys=[RedisHandlers.AUTH_TOKEN, token, str(already_token.user_uu_id)],
|
list_keys=[
|
||||||
|
RedisHandlers.AUTH_TOKEN,
|
||||||
|
token,
|
||||||
|
str(already_token.user_uu_id),
|
||||||
|
],
|
||||||
value=already_token.model_dump(),
|
value=already_token.model_dump(),
|
||||||
expires={"hours": 1, "minutes": 30},
|
expires={"hours": 1, "minutes": 30},
|
||||||
)
|
)
|
||||||
|
print("result.first", result.first)
|
||||||
return result.first
|
return result.first
|
||||||
raise ValueError("Something went wrong")
|
raise ValueError("Something went wrong")
|
||||||
|
|
||||||
|
|
@ -118,6 +130,14 @@ class UserHandlers:
|
||||||
"""
|
"""
|
||||||
Check if the password is valid.
|
Check if the password is valid.
|
||||||
"""
|
"""
|
||||||
|
print(
|
||||||
|
dict(
|
||||||
|
domain=domain,
|
||||||
|
id_=id_,
|
||||||
|
password=password,
|
||||||
|
password_hashed=password_hashed,
|
||||||
|
)
|
||||||
|
)
|
||||||
if PasswordModule.check_password(
|
if PasswordModule.check_password(
|
||||||
domain=domain, id_=id_, password=password, password_hashed=password_hashed
|
domain=domain, id_=id_, password=password, password_hashed=password_hashed
|
||||||
):
|
):
|
||||||
|
|
@ -135,7 +155,6 @@ class LoginHandler:
|
||||||
def is_employee(email: str):
|
def is_employee(email: str):
|
||||||
return str(email).split("@")[1] == api_config.ACCESS_EMAIL_EXT
|
return str(email).split("@")[1] == api_config.ACCESS_EMAIL_EXT
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def do_employee_login(
|
def do_employee_login(
|
||||||
cls, request: Any, data: Any, extra_dict: Optional[Dict[str, Any]] = None
|
cls, request: Any, data: Any, extra_dict: Optional[Dict[str, Any]] = None
|
||||||
|
|
@ -154,10 +173,10 @@ class LoginHandler:
|
||||||
)
|
)
|
||||||
|
|
||||||
if not user_handler.check_password_valid(
|
if not user_handler.check_password_valid(
|
||||||
domain=data.domain,
|
domain=domain or "",
|
||||||
id_=str(found_user.uu_id),
|
id_=str(found_user.uu_id),
|
||||||
password=data.password,
|
password=data.password,
|
||||||
password_hashed=found_user.hash_password
|
password_hashed=found_user.hash_password,
|
||||||
):
|
):
|
||||||
raise ValueError("EYS_0005")
|
raise ValueError("EYS_0005")
|
||||||
|
|
||||||
|
|
@ -230,6 +249,20 @@ class LoginHandler:
|
||||||
return {
|
return {
|
||||||
"access_token": access_token,
|
"access_token": access_token,
|
||||||
"user_type": UserType.employee.name,
|
"user_type": UserType.employee.name,
|
||||||
|
"user": found_user.get_dict(
|
||||||
|
exclude_list=[
|
||||||
|
Users.hash_password,
|
||||||
|
Users.cryp_uu_id,
|
||||||
|
Users.password_token,
|
||||||
|
Users.created_credentials_token,
|
||||||
|
Users.updated_credentials_token,
|
||||||
|
Users.confirmed_credentials_token,
|
||||||
|
Users.is_confirmed,
|
||||||
|
Users.is_notification_send,
|
||||||
|
Users.is_email_send,
|
||||||
|
Users.remember_me,
|
||||||
|
]
|
||||||
|
),
|
||||||
"selection_list": companies_list,
|
"selection_list": companies_list,
|
||||||
}
|
}
|
||||||
raise ValueError("Something went wrong")
|
raise ValueError("Something went wrong")
|
||||||
|
|
@ -254,7 +287,7 @@ class LoginHandler:
|
||||||
domain=data.domain,
|
domain=data.domain,
|
||||||
id_=str(found_user.uu_id),
|
id_=str(found_user.uu_id),
|
||||||
password=data.password,
|
password=data.password,
|
||||||
password_hashed=found_user.hash_password
|
password_hashed=found_user.hash_password,
|
||||||
):
|
):
|
||||||
raise ValueError("EYS_0005")
|
raise ValueError("EYS_0005")
|
||||||
|
|
||||||
|
|
@ -300,7 +333,9 @@ class LoginHandler:
|
||||||
"occupants": [occupant_data],
|
"occupants": [occupant_data],
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
occupants_selection_dict[build_key]["occupants"].append(occupant_data)
|
occupants_selection_dict[build_key]["occupants"].append(
|
||||||
|
occupant_data
|
||||||
|
)
|
||||||
|
|
||||||
person = found_user.person
|
person = found_user.person
|
||||||
model_value = OccupantTokenObject(
|
model_value = OccupantTokenObject(
|
||||||
|
|
@ -344,9 +379,9 @@ class LoginHandler:
|
||||||
Returns:
|
Returns:
|
||||||
SuccessResponse containing authentication token and user info
|
SuccessResponse containing authentication token and user info
|
||||||
"""
|
"""
|
||||||
language = request.headers("language", "tr")
|
language = request.headers.get("language", "tr")
|
||||||
domain = request.headers("domain", None)
|
domain = request.headers.get("domain", None)
|
||||||
timezone = request.headers("tz", None) or "GMT+3"
|
timezone = request.headers.get("tz", None) or "GMT+3"
|
||||||
|
|
||||||
if cls.is_employee(data.access_key):
|
if cls.is_employee(data.access_key):
|
||||||
return cls.do_employee_login(
|
return cls.do_employee_login(
|
||||||
|
|
@ -386,7 +421,9 @@ class LoginHandler:
|
||||||
return request.headers.get(api_config.ACCESS_TOKEN_TAG)
|
return request.headers.get(api_config.ACCESS_TOKEN_TAG)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def handle_employee_selection(cls, access_token: str, data: Any, token_dict: TokenDictType):
|
def handle_employee_selection(
|
||||||
|
cls, access_token: str, data: Any, token_dict: TokenDictType
|
||||||
|
):
|
||||||
with Users.new_session() as db:
|
with Users.new_session() as db:
|
||||||
if data.company_uu_id not in token_dict.companies_uu_id_list:
|
if data.company_uu_id not in token_dict.companies_uu_id_list:
|
||||||
ValueError("EYS_0011")
|
ValueError("EYS_0011")
|
||||||
|
|
@ -407,7 +444,9 @@ class LoginHandler:
|
||||||
# Get staff IDs
|
# Get staff IDs
|
||||||
staff_ids = [
|
staff_ids = [
|
||||||
staff.id
|
staff.id
|
||||||
for staff in Staff.filter_all(Staff.duties_id.in_(duties_ids), db=db).data
|
for staff in Staff.filter_all(
|
||||||
|
Staff.duties_id.in_(duties_ids), db=db
|
||||||
|
).data
|
||||||
]
|
]
|
||||||
|
|
||||||
# Get employee
|
# Get employee
|
||||||
|
|
@ -456,13 +495,12 @@ class LoginHandler:
|
||||||
reachable_event_codes=reachable_event_codes,
|
reachable_event_codes=reachable_event_codes,
|
||||||
)
|
)
|
||||||
redis_handler = RedisHandlers()
|
redis_handler = RedisHandlers()
|
||||||
try: # Update Redis
|
redis_result = redis_handler.update_token_at_redis(
|
||||||
return redis_handler.update_token_at_redis(
|
|
||||||
token=access_token, add_payload=company_token
|
token=access_token, add_payload=company_token
|
||||||
)
|
)
|
||||||
except Exception as e:
|
return {
|
||||||
err = e
|
"selected_uu_id": data.company_uu_id,
|
||||||
ValueError("EYS_0008")
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def handle_occupant_selection(
|
def handle_occupant_selection(
|
||||||
|
|
@ -526,12 +564,12 @@ class LoginHandler:
|
||||||
reachable_event_codes=reachable_event_codes,
|
reachable_event_codes=reachable_event_codes,
|
||||||
)
|
)
|
||||||
redis_handler = RedisHandlers()
|
redis_handler = RedisHandlers()
|
||||||
try: # Update Redis
|
redis_handler.update_token_at_redis(
|
||||||
return redis_handler.update_token_at_redis(
|
|
||||||
token=access_token, add_payload=occupant_token
|
token=access_token, add_payload=occupant_token
|
||||||
)
|
)
|
||||||
except Exception as e:
|
return {
|
||||||
raise ValueError("EYS_0008")
|
"selected_uu_id": data.company_uu_id,
|
||||||
|
}
|
||||||
|
|
||||||
@classmethod # Requires auth context
|
@classmethod # Requires auth context
|
||||||
def authentication_select_company_or_occupant_type(cls, request: Any, data: Any):
|
def authentication_select_company_or_occupant_type(cls, request: Any, data: Any):
|
||||||
|
|
@ -549,16 +587,119 @@ class LoginHandler:
|
||||||
if not access_token:
|
if not access_token:
|
||||||
raise ValueError("EYS_0001")
|
raise ValueError("EYS_0001")
|
||||||
|
|
||||||
token_object = RedisHandlers().get_object_from_redis(access_token=access_token)
|
token_object = RedisHandlers.get_object_from_redis(access_token=access_token)
|
||||||
if token_object.is_employee and isinstance(data, CompanyToken):
|
if token_object.is_employee:
|
||||||
return cls.handle_employee_selection(
|
return cls.handle_employee_selection(
|
||||||
access_token=access_token, data=data, token_dict=token_object,
|
access_token=access_token,
|
||||||
|
data=data,
|
||||||
|
token_dict=token_object,
|
||||||
)
|
)
|
||||||
elif token_object.is_occupant and isinstance(data, OccupantToken):
|
elif token_object.is_occupant:
|
||||||
return cls.handle_occupant_selection(
|
return cls.handle_occupant_selection(
|
||||||
access_token=access_token, data=data, token_dict=token_object,
|
access_token=access_token,
|
||||||
|
data=data,
|
||||||
|
token_dict=token_object,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordHandler:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_password(password, password_token=None):
|
||||||
|
with Users.new_session() as db_session:
|
||||||
|
found_user = Users.filter_one(
|
||||||
|
Users.password_token == password_token, db=db_session
|
||||||
|
).data
|
||||||
|
if not found_user:
|
||||||
|
raise ValueError("EYS_0031")
|
||||||
|
|
||||||
|
if found_user.password_token:
|
||||||
|
replace_day = 0
|
||||||
|
try:
|
||||||
|
replace_day = int(
|
||||||
|
str(found_user.password_expires_day or 0)
|
||||||
|
.split(",")[0]
|
||||||
|
.replace(" days", "")
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
err = e
|
||||||
|
token_is_expired = arrow.now() >= arrow.get(
|
||||||
|
str(found_user.password_expiry_begins)
|
||||||
|
).shift(days=replace_day)
|
||||||
|
|
||||||
|
if not password_token == found_user.password_token and token_is_expired:
|
||||||
|
raise ValueError("")
|
||||||
|
|
||||||
|
collection_name = f"{found_user.related_company}*Domain"
|
||||||
|
print("collection_name", collection_name)
|
||||||
|
with mongo_handler.collection(collection_name) as mongo_engine:
|
||||||
|
print({"user_uu_id": str(found_user.uu_id)})
|
||||||
|
domain_via_user = mongo_engine.find_one(
|
||||||
|
{"user_uu_id": str(found_user.uu_id)}
|
||||||
|
)
|
||||||
|
print("domain_via_user", domain_via_user)
|
||||||
|
if not domain_via_user:
|
||||||
|
raise ValueError("EYS_0024")
|
||||||
|
domain_via_user = domain_via_user.get("main_domain", None)
|
||||||
|
new_password_dict = {
|
||||||
|
"password": PasswordModule.create_hashed_password(
|
||||||
|
domain=domain_via_user,
|
||||||
|
id_=str(found_user.uu_id),
|
||||||
|
password=password,
|
||||||
|
),
|
||||||
|
"date": str(arrow.now().date()),
|
||||||
|
}
|
||||||
|
history_dict = PasswordHistoryViaUser(
|
||||||
|
user_uu_id=str(found_user.uu_id),
|
||||||
|
password_add=new_password_dict,
|
||||||
|
access_history_detail={"request": "", "ip": ""},
|
||||||
|
)
|
||||||
|
found_user.password_expiry_begins = str(arrow.now())
|
||||||
|
found_user.hash_password = new_password_dict.get("password")
|
||||||
|
found_user.password_token = "" if found_user.password_token else ""
|
||||||
|
|
||||||
|
collection_name = f"{found_user.related_company}*PasswordHistory"
|
||||||
|
with mongo_handler.collection(collection_name) as mongo_engine_sc:
|
||||||
|
password_history_item = mongo_engine_sc.find_one(
|
||||||
|
{"user_uu_id": str(found_user.uu_id)}
|
||||||
|
)
|
||||||
|
if not password_history_item:
|
||||||
|
mongo_engine_sc.insert_one(
|
||||||
|
document={
|
||||||
|
"user_uu_id": str(found_user.uu_id),
|
||||||
|
"password_history": [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
password_history_item = mongo_engine_sc.find_one(
|
||||||
|
{"user_uu_id": str(found_user.uu_id)}
|
||||||
|
)
|
||||||
|
password_history_list = password_history_item.get(
|
||||||
|
"password_history", []
|
||||||
|
)
|
||||||
|
hashed_password = history_dict.password_add.get("password")
|
||||||
|
for password_in_history in password_history_list:
|
||||||
|
if str(password_in_history.get("password")) == str(
|
||||||
|
hashed_password
|
||||||
|
):
|
||||||
|
raise ValueError("EYS_0032")
|
||||||
|
if len(password_history_list) > 3:
|
||||||
|
password_history_list.pop(0)
|
||||||
|
password_history_list.append(history_dict.password_add)
|
||||||
|
return mongo_engine_sc.update_one(
|
||||||
|
filter={"user_uu_id": str(found_user.uu_id)},
|
||||||
|
update={
|
||||||
|
"$set": {
|
||||||
|
"password_history": password_history_list,
|
||||||
|
"modified_at": arrow.now().timestamp(),
|
||||||
|
"access_history_detail": history_dict.access_history_detail,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
upsert=True,
|
||||||
|
)
|
||||||
|
found_user.save(db=db_session)
|
||||||
|
return found_user
|
||||||
|
|
||||||
|
|
||||||
class AuthHandlers:
|
class AuthHandlers:
|
||||||
LoginHandler: LoginHandler = LoginHandler()
|
LoginHandler: LoginHandler = LoginHandler()
|
||||||
|
PasswordHandler: PasswordHandler = PasswordHandler()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
from typing import Optional
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class DomainViaUser(BaseModel):
|
||||||
|
user_uu_id: str
|
||||||
|
main_domain: str
|
||||||
|
other_domains_list: Optional[list] = None
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordHistoryViaUser(BaseModel):
|
||||||
|
user_uu_id: str
|
||||||
|
password_add: dict
|
||||||
|
access_history_detail: Optional[dict]
|
||||||
|
|
||||||
|
|
||||||
|
class AccessHistoryViaUser(BaseModel):
|
||||||
|
user_uu_id: str
|
||||||
|
access_history: dict
|
||||||
|
|
@ -5,8 +5,7 @@ from ..config import api_config
|
||||||
|
|
||||||
|
|
||||||
async def token_middleware(request: Request, call_next):
|
async def token_middleware(request: Request, call_next):
|
||||||
|
base_url = request.url.path
|
||||||
base_url = "/".join(request.url.path.split("/")[:3])
|
|
||||||
safe_endpoints = [_[0] for _ in get_safe_endpoint_urls()]
|
safe_endpoints = [_[0] for _ in get_safe_endpoint_urls()]
|
||||||
if base_url in safe_endpoints:
|
if base_url in safe_endpoints:
|
||||||
return await call_next(request)
|
return await call_next(request)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,11 @@ class RequestLogin(BaseModel):
|
||||||
remember_me: Optional[bool]
|
remember_me: Optional[bool]
|
||||||
|
|
||||||
|
|
||||||
|
class RequestVerifyOTP(BaseModel):
|
||||||
|
token: str
|
||||||
|
otp: str
|
||||||
|
|
||||||
|
|
||||||
class RequestSelectOccupant(BaseModel):
|
class RequestSelectOccupant(BaseModel):
|
||||||
|
|
||||||
company_uu_id: str
|
company_uu_id: str
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ RUN poetry config virtualenvs.create false \
|
||||||
|
|
||||||
# Copy application code
|
# Copy application code
|
||||||
COPY /ApiServices/InitialService /ApiServices/InitialService
|
COPY /ApiServices/InitialService /ApiServices/InitialService
|
||||||
|
COPY /ApiServices/InitialService /
|
||||||
COPY /Controllers /Controllers
|
COPY /Controllers /Controllers
|
||||||
COPY /Schemas/building /Schemas/building
|
COPY /Modules /Modules
|
||||||
COPY /Schemas/company /Schemas/company
|
COPY /Schemas /Schemas
|
||||||
COPY /Schemas/identity /Schemas/identity
|
|
||||||
|
|
||||||
# Set Python path to include app directory
|
# Set Python path to include app directory
|
||||||
ENV PYTHONPATH=/ PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
|
ENV PYTHONPATH=/ PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
# A generic, single database configuration.
|
||||||
|
|
||||||
|
[alembic]
|
||||||
|
# path to migration scripts
|
||||||
|
# Use forward slashes (/) also on windows to provide an os agnostic path
|
||||||
|
script_location = alembic
|
||||||
|
|
||||||
|
# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
|
||||||
|
# Uncomment the line below if you want the files to be prepended with date and time
|
||||||
|
# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file
|
||||||
|
# for all available tokens
|
||||||
|
# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
|
||||||
|
|
||||||
|
# sys.path path, will be prepended to sys.path if present.
|
||||||
|
# defaults to the current working directory.
|
||||||
|
prepend_sys_path = .
|
||||||
|
|
||||||
|
# timezone to use when rendering the date within the migration file
|
||||||
|
# as well as the filename.
|
||||||
|
# If specified, requires the python>=3.9 or backports.zoneinfo library and tzdata library.
|
||||||
|
# Any required deps can installed by adding `alembic[tz]` to the pip requirements
|
||||||
|
# string value is passed to ZoneInfo()
|
||||||
|
# leave blank for localtime
|
||||||
|
# timezone =
|
||||||
|
|
||||||
|
# max length of characters to apply to the "slug" field
|
||||||
|
# truncate_slug_length = 40
|
||||||
|
|
||||||
|
# set to 'true' to run the environment during
|
||||||
|
# the 'revision' command, regardless of autogenerate
|
||||||
|
# revision_environment = false
|
||||||
|
|
||||||
|
# set to 'true' to allow .pyc and .pyo files without
|
||||||
|
# a source .py file to be detected as revisions in the
|
||||||
|
# versions/ directory
|
||||||
|
# sourceless = false
|
||||||
|
|
||||||
|
# version location specification; This defaults
|
||||||
|
# to alembic/versions. When using multiple version
|
||||||
|
# directories, initial revisions must be specified with --version-path.
|
||||||
|
# The path separator used here should be the separator specified by "version_path_separator" below.
|
||||||
|
# version_locations = %(here)s/bar:%(here)s/bat:alembic/versions
|
||||||
|
|
||||||
|
# version path separator; As mentioned above, this is the character used to split
|
||||||
|
# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
|
||||||
|
# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.
|
||||||
|
# Valid values for version_path_separator are:
|
||||||
|
#
|
||||||
|
# version_path_separator = :
|
||||||
|
# version_path_separator = ;
|
||||||
|
# version_path_separator = space
|
||||||
|
# version_path_separator = newline
|
||||||
|
#
|
||||||
|
# Use os.pathsep. Default configuration used for new projects.
|
||||||
|
version_path_separator = os
|
||||||
|
|
||||||
|
# set to 'true' to search source files recursively
|
||||||
|
# in each "version_locations" directory
|
||||||
|
# new in Alembic version 1.10
|
||||||
|
# recursive_version_locations = false
|
||||||
|
|
||||||
|
# the output encoding used when revision files
|
||||||
|
# are written from script.py.mako
|
||||||
|
# output_encoding = utf-8
|
||||||
|
|
||||||
|
sqlalchemy.url = postgresql+psycopg2://berkay_wag_user:berkay_wag_user_password@postgres-service:5432/wag_database
|
||||||
|
|
||||||
|
|
||||||
|
[post_write_hooks]
|
||||||
|
# post_write_hooks defines scripts or Python functions that are run
|
||||||
|
# on newly generated revision scripts. See the documentation for further
|
||||||
|
# detail and examples
|
||||||
|
|
||||||
|
# format using "black" - use the console_scripts runner, against the "black" entrypoint
|
||||||
|
# hooks = black
|
||||||
|
# black.type = console_scripts
|
||||||
|
# black.entrypoint = black
|
||||||
|
# black.options = -l 79 REVISION_SCRIPT_FILENAME
|
||||||
|
|
||||||
|
# lint with attempts to fix using "ruff" - use the exec runner, execute a binary
|
||||||
|
# hooks = ruff
|
||||||
|
# ruff.type = exec
|
||||||
|
# ruff.executable = %(here)s/.venv/bin/ruff
|
||||||
|
# ruff.options = check --fix REVISION_SCRIPT_FILENAME
|
||||||
|
|
||||||
|
# Logging configuration
|
||||||
|
[loggers]
|
||||||
|
keys = root,sqlalchemy,alembic
|
||||||
|
|
||||||
|
[handlers]
|
||||||
|
keys = console
|
||||||
|
|
||||||
|
[formatters]
|
||||||
|
keys = generic
|
||||||
|
|
||||||
|
[logger_root]
|
||||||
|
level = WARNING
|
||||||
|
handlers = console
|
||||||
|
qualname =
|
||||||
|
|
||||||
|
[logger_sqlalchemy]
|
||||||
|
level = WARNING
|
||||||
|
handlers =
|
||||||
|
qualname = sqlalchemy.engine
|
||||||
|
|
||||||
|
[logger_alembic]
|
||||||
|
level = INFO
|
||||||
|
handlers =
|
||||||
|
qualname = alembic
|
||||||
|
|
||||||
|
[handler_console]
|
||||||
|
class = StreamHandler
|
||||||
|
args = (sys.stderr,)
|
||||||
|
level = NOTSET
|
||||||
|
formatter = generic
|
||||||
|
|
||||||
|
[formatter_generic]
|
||||||
|
format = %(levelname)-5.5s [%(name)s] %(message)s
|
||||||
|
datefmt = %H:%M:%S
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Generic single-database configuration.
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
from logging.config import fileConfig
|
||||||
|
|
||||||
|
from sqlalchemy import engine_from_config
|
||||||
|
from sqlalchemy import pool
|
||||||
|
|
||||||
|
from alembic import context
|
||||||
|
from Schemas import *
|
||||||
|
from Controllers.Postgres.database import Base
|
||||||
|
|
||||||
|
# this is the Alembic Config object, which provides
|
||||||
|
# access to the values within the .ini file in use.
|
||||||
|
config = context.config
|
||||||
|
|
||||||
|
# Interpret the config file for Python logging.
|
||||||
|
# This line sets up loggers basically.
|
||||||
|
if config.config_file_name is not None:
|
||||||
|
fileConfig(config.config_file_name)
|
||||||
|
|
||||||
|
target_metadata = Base.metadata
|
||||||
|
|
||||||
|
# other values from the config, defined by the needs of env.py,
|
||||||
|
# can be acquired:
|
||||||
|
# my_important_option = config.get_main_option("my_important_option")
|
||||||
|
# ... etc.
|
||||||
|
|
||||||
|
|
||||||
|
def run_migrations_offline() -> None:
|
||||||
|
"""Run migrations in 'offline' mode.
|
||||||
|
|
||||||
|
This configures the context with just a URL
|
||||||
|
and not an Engine, though an Engine is acceptable
|
||||||
|
here as well. By skipping the Engine creation
|
||||||
|
we don't even need a DBAPI to be available.
|
||||||
|
|
||||||
|
Calls to context.execute() here emit the given string to the
|
||||||
|
script output.
|
||||||
|
|
||||||
|
"""
|
||||||
|
url = config.get_main_option("sqlalchemy.url")
|
||||||
|
context.configure(
|
||||||
|
url=url,
|
||||||
|
target_metadata=target_metadata,
|
||||||
|
literal_binds=True,
|
||||||
|
dialect_opts={"paramstyle": "named"},
|
||||||
|
)
|
||||||
|
|
||||||
|
with context.begin_transaction():
|
||||||
|
context.run_migrations()
|
||||||
|
|
||||||
|
|
||||||
|
def run_migrations_online() -> None:
|
||||||
|
"""Run migrations in 'online' mode.
|
||||||
|
|
||||||
|
In this scenario we need to create an Engine
|
||||||
|
and associate a connection with the context.
|
||||||
|
|
||||||
|
"""
|
||||||
|
connectable = engine_from_config(
|
||||||
|
config.get_section(config.config_ini_section, {}),
|
||||||
|
prefix="sqlalchemy.",
|
||||||
|
poolclass=pool.NullPool,
|
||||||
|
)
|
||||||
|
|
||||||
|
with connectable.connect() as connection:
|
||||||
|
context.configure(connection=connection, target_metadata=target_metadata)
|
||||||
|
|
||||||
|
with context.begin_transaction():
|
||||||
|
context.run_migrations()
|
||||||
|
|
||||||
|
|
||||||
|
if context.is_offline_mode():
|
||||||
|
run_migrations_offline()
|
||||||
|
else:
|
||||||
|
run_migrations_online()
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
"""${message}
|
||||||
|
|
||||||
|
Revision ID: ${up_revision}
|
||||||
|
Revises: ${down_revision | comma,n}
|
||||||
|
Create Date: ${create_date}
|
||||||
|
|
||||||
|
"""
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
${imports if imports else ""}
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = ${repr(up_revision)}
|
||||||
|
down_revision: Union[str, None] = ${repr(down_revision)}
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
|
||||||
|
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
"""Upgrade schema."""
|
||||||
|
${upgrades if upgrades else "pass"}
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
"""Downgrade schema."""
|
||||||
|
${downgrades if downgrades else "pass"}
|
||||||
|
|
@ -1,18 +1,21 @@
|
||||||
from Schemas import (
|
from Controllers.Postgres.database import get_db
|
||||||
BuildLivingSpace,
|
|
||||||
BuildParts,
|
from init_app_defaults import create_application_defaults
|
||||||
Companies,
|
from init_enums import init_api_enums_build_types
|
||||||
Departments,
|
from init_alembic import generate_alembic
|
||||||
Duties,
|
from init_occupant_types import create_occupant_types_defaults
|
||||||
Duty,
|
from init_services import create_modules_and_services_and_actions
|
||||||
Staff,
|
from init_address import create_one_address
|
||||||
Employees,
|
|
||||||
Event2Employee,
|
set_alembic = True
|
||||||
Event2Occupant,
|
|
||||||
OccupantTypes,
|
|
||||||
Users,
|
|
||||||
UsersTokens,
|
|
||||||
)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
pass
|
|
||||||
|
with get_db() as db_session:
|
||||||
|
if set_alembic:
|
||||||
|
generate_alembic(session=db_session)
|
||||||
|
init_api_enums_build_types(db_session=db_session)
|
||||||
|
create_application_defaults(db_session=db_session)
|
||||||
|
create_occupant_types_defaults(db_session=db_session)
|
||||||
|
create_modules_and_services_and_actions(db_session=db_session)
|
||||||
|
create_one_address(db_session=db_session)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
from Schemas import (
|
||||||
|
AddressCity,
|
||||||
|
AddressStreet,
|
||||||
|
AddressLocality,
|
||||||
|
AddressDistrict,
|
||||||
|
AddressNeighborhood,
|
||||||
|
AddressState,
|
||||||
|
AddressCountry,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_one_address(db_session):
|
||||||
|
|
||||||
|
address_list = []
|
||||||
|
country = AddressCountry.find_or_create(
|
||||||
|
country_name="TÜRKİYE", country_code="TR", db=db_session, is_confirmed=True
|
||||||
|
)
|
||||||
|
address_list.append(country)
|
||||||
|
state = AddressState.find_or_create(
|
||||||
|
state_name="TÜRKİYE",
|
||||||
|
state_code="TR",
|
||||||
|
phone_code="90",
|
||||||
|
country_id=country.id,
|
||||||
|
country_uu_id=str(country.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
address_list.append(state)
|
||||||
|
city = AddressCity.find_or_create(
|
||||||
|
city_name="ANKARA",
|
||||||
|
city_code="6",
|
||||||
|
licence_plate="06",
|
||||||
|
state_id=state.id,
|
||||||
|
state_uu_id=str(state.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
address_list.append(city)
|
||||||
|
district = AddressDistrict.find_or_create(
|
||||||
|
district_name="ÇANKAYA",
|
||||||
|
district_code="1231",
|
||||||
|
city_id=city.id,
|
||||||
|
city_uu_id=str(city.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
address_list.append(district)
|
||||||
|
locality = AddressLocality.find_or_create(
|
||||||
|
locality_name="MERKEZ",
|
||||||
|
locality_code="2431",
|
||||||
|
type_code="3",
|
||||||
|
type_description=None,
|
||||||
|
district_id=district.id,
|
||||||
|
district_uu_id=str(district.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
address_list.append(locality)
|
||||||
|
neighborhood = AddressNeighborhood.find_or_create(
|
||||||
|
neighborhood_name="AYRANCI MAHALLESİ",
|
||||||
|
neighborhood_code="1522",
|
||||||
|
type_code="1",
|
||||||
|
type_description="MAHALLESİ",
|
||||||
|
locality_id=locality.id,
|
||||||
|
locality_uu_id=str(locality.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
address_list.append(neighborhood)
|
||||||
|
street = AddressStreet.find_or_create(
|
||||||
|
street_name="REŞAT NURİ CADDESİ",
|
||||||
|
type_description="CADDESİ",
|
||||||
|
type_code="3",
|
||||||
|
street_code="52270",
|
||||||
|
neighborhood_id=neighborhood.id,
|
||||||
|
neighborhood_uu_id=str(neighborhood.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
address_list.append(street)
|
||||||
|
for address_single in address_list:
|
||||||
|
address_single.save(db=db_session)
|
||||||
|
return
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def generate_alembic(session):
|
||||||
|
from sqlalchemy import text
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = session.execute(
|
||||||
|
text(
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = "
|
||||||
|
"'alembic_version') AS table_existence;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if result.first()[0]:
|
||||||
|
session.execute(text("delete from alembic_version;"))
|
||||||
|
session.commit()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
finally:
|
||||||
|
run_command = "python -m alembic stamp head;"
|
||||||
|
run_command += (
|
||||||
|
"python -m alembic revision --autogenerate;python -m alembic upgrade head;"
|
||||||
|
)
|
||||||
|
os.system(run_command)
|
||||||
|
|
@ -0,0 +1,410 @@
|
||||||
|
import arrow
|
||||||
|
|
||||||
|
from Modules.Token.password_module import PasswordModule
|
||||||
|
from Controllers.Mongo.database import mongo_handler
|
||||||
|
|
||||||
|
|
||||||
|
def create_application_defaults(db_session):
|
||||||
|
|
||||||
|
from Schemas import (
|
||||||
|
Companies,
|
||||||
|
Departments,
|
||||||
|
Duty,
|
||||||
|
Duties,
|
||||||
|
Employees,
|
||||||
|
People,
|
||||||
|
Users,
|
||||||
|
Staff,
|
||||||
|
RelationshipDutyCompany,
|
||||||
|
)
|
||||||
|
|
||||||
|
created_list = []
|
||||||
|
created_by, confirmed_by = "System", "System"
|
||||||
|
company_management = Companies.find_or_create(
|
||||||
|
**{
|
||||||
|
"formal_name": "Evyos LTD",
|
||||||
|
"public_name": "Evyos Verimlilik Sistemleri",
|
||||||
|
"company_type": "LTD",
|
||||||
|
"commercial_type": "Commercial",
|
||||||
|
"tax_no": "123132123132",
|
||||||
|
"company_tag": "Evyos",
|
||||||
|
"default_lang_type": "TR",
|
||||||
|
"default_money_type": "TL",
|
||||||
|
"is_commercial": True,
|
||||||
|
"is_confirmed": True,
|
||||||
|
},
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(company_management)
|
||||||
|
active_row = dict(
|
||||||
|
is_confirmed=True, active=True, deleted=False, is_notification_send=True
|
||||||
|
)
|
||||||
|
company_id, company_uu_id = company_management.id, str(company_management.uu_id)
|
||||||
|
created_list = []
|
||||||
|
execution = Departments.find_or_create(
|
||||||
|
department_name="Execution Office",
|
||||||
|
department_code="EO001",
|
||||||
|
company_id=company_id,
|
||||||
|
company_uu_id=str(company_uu_id),
|
||||||
|
**active_row,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(execution)
|
||||||
|
it_dept = Departments.find_or_create(
|
||||||
|
department_name="IT Department",
|
||||||
|
department_code="ITD001",
|
||||||
|
company_id=company_id,
|
||||||
|
company_uu_id=str(company_uu_id),
|
||||||
|
**active_row,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(it_dept)
|
||||||
|
bm_duty = Duty.find_or_create(
|
||||||
|
duty_name="Business Manager",
|
||||||
|
duty_code="BM0001",
|
||||||
|
duty_description="Business Manager",
|
||||||
|
**active_row,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(bm_duty)
|
||||||
|
it_duty = Duty.find_or_create(
|
||||||
|
duty_name="IT Manager",
|
||||||
|
duty_code="IT0001",
|
||||||
|
duty_description="IT Manager",
|
||||||
|
**active_row,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(it_duty)
|
||||||
|
bulk_duty = Duty.find_or_create(
|
||||||
|
duty_name="BULK",
|
||||||
|
duty_code="BULK",
|
||||||
|
duty_description="BULK RECORDS OF THE COMPANY",
|
||||||
|
**active_row,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(bulk_duty)
|
||||||
|
occu_duty = Duty.find_or_create(
|
||||||
|
duty_name="OCCUPANT",
|
||||||
|
duty_code="OCCUPANT",
|
||||||
|
duty_description="OCCUPANT RECORDS OF THE COMPANY",
|
||||||
|
**active_row,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(occu_duty)
|
||||||
|
duties_created_bm = Duties.find_or_create(
|
||||||
|
company_id=company_id,
|
||||||
|
company_uu_id=str(company_uu_id),
|
||||||
|
duties_id=bm_duty.id,
|
||||||
|
duties_uu_id=str(bm_duty.uu_id),
|
||||||
|
department_id=execution.id,
|
||||||
|
department_uu_id=str(execution.uu_id),
|
||||||
|
**active_row,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(duties_created_bm)
|
||||||
|
duties_created_it = Duties.find_or_create(
|
||||||
|
company_id=company_id,
|
||||||
|
company_uu_id=str(company_uu_id),
|
||||||
|
duties_id=it_duty.id,
|
||||||
|
duties_uu_id=str(it_duty.uu_id),
|
||||||
|
department_id=it_dept.id,
|
||||||
|
department_uu_id=str(it_dept.uu_id),
|
||||||
|
**active_row,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(duties_created_it)
|
||||||
|
duties_created__ex = Duties.find_or_create(
|
||||||
|
company_id=company_id,
|
||||||
|
company_uu_id=str(company_uu_id),
|
||||||
|
duties_id=bulk_duty.id,
|
||||||
|
duties_uu_id=str(bulk_duty.uu_id),
|
||||||
|
department_id=execution.id,
|
||||||
|
department_uu_id=str(execution.uu_id),
|
||||||
|
**active_row,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(duties_created__ex)
|
||||||
|
duties_created_at = Duties.find_or_create(
|
||||||
|
company_id=company_id,
|
||||||
|
company_uu_id=str(company_uu_id),
|
||||||
|
duties_id=occu_duty.id,
|
||||||
|
duties_uu_id=str(occu_duty.uu_id),
|
||||||
|
department_id=execution.id,
|
||||||
|
department_uu_id=str(execution.uu_id),
|
||||||
|
**active_row,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(duties_created_at)
|
||||||
|
bulk_duty = Duty.filter_by_one(system=True, duty_code="BULK", db=db_session).data
|
||||||
|
|
||||||
|
it_dept = Departments.filter_by_one(
|
||||||
|
system=True,
|
||||||
|
department_name="IT Department",
|
||||||
|
department_code="ITD001",
|
||||||
|
company_id=company_management.id,
|
||||||
|
company_uu_id=str(company_management.uu_id),
|
||||||
|
db=db_session,
|
||||||
|
).data
|
||||||
|
|
||||||
|
created_duty = Duty.find_or_create(
|
||||||
|
duty_name="Database Manager",
|
||||||
|
duty_code="DM",
|
||||||
|
duty_description="Database Manager",
|
||||||
|
created_by=created_by,
|
||||||
|
confirmed_by=confirmed_by,
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(created_duty)
|
||||||
|
|
||||||
|
created_duty = Duty.find_or_create(
|
||||||
|
duty_name="Network Manager",
|
||||||
|
duty_code="NM",
|
||||||
|
duty_description="Network Manager",
|
||||||
|
created_by=created_by,
|
||||||
|
confirmed_by=confirmed_by,
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(created_duty)
|
||||||
|
|
||||||
|
application_manager_duty = Duty.find_or_create(
|
||||||
|
duty_name="Application Manager",
|
||||||
|
duty_code="AM",
|
||||||
|
duty_description="Application Manager",
|
||||||
|
created_by=created_by,
|
||||||
|
confirmed_by=confirmed_by,
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(application_manager_duty)
|
||||||
|
application_super_user_duty = Duty.find_or_create(
|
||||||
|
duty_name="Super User",
|
||||||
|
duty_code="SUE",
|
||||||
|
duty_description="Super User",
|
||||||
|
created_by=created_by,
|
||||||
|
confirmed_by=confirmed_by,
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(application_super_user_duty)
|
||||||
|
application_manager_duties = Duties.find_or_create(
|
||||||
|
department_id=it_dept.id,
|
||||||
|
department_uu_id=str(it_dept.uu_id),
|
||||||
|
duties_id=application_manager_duty.id,
|
||||||
|
duties_uu_id=str(application_manager_duty.uu_id),
|
||||||
|
company_id=company_management.id,
|
||||||
|
company_uu_id=str(company_management.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(application_manager_duties)
|
||||||
|
super_user_duties = Duties.find_or_create(
|
||||||
|
department_id=it_dept.id,
|
||||||
|
department_uu_id=str(it_dept.uu_id),
|
||||||
|
duties_id=application_super_user_duty.id,
|
||||||
|
duties_uu_id=str(application_manager_duty.uu_id),
|
||||||
|
company_id=company_management.id,
|
||||||
|
company_uu_id=str(company_management.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(super_user_duties)
|
||||||
|
RelationshipDutyCompany.find_or_create(
|
||||||
|
duties_id=application_manager_duties.id,
|
||||||
|
owner_id=company_management.id,
|
||||||
|
member_id=company_management.id,
|
||||||
|
parent_id=None,
|
||||||
|
child_count=0,
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(application_manager_duties)
|
||||||
|
RelationshipDutyCompany.find_or_create(
|
||||||
|
duties_id=super_user_duties.id,
|
||||||
|
owner_id=company_management.id,
|
||||||
|
member_id=company_management.id,
|
||||||
|
parent_id=None,
|
||||||
|
child_count=0,
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(super_user_duties)
|
||||||
|
|
||||||
|
app_manager = People.find_or_create(
|
||||||
|
**{
|
||||||
|
"person_tag": "BAM-System",
|
||||||
|
"firstname": "Berkay Application Manager",
|
||||||
|
"surname": "Karatay",
|
||||||
|
"sex_code": "M",
|
||||||
|
"middle_name": "",
|
||||||
|
"father_name": "Father",
|
||||||
|
"mother_name": "Mother",
|
||||||
|
"country_code": "TR",
|
||||||
|
"national_identity_id": "12312312312",
|
||||||
|
"birth_place": "Ankara",
|
||||||
|
"birth_date": "01.07.1990",
|
||||||
|
"tax_no": "1231231231",
|
||||||
|
"is_confirmed": True,
|
||||||
|
},
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(app_manager)
|
||||||
|
sup_manager = People.find_or_create(
|
||||||
|
**{
|
||||||
|
"person_tag": "BSU-System",
|
||||||
|
"firstname": "Berkay Super User",
|
||||||
|
"surname": "Karatay",
|
||||||
|
"sex_code": "M",
|
||||||
|
"middle_name": "",
|
||||||
|
"father_name": "Father",
|
||||||
|
"mother_name": "Mother",
|
||||||
|
"country_code": "TR",
|
||||||
|
"national_identity_id": "12312312313",
|
||||||
|
"birth_place": "Ankara",
|
||||||
|
"birth_date": "01.07.1990",
|
||||||
|
"tax_no": "1231231232",
|
||||||
|
},
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(sup_manager)
|
||||||
|
application_manager_staff = Staff.find_or_create(
|
||||||
|
staff_description="Application Manager",
|
||||||
|
staff_name="Application Manager Employee",
|
||||||
|
staff_code="AME",
|
||||||
|
duties_id=application_manager_duties.id,
|
||||||
|
duties_uu_id=str(application_manager_duty.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(application_manager_staff)
|
||||||
|
super_user_staff = Staff.find_or_create(
|
||||||
|
staff_description="Super User",
|
||||||
|
staff_name="Super User Employee",
|
||||||
|
staff_code="SUE",
|
||||||
|
duties_id=super_user_duties.id,
|
||||||
|
duties_uu_id=str(application_manager_duty.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(super_user_staff)
|
||||||
|
app_manager_employee = Employees.find_or_create(
|
||||||
|
staff_id=application_manager_staff.id,
|
||||||
|
staff_uu_id=str(application_manager_staff.uu_id),
|
||||||
|
people_id=app_manager.id,
|
||||||
|
people_uu_id=str(app_manager.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(app_manager_employee)
|
||||||
|
|
||||||
|
super_user_employee = Employees.find_or_create(
|
||||||
|
staff_id=super_user_staff.id,
|
||||||
|
staff_uu_id=str(super_user_staff.uu_id),
|
||||||
|
people_id=sup_manager.id,
|
||||||
|
people_uu_id=str(sup_manager.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(super_user_employee)
|
||||||
|
|
||||||
|
app_manager_user = Users.find_or_create(
|
||||||
|
person_id=app_manager.id,
|
||||||
|
person_uu_id=str(app_manager.uu_id),
|
||||||
|
user_tag=app_manager.person_tag,
|
||||||
|
email="karatay.berkay.man@evyos.com.tr",
|
||||||
|
phone_number="+901111111111",
|
||||||
|
avatar="https://s.tmimgcdn.com/scr/800x500/276800/building-home-nature-logo-vector-template-3_276851-original.jpg",
|
||||||
|
related_company=str(company_management.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(app_manager_user)
|
||||||
|
app_manager_user.password_expiry_begins = str(arrow.now())
|
||||||
|
app_manager_user.password_token = PasswordModule.generate_refresher_token()
|
||||||
|
|
||||||
|
main_domain, collection_name = (
|
||||||
|
"evyos.com.tr",
|
||||||
|
f"{str(company_management.uu_id)}*Domain",
|
||||||
|
)
|
||||||
|
with mongo_handler.collection(collection_name) as mongo_engine:
|
||||||
|
mongo_engine.insert_one(
|
||||||
|
document={
|
||||||
|
"user_uu_id": str(app_manager_user.uu_id),
|
||||||
|
"other_domains_list": [main_domain],
|
||||||
|
"main_domain": main_domain,
|
||||||
|
"modified_at": arrow.now().timestamp(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
sup_manager_employee = Users.find_or_create(
|
||||||
|
person_id=sup_manager.id,
|
||||||
|
person_uu_id=str(sup_manager.uu_id),
|
||||||
|
user_tag=sup_manager.person_tag,
|
||||||
|
email="karatay.berkay.sup@evyos.com.tr",
|
||||||
|
phone_number="+901111111112",
|
||||||
|
avatar="https://s.tmimgcdn.com/scr/800x500/276800/building-home-nature-logo-vector-template-3_276851-original.jpg",
|
||||||
|
created_by=created_by,
|
||||||
|
confirmed_by=confirmed_by,
|
||||||
|
related_company=str(company_management.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
is_notification_send=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_list.append(sup_manager_employee)
|
||||||
|
|
||||||
|
sup_manager_employee.password_expiry_begins = str(arrow.now())
|
||||||
|
sup_manager_employee.password_token = PasswordModule.generate_refresher_token()
|
||||||
|
with mongo_handler.collection(collection_name) as mongo_engine:
|
||||||
|
mongo_engine.insert_one(
|
||||||
|
document={
|
||||||
|
"user_uu_id": str(sup_manager_employee.uu_id),
|
||||||
|
"other_domains_list": [main_domain],
|
||||||
|
"main_domain": main_domain,
|
||||||
|
"modified_at": arrow.now().timestamp(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
db_session.commit()
|
||||||
|
|
||||||
|
print("All Defaults Create is now completed")
|
||||||
|
|
@ -0,0 +1,253 @@
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class InsertBuildTypes(BaseModel):
|
||||||
|
function_code: str
|
||||||
|
type_code: str
|
||||||
|
lang: str
|
||||||
|
type_name: str
|
||||||
|
|
||||||
|
|
||||||
|
def init_api_enums_build_types(db_session):
|
||||||
|
from Schemas import BuildTypes, ApiEnumDropdown
|
||||||
|
|
||||||
|
insert_types = [
|
||||||
|
{
|
||||||
|
"function_code": "EVYOS",
|
||||||
|
"type_code": "APT_KZN",
|
||||||
|
"type_name": "Apartman Kazan Dairesi",
|
||||||
|
"lang": "TR",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function_code": "EVYOS",
|
||||||
|
"type_code": "APT_GRJ",
|
||||||
|
"type_name": "Apartman Garaj",
|
||||||
|
"lang": "TR",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function_code": "EVYOS",
|
||||||
|
"type_code": "APT_DP",
|
||||||
|
"type_name": "Apartman Depo",
|
||||||
|
"lang": "TR",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function_code": "EVYOS",
|
||||||
|
"type_code": "DAIRE",
|
||||||
|
"type_name": "Apartman Dairesi",
|
||||||
|
"lang": "TR",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function_code": "EVYOS",
|
||||||
|
"type_code": "APT",
|
||||||
|
"type_name": "Apartman Binası",
|
||||||
|
"lang": "TR",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function_code": "EVYOS",
|
||||||
|
"type_code": "APT_YNT",
|
||||||
|
"type_name": "Apartman Yönetimi",
|
||||||
|
"lang": "TR",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function_code": "EVYOS",
|
||||||
|
"type_code": "APT_PRK",
|
||||||
|
"type_name": "Apartman Açık Park Alanı",
|
||||||
|
"lang": "TR",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function_code": "EVYOS",
|
||||||
|
"type_code": "APT_YSL",
|
||||||
|
"type_name": "Apartman Yeşil Alan",
|
||||||
|
"lang": "TR",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"function_code": "EVYOS",
|
||||||
|
"type_code": "APT_YOL",
|
||||||
|
"type_name": "Apartman Ara Yol",
|
||||||
|
"lang": "TR",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
for insert_type in insert_types:
|
||||||
|
build_types = InsertBuildTypes(
|
||||||
|
function_code="EVYOS",
|
||||||
|
lang=insert_type["lang"],
|
||||||
|
type_code=str(insert_type["type_code"]).upper(),
|
||||||
|
type_name=insert_type["type_name"],
|
||||||
|
)
|
||||||
|
created_build_type = BuildTypes.find_or_create(
|
||||||
|
**build_types.model_dump(), is_confirmed=True, db=db_session
|
||||||
|
)
|
||||||
|
created_build_type.save(db=db_session)
|
||||||
|
|
||||||
|
insert_enums = [
|
||||||
|
{"enum_class": "BuildDuesTypes", "type_code": "BDT-D", "type_name": "Debit"},
|
||||||
|
{
|
||||||
|
"enum_class": "BuildDuesTypes",
|
||||||
|
"type_code": "BDT-A",
|
||||||
|
"type_name": "Add Debit",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "BuildDuesTypes",
|
||||||
|
"type_code": "BDT-R",
|
||||||
|
"type_name": "Renovation",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "BuildDuesTypes",
|
||||||
|
"type_code": "BDT-L",
|
||||||
|
"type_name": "Lawyer expence",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "BuildDuesTypes",
|
||||||
|
"type_code": "BDT-S",
|
||||||
|
"type_name": "Service fee",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "BuildDuesTypes",
|
||||||
|
"type_code": "BDT-I",
|
||||||
|
"type_name": "Information",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "AccountingReceiptTypes",
|
||||||
|
"type_code": "ART-A",
|
||||||
|
"type_name": "Kasa Tahsil Fişi",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "AccountingReceiptTypes",
|
||||||
|
"type_code": "ART-E",
|
||||||
|
"type_name": "Kasa Tediye Fişi",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "AccountingReceiptTypes",
|
||||||
|
"type_code": "ART-M",
|
||||||
|
"type_name": "Mahsup Fişi",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "AccountingReceiptTypes",
|
||||||
|
"type_code": "ART-O",
|
||||||
|
"type_name": "Açılış Fişi",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "AccountingReceiptTypes",
|
||||||
|
"type_code": "ART-C",
|
||||||
|
"type_name": "Kapanış Fişi",
|
||||||
|
},
|
||||||
|
{"enum_class": "IbanBudgetType", "type_code": "IBT-I", "type_name": "Iban"},
|
||||||
|
{"enum_class": "IbanBudgetType", "type_code": "IBT-B", "type_name": "Budget"},
|
||||||
|
{
|
||||||
|
"enum_class": "IbanBudgetType",
|
||||||
|
"type_code": "IBT-TR",
|
||||||
|
"type_name": "Transaction records",
|
||||||
|
},
|
||||||
|
{"enum_class": "ProjectTypes", "type_code": "R", "type_name": "Tadilat"},
|
||||||
|
{
|
||||||
|
"enum_class": "ProjectTypes",
|
||||||
|
"type_code": "PT-C",
|
||||||
|
"type_name": "Mahkeme süreçleri",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "ProjectTypes",
|
||||||
|
"type_code": "PT-Z",
|
||||||
|
"type_name": "Sıfır Bakiye",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "EdmBudgetType",
|
||||||
|
"type_code": "PT-B",
|
||||||
|
"type_name": "Banka records",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "EdmBudgetType",
|
||||||
|
"type_code": "PT-S",
|
||||||
|
"type_name": "Sistem kaydı",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "EdmBudgetType",
|
||||||
|
"type_code": "EBT-C",
|
||||||
|
"type_name": "Build, Flat or Site records",
|
||||||
|
},
|
||||||
|
{"enum_class": "ExpireType", "type_code": "1", "type_name": "daily"},
|
||||||
|
{"enum_class": "ExpireType", "type_code": "7", "type_name": "weekly"},
|
||||||
|
{"enum_class": "ExpireType", "type_code": "30", "type_name": "monthly"},
|
||||||
|
{"enum_class": "ExpireType", "type_code": "90", "type_name": "quarter"},
|
||||||
|
{"enum_class": "ExpireType", "type_code": "180", "type_name": "six_month"},
|
||||||
|
{"enum_class": "ExpireType", "type_code": "365", "type_name": "yearly"},
|
||||||
|
{"enum_class": "PhoneType", "type_code": "M", "type_name": "cep tel"},
|
||||||
|
{"enum_class": "PhoneType", "type_code": "L", "type_name": "sabit telefon"},
|
||||||
|
{"enum_class": "PhoneType", "type_code": "F", "type_name": "fax"},
|
||||||
|
{"enum_class": "PhoneType", "type_code": "C", "type_name": "santral"},
|
||||||
|
{
|
||||||
|
"enum_class": "PhoneType",
|
||||||
|
"type_code": "G",
|
||||||
|
"type_name": "ülke genelindeki hatlar 444",
|
||||||
|
},
|
||||||
|
{"enum_class": "PerComType", "type_code": "1", "type_name": "Person"},
|
||||||
|
{"enum_class": "PerComType", "type_code": "2", "type_name": "Company"},
|
||||||
|
{"enum_class": "Directions", "type_code": "NN", "type_name": "North"},
|
||||||
|
{"enum_class": "Directions", "type_code": "EE", "type_name": "East"},
|
||||||
|
{"enum_class": "Directions", "type_code": "SS", "type_name": "South"},
|
||||||
|
{"enum_class": "Directions", "type_code": "WW", "type_name": "West"},
|
||||||
|
{"enum_class": "Directions", "type_code": "NE", "type_name": "North East"},
|
||||||
|
{"enum_class": "Directions", "type_code": "NW", "type_name": "North West"},
|
||||||
|
{"enum_class": "Directions", "type_code": "SE", "type_name": "South East"},
|
||||||
|
{"enum_class": "Directions", "type_code": "SW", "type_name": "South West"},
|
||||||
|
{
|
||||||
|
"enum_class": "MeetingTypes",
|
||||||
|
"type_code": "MT-RBM",
|
||||||
|
"type_name": "Regular Building Meeting",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "MeetingTypes",
|
||||||
|
"type_code": "MT-DBM",
|
||||||
|
"type_name": "Disaster Building Meeting",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "MeetingTypes",
|
||||||
|
"type_code": "MT-EBM",
|
||||||
|
"type_name": "Emergency Building Meeting",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "DebitTypes",
|
||||||
|
"type_code": "DT-D",
|
||||||
|
"type_name": "Debit Sender",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "DebitTypes",
|
||||||
|
"type_code": "DT-R",
|
||||||
|
"type_name": "Credit Receiver",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "DebitTypes",
|
||||||
|
"type_code": "DT-Z",
|
||||||
|
"type_name": "Zero Balance",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "TimePeriod",
|
||||||
|
"type_code": "TP-W",
|
||||||
|
"type_name": "Weekly",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "TimePeriod",
|
||||||
|
"type_code": "TP-M",
|
||||||
|
"type_name": "Monthly",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "TimePeriod",
|
||||||
|
"type_code": "TP-Q",
|
||||||
|
"type_name": "Quarterly",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum_class": "TimePeriod",
|
||||||
|
"type_code": "TP-Y",
|
||||||
|
"type_name": "Yearly",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
for insert_enum in insert_enums:
|
||||||
|
created_api_enum = ApiEnumDropdown.find_or_create(
|
||||||
|
enum_class=insert_enum["enum_class"],
|
||||||
|
value=insert_enum["type_name"],
|
||||||
|
key=str(insert_enum["type_code"]).upper(),
|
||||||
|
description=insert_enum["type_name"],
|
||||||
|
is_confirmed=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_api_enum.save(db=db_session)
|
||||||
|
|
@ -0,0 +1,218 @@
|
||||||
|
def create_occupant_types_defaults(db_session):
|
||||||
|
from Schemas import OccupantTypes
|
||||||
|
|
||||||
|
"""
|
||||||
|
occupant_category = mapped_column(String, server_default="")
|
||||||
|
occupant_category_type = mapped_column(String, server_default="")
|
||||||
|
occupant_is_unique = mapped_column(Boolean, server_default="0")
|
||||||
|
"""
|
||||||
|
list_occupant_types = [
|
||||||
|
{
|
||||||
|
"occupant_type": "Toplantı Başkanı",
|
||||||
|
"occupant_description": "Toplantı Başkanı",
|
||||||
|
"occupant_code": "MT-PRS",
|
||||||
|
"occupant_category": "Toplantı",
|
||||||
|
"occupant_category_type": "MT",
|
||||||
|
"occupant_is_unique": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Toplantı Katip",
|
||||||
|
"occupant_description": "Toplantıda tutanak tutan kişi",
|
||||||
|
"occupant_code": "MT-WRT",
|
||||||
|
"occupant_category": "Toplantı",
|
||||||
|
"occupant_category_type": "MT",
|
||||||
|
"occupant_is_unique": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Toplantı Katılımcısı",
|
||||||
|
"occupant_description": "Toplantıda sadece katılan kişi",
|
||||||
|
"occupant_code": "MT-ATT",
|
||||||
|
"occupant_category": "Toplantı",
|
||||||
|
"occupant_category_type": "MT",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Toplantı Danışman",
|
||||||
|
"occupant_description": "Toplantıda danışmanlık yapan kişi",
|
||||||
|
"occupant_code": "MT-ADV",
|
||||||
|
"occupant_category": "Toplantı",
|
||||||
|
"occupant_category_type": "MT",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Toplantı Seçilmiş Başkanı",
|
||||||
|
"occupant_description": "Toplantı Seçilmiş Başkanı",
|
||||||
|
"occupant_code": "MT-VPR",
|
||||||
|
"occupant_category": "Toplantı",
|
||||||
|
"occupant_category_type": "MT",
|
||||||
|
"occupant_is_unique": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Daire Sahibi",
|
||||||
|
"occupant_description": "Daire Sahibi",
|
||||||
|
"occupant_code": "FL-OWN",
|
||||||
|
"occupant_category": "Daire",
|
||||||
|
"occupant_category_type": "FL",
|
||||||
|
"occupant_is_unique": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Daire Kiracısı",
|
||||||
|
"occupant_description": "Daire Kiracısı",
|
||||||
|
"occupant_code": "FL-TEN",
|
||||||
|
"occupant_category": "Daire",
|
||||||
|
"occupant_category_type": "FL",
|
||||||
|
"occupant_is_unique": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Daire Sakini",
|
||||||
|
"occupant_description": "Daire Sakini",
|
||||||
|
"occupant_code": "FL-RES",
|
||||||
|
"occupant_category": "Daire",
|
||||||
|
"occupant_category_type": "FL",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Daire Sakini Vekili",
|
||||||
|
"occupant_description": "Daire Sakini Vekili",
|
||||||
|
"occupant_code": "FL-REP",
|
||||||
|
"occupant_category": "Daire",
|
||||||
|
"occupant_category_type": "FL",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Bina Avukatı",
|
||||||
|
"occupant_description": "Bina Avukatı",
|
||||||
|
"occupant_code": "BU-ATT",
|
||||||
|
"occupant_category": "Bina",
|
||||||
|
"occupant_category_type": "BU",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Bina Avukatı Yardımcısı",
|
||||||
|
"occupant_description": "Bina Avukatı Yardımcısı",
|
||||||
|
"occupant_code": "BU-ATA",
|
||||||
|
"occupant_category": "Bina",
|
||||||
|
"occupant_category_type": "BU",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Bina Denetmen Yardımcısı",
|
||||||
|
"occupant_description": "Bina Denetmen Yardımcısı",
|
||||||
|
"occupant_code": "BU-SPA",
|
||||||
|
"occupant_category": "Bina",
|
||||||
|
"occupant_category_type": "BU",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Bina Denetmeni",
|
||||||
|
"occupant_description": "Bina Denetmeni",
|
||||||
|
"occupant_code": "BU-SPV",
|
||||||
|
"occupant_category": "Bina",
|
||||||
|
"occupant_category_type": "BU",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Bina Yönetici Yardımcısı",
|
||||||
|
"occupant_description": "Bina Yönetici Yardımcısı",
|
||||||
|
"occupant_code": "BU-MNA",
|
||||||
|
"occupant_category": "Bina",
|
||||||
|
"occupant_category_type": "BU",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Bina Yöneticisi",
|
||||||
|
"occupant_description": "Bina Yöneticisi",
|
||||||
|
"occupant_code": "BU-MNG",
|
||||||
|
"occupant_category": "Bina",
|
||||||
|
"occupant_category_type": "BU",
|
||||||
|
"occupant_is_unique": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Bina Muhasabecisi",
|
||||||
|
"occupant_description": "Bina Muhasabecisi",
|
||||||
|
"occupant_code": "BU-ACC",
|
||||||
|
"occupant_category": "Bina",
|
||||||
|
"occupant_category_type": "BU",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Proje Lideri",
|
||||||
|
"occupant_description": "Proje Lideri",
|
||||||
|
"occupant_code": "PRJ-LDR",
|
||||||
|
"occupant_category": "Proje",
|
||||||
|
"occupant_category_type": "PRJ",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Proje Sorumlusu",
|
||||||
|
"occupant_description": "Proje Sorumlusu",
|
||||||
|
"occupant_code": "PRJ-RES",
|
||||||
|
"occupant_category": "Proje",
|
||||||
|
"occupant_category_type": "PRJ",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Proje Ekibi",
|
||||||
|
"occupant_description": "Proje Ekibi",
|
||||||
|
"occupant_code": "PRJ-EMP",
|
||||||
|
"occupant_category": "Proje",
|
||||||
|
"occupant_category_type": "PRJ",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Proje Finans Sorumlusu",
|
||||||
|
"occupant_description": "Proje Finans Sorumlusu",
|
||||||
|
"occupant_code": "PRJ-FIN",
|
||||||
|
"occupant_category": "Proje",
|
||||||
|
"occupant_category_type": "PRJ",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Proje Teknik Sorumlusu",
|
||||||
|
"occupant_description": "Proje Teknik Sorumlusu",
|
||||||
|
"occupant_code": "PRJ-TEC",
|
||||||
|
"occupant_category": "Proje",
|
||||||
|
"occupant_category_type": "PRJ",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Daire Mülkiyet Vekili",
|
||||||
|
"occupant_description": "Daire Mülkiyet Vekili",
|
||||||
|
"occupant_code": "FL-DEP", # deputy
|
||||||
|
"occupant_category": "Daire",
|
||||||
|
"occupant_category_type": "FL",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Bina Teknik Sorumlusu",
|
||||||
|
"occupant_description": "Bina Teknik Sorumlusu",
|
||||||
|
"occupant_code": "BU-TEC",
|
||||||
|
"occupant_category": "Bina",
|
||||||
|
"occupant_category_type": "BU",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Bina Teknik Elemanı",
|
||||||
|
"occupant_description": "Bina Teknik Elemanı",
|
||||||
|
"occupant_code": "BU-EMP",
|
||||||
|
"occupant_category": "Bina",
|
||||||
|
"occupant_category_type": "BU",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"occupant_type": "Bina Teknik Freelancer",
|
||||||
|
"occupant_description": "Bina Teknik Freelancer",
|
||||||
|
"occupant_code": "BU-FLC",
|
||||||
|
"occupant_category": "Bina",
|
||||||
|
"occupant_category_type": "BU",
|
||||||
|
"occupant_is_unique": False,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
for list_occupant_type in list_occupant_types:
|
||||||
|
try:
|
||||||
|
created_type = OccupantTypes.find_or_create(
|
||||||
|
**list_occupant_type, is_confirmed=True, db=db_session
|
||||||
|
)
|
||||||
|
created_type.save(db=db_session)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
def create_modules_and_services_and_actions(db_session):
|
||||||
|
from Schemas import (
|
||||||
|
Duty,
|
||||||
|
OccupantTypes,
|
||||||
|
Modules,
|
||||||
|
Services,
|
||||||
|
)
|
||||||
|
|
||||||
|
erp_module = Modules.find_or_create(
|
||||||
|
**{
|
||||||
|
"module_name": "EVYOS ERP",
|
||||||
|
"module_description": "EVYOS Enterprise Resource Planning",
|
||||||
|
"module_code": "EVYOS-ERP",
|
||||||
|
"module_layer": 1,
|
||||||
|
"is_default_module": False,
|
||||||
|
"is_confirmed": True,
|
||||||
|
},
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
erp_module.save(db=db_session)
|
||||||
|
|
||||||
|
build_module = Modules.find_or_create(
|
||||||
|
**{
|
||||||
|
"module_name": "Bina Yönetim Modülü",
|
||||||
|
"module_description": "Building Management Module",
|
||||||
|
"module_code": "BLD-MNG",
|
||||||
|
"module_layer": 1,
|
||||||
|
"is_default_module": False,
|
||||||
|
"is_confirmed": True,
|
||||||
|
},
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
build_module.save(db=db_session)
|
||||||
|
|
||||||
|
user_module = Modules.find_or_create(
|
||||||
|
**{
|
||||||
|
"module_name": "Kullancı Modülü",
|
||||||
|
"module_description": "Kullanıcı Genel Modülü",
|
||||||
|
"module_code": "USR-PUB",
|
||||||
|
"module_layer": 1,
|
||||||
|
"is_default_module": True,
|
||||||
|
"is_confirmed": True,
|
||||||
|
},
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
user_module.save(db=db_session)
|
||||||
|
|
||||||
|
erp_module_module_dict = dict(
|
||||||
|
module_id=erp_module.id,
|
||||||
|
module_uu_id=str(erp_module.uu_id),
|
||||||
|
)
|
||||||
|
build_module_module_dict = dict(
|
||||||
|
module_id=build_module.id,
|
||||||
|
module_uu_id=str(build_module.uu_id),
|
||||||
|
)
|
||||||
|
duty_objects = Duty.filter_all(
|
||||||
|
Duty.duty_code.notin_(["BULK", "OCCUPANT", "BM0001"]),
|
||||||
|
db=db_session,
|
||||||
|
).data
|
||||||
|
for duty_object in duty_objects:
|
||||||
|
created_service = Services.find_or_create(
|
||||||
|
**erp_module_module_dict,
|
||||||
|
service_name=duty_object.duty_name,
|
||||||
|
service_description=duty_object.duty_description,
|
||||||
|
service_code=f"SRE-{duty_object.duty_code}",
|
||||||
|
related_responsibility=duty_object.duty_code,
|
||||||
|
is_confirmed=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_service.save(db=db_session)
|
||||||
|
|
||||||
|
occupant_types = OccupantTypes.filter_all(db=db_session).data
|
||||||
|
for occupant_type in occupant_types:
|
||||||
|
created_service = Services.find_or_create(
|
||||||
|
**build_module_module_dict,
|
||||||
|
service_name=occupant_type.occupant_type,
|
||||||
|
service_description=occupant_type.occupant_description,
|
||||||
|
service_code=f"SRO-{occupant_type.occupant_code}",
|
||||||
|
related_responsibility=occupant_type.occupant_code,
|
||||||
|
is_confirmed=True,
|
||||||
|
db=db_session,
|
||||||
|
)
|
||||||
|
created_service.save(db=db_session)
|
||||||
|
|
@ -8,9 +8,9 @@ class Configs(BaseSettings):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PATH: str = ""
|
PATH: str = ""
|
||||||
HOST: str = ("",)
|
HOST: str = ""
|
||||||
PORT: int = (0,)
|
PORT: int = 0
|
||||||
LOG_LEVEL: str = ("info",)
|
LOG_LEVEL: str = "info"
|
||||||
RELOAD: int = 0
|
RELOAD: int = 0
|
||||||
ACCESS_TOKEN_TAG: str = ""
|
ACCESS_TOKEN_TAG: str = ""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,14 @@ from ApiServices.TemplateService.initializer.create_route import RouteRegisterCo
|
||||||
from .config import api_config
|
from .config import api_config
|
||||||
|
|
||||||
|
|
||||||
|
def create_events_if_any_cluster_set():
|
||||||
|
import events
|
||||||
|
|
||||||
|
for event_str in events.__all__:
|
||||||
|
if to_set_events := getattr(events, event_str, None):
|
||||||
|
to_set_events.set_events_to_database()
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
|
|
||||||
application = FastAPI(**api_config.api_info)
|
application = FastAPI(**api_config.api_info)
|
||||||
|
|
@ -36,6 +44,6 @@ def create_app():
|
||||||
|
|
||||||
route_register = RouteRegisterController(app=application, router_list=get_routes())
|
route_register = RouteRegisterController(app=application, router_list=get_routes())
|
||||||
application = route_register.register_routes()
|
application = route_register.register_routes()
|
||||||
|
create_events_if_any_cluster_set()
|
||||||
application.openapi = lambda _=application: create_openapi_schema(_)
|
application.openapi = lambda _=application: create_openapi_schema(_)
|
||||||
return application
|
return application
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from fastapi import APIRouter, Request, Response
|
from fastapi import APIRouter, Request, Response
|
||||||
|
|
||||||
from ApiServices.TemplateService.events.events_setter import event_cluster
|
from ApiServices.TemplateService.events.template.event import template_event_cluster
|
||||||
|
|
||||||
test_template_route = APIRouter(prefix="/test", tags=["Test"])
|
test_template_route = APIRouter(prefix="/test", tags=["Test"])
|
||||||
|
|
||||||
|
|
@ -8,30 +8,23 @@ test_template_route = APIRouter(prefix="/test", tags=["Test"])
|
||||||
@test_template_route.get(
|
@test_template_route.get(
|
||||||
path="/template",
|
path="/template",
|
||||||
description="Test Template Route",
|
description="Test Template Route",
|
||||||
operation_id="bb20c8c6-a289-4cab-9da7-34ca8a36c8e5"
|
operation_id="bb20c8c6-a289-4cab-9da7-34ca8a36c8e5",
|
||||||
)
|
)
|
||||||
def test_template(request: Request, response: Response):
|
def test_template(request: Request, response: Response):
|
||||||
"""
|
"""
|
||||||
Test Template Route
|
Test Template Route
|
||||||
"""
|
"""
|
||||||
headers = dict(request.headers)
|
event_cluster_matched = template_event_cluster.match_event(
|
||||||
event_cluster_matched = event_cluster.match_event(
|
|
||||||
event_keys=[
|
event_keys=[
|
||||||
"3f510dcf-9f84-4eb9-b919-f582f30adab1",
|
"3f510dcf-9f84-4eb9-b919-f582f30adab1",
|
||||||
"9f403034-deba-4e1f-b43e-b25d3c808d39",
|
"9f403034-deba-4e1f-b43e-b25d3c808d39",
|
||||||
"b8ec6e64-286a-4f60-8554-7a3865454944"
|
"b8ec6e64-286a-4f60-8554-7a3865454944",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
event_cluster_matched.example_callable()
|
|
||||||
response.headers["X-Header"] = "Test Header GET"
|
response.headers["X-Header"] = "Test Header GET"
|
||||||
return {
|
if runner_callable := event_cluster_matched.example_callable():
|
||||||
"completed": True,
|
return runner_callable
|
||||||
"message": "Test Template Route",
|
raise ValueError("Event key not found or multiple matches found")
|
||||||
"info": {
|
|
||||||
"host": headers.get("host", "Not Found"),
|
|
||||||
"user_agent": headers.get("user-agent", "Not Found"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@test_template_route.post(
|
@test_template_route.post(
|
||||||
|
|
@ -42,13 +35,14 @@ def test_template_post(request: Request, response: Response):
|
||||||
"""
|
"""
|
||||||
Test Template Route with Post Method
|
Test Template Route with Post Method
|
||||||
"""
|
"""
|
||||||
headers = dict(request.headers)
|
event_cluster_matched = template_event_cluster.match_event(
|
||||||
|
event_keys=[
|
||||||
|
"3f510dcf-9f84-4eb9-b919-f582f30adab1",
|
||||||
|
"9f403034-deba-4e1f-b43e-b25d3c808d39",
|
||||||
|
"b8ec6e64-286a-4f60-8554-7a3865454944",
|
||||||
|
]
|
||||||
|
)
|
||||||
response.headers["X-Header"] = "Test Header POST"
|
response.headers["X-Header"] = "Test Header POST"
|
||||||
return {
|
if runner_callable := event_cluster_matched.example_callable():
|
||||||
"completed": True,
|
return runner_callable
|
||||||
"message": "Test Template Route with Post Method",
|
raise ValueError("Event key not found or multiple matches found")
|
||||||
"info": {
|
|
||||||
"host": headers.get("host", "Not Found"),
|
|
||||||
"user_agent": headers.get("user-agent", "Not Found"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
from .template.event import template_event_cluster
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"template_event_cluster",
|
||||||
|
]
|
||||||
|
|
@ -9,6 +9,7 @@ single_event = Event(
|
||||||
description="Example event description",
|
description="Example event description",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def example_callable():
|
def example_callable():
|
||||||
"""
|
"""
|
||||||
Example callable method
|
Example callable method
|
||||||
|
|
@ -21,6 +22,8 @@ def example_callable():
|
||||||
"user_agent": "example_user_agent",
|
"user_agent": "example_user_agent",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
single_event.event_callable = example_callable
|
single_event.event_callable = example_callable
|
||||||
|
|
||||||
other_event = Event(
|
other_event = Event(
|
||||||
|
|
@ -30,6 +33,8 @@ other_event = Event(
|
||||||
response_validator=None, # TODO: Add response validator
|
response_validator=None, # TODO: Add response validator
|
||||||
description="Example event 2 description",
|
description="Example event 2 description",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def example_callable_other():
|
def example_callable_other():
|
||||||
"""
|
"""
|
||||||
Example callable method
|
Example callable method
|
||||||
|
|
@ -42,6 +47,8 @@ def example_callable_other():
|
||||||
"user_agent": "example_user_agent",
|
"user_agent": "example_user_agent",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
other_event.event_callable = example_callable_other
|
other_event.event_callable = example_callable_other
|
||||||
|
|
||||||
tokens_in_redis = [
|
tokens_in_redis = [
|
||||||
|
|
@ -49,9 +56,11 @@ tokens_in_redis = [
|
||||||
"9f403034-deba-4e1f-b43e-b25d3c808d39",
|
"9f403034-deba-4e1f-b43e-b25d3c808d39",
|
||||||
"b8ec6e64-286a-4f60-8554-7a3865454944",
|
"b8ec6e64-286a-4f60-8554-7a3865454944",
|
||||||
"176b829c-7622-4cf2-b474-421e5acb637c",
|
"176b829c-7622-4cf2-b474-421e5acb637c",
|
||||||
]
|
]
|
||||||
template_event_cluster = EventCluster(endpoint_uu_id="bb20c8c6-a289-4cab-9da7-34ca8a36c8e5")
|
template_event_cluster = EventCluster(
|
||||||
|
endpoint_uu_id="bb20c8c6-a289-4cab-9da7-34ca8a36c8e5"
|
||||||
|
)
|
||||||
template_event_cluster.add_event([single_event, other_event])
|
template_event_cluster.add_event([single_event, other_event])
|
||||||
matched_event = template_event_cluster.match_event(event_keys=tokens_in_redis)
|
# matched_event = template_event_cluster.match_event(event_keys=tokens_in_redis)
|
||||||
|
|
||||||
print('event_callable', matched_event.event_callable())
|
# print('event_callable', matched_event.event_callable())
|
||||||
|
|
|
||||||
|
|
@ -9,29 +9,30 @@ class RouteRegisterController:
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_router_with_event_to_database(route: APIRouter):
|
def add_router_with_event_to_database(router: APIRouter):
|
||||||
from Schemas import EndpointRestriction
|
from Schemas import EndpointRestriction
|
||||||
|
|
||||||
with EndpointRestriction.new_session() as db_session:
|
with EndpointRestriction.new_session() as db_session:
|
||||||
|
for route in router.routes:
|
||||||
route_path = str(getattr(route, "path"))
|
route_path = str(getattr(route, "path"))
|
||||||
route_summary = str(getattr(route, "name")) or ""
|
route_summary = str(getattr(route, "name"))
|
||||||
operation_id = str(getattr(route, "operation_id")) or ""
|
operation_id = getattr(route, "operation_id", None)
|
||||||
if not operation_id:
|
if not operation_id:
|
||||||
return
|
continue
|
||||||
|
|
||||||
for route_method in [method.lower() for method in getattr(route, "methods")]:
|
for route_method in [
|
||||||
|
method.lower() for method in getattr(route, "methods")
|
||||||
|
]:
|
||||||
restriction = EndpointRestriction.find_or_create(
|
restriction = EndpointRestriction.find_or_create(
|
||||||
**dict(
|
|
||||||
endpoint_method=route_method,
|
endpoint_method=route_method,
|
||||||
endpoint_name=route_path,
|
endpoint_name=route_path,
|
||||||
endpoint_desc=route_summary.replace("_", " "),
|
endpoint_desc=route_summary.replace("_", " "),
|
||||||
endpoint_function=route_summary,
|
endpoint_function=route_summary,
|
||||||
operation_uu_id=operation_id, # UUID of the endpoint
|
operation_uu_id=operation_id, # UUID of the endpoint
|
||||||
is_confirmed=True,
|
is_confirmed=True,
|
||||||
|
db=db_session,
|
||||||
)
|
)
|
||||||
)
|
if restriction.meta_data.created:
|
||||||
if not restriction.meta_data.created:
|
|
||||||
restriction.endpoint_code = f"AR{str(restriction.id).zfill(3)}"
|
|
||||||
restriction.save(db=db_session)
|
restriction.save(db=db_session)
|
||||||
|
|
||||||
def register_routes(self):
|
def register_routes(self):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
class EventCluster:
|
class EventCluster:
|
||||||
|
|
||||||
def __init__(self, endpoint_uu_id: str):
|
def __init__(self, endpoint_uu_id: str):
|
||||||
|
|
@ -25,33 +24,39 @@ class EventCluster:
|
||||||
|
|
||||||
def set_events_to_database(self):
|
def set_events_to_database(self):
|
||||||
from Schemas import Events, EndpointRestriction
|
from Schemas import Events, EndpointRestriction
|
||||||
with Events.new_session() as db_session:
|
|
||||||
|
|
||||||
|
with Events.new_session() as db_session:
|
||||||
if to_save_endpoint := EndpointRestriction.filter_one(
|
if to_save_endpoint := EndpointRestriction.filter_one(
|
||||||
EndpointRestriction.uu_id == self.endpoint_uu_id,
|
EndpointRestriction.operation_uu_id == self.endpoint_uu_id,
|
||||||
db=db_session,
|
db=db_session,
|
||||||
).data:
|
).data:
|
||||||
for event in self.events:
|
for event in self.events:
|
||||||
event_obj = Events.find_or_create(
|
event_to_save_database = Events.find_or_create(
|
||||||
function_code=event.key,
|
function_code=event.key,
|
||||||
function_class=event.name,
|
function_class=event.name,
|
||||||
description=event.description,
|
description=event.description,
|
||||||
|
endpoint_code=self.endpoint_uu_id,
|
||||||
endpoint_id=to_save_endpoint.id,
|
endpoint_id=to_save_endpoint.id,
|
||||||
endpoint_uu_id=str(to_save_endpoint.uu_id),
|
endpoint_uu_id=str(to_save_endpoint.uu_id),
|
||||||
is_confirmed=True,
|
is_confirmed=True,
|
||||||
active=True,
|
active=True,
|
||||||
db=db_session,
|
db=db_session,
|
||||||
)
|
)
|
||||||
event_obj.save()
|
if event_to_save_database.meta_data.created:
|
||||||
print(f'UUID: {event_obj.uu_id} event is saved to {to_save_endpoint.uu_id}')
|
event_to_save_database.save(db=db_session)
|
||||||
|
print(
|
||||||
|
f"UUID: {event_to_save_database.uu_id} event is saved to {to_save_endpoint.uu_id}"
|
||||||
|
)
|
||||||
|
|
||||||
def match_event(self, event_keys: list[str]) -> "Event":
|
def match_event(self, event_keys: list[str]) -> "Event":
|
||||||
"""
|
"""
|
||||||
Match an event by its key
|
Match an event by its key
|
||||||
"""
|
"""
|
||||||
print('set(event_keys)', set(event_keys))
|
# print('set(event_keys)', set(event_keys))
|
||||||
print('event.keys', set([event.key for event in self.events]))
|
# print('event.keys', set([event.key for event in self.events]))
|
||||||
intersection_of_key: set[str] = set(event_keys) & set([event.key for event in self.events])
|
intersection_of_key: set[str] = set(event_keys) & set(
|
||||||
|
[event.key for event in self.events]
|
||||||
|
)
|
||||||
if not len(intersection_of_key) == 1:
|
if not len(intersection_of_key) == 1:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Event key not found or multiple matches found: {intersection_of_key}"
|
f"Event key not found or multiple matches found: {intersection_of_key}"
|
||||||
|
|
@ -75,7 +80,6 @@ class Event:
|
||||||
self.response_validator = response_validator
|
self.response_validator = response_validator
|
||||||
self.description = description
|
self.description = description
|
||||||
|
|
||||||
|
|
||||||
def event_callable(self):
|
def event_callable(self):
|
||||||
"""
|
"""
|
||||||
Example callable method
|
Example callable method
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from ..config import api_config
|
||||||
|
|
||||||
async def token_middleware(request: Request, call_next):
|
async def token_middleware(request: Request, call_next):
|
||||||
|
|
||||||
base_url = "/".join(request.url.path.split("/")[:3])
|
base_url = request.url.path
|
||||||
safe_endpoints = [_[0] for _ in get_safe_endpoint_urls()]
|
safe_endpoints = [_[0] for _ in get_safe_endpoint_urls()]
|
||||||
if base_url in safe_endpoints:
|
if base_url in safe_endpoints:
|
||||||
return await call_next(request)
|
return await call_next(request)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ from fastapi import FastAPI
|
||||||
from fastapi.routing import APIRoute
|
from fastapi.routing import APIRoute
|
||||||
from fastapi.openapi.utils import get_openapi
|
from fastapi.openapi.utils import get_openapi
|
||||||
|
|
||||||
from ApiServices.TemplateService.config import template_api_config
|
from .config import api_config as template_api_config
|
||||||
from ApiServices.TemplateService.endpoints.routes import get_safe_endpoint_urls
|
from ApiServices.TemplateService.endpoints.routes import get_safe_endpoint_urls
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
|
|
||||||
|
class Configs(BaseSettings):
|
||||||
|
"""
|
||||||
|
Email configuration settings.
|
||||||
|
"""
|
||||||
|
|
||||||
|
HOST: str = ""
|
||||||
|
USERNAME: str = ""
|
||||||
|
PASSWORD: str = ""
|
||||||
|
PORT: int = 0
|
||||||
|
SEND: bool = False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_send(self):
|
||||||
|
return bool(self.SEND)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def as_dict(cls):
|
||||||
|
return dict(
|
||||||
|
host=cls.EMAIL_HOST,
|
||||||
|
port=cls.EMAIL_PORT,
|
||||||
|
username=cls.EMAIL_USERNAME,
|
||||||
|
password=cls.EMAIL_PASSWORD,
|
||||||
|
)
|
||||||
|
|
||||||
|
model_config = SettingsConfigDict(env_prefix="EMAIL_")
|
||||||
|
|
||||||
|
|
||||||
|
# singleton instance of the POSTGRESQL configuration settings
|
||||||
|
email_configs = Configs()
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
from send_email import EmailService, EmailSendModel
|
||||||
|
|
||||||
|
|
||||||
|
# Create email parameters
|
||||||
|
email_params = EmailSendModel(
|
||||||
|
subject="Test Email",
|
||||||
|
html="<p>Hello world!</p>",
|
||||||
|
receivers=["recipient@example.com"],
|
||||||
|
text="Hello world!",
|
||||||
|
)
|
||||||
|
|
||||||
|
another_email_params = EmailSendModel(
|
||||||
|
subject="Test Email2",
|
||||||
|
html="<p>Hello world!2</p>",
|
||||||
|
receivers=["recipient@example.com"],
|
||||||
|
text="Hello world!2",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# The context manager handles connection errors
|
||||||
|
with EmailService.new_session() as email_session:
|
||||||
|
# Send email - any exceptions here will propagate up
|
||||||
|
EmailService.send_email(email_session, email_params)
|
||||||
|
|
||||||
|
# Or send directly through the session
|
||||||
|
email_session.send(email_params)
|
||||||
|
|
||||||
|
# Send more emails in the same session if needed
|
||||||
|
EmailService.send_email(email_session, another_email_params)
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
from redmail import EmailSender
|
||||||
|
from typing import List, Optional, Dict
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from config import Configs
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
|
||||||
|
class EmailSendModel(BaseModel):
|
||||||
|
subject: str
|
||||||
|
html: str = ""
|
||||||
|
receivers: List[str]
|
||||||
|
text: Optional[str] = ""
|
||||||
|
cc: Optional[List[str]] = None
|
||||||
|
bcc: Optional[List[str]] = None
|
||||||
|
headers: Optional[Dict] = None
|
||||||
|
attachments: Optional[Dict] = None
|
||||||
|
|
||||||
|
|
||||||
|
class EmailSession:
|
||||||
|
|
||||||
|
def __init__(self, email_sender):
|
||||||
|
self.email_sender = email_sender
|
||||||
|
|
||||||
|
def send(self, params: EmailSendModel) -> bool:
|
||||||
|
"""Send email using this session."""
|
||||||
|
if not Configs.is_send:
|
||||||
|
print("Email sending is disabled", params)
|
||||||
|
return False
|
||||||
|
|
||||||
|
receivers = [Configs.USERNAME]
|
||||||
|
self.email_sender.send(
|
||||||
|
subject=params.subject,
|
||||||
|
receivers=receivers,
|
||||||
|
text=params.text + f" : Gonderilen [{str(receivers)}]",
|
||||||
|
html=params.html,
|
||||||
|
cc=params.cc,
|
||||||
|
bcc=params.bcc,
|
||||||
|
headers=params.headers or {},
|
||||||
|
attachments=params.attachments or {},
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class EmailService:
|
||||||
|
_instance = None
|
||||||
|
|
||||||
|
def __new__(cls):
|
||||||
|
if cls._instance is None:
|
||||||
|
cls._instance = super(EmailService, cls).__new__(cls)
|
||||||
|
return cls._instance
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@contextmanager
|
||||||
|
def new_session(cls):
|
||||||
|
"""Create and yield a new email session with active connection."""
|
||||||
|
email_sender = EmailSender(**Configs.as_dict())
|
||||||
|
session = EmailSession(email_sender)
|
||||||
|
try:
|
||||||
|
email_sender.connect()
|
||||||
|
yield session
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error with email connection: {e}")
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
email_sender.close()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def send_email(cls, session: EmailSession, params: EmailSendModel) -> bool:
|
||||||
|
"""Send email using the provided session."""
|
||||||
|
return session.send(params)
|
||||||
|
|
@ -23,4 +23,3 @@ class Configs(BaseSettings):
|
||||||
|
|
||||||
|
|
||||||
redis_configs = Configs() # singleton instance of the REDIS configuration settings
|
redis_configs = Configs() # singleton instance of the REDIS configuration settings
|
||||||
print(redis_configs.as_dict())
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import uuid
|
||||||
import secrets
|
import secrets
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from config import token_config
|
from .config import token_config
|
||||||
|
|
||||||
|
|
||||||
class PasswordModule:
|
class PasswordModule:
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ from sqlalchemy import (
|
||||||
from sqlalchemy.orm import mapped_column, relationship, Mapped
|
from sqlalchemy.orm import mapped_column, relationship, Mapped
|
||||||
|
|
||||||
from Controllers.Postgres.mixin import CrudCollection
|
from Controllers.Postgres.mixin import CrudCollection
|
||||||
from Schemas import Duties, Addresses
|
|
||||||
|
|
||||||
|
|
||||||
class RelationshipDutyCompany(CrudCollection):
|
class RelationshipDutyCompany(CrudCollection):
|
||||||
|
|
@ -60,6 +59,8 @@ class RelationshipDutyCompany(CrudCollection):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def match_company_to_company_commercial(cls, data: Any, token):
|
def match_company_to_company_commercial(cls, data: Any, token):
|
||||||
|
from Schemas import Duties
|
||||||
|
|
||||||
with cls.new_session() as db_session:
|
with cls.new_session() as db_session:
|
||||||
token_duties_id, token_company_id = token.get("duty_id"), token.get(
|
token_duties_id, token_company_id = token.get("duty_id"), token.get(
|
||||||
"company_id"
|
"company_id"
|
||||||
|
|
@ -108,6 +109,8 @@ class RelationshipDutyCompany(CrudCollection):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def match_company_to_company_organization(cls, data: Any, token):
|
def match_company_to_company_organization(cls, data: Any, token):
|
||||||
|
from Schemas import Duties
|
||||||
|
|
||||||
with cls.new_session() as db_session:
|
with cls.new_session() as db_session:
|
||||||
token_duties_id, token_company_id = token.get("duty_id"), token.get(
|
token_duties_id, token_company_id = token.get("duty_id"), token.get(
|
||||||
"company_id"
|
"company_id"
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ from sqlalchemy import (
|
||||||
)
|
)
|
||||||
from sqlalchemy.orm import mapped_column, Mapped
|
from sqlalchemy.orm import mapped_column, Mapped
|
||||||
from Controllers.Postgres.mixin import CrudCollection
|
from Controllers.Postgres.mixin import CrudCollection
|
||||||
from Schemas import OccupantTypes
|
|
||||||
|
|
||||||
|
|
||||||
class Events(CrudCollection):
|
class Events(CrudCollection):
|
||||||
|
|
@ -21,26 +20,24 @@ class Events(CrudCollection):
|
||||||
__tablename__ = "events"
|
__tablename__ = "events"
|
||||||
__exclude__fields__ = []
|
__exclude__fields__ = []
|
||||||
|
|
||||||
event_type: Mapped[str] = mapped_column(
|
|
||||||
String, nullable=False, comment="Event Type"
|
|
||||||
)
|
|
||||||
function_code: Mapped[str] = mapped_column(
|
function_code: Mapped[str] = mapped_column(
|
||||||
String, nullable=False, comment="function code"
|
String, nullable=False, comment="function code", unique=True
|
||||||
)
|
)
|
||||||
function_class: Mapped[str] = mapped_column(
|
function_class: Mapped[str] = mapped_column(
|
||||||
String, nullable=False, comment="class name"
|
String, nullable=False, comment="class name"
|
||||||
)
|
)
|
||||||
|
|
||||||
# name: Mapped[str] = mapped_column(String, nullable=True) # form or page title
|
# name: Mapped[str] = mapped_column(String, nullable=True) # form or page title
|
||||||
description: Mapped[str] = mapped_column(
|
description: Mapped[str] = mapped_column(String, server_default="")
|
||||||
String, server_default=""
|
|
||||||
) # form or page description
|
|
||||||
property_description: Mapped[str] = mapped_column(String, server_default="")
|
property_description: Mapped[str] = mapped_column(String, server_default="")
|
||||||
|
|
||||||
marketing_layer = mapped_column(SmallInteger, server_default="3")
|
marketing_layer = mapped_column(SmallInteger, server_default="3")
|
||||||
cost: Mapped[float] = mapped_column(Numeric(20, 2), server_default="0.00")
|
cost: Mapped[float] = mapped_column(Numeric(20, 2), server_default="0.00")
|
||||||
unit_price: Mapped[float] = mapped_column(Numeric(20, 2), server_default="0.00")
|
unit_price: Mapped[float] = mapped_column(Numeric(20, 2), server_default="0.00")
|
||||||
|
|
||||||
|
endpoint_code: Mapped[str] = mapped_column(
|
||||||
|
String, nullable=False, comment="Event Type"
|
||||||
|
)
|
||||||
endpoint_id: Mapped[int] = mapped_column(
|
endpoint_id: Mapped[int] = mapped_column(
|
||||||
ForeignKey("endpoint_restriction.id"), nullable=True
|
ForeignKey("endpoint_restriction.id"), nullable=True
|
||||||
)
|
)
|
||||||
|
|
@ -108,6 +105,8 @@ class Services(CrudCollection):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def retrieve_service_via_occupant_code(cls, occupant_code):
|
def retrieve_service_via_occupant_code(cls, occupant_code):
|
||||||
|
from Schemas import OccupantTypes
|
||||||
|
|
||||||
with cls.new_session() as db_session:
|
with cls.new_session() as db_session:
|
||||||
occupant_type = OccupantTypes.filter_by_one(
|
occupant_type = OccupantTypes.filter_by_one(
|
||||||
system=True, occupant_code=occupant_code, db=db_session
|
system=True, occupant_code=occupant_code, db=db_session
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class UsersTokens(CrudCollection):
|
||||||
domain: Mapped[str] = mapped_column(String, server_default="")
|
domain: Mapped[str] = mapped_column(String, server_default="")
|
||||||
expires_at: Mapped[TIMESTAMP] = mapped_column(
|
expires_at: Mapped[TIMESTAMP] = mapped_column(
|
||||||
TIMESTAMP(timezone=True),
|
TIMESTAMP(timezone=True),
|
||||||
default=str(arrow.now().shift(date=arrow.now(), days=3)),
|
default=str(arrow.now().shift(days=3)),
|
||||||
)
|
)
|
||||||
|
|
||||||
# users = relationship("Users", back_populates="tokens", foreign_keys=[user_id])
|
# users = relationship("Users", back_populates="tokens", foreign_keys=[user_id])
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class EndpointRestriction(CrudCollection):
|
||||||
__exclude__fields__ = []
|
__exclude__fields__ = []
|
||||||
|
|
||||||
operation_uu_id: Mapped[UUID] = mapped_column(
|
operation_uu_id: Mapped[UUID] = mapped_column(
|
||||||
String, comment="UUID of the operation",
|
String, comment="UUID of the operation", nullable=False, unique=True
|
||||||
)
|
)
|
||||||
endpoint_function: Mapped[str] = mapped_column(
|
endpoint_function: Mapped[str] = mapped_column(
|
||||||
String, server_default="", comment="Function name of the API endpoint"
|
String, server_default="", comment="Function name of the API endpoint"
|
||||||
|
|
@ -33,6 +33,3 @@ class EndpointRestriction(CrudCollection):
|
||||||
endpoint_desc: Mapped[str] = mapped_column(
|
endpoint_desc: Mapped[str] = mapped_column(
|
||||||
String, server_default="", comment="Description of the endpoint"
|
String, server_default="", comment="Description of the endpoint"
|
||||||
)
|
)
|
||||||
endpoint_code: Mapped[str] = mapped_column(
|
|
||||||
String, server_default="", unique=True, comment="Unique code for the endpoint"
|
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
## Next-js service serves with other api services
|
||||||
|
|
||||||
|
### Client-Frontend
|
||||||
|
|
||||||
|
4 Client use only
|
||||||
|
|
||||||
|
### Management-Backend
|
||||||
|
|
||||||
|
4 Management use only
|
||||||
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.*
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/versions
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# env files (can opt-in for committing if needed)
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
FROM node:18-alpine
|
||||||
|
|
||||||
|
WORKDIR /
|
||||||
|
|
||||||
|
# Copy package.json and package-lock.json
|
||||||
|
COPY /WebServices/client-frontend/package*.json ./WebServices/client-frontend/
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN cd ./WebServices/client-frontend && npm install
|
||||||
|
|
||||||
|
# Copy the rest of the application
|
||||||
|
COPY /WebServices/client-frontend ./WebServices/client-frontend
|
||||||
|
|
||||||
|
## Build the Next.js app
|
||||||
|
#RUN cd ./WebServices/client-frontend && npm run dev
|
||||||
|
|
||||||
|
# Expose the port the app runs on
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Command to run the app
|
||||||
|
CMD ["sh", "-c", "cd /WebServices/client-frontend && npm run dev"]
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
First, run the development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
# or
|
||||||
|
yarn dev
|
||||||
|
# or
|
||||||
|
pnpm dev
|
||||||
|
# or
|
||||||
|
bun dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||||
|
|
||||||
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||||
|
|
||||||
|
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||||
|
|
||||||
|
## Learn More
|
||||||
|
|
||||||
|
To learn more about Next.js, take a look at the following resources:
|
||||||
|
|
||||||
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||||
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||||
|
|
||||||
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||||
|
|
||||||
|
## Deploy on Vercel
|
||||||
|
|
||||||
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||||
|
|
||||||
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
/* config options here */
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"name": "client-frontend",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "next lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react": "^19.0.0",
|
||||||
|
"react-dom": "^19.0.0",
|
||||||
|
"next": "15.2.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5",
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/react": "^19",
|
||||||
|
"@types/react-dom": "^19",
|
||||||
|
"@tailwindcss/postcss": "^4",
|
||||||
|
"tailwindcss": "^4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
const config = {
|
||||||
|
plugins: ["@tailwindcss/postcss"],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 391 B |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
||||||
|
After Width: | Height: | Size: 128 B |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
||||||
|
After Width: | Height: | Size: 385 B |
|
After Width: | Height: | Size: 25 KiB |
|
|
@ -0,0 +1,26 @@
|
||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--background: #ffffff;
|
||||||
|
--foreground: #171717;
|
||||||
|
}
|
||||||
|
|
||||||
|
@theme inline {
|
||||||
|
--color-background: var(--background);
|
||||||
|
--color-foreground: var(--foreground);
|
||||||
|
--font-sans: var(--font-geist-sans);
|
||||||
|
--font-mono: var(--font-geist-mono);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--background: #0a0a0a;
|
||||||
|
--foreground: #ededed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--background);
|
||||||
|
color: var(--foreground);
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import type { Metadata } from "next";
|
||||||
|
import { Geist, Geist_Mono } from "next/font/google";
|
||||||
|
import "./globals.css";
|
||||||
|
|
||||||
|
const geistSans = Geist({
|
||||||
|
variable: "--font-geist-sans",
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
|
const geistMono = Geist_Mono({
|
||||||
|
variable: "--font-geist-mono",
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Create Next App",
|
||||||
|
description: "Generated by create next app",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<body
|
||||||
|
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
|
||||||
|
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
|
||||||
|
<Image
|
||||||
|
className="dark:invert"
|
||||||
|
src="/next.svg"
|
||||||
|
alt="Next.js logo"
|
||||||
|
width={180}
|
||||||
|
height={38}
|
||||||
|
priority
|
||||||
|
/>
|
||||||
|
<ol className="list-inside list-decimal text-sm/6 text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
|
||||||
|
<li className="mb-2 tracking-[-.01em]">
|
||||||
|
Get started by editing{" "}
|
||||||
|
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-[family-name:var(--font-geist-mono)] font-semibold">
|
||||||
|
src/app/page.tsx
|
||||||
|
</code>
|
||||||
|
.
|
||||||
|
</li>
|
||||||
|
<li className="tracking-[-.01em]">
|
||||||
|
Save and see your changes instantly.
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<div className="flex gap-4 items-center flex-col sm:flex-row">
|
||||||
|
<a
|
||||||
|
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
|
||||||
|
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
className="dark:invert"
|
||||||
|
src="/vercel.svg"
|
||||||
|
alt="Vercel logomark"
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
/>
|
||||||
|
Deploy now
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
|
||||||
|
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Read our docs
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
|
||||||
|
<a
|
||||||
|
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||||
|
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
aria-hidden
|
||||||
|
src="/file.svg"
|
||||||
|
alt="File icon"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
Learn
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||||
|
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
aria-hidden
|
||||||
|
src="/window.svg"
|
||||||
|
alt="Window icon"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
Examples
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||||
|
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
aria-hidden
|
||||||
|
src="/globe.svg"
|
||||||
|
alt="Globe icon"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
Go to nextjs.org →
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.*
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/versions
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# env files (can opt-in for committing if needed)
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
FROM node:18-alpine
|
||||||
|
|
||||||
|
WORKDIR /
|
||||||
|
|
||||||
|
# Copy package.json and package-lock.json
|
||||||
|
COPY WebServices/management-frontend/package*.json ./WebServices/management-frontend/
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN cd ./WebServices/management-frontend && npm install
|
||||||
|
|
||||||
|
# Copy the rest of the application
|
||||||
|
COPY WebServices/management-frontend ./WebServices/management-frontend
|
||||||
|
|
||||||
|
## Build the Next.js app
|
||||||
|
#RUN cd ./WebServices/management-frontend && npm run build
|
||||||
|
|
||||||
|
# Expose the port the app runs on
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Command to run the app
|
||||||
|
CMD ["sh", "-c", "cd /WebServices/management-frontend && npm run dev"]
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
First, run the development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
# or
|
||||||
|
yarn dev
|
||||||
|
# or
|
||||||
|
pnpm dev
|
||||||
|
# or
|
||||||
|
bun dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||||
|
|
||||||
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||||
|
|
||||||
|
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||||
|
|
||||||
|
## Learn More
|
||||||
|
|
||||||
|
To learn more about Next.js, take a look at the following resources:
|
||||||
|
|
||||||
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||||
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||||
|
|
||||||
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||||
|
|
||||||
|
## Deploy on Vercel
|
||||||
|
|
||||||
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||||
|
|
||||||
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
/* config options here */
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"name": "management-frontend",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "next lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react": "^19.0.0",
|
||||||
|
"react-dom": "^19.0.0",
|
||||||
|
"next": "15.2.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5",
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/react": "^19",
|
||||||
|
"@types/react-dom": "^19",
|
||||||
|
"@tailwindcss/postcss": "^4",
|
||||||
|
"tailwindcss": "^4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
const config = {
|
||||||
|
plugins: ["@tailwindcss/postcss"],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 391 B |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
||||||
|
After Width: | Height: | Size: 128 B |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
||||||
|
After Width: | Height: | Size: 385 B |
|
After Width: | Height: | Size: 25 KiB |
|
|
@ -0,0 +1,26 @@
|
||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--background: #ffffff;
|
||||||
|
--foreground: #171717;
|
||||||
|
}
|
||||||
|
|
||||||
|
@theme inline {
|
||||||
|
--color-background: var(--background);
|
||||||
|
--color-foreground: var(--foreground);
|
||||||
|
--font-sans: var(--font-geist-sans);
|
||||||
|
--font-mono: var(--font-geist-mono);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--background: #0a0a0a;
|
||||||
|
--foreground: #ededed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--background);
|
||||||
|
color: var(--foreground);
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import type { Metadata } from "next";
|
||||||
|
import { Geist, Geist_Mono } from "next/font/google";
|
||||||
|
import "./globals.css";
|
||||||
|
|
||||||
|
const geistSans = Geist({
|
||||||
|
variable: "--font-geist-sans",
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
|
const geistMono = Geist_Mono({
|
||||||
|
variable: "--font-geist-mono",
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Create Next App",
|
||||||
|
description: "Generated by create next app",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<body
|
||||||
|
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
|
||||||
|
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
|
||||||
|
<Image
|
||||||
|
className="dark:invert"
|
||||||
|
src="/next.svg"
|
||||||
|
alt="Next.js logo"
|
||||||
|
width={180}
|
||||||
|
height={38}
|
||||||
|
priority
|
||||||
|
/>
|
||||||
|
<ol className="list-inside list-decimal text-sm/6 text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
|
||||||
|
<li className="mb-2 tracking-[-.01em]">
|
||||||
|
Get started by editing{" "}
|
||||||
|
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-[family-name:var(--font-geist-mono)] font-semibold">
|
||||||
|
src/app/page.tsx
|
||||||
|
</code>
|
||||||
|
.
|
||||||
|
</li>
|
||||||
|
<li className="tracking-[-.01em]">
|
||||||
|
Save and see your changes instantly.
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<div className="flex gap-4 items-center flex-col sm:flex-row">
|
||||||
|
<a
|
||||||
|
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
|
||||||
|
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
className="dark:invert"
|
||||||
|
src="/vercel.svg"
|
||||||
|
alt="Vercel logomark"
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
/>
|
||||||
|
Deploy now
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
|
||||||
|
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Read our docs
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
|
||||||
|
<a
|
||||||
|
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||||
|
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
aria-hidden
|
||||||
|
src="/file.svg"
|
||||||
|
alt="File icon"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
Learn
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||||
|
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
aria-hidden
|
||||||
|
src="/window.svg"
|
||||||
|
alt="Window icon"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
Examples
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||||
|
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
aria-hidden
|
||||||
|
src="/globe.svg"
|
||||||
|
alt="Globe icon"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
Go to nextjs.org →
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
|
|
@ -20,7 +20,6 @@ REDIS_HOST=redis_service
|
||||||
REDIS_PASSWORD=commercial_redis_password
|
REDIS_PASSWORD=commercial_redis_password
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
REDIS_DB=0
|
REDIS_DB=0
|
||||||
API_ACCESS_TOKEN_TAG=evyos-session-key
|
|
||||||
API_ACCESS_EMAIL_EXT=evyos.com.tr
|
API_ACCESS_EMAIL_EXT=evyos.com.tr
|
||||||
API_ALGORITHM=HS256
|
API_ALGORITHM=HS256
|
||||||
API_ACCESS_TOKEN_LENGTH=90
|
API_ACCESS_TOKEN_LENGTH=90
|
||||||
|
|
@ -29,3 +28,9 @@ API_EMAIL_HOST=10.10.2.36
|
||||||
API_DATETIME_FORMAT=YYYY-MM-DD HH:mm:ss Z
|
API_DATETIME_FORMAT=YYYY-MM-DD HH:mm:ss Z
|
||||||
API_FORGOT_LINK=https://www.evyos.com.tr/password/create?tokenUrl=
|
API_FORGOT_LINK=https://www.evyos.com.tr/password/create?tokenUrl=
|
||||||
API_VERSION=0.1.001
|
API_VERSION=0.1.001
|
||||||
|
API_ACCESS_TOKEN_TAG=eys-acs-tkn
|
||||||
|
EMAIL_HOST=10.10.2.34
|
||||||
|
EMAIL_USERNAME=karatay@mehmetkaratay.com.tr
|
||||||
|
EMAIL_PASSWORD=system
|
||||||
|
EMAIL_PORT=587
|
||||||
|
EMAIL_SEND=0
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,52 @@ services:
|
||||||
ports:
|
ports:
|
||||||
- "11222:6379"
|
- "11222:6379"
|
||||||
|
|
||||||
|
client_frontend:
|
||||||
|
container_name: client_frontend
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: WebServices/client-frontend/Dockerfile
|
||||||
|
networks:
|
||||||
|
- wag-services
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
volumes:
|
||||||
|
- .WebServices/client-frontend:WebServices/client-frontend
|
||||||
|
- WebServices/client-frontend/node_modules
|
||||||
|
- WebServices/client-frontend/.next
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=development
|
||||||
|
|
||||||
|
management_frontend:
|
||||||
|
container_name: management_frontend
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: WebServices/management-frontend/Dockerfile
|
||||||
|
networks:
|
||||||
|
- wag-services
|
||||||
|
ports:
|
||||||
|
- "3001:3000" # Using different host port to avoid conflicts
|
||||||
|
volumes:
|
||||||
|
- .WebServices/management-frontend:WebServices/management-frontend
|
||||||
|
- WebServices/management-frontend/node_modules
|
||||||
|
- WebServices/management-frontend/.next
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=development
|
||||||
|
|
||||||
|
# initializer_service:
|
||||||
|
# container_name: initializer_service
|
||||||
|
# build:
|
||||||
|
# context: .
|
||||||
|
# dockerfile: ApiServices/InitialService/Dockerfile
|
||||||
|
# networks:
|
||||||
|
# - wag-services
|
||||||
|
# env_file:
|
||||||
|
# - api_env.env
|
||||||
|
# depends_on:
|
||||||
|
# - postgres-service
|
||||||
|
# - mongo_service
|
||||||
|
# - redis_service
|
||||||
|
|
||||||
# template_service:
|
# template_service:
|
||||||
# container_name: template_service
|
# container_name: template_service
|
||||||
# build:
|
# build:
|
||||||
|
|
@ -93,7 +139,6 @@ services:
|
||||||
- API_PORT=8001
|
- API_PORT=8001
|
||||||
- API_LOG_LEVEL=info
|
- API_LOG_LEVEL=info
|
||||||
- API_RELOAD=1
|
- API_RELOAD=1
|
||||||
- API_ACCESS_TOKEN_TAG=eys-acs-tkn
|
|
||||||
- API_APP_NAME=evyos-auth-api-gateway
|
- API_APP_NAME=evyos-auth-api-gateway
|
||||||
- API_TITLE=WAG API Auth Api Gateway
|
- API_TITLE=WAG API Auth Api Gateway
|
||||||
- API_FORGOT_LINK=https://auth_service/forgot-password
|
- API_FORGOT_LINK=https://auth_service/forgot-password
|
||||||
|
|
@ -116,6 +161,7 @@ services:
|
||||||
# networks:
|
# networks:
|
||||||
# - wag-services
|
# - wag-services
|
||||||
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
wag-services:
|
wag-services:
|
||||||
|
|
||||||
|
|
|
||||||