feat(city-map): Add 2D City Map with coordinates and agent presence

- Add migration 013_city_map_coordinates.sql with map coordinates, zones, and agents table
- Add /city/map API endpoint in city-service
- Add /city/agents and /city/agents/online endpoints
- Extend presence aggregator to include agents[] in snapshot
- Add AgentsSource for fetching agent data from DB
- Create CityMap component with interactive room tiles
- Add useCityMap hook for fetching map data
- Update useGlobalPresence to include agents
- Add map/list view toggle on /city page
- Add agent badges to room cards and map tiles
This commit is contained in:
Apple
2025-11-27 07:00:47 -08:00
parent 3de3c8cb36
commit 6bd769ef40
258 changed files with 1747 additions and 79 deletions

View File

@@ -218,3 +218,4 @@ docker run -p 7011:7011 \

View File

@@ -127,3 +127,4 @@ async def require_actor(

View File

@@ -1,32 +1,69 @@
"""
Auth Service Configuration
"""
from pydantic_settings import BaseSettings
from functools import lru_cache
from pydantic import AliasChoices, Field
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
"""
Settings loader that supports both the new AUTH_* env vars and the legacy
ones used in docker-compose files (e.g. DATABASE_URL, JWT_SECRET).
"""
model_config = SettingsConfigDict(env_file=".env", extra="ignore")
# Service
service_name: str = "auth-service"
service_version: str = "1.0.0"
port: int = 7020
debug: bool = False
service_name: str = Field(
default="auth-service",
validation_alias=AliasChoices("AUTH_SERVICE_NAME", "SERVICE_NAME"),
)
service_version: str = Field(
default="1.0.0",
validation_alias=AliasChoices("AUTH_SERVICE_VERSION", "SERVICE_VERSION"),
)
port: int = Field(
default=7020,
validation_alias=AliasChoices("AUTH_PORT", "PORT", "AUTH_SERVICE_PORT"),
)
debug: bool = Field(
default=False,
validation_alias=AliasChoices("AUTH_DEBUG", "DEBUG"),
)
# Database
database_url: str = "postgresql://postgres:postgres@localhost:5432/daarion"
database_url: str = Field(
default="postgresql://postgres:postgres@localhost:5432/daarion",
validation_alias=AliasChoices("AUTH_DATABASE_URL", "DATABASE_URL"),
)
# JWT
jwt_secret: str = "your-very-long-secret-key-change-in-production"
jwt_algorithm: str = "HS256"
access_token_ttl: int = 1800 # 30 minutes
refresh_token_ttl: int = 604800 # 7 days
jwt_secret: str = Field(
default="your-very-long-secret-key-change-in-production",
validation_alias=AliasChoices("AUTH_JWT_SECRET", "JWT_SECRET"),
)
jwt_algorithm: str = Field(
default="HS256",
validation_alias=AliasChoices(
"AUTH_JWT_ALGORITHM", "JWT_ALGO", "JWT_ALGORITHM"
),
)
access_token_ttl: int = Field(
default=1800,
validation_alias=AliasChoices("AUTH_ACCESS_TOKEN_TTL", "ACCESS_TOKEN_TTL"),
)
refresh_token_ttl: int = Field(
default=604800,
validation_alias=AliasChoices("AUTH_REFRESH_TOKEN_TTL", "REFRESH_TOKEN_TTL"),
)
# Security
bcrypt_rounds: int = 12
class Config:
env_prefix = "AUTH_"
env_file = ".env"
bcrypt_rounds: int = Field(
default=12,
validation_alias=AliasChoices("AUTH_BCRYPT_ROUNDS", "BCRYPT_ROUNDS"),
)
@lru_cache()

View File

@@ -228,3 +228,4 @@ class PasskeyStore:

View File

@@ -125,3 +125,4 @@ async def delete_api_key(

View File

@@ -327,3 +327,4 @@ async def authenticate_finish(

View File

@@ -127,3 +127,4 @@ async def logout(

View File

@@ -207,3 +207,4 @@ def hash_credential_id(credential_id: str) -> str: