feat(deployments): soft-delete, correlation IDs, graceful shutdown, analytics optimization#685
Merged
temma02 merged 1 commit intoMay 28, 2026
Conversation
…nalytics optimization Closes StellerCraft#597, StellerCraft#598, StellerCraft#599, StellerCraft#600 StellerCraft#597 – Soft-delete & tombstone pattern - Add deleted_at tombstone column via migration 010 - Exclude soft-deleted records from all default queries (list, get, count, withDeploymentAuth) - Soft-delete on DELETE instead of hard-delete; external cleanup remains best-effort - POST /api/deployments/[id]/restore within the retention window (DEPLOYMENT_TOMBSTONE_RETENTION_DAYS, default 30) - Cron /api/cron/purge-tombstoned-deployments permanently removes records past the window StellerCraft#598 – Structured logging correlation IDs - Analytics route now uses log/correlationId from withDeploymentAuth context - correlationId included in all 5xx error responses for support correlation - Replaces raw console.error with structured log.error in analytics handler StellerCraft#599 – Graceful shutdown for in-flight deployments - shutdown-manager.ts: isDraining / trackOperation / drain() with configurable timeout - instrumentation.ts: SIGTERM/SIGINT handlers that call drain() before process.exit - POST /api/deployments returns 503 with Retry-After during drain StellerCraft#600 – Analytics aggregation query optimization - Migration 011: composite indexes on (deployment_id, metric_type, metric_value) and (deployment_id, recorded_at DESC) - get_analytics_summary() DB function replaces 3 separate full-table scans with a single GROUP BY aggregation pass via supabase.rpc() - 60-second in-process cache (summaryCache) for high-frequency dashboard polls; invalidated on every write Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@joel-metal Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
deleted_atcolumn via migration 010;DELETEnow sets the timestamp instead of hard-deleting;POST /api/deployments/[id]/restorerecovers within the retention window; daily cron permanently purges records pastDEPLOYMENT_TOMBSTONE_RETENTION_DAYS(default 30 d); all list/get queries andwithDeploymentAuthexclude tombstoned records.log/correlationIdfrom thewithDeploymentAuthcontext;log.error()replaces rawconsole.error;correlationIdis included in all 5xx error responses.shutdown-manager.tsexposesisDraining(),trackOperation(), anddrain();instrumentation.tsregistersSIGTERM/SIGINThandlers that drain before exit;POST /api/deploymentsresponds503 + Retry-Afterwhile draining.get_analytics_summary()SQL function;getAnalyticsSummarynow issues a singlerpc()call instead of three full-table scans; a 60-second in-process cache reduces load for high-frequency dashboard polls.Changes
supabase/migrations/010_deployment_soft_delete.sqldeleted_atcolumn + partial indexessupabase/migrations/011_analytics_query_optimization.sqlget_analytics_summary()functionapps/backend/src/app/api/deployments/[id]/route.tsapps/backend/src/app/api/deployments/[id]/restore/route.tsapps/backend/src/app/api/cron/purge-tombstoned-deployments/route.tsapps/backend/src/app/api/deployments/route.tsapps/backend/src/lib/api/with-auth.tswithDeploymentAuthexcludes tombstoned recordsapps/backend/src/lib/shutdown-manager.tsapps/backend/src/instrumentation.tsapps/backend/src/services/analytics.service.tsapps/backend/src/app/api/deployments/[id]/analytics/route.tsCloses
Closes #597
closes #598
closes #599
closes #600
🤖 Generated with Claude Code