- bundle: reject tar entry names that differ from their trimmed form instead of normalizing padded names into the allowlist - repo: reserve expected bytes on receiving rows and count receiving+ready in the per-user byte quota so concurrent/multi-node uploads can't overshoot - contract: require the crash object for event report types and keep it absent for manual; add contract tests - settings/service: seed diagnostics.server_instance_id atomically via insert-if-absent and adopt the winning value across nodes - bundle/service: capture the embedded manifest.json during ValidateBundle and reject reports whose embedded manifest disagrees with the part-1 manifest (minus archive); add tests - admin: delete the DB row before the blob on DeleteReport; log bucket/key when the blob delete fails instead of leaving a visible report with a missing bundle - bundle: reject PAX/GNU tar formats and extension records that smuggle bytes past validation; add a PAX-archive rejection test - migration: add CHECK constraints for state, report_type, and platform - docs: add text/jsonc language identifiers to the two unfenced code blocks - cleanup: log-and-continue per report and aggregate errors so one poisoned report no longer blocks the whole run; update tests - tasks: give diagnostics its own cleanup interval key instead of reusing the opslog key, and bound the startup settings lookup Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012e3QjbPo96ed9Mn2qRiUkh
32 lines
1.2 KiB
SQL
32 lines
1.2 KiB
SQL
-- +goose Up
|
|
CREATE TABLE client_diagnostic_reports (
|
|
id UUID PRIMARY KEY,
|
|
short_id TEXT NOT NULL,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
profile_id TEXT,
|
|
state TEXT NOT NULL CHECK (state IN ('receiving', 'ready', 'failed')),
|
|
captured_at TIMESTAMPTZ NOT NULL,
|
|
received_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
report_type TEXT NOT NULL CHECK (report_type IN ('crash', 'anr', 'native_crash', 'hang', 'abnormal_exit', 'manual')),
|
|
platform TEXT NOT NULL CHECK (platform IN ('android', 'android-tv', 'ios', 'tvos')),
|
|
app_version TEXT NOT NULL,
|
|
crash_summary TEXT,
|
|
manifest JSONB NOT NULL,
|
|
playback_session_ids TEXT[] NOT NULL DEFAULT '{}',
|
|
blob_bucket TEXT,
|
|
blob_key TEXT,
|
|
blob_bytes BIGINT,
|
|
uncompressed_bytes BIGINT,
|
|
blob_sha256 TEXT
|
|
);
|
|
|
|
CREATE UNIQUE INDEX client_diagnostic_reports_short_id_lower_idx
|
|
ON client_diagnostic_reports (lower(short_id));
|
|
CREATE INDEX client_diagnostic_reports_user_received_idx
|
|
ON client_diagnostic_reports (user_id, received_at DESC);
|
|
CREATE INDEX client_diagnostic_reports_received_idx
|
|
ON client_diagnostic_reports (received_at);
|
|
|
|
-- +goose Down
|
|
DROP TABLE IF EXISTS client_diagnostic_reports;
|