update latest
This commit is contained in:
parent
e0440e8ab1
commit
654ad382fe
|
|
@ -1,5 +1,7 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from typing import Any, Dict, List
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
import uuid6
|
import uuid6
|
||||||
from pytz import timezone
|
from pytz import timezone
|
||||||
|
|
@ -15,6 +17,7 @@ class MapsetStatus(str, Enum):
|
||||||
approved = "approved"
|
approved = "approved"
|
||||||
rejected = "rejected"
|
rejected = "rejected"
|
||||||
on_verification = "on_verification"
|
on_verification = "on_verification"
|
||||||
|
on_process = "on_process"
|
||||||
|
|
||||||
|
|
||||||
class MapsetModel(Base):
|
class MapsetModel(Base):
|
||||||
|
|
@ -67,3 +70,10 @@ class MapsetModel(Base):
|
||||||
viewonly=True,
|
viewonly=True,
|
||||||
)
|
)
|
||||||
producer = relationship("OrganizationModel", back_populates="mapsets", uselist=False, lazy="joined")
|
producer = relationship("OrganizationModel", back_populates="mapsets", uselist=False, lazy="joined")
|
||||||
|
|
||||||
|
class MapsetFile(BaseModel):
|
||||||
|
title: str
|
||||||
|
path: str
|
||||||
|
columns: List[str]
|
||||||
|
author: Dict[str, Any]
|
||||||
|
style: str
|
||||||
22
app/response/res.py
Normal file
22
app/response/res.py
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
from fastapi import HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
def successRes(data=None, message="Success", status_code=200):
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status_code,
|
||||||
|
content={
|
||||||
|
"status": "success",
|
||||||
|
"message": message,
|
||||||
|
"data": data,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def errorRes(message="Error", status_code=400, details=None):
|
||||||
|
return HTTPException(
|
||||||
|
status_code=status_code,
|
||||||
|
detail={
|
||||||
|
"status": "error",
|
||||||
|
"message": message,
|
||||||
|
"details": details
|
||||||
|
}
|
||||||
|
)
|
||||||
65
app/utils/logger_config.py
Normal file
65
app/utils/logger_config.py
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
from sqlalchemy import text
|
||||||
|
from database.connection import engine
|
||||||
|
|
||||||
|
LOG_DIR = "logs"
|
||||||
|
os.makedirs(LOG_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
def setup_logger(name: str):
|
||||||
|
"""
|
||||||
|
Konfigurasi logger standar untuk seluruh service.
|
||||||
|
Format log:
|
||||||
|
[LEVEL] [Nama Modul] Pesan
|
||||||
|
"""
|
||||||
|
logger = logging.getLogger(name)
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
# Handler untuk menulis ke file
|
||||||
|
file_handler = logging.FileHandler(os.path.join(LOG_DIR, "app.log"))
|
||||||
|
file_handler.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
# Handler untuk console (stdout)
|
||||||
|
console_handler = logging.StreamHandler()
|
||||||
|
console_handler.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
formatter = logging.Formatter('[%(levelname)s] [%(name)s] %(message)s')
|
||||||
|
file_handler.setFormatter(formatter)
|
||||||
|
console_handler.setFormatter(formatter)
|
||||||
|
|
||||||
|
if not logger.handlers:
|
||||||
|
logger.addHandler(file_handler)
|
||||||
|
logger.addHandler(console_handler)
|
||||||
|
|
||||||
|
return logger
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def log_activity(user_id, action_type, action_title, details=None):
|
||||||
|
payload = {
|
||||||
|
"user_id": user_id,
|
||||||
|
"action_type": action_type,
|
||||||
|
"action_title": action_title,
|
||||||
|
"action_details": json.dumps(details) if details else None
|
||||||
|
}
|
||||||
|
|
||||||
|
async with engine.begin() as conn:
|
||||||
|
await conn.execute(
|
||||||
|
text("""
|
||||||
|
INSERT INTO backend.system_logs (
|
||||||
|
user_id,
|
||||||
|
action_type,
|
||||||
|
action_title,
|
||||||
|
action_details
|
||||||
|
) VALUES (
|
||||||
|
:user_id,
|
||||||
|
:action_type,
|
||||||
|
:action_title,
|
||||||
|
:action_details
|
||||||
|
)
|
||||||
|
"""),
|
||||||
|
payload
|
||||||
|
)
|
||||||
|
|
@ -138,6 +138,19 @@ def upgrade() -> None:
|
||||||
ON CONFLICT (id) DO NOTHING;
|
ON CONFLICT (id) DO NOTHING;
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
op.execute("""
|
||||||
|
INSERT INTO public.classifications (id, name, is_open, is_limited, is_secret)
|
||||||
|
VALUES
|
||||||
|
('01968b4b-d3f9-76c9-888c-ee887ac31ce4', 'terbuka', true, false, false),
|
||||||
|
('01968b4c-0c2b-7fea-a4cf-0f332fcb0025', 'terbatas', true, true, false),
|
||||||
|
('01968b4c-2e16-7c96-a982-6fd1e2abd378', 'rahasia', true, false, true);
|
||||||
|
""")
|
||||||
|
|
||||||
|
op.execute("""
|
||||||
|
INSERT INTO public.map_projection_systems (id, name)
|
||||||
|
VALUES
|
||||||
|
('0196c746-d1ba-7f1c-9706-5df738679cc7', 'WGS 84');
|
||||||
|
""")
|
||||||
|
|
||||||
def downgrade() -> None:
|
def downgrade() -> None:
|
||||||
# Delete in reverse order due to foreign key constraints
|
# Delete in reverse order due to foreign key constraints
|
||||||
|
|
|
||||||
1600
poetry.lock
generated
1600
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
|
|
@ -29,6 +29,17 @@ shapely = "^2.1.0"
|
||||||
colour = "^0.1.5"
|
colour = "^0.1.5"
|
||||||
httpx = {extras = ["http2"], version = "^0.28.1"}
|
httpx = {extras = ["http2"], version = "^0.28.1"}
|
||||||
psutil = "^7.0.0"
|
psutil = "^7.0.0"
|
||||||
|
pandas = "^3.0.0"
|
||||||
|
geopandas = "^1.1.2"
|
||||||
|
fiona = "^1.10.1"
|
||||||
|
numpy = "^2.4.2"
|
||||||
|
pdfplumber = "^0.11.9"
|
||||||
|
py7zr = "^1.1.0"
|
||||||
|
pyogrio = "^0.12.1"
|
||||||
|
rapidfuzz = "^3.14.3"
|
||||||
|
requests = "^2.32.5"
|
||||||
|
openpyxl = "^3.1.5"
|
||||||
|
pyarrow = "21.0.0"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user