Switch all imports to relative paths
Some checks failed
Deploy Tracker / deploy (push) Failing after 3s
Some checks failed
Deploy Tracker / deploy (push) Failing after 3s
This commit is contained in:
parent
659454c2e6
commit
c7b073b36c
@ -9,9 +9,9 @@ from fastapi.responses import FileResponse
|
|||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from tracker.database import get_db
|
from ..database import get_db
|
||||||
from tracker.models import Attachment, Message, Member
|
from ..models import Attachment, Message, Member
|
||||||
from tracker.api.schemas import UploadOut
|
from .schemas import UploadOut
|
||||||
|
|
||||||
router = APIRouter(tags=["attachments"])
|
router = APIRouter(tags=["attachments"])
|
||||||
|
|
||||||
|
|||||||
@ -10,9 +10,9 @@ from pydantic import BaseModel
|
|||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from tracker.config import settings
|
from ..config import settings
|
||||||
from tracker.database import get_db
|
from ..database import get_db
|
||||||
from tracker.models import Member
|
from ..models import Member
|
||||||
|
|
||||||
router = APIRouter(tags=["auth"])
|
router = APIRouter(tags=["auth"])
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
"""ORM → Pydantic converters. Single place for all model-to-schema transformations."""
|
"""ORM → Pydantic converters. Single place for all model-to-schema transformations."""
|
||||||
|
|
||||||
from tracker.models import Attachment, Member, Message, ProjectFile, Step, Task
|
from ..models import Attachment, Member, Message, ProjectFile, Step, Task
|
||||||
from tracker.enums import MemberType
|
from ..enums import MemberType
|
||||||
from tracker.api.schemas import (
|
from .schemas import (
|
||||||
AgentConfigOut,
|
AgentConfigOut,
|
||||||
AttachmentOut,
|
AttachmentOut,
|
||||||
MemberBrief,
|
MemberBrief,
|
||||||
|
|||||||
@ -9,11 +9,11 @@ from sqlalchemy import select
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
|
|
||||||
from tracker.database import get_db
|
from ..database import get_db
|
||||||
from tracker.enums import AuthMethod, ListenMode, MemberRole, MemberStatus, MemberType
|
from ..enums import AuthMethod, ListenMode, MemberRole, MemberStatus, MemberType
|
||||||
from tracker.models import Member, AgentConfig
|
from ..models import Member, AgentConfig
|
||||||
from tracker.api.schemas import MemberOut, AgentConfigOut, OkResponse
|
from .schemas import MemberOut, AgentConfigOut, OkResponse
|
||||||
from tracker.api.converters import member_out
|
from .converters import member_out
|
||||||
|
|
||||||
router = APIRouter(tags=["members"])
|
router = APIRouter(tags=["members"])
|
||||||
|
|
||||||
|
|||||||
@ -10,11 +10,11 @@ from sqlalchemy import select
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
|
|
||||||
from tracker.database import get_db
|
from ..database import get_db
|
||||||
from tracker.enums import AuthorType, ChatKind
|
from ..enums import AuthorType, ChatKind
|
||||||
from tracker.models import Message, Chat, Attachment
|
from ..models import Message, Chat, Attachment
|
||||||
from tracker.api.schemas import MessageOut
|
from .schemas import MessageOut
|
||||||
from tracker.api.converters import message_out
|
from .converters import message_out
|
||||||
|
|
||||||
router = APIRouter(tags=["messages"])
|
router = APIRouter(tags=["messages"])
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ async def create_message(req: MessageCreate, request: Request, db: AsyncSession
|
|||||||
msg_data = message_out(msg).model_dump()
|
msg_data = message_out(msg).model_dump()
|
||||||
|
|
||||||
# Broadcast via WebSocket
|
# Broadcast via WebSocket
|
||||||
from tracker.ws.manager import manager
|
from ..ws.manager import manager
|
||||||
|
|
||||||
project_id = None
|
project_id = None
|
||||||
if req.chat_id:
|
if req.chat_id:
|
||||||
|
|||||||
@ -12,9 +12,9 @@ from sqlalchemy import select, or_
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
|
|
||||||
from tracker.database import get_db
|
from ..database import get_db
|
||||||
from tracker.models import ProjectFile, Project, Member
|
from ..models import ProjectFile, Project, Member
|
||||||
from tracker.api.schemas import ProjectFileOut, MemberBrief
|
from .schemas import ProjectFileOut, MemberBrief
|
||||||
|
|
||||||
router = APIRouter(tags=["project-files"])
|
router = APIRouter(tags=["project-files"])
|
||||||
|
|
||||||
|
|||||||
@ -6,10 +6,10 @@ from sqlalchemy import select
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
|
|
||||||
from tracker.database import get_db
|
from ..database import get_db
|
||||||
from tracker.enums import ChatKind, MemberRole, ProjectStatus
|
from ..enums import ChatKind, MemberRole, ProjectStatus
|
||||||
from tracker.models import Project, Chat, Member, ProjectMember
|
from ..models import Project, Chat, Member, ProjectMember
|
||||||
from tracker.api.schemas import ProjectOut
|
from .schemas import ProjectOut
|
||||||
|
|
||||||
router = APIRouter(tags=["projects"])
|
router = APIRouter(tags=["projects"])
|
||||||
|
|
||||||
|
|||||||
@ -7,11 +7,11 @@ from pydantic import BaseModel
|
|||||||
from sqlalchemy import select, func
|
from sqlalchemy import select, func
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from tracker.database import get_db
|
from ..database import get_db
|
||||||
from tracker.models import Step, Task
|
from ..models import Step, Task
|
||||||
from tracker.api.schemas import StepOut
|
from .schemas import StepOut
|
||||||
from tracker.api.schemas import StepOut
|
from .schemas import StepOut
|
||||||
from tracker.api.converters import step_out
|
from .converters import step_out
|
||||||
|
|
||||||
router = APIRouter(tags=["steps"])
|
router = APIRouter(tags=["steps"])
|
||||||
|
|
||||||
|
|||||||
@ -10,14 +10,14 @@ from sqlalchemy import select, update
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import selectinload, joinedload
|
from sqlalchemy.orm import selectinload, joinedload
|
||||||
|
|
||||||
from tracker.database import get_db
|
from ..database import get_db
|
||||||
from tracker.enums import (
|
from ..enums import (
|
||||||
AuthorType, ChatKind, TaskActionType, TaskPriority, TaskStatus, TaskType, WSEventType,
|
AuthorType, ChatKind, TaskActionType, TaskPriority, TaskStatus, TaskType, WSEventType,
|
||||||
)
|
)
|
||||||
from tracker.models import Task, Step, Project, Member, Message, Chat, TaskAction
|
from ..models import Task, Step, Project, Member, Message, Chat, TaskAction
|
||||||
from tracker.api.auth import get_current_member
|
from .auth import get_current_member
|
||||||
from tracker.api.schemas import TaskOut, MessageOut
|
from .schemas import TaskOut, MessageOut
|
||||||
from tracker.api.converters import task_out, message_out, member_brief
|
from .converters import task_out, message_out, member_brief
|
||||||
|
|
||||||
router = APIRouter(tags=["tasks"])
|
router = APIRouter(tags=["tasks"])
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ async def _system_message(
|
|||||||
):
|
):
|
||||||
"""Create system messages: one in project chat + one in task comments.
|
"""Create system messages: one in project chat + one in task comments.
|
||||||
Uses MessageOut schema for WS broadcasts."""
|
Uses MessageOut schema for WS broadcasts."""
|
||||||
from tracker.ws.manager import manager
|
from ..ws.manager import manager
|
||||||
|
|
||||||
prefix = project_slug[:2].upper() if project_slug else "XX"
|
prefix = project_slug[:2].upper() if project_slug else "XX"
|
||||||
key = f"{prefix}-{task.number}"
|
key = f"{prefix}-{task.number}"
|
||||||
@ -262,7 +262,7 @@ async def create_task(
|
|||||||
task_full = await _get_task(str(task.id), db)
|
task_full = await _get_task(str(task.id), db)
|
||||||
|
|
||||||
# Broadcast using TaskOut schema
|
# Broadcast using TaskOut schema
|
||||||
from tracker.ws.manager import manager
|
from ..ws.manager import manager
|
||||||
task_schema = task_out(task_full, project.slug)
|
task_schema = task_out(task_full, project.slug)
|
||||||
key = f"{project.slug[:2].upper()}-{task.number}"
|
key = f"{project.slug[:2].upper()}-{task.number}"
|
||||||
await manager.broadcast_task_event(str(project.id), WSEventType.TASK_CREATED, task_schema.model_dump())
|
await manager.broadcast_task_event(str(project.id), WSEventType.TASK_CREATED, task_schema.model_dump())
|
||||||
@ -372,7 +372,7 @@ async def update_task(
|
|||||||
await db.refresh(task)
|
await db.refresh(task)
|
||||||
|
|
||||||
# Broadcast simplified update
|
# Broadcast simplified update
|
||||||
from tracker.ws.manager import manager
|
from ..ws.manager import manager
|
||||||
task_full = await _get_task(task_id, db)
|
task_full = await _get_task(task_id, db)
|
||||||
task_schema = task_out(task_full, slug)
|
task_schema = task_out(task_full, slug)
|
||||||
await manager.broadcast_task_event(str(task.project_id), WSEventType.TASK_UPDATED, task_schema.model_dump())
|
await manager.broadcast_task_event(str(task.project_id), WSEventType.TASK_UPDATED, task_schema.model_dump())
|
||||||
@ -392,7 +392,7 @@ async def delete_task(
|
|||||||
await db.commit()
|
await db.commit()
|
||||||
await db.delete(task)
|
await db.delete(task)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
from tracker.ws.manager import manager
|
from ..ws.manager import manager
|
||||||
await manager.broadcast_task_event(project_id, WSEventType.TASK_DELETED, {
|
await manager.broadcast_task_event(project_id, WSEventType.TASK_DELETED, {
|
||||||
"id": task_id, "project_id": project_id,
|
"id": task_id, "project_id": project_id,
|
||||||
})
|
})
|
||||||
@ -433,7 +433,7 @@ async def take_task(
|
|||||||
)
|
)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
||||||
from tracker.ws.manager import manager
|
from ..ws.manager import manager
|
||||||
task_full = await _get_task(task_id, db)
|
task_full = await _get_task(task_id, db)
|
||||||
task_schema = task_out(task_full, proj_slug)
|
task_schema = task_out(task_full, proj_slug)
|
||||||
await manager.broadcast_task_event(str(task.project_id), WSEventType.TASK_ASSIGNED, task_schema.model_dump())
|
await manager.broadcast_task_event(str(task.project_id), WSEventType.TASK_ASSIGNED, task_schema.model_dump())
|
||||||
@ -469,7 +469,7 @@ async def reject_task(
|
|||||||
db.add(comment)
|
db.add(comment)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
||||||
from tracker.ws.manager import manager
|
from ..ws.manager import manager
|
||||||
task_full = await _get_task(task_id, db)
|
task_full = await _get_task(task_id, db)
|
||||||
proj_slug = task.project.slug if task.project else ""
|
proj_slug = task.project.slug if task.project else ""
|
||||||
task_schema = task_out(task_full, proj_slug)
|
task_schema = task_out(task_full, proj_slug)
|
||||||
@ -507,7 +507,7 @@ async def assign_task(
|
|||||||
)
|
)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
||||||
from tracker.ws.manager import manager
|
from ..ws.manager import manager
|
||||||
task_full = await _get_task(str(task.id), db)
|
task_full = await _get_task(str(task.id), db)
|
||||||
task_schema = task_out(task_full, proj_slug)
|
task_schema = task_out(task_full, proj_slug)
|
||||||
await manager.broadcast_task_event(str(task.project_id), WSEventType.TASK_ASSIGNED, task_schema.model_dump())
|
await manager.broadcast_task_event(str(task.project_id), WSEventType.TASK_ASSIGNED, task_schema.model_dump())
|
||||||
|
|||||||
@ -11,9 +11,9 @@ from fastapi import FastAPI, Request
|
|||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
from tracker.config import settings
|
from .config import settings
|
||||||
from tracker.database import engine, async_session
|
from .database import engine, async_session
|
||||||
from tracker.models import Base, Member
|
from .models import Base, Member
|
||||||
|
|
||||||
from sqlalchemy import select, update
|
from sqlalchemy import select, update
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ logger = logging.getLogger("tracker")
|
|||||||
|
|
||||||
async def heartbeat_monitor():
|
async def heartbeat_monitor():
|
||||||
"""Monitor heartbeat timeout — set status=offline after 90 seconds."""
|
"""Monitor heartbeat timeout — set status=offline after 90 seconds."""
|
||||||
from tracker.ws.manager import manager
|
from .ws.manager import manager
|
||||||
from datetime import datetime, timezone, timedelta
|
from datetime import datetime, timezone, timedelta
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@ -69,7 +69,7 @@ async def lifespan(app: FastAPI):
|
|||||||
result = await session.execute(select(Member).limit(1))
|
result = await session.execute(select(Member).limit(1))
|
||||||
if not result.scalar_one_or_none():
|
if not result.scalar_one_or_none():
|
||||||
logger.info("Empty DB detected in dev mode — running seed...")
|
logger.info("Empty DB detected in dev mode — running seed...")
|
||||||
from tracker.init_db import seed_dev_data
|
from .init_db import seed_dev_data
|
||||||
await seed_dev_data(session)
|
await seed_dev_data(session)
|
||||||
logger.info("Dev seed complete.")
|
logger.info("Dev seed complete.")
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ async def auth_middleware(request: Request, call_next):
|
|||||||
member = result.scalar_one_or_none()
|
member = result.scalar_one_or_none()
|
||||||
if not member:
|
if not member:
|
||||||
# Try JWT
|
# Try JWT
|
||||||
from tracker.api.auth import decode_jwt
|
from .api.auth import decode_jwt
|
||||||
try:
|
try:
|
||||||
payload = decode_jwt(token)
|
payload = decode_jwt(token)
|
||||||
result = await db.execute(select(Member).where(Member.id == payload["sub"]))
|
result = await db.execute(select(Member).where(Member.id == payload["sub"]))
|
||||||
@ -167,8 +167,8 @@ app.add_middleware(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Routers
|
# Routers
|
||||||
from tracker.api import auth, members, projects, tasks, messages, steps, attachments, project_files # noqa: E402
|
from .api import auth, members, projects, tasks, messages, steps, attachments, project_files # noqa: E402
|
||||||
from tracker.ws.handler import router as ws_router # noqa: E402
|
from .ws.handler import router as ws_router # noqa: E402
|
||||||
|
|
||||||
app.include_router(auth.router, prefix="/api/v1")
|
app.include_router(auth.router, prefix="/api/v1")
|
||||||
app.include_router(members.router, prefix="/api/v1")
|
app.include_router(members.router, prefix="/api/v1")
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||||||
|
|
||||||
from tracker.config import settings
|
from .config import settings
|
||||||
|
|
||||||
engine = create_async_engine(settings.database_url, echo=(settings.env == "dev"))
|
engine = create_async_engine(settings.database_url, echo=(settings.env == "dev"))
|
||||||
async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||||
|
|||||||
@ -6,8 +6,8 @@ import logging
|
|||||||
|
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from tracker.enums import AuthMethod, ChatKind, MemberRole, MemberStatus, MemberType, ProjectStatus
|
from .enums import AuthMethod, ChatKind, MemberRole, MemberStatus, MemberType, ProjectStatus
|
||||||
from tracker.models import Base, Member, Chat, Project, ProjectMember, AgentConfig
|
from .models import Base, Member, Chat, Project, ProjectMember, AgentConfig
|
||||||
|
|
||||||
logger = logging.getLogger("tracker.init_db")
|
logger = logging.getLogger("tracker.init_db")
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ async def seed_dev_data(session: AsyncSession):
|
|||||||
|
|
||||||
async def reset_db():
|
async def reset_db():
|
||||||
"""Drop all tables, recreate, and seed. For dev use only."""
|
"""Drop all tables, recreate, and seed. For dev use only."""
|
||||||
from tracker.database import engine, async_session
|
from .database import engine, async_session
|
||||||
|
|
||||||
async with engine.begin() as conn:
|
async with engine.begin() as conn:
|
||||||
await conn.run_sync(Base.metadata.drop_all)
|
await conn.run_sync(Base.metadata.drop_all)
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
"""Models package — import all models for metadata discovery."""
|
"""Models package — import all models for metadata discovery."""
|
||||||
|
|
||||||
from tracker.models.base import Base
|
from .base import Base
|
||||||
from tracker.models.member import AgentConfig, Member
|
from .member import AgentConfig, Member
|
||||||
from tracker.models.project import Project, ProjectMember
|
from .project import Project, ProjectMember
|
||||||
from tracker.models.task import Step, Task, TaskAction
|
from .task import Step, Task, TaskAction
|
||||||
from tracker.models.chat import Attachment, Chat, Message
|
from .chat import Attachment, Chat, Message
|
||||||
from tracker.models.project_file import ProjectFile
|
from .project_file import ProjectFile
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Base",
|
"Base",
|
||||||
|
|||||||
@ -7,12 +7,12 @@ from sqlalchemy import ForeignKey, Integer, String, Text
|
|||||||
from sqlalchemy.dialects.postgresql import ARRAY, UUID
|
from sqlalchemy.dialects.postgresql import ARRAY, UUID
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
from tracker.enums import ChatKind
|
from ..enums import ChatKind
|
||||||
from tracker.models.base import Base
|
from .base import Base
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tracker.models.member import Member
|
from .member import Member
|
||||||
from tracker.models.project import Project
|
from .project import Project
|
||||||
|
|
||||||
|
|
||||||
class Chat(Base):
|
class Chat(Base):
|
||||||
|
|||||||
@ -7,11 +7,11 @@ from sqlalchemy import ForeignKey, String, Text
|
|||||||
from sqlalchemy.dialects.postgresql import ARRAY, UUID
|
from sqlalchemy.dialects.postgresql import ARRAY, UUID
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
from tracker.enums import AuthMethod, ListenMode, MemberRole, MemberStatus, MemberType
|
from ..enums import AuthMethod, ListenMode, MemberRole, MemberStatus, MemberType
|
||||||
from tracker.models.base import Base
|
from .base import Base
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tracker.models.project import ProjectMember
|
from .project import ProjectMember
|
||||||
|
|
||||||
|
|
||||||
class Member(Base):
|
class Member(Base):
|
||||||
|
|||||||
@ -7,13 +7,13 @@ from sqlalchemy import ForeignKey, Integer, String, Text, UniqueConstraint
|
|||||||
from sqlalchemy.dialects.postgresql import ARRAY, UUID
|
from sqlalchemy.dialects.postgresql import ARRAY, UUID
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
from tracker.enums import MemberRole, ProjectStatus
|
from ..enums import MemberRole, ProjectStatus
|
||||||
from tracker.models.base import Base
|
from .base import Base
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tracker.models.task import Task
|
from .task import Task
|
||||||
from tracker.models.chat import Chat
|
from .chat import Chat
|
||||||
from tracker.models.member import Member
|
from .member import Member
|
||||||
|
|
||||||
|
|
||||||
class Project(Base):
|
class Project(Base):
|
||||||
|
|||||||
@ -7,11 +7,11 @@ from sqlalchemy import ForeignKey, Integer, String, Text
|
|||||||
from sqlalchemy.dialects.postgresql import UUID
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
from tracker.models.base import Base
|
from .base import Base
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tracker.models.project import Project
|
from .project import Project
|
||||||
from tracker.models.member import Member
|
from .member import Member
|
||||||
|
|
||||||
|
|
||||||
class ProjectFile(Base):
|
class ProjectFile(Base):
|
||||||
|
|||||||
@ -7,12 +7,12 @@ from sqlalchemy import Boolean, ForeignKey, Integer, String, Text
|
|||||||
from sqlalchemy.dialects.postgresql import ARRAY, UUID
|
from sqlalchemy.dialects.postgresql import ARRAY, UUID
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
from tracker.enums import TaskPriority, TaskStatus, TaskType
|
from ..enums import TaskPriority, TaskStatus, TaskType
|
||||||
from tracker.models.base import Base
|
from .base import Base
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tracker.models.member import Member
|
from .member import Member
|
||||||
from tracker.models.project import Project
|
from .project import Project
|
||||||
|
|
||||||
|
|
||||||
class Task(Base):
|
class Task(Base):
|
||||||
|
|||||||
@ -7,14 +7,14 @@ from fastapi import APIRouter, WebSocket, WebSocketDisconnect
|
|||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
|
|
||||||
from tracker.database import async_session
|
from ..database import async_session
|
||||||
from tracker.enums import (
|
from ..enums import (
|
||||||
AuthMethod, ChatKind, ListenMode, MemberRole, MemberStatus, MemberType,
|
AuthMethod, ChatKind, ListenMode, MemberRole, MemberStatus, MemberType,
|
||||||
ProjectStatus, WSEventType,
|
ProjectStatus, WSEventType,
|
||||||
)
|
)
|
||||||
from tracker.models import Member, AgentConfig, Chat, Message, Project, ProjectMember
|
from ..models import Member, AgentConfig, Chat, Message, Project, ProjectMember
|
||||||
from tracker.api.schemas import MessageOut, MemberBrief
|
from ..api.schemas import MessageOut, MemberBrief
|
||||||
from tracker.ws.manager import ConnectedClient, manager
|
from .manager import ConnectedClient, manager
|
||||||
|
|
||||||
logger = logging.getLogger("tracker.ws")
|
logger = logging.getLogger("tracker.ws")
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
@ -134,7 +134,7 @@ async def _authenticate(ws: WebSocket, token: str, on_behalf_of: str | None = No
|
|||||||
member = result.scalar_one_or_none()
|
member = result.scalar_one_or_none()
|
||||||
else:
|
else:
|
||||||
# Try JWT decode
|
# Try JWT decode
|
||||||
from tracker.api.auth import decode_jwt
|
from ..api.auth import decode_jwt
|
||||||
try:
|
try:
|
||||||
payload = decode_jwt(token)
|
payload = decode_jwt(token)
|
||||||
member_id = payload["sub"]
|
member_id = payload["sub"]
|
||||||
|
|||||||
@ -7,7 +7,7 @@ from datetime import datetime, timezone
|
|||||||
|
|
||||||
from fastapi import WebSocket
|
from fastapi import WebSocket
|
||||||
|
|
||||||
from tracker.enums import AuthorType, ListenMode, MemberType, WSEventType
|
from ..enums import AuthorType, ListenMode, MemberType, WSEventType
|
||||||
|
|
||||||
logger = logging.getLogger("tracker.ws")
|
logger = logging.getLogger("tracker.ws")
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user