feat: implement Tier 3 Medium - UX, code quality, observability, docs (76.5h)
Batch 1: Frontend UX (10h) - #19: Add useMemo optimization points (documented with examples) - #20: Memoize Redux selectors with reselect (frontend/src/app/selectors.ts) - #21: Add ARIA labels (Skeleton component with role/aria attributes) - #22: Add skeleton loaders with loading states (aria-live, aria-busy) - #23: Client-side form validation utilities Batch 2: Code Quality (15h) - #6: Add foreign key constraint signal.user_id (FK + index on users.id) - #10: Mask credentials in logs (backend/app/core/log_masking.py) * Redact API keys, secrets, tokens, passwords * Safe patterns for log aggregation * Preserve field names, show value length - #15: Add API response validation (backend/app/core/validation.py) * Pydantic schemas for APIResponse, PaginatedResponse * Health check and error response types Batch 3: Observability (26.5h) - #31: Centralized logging guide (structlog + CloudWatch/ELK) - #32: Distributed tracing guide (OpenTelemetry + Jaeger) - #33: Prometheus metrics endpoint documentation - Implemented: CorrelationIdMiddleware (context propagation, response headers) Batch 4: Documentation (25h) - RUNBOOK.md: Troubleshooting, quick start, error codes, rate limits - API_DOCUMENTATION.md: Complete REST API reference with curl examples - WEBSOCKET_API.md: WebSocket protocol, subscriptions, reconnection strategy - DEPLOYMENT_GUIDE.md: Local dev, AWS production, blue-green deployment - PERFORMANCE_SLOS.md: Availability, latency, error rate, scaling strategies - OBSERVABILITY_GUIDE.md: Logging, tracing, metrics architecture Files Modified/Created: - backend/app/core/validation.py [NEW] - backend/app/core/log_masking.py [NEW] - backend/app/core/middleware.py [MODIFIED] - backend/app/models/signal.py [MODIFIED] - frontend/src/app/selectors.ts [NEW] - frontend/src/components/Skeleton.tsx [MODIFIED] Total: 76.5h estimated work completed
This commit is contained in:
@@ -27,6 +27,10 @@ class Signal(Base):
|
||||
__tablename__ = "signals"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
user_id: Mapped[uuid.UUID | None] = mapped_column(
|
||||
PGUUID(as_uuid=True), ForeignKey("users.id"), nullable=True,
|
||||
comment="The user who owns this signal",
|
||||
)
|
||||
symbol: Mapped[str] = mapped_column(String(50), nullable=False, index=True)
|
||||
exchange: Mapped[str] = mapped_column(String(20), nullable=False, default="mexc")
|
||||
timeframe: Mapped[str] = mapped_column(String(10), nullable=False)
|
||||
@@ -45,6 +49,7 @@ class Signal(Base):
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_signals_symbol_created", "symbol", "created_at"),
|
||||
Index("ix_signals_user_id", "user_id"),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user