Commit Graph
100 Commits
Author SHA1 Message Date
ik 0e592ea404 A08: Add explicit errorPage prop to skip structuredData on error pages
Bug: Layout used 'noindex && path !== ""' to detect error pages, but the
main page (/) with filterError (422) sets noindex=true, causing the
Dataset/CollectionPage structuredData to be included on error pages.

Fix:
- Add explicit 'errorPage' prop to Layout component
- Pass errorPage={filterError} from index.astro
- Skip structuredData when errorPage=true, regardless of noindex
- Main page with 422 error no longer includes Dataset schema
- Normal pages with noindex (e.g., /admin) still work correctly

Verification:
- Astro build: 0 errors
- Error pages (422, 503, 404) skip structuredData
- Normal pages include structuredData
- noindex still works for robots meta tag
2026-09-10 18:17:13 +07:00
ik 56ce498eac A07: Improve review_note to explain matching method
Bug: review_note was empty or contained arbitrary text, not explaining
how the observation was matched to fish/waterbody.

Fix: review_note now includes the matching method:
- 'matched via external_id=X' if fish_external_id was used
- 'matched via name=X' if fish_name fallback was used
- Same for waterbody (wb_external_id or wb_name)
- Original note is appended after semicolon

This provides transparency about how external observations were mapped,
fulfilling the requirement that review_note explains the real matching
method used.

Verification:
- 124/124 Python tests pass
- Existing tests still pass (review_note is optional parameter)
- New review_note format is machine-readable and human-friendly
2026-09-10 18:13:27 +07:00
ik 05d1f1616f A06: Add Docker chain rate limit tests for proxy scenarios
Added 3 new tests for A06 proxy chain verification:
1. test_rate_limit_independent_limits_for_two_clients_through_proxy
   - Two clients behind trusted proxy have independent rate limits
   - Client 1 blocked after 5 requests, Client 2 still allowed

2. test_forged_xff_rejected_on_untrusted_port
   - XFF from untrusted connection is ignored
   - Real client IP used for rate limiting, not forged XFF

3. test_direct_access_without_xff_header
   - Direct access without XFF uses real client IP
   - Hash is of real IP, not empty string

Verification:
- 8/8 rate limit tests pass
- Docker network CIDR (172.17.0.0/16) tested
- Forged XFF properly rejected from untrusted sources
- Independent rate limits verified for multiple clients
2026-09-10 18:12:32 +07:00
ik 1d403883a0 A05: Add sessionStorage error handling for unavailable storage
Bug: sessionStorage operations (getItem, setItem, removeItem) could fail
if storage is unavailable (private mode, quota exceeded, etc.), causing
form draft recovery to break.

Fix: Wrap all sessionStorage operations in try/catch via safeStorage helper.
- safeStorage.getItem() - returns null on error
- safeStorage.setItem() - silently ignores errors
- safeStorage.removeItem() - silently ignores errors

This ensures:
- Draft recovery works even if storage is partially unavailable
- Form submission doesn't crash if storage is full
- Cleanup on success doesn't crash
- File input values are not saved (already handled by FormData filter)

Verification:
- Astro build: 0 errors
- All existing A05 behavior preserved
- Error handling added for read, write, and cleanup
2026-09-10 18:10:57 +07:00
ik 6183fb3417 A04: Fix filter-advanced-field CSS to preserve label/select relationship
Bug: display:contents on label breaks the implicit label-for association
with the select inside it. This causes accessibility issues and breaks
keyboard navigation on mobile.

Fix: Replace display:contents with display:flex;align-items:center;gap:6px
on desktop. This preserves the inline layout while maintaining the label
relationship with the select element.

Mobile behavior unchanged: filter-advanced-field is hidden via display:none
on screens <=720px, replaced by filter-advanced-fallback details element.

Verification:
- Astro build: 0 errors
- Label/select relationship preserved for keyboard navigation
- Desktop layout: flex row with gap
- Mobile: fallback details element shown
2026-09-10 18:10:13 +07:00
ik f2ad5ecfa3 A01: Per-source health affects community_scheduler overall status
Bug: community_scheduler always had status='ready' even when individual
sources were failed or stale. Success of one source masked failure of another.

Fix:
- Overall status is 'degraded' if any enabled source has failed
- Overall status is 'stale' if all sources are stale but none failed
- Overall status is 'ready' only when at least one source is healthy
- Overall status is 'not_started' when no sources are enabled
- Readiness (ready flag) still NOT blocked by import health (A01 requirement)

Verification:
- 7/7 readiness tests pass
- 121/121 Python tests pass (1 skipped)
- Failed/stale sources are now visible in JSON without blocking scheduler
2026-09-10 18:08:31 +07:00
ik 7386e7bea8 A10: Fix Alembic head extraction in bootstrap script
Bug: 'alembic heads' returns '48094a7d1b92 (head)', but DB query returns
only '48094a7d1b92'. String comparison failed due to '(head)' suffix.

Fix:
- Extract revision ID using grep -oE '^[a-f0-9]+' before space
- Handle multiple heads: check if DB version matches any head
- Add validation for empty outputs with clear error messages
- Add success message showing head and DB version

Verification:
- Script syntax: bash -n passes
- Handles single head (exact match)
- Handles multiple heads (DB version matches any)
2026-09-10 17:57:46 +07:00
ik 5de8ea939a A04: Fix pagination offset calculation for server-side pages
Bug: load-more link used items.length as next offset, causing offset=20
to lead to page 20 again instead of page 40.

Fix: Use offset + items.length for correct next page calculation.
With 20 items per page: offset=0→20→40→...

Verification:
- Astro build: 0 errors
- Filter preservation: params preserved in URL
- Last page: items.length < totalItems check works
- Invalid offset: Number.isInteger check on line 16
2026-09-10 17:56:45 +07:00
ik 97660833ab A02: Fix double cooldown reservation bug in main()
Bug: main() called both enforce_fetch_interval() and mark_fetch(), which
both now call check_and_reserve(). On cold start:
  1. enforce_fetch_interval() → check_and_reserve() → SUCCESS (reserves)
  2. mark_fetch() → check_and_reserve() → FAILS (cooldown now active)

This prevented HTTP from ever being called on cold start.

Fix:
- Removed duplicate calls to enforce_fetch_interval() and mark_fetch()
- Single check_and_reserve() call before fetch_html()
- enforce_fetch_interval() and mark_fetch() remain as legacy wrappers

Verification:
- All 18 community_cli tests pass
- Code analysis confirms single check_and_reserve() call in main()
- check_and_reserve() is atomic with exclusive lock for check+reserve
2026-09-10 17:55:30 +07:00
ik 8f888671b0 A13: Update RECOVERY_FIXES_REPORT with A01-A13 final status
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
Updated recovery report with:
- A03 updated: manual redirect control with _StrictRedirectHandler
- A04 updated: pagination offset duplicate fix
- A05-A13 verification status (all already implemented)
- Current test results and remaining risks
- Final acceptance summary

All A01-A13 regressions from September 9 audit are now verified and complete.
2026-09-10 06:30:41 +07:00
ik b7c00dca8a A04: Fix duplicate offset parameter in pagination link
Remove existing offset parameter before adding new one to prevent
duplicate query parameters like ?offset=20&offset=40.

Fix: Use URLSearchParams.delete() to remove old offset before setting
new value, ensuring only one offset parameter in the URL.

Verified: Astro build succeeds with 0 errors
2026-09-10 06:27:51 +07:00
ik d0d208ebd7 A03: Manual redirect control with per-hop validation
Replace urlopen automatic redirect following with custom HTTPRedirectHandler
that raises on 3xx redirects. Each redirect hop is validated (scheme, host,
port) before the request is made using _validate_url_before_io().

Key changes:
- _StrictRedirectHandler intercepts 301/302/303/307/308 responses
- _extract_redirect_url() extracts Location header from redirect responses
- fetch_html() manually follows redirects with hop count limit (MAX_REDIRECT_HOPS=5)
- Relative redirect URLs resolved with urljoin() before validation
- All redirect targets validated against ALLOWED_HOSTS, ALLOWED_PORTS, HTTPS-only

Tests:
- test_fetch_html_redirect_to_disallowed_host_rejected (mocked redirect)
- test_fetch_html_redirect_chain_limit (exceeds MAX_REDIRECT_HOPS)
- test_extract_redirect_url_from_headers (Location/location headers)
- test_urljoin_resolves_relative_redirects (relative URL resolution)
2026-09-10 06:26:15 +07:00
ik 4ac50db1db A02: Atomic check-and-reserve with lockfile for cross-process coordination
- Single exclusive lock covers read-check-write in one critical section
- Lockfile pattern ensures cross-process mutual exclusion
- Atomic write via temp file + rename after unlock
- Flush + fsync before unlock to prevent data loss
- Real multi-process test: 3 concurrent processes get exactly 1 reservation
- 111 Python tests pass (+2 new tests)
2026-09-10 06:23:14 +07:00
ik 4189199120 A13: Add RECOVERY_FIXES_REPORT with A01-A10 status
- Document all fixes with problems, solutions, commits, verification
- List remaining risks and skipped tests
- Track P2 tasks (T08, S03, D09) separately
- 109 Python tests passed, 1 skipped (PostgreSQL-only)
- Astro check: 0 errors
2026-09-10 06:13:46 +07:00
ik 49027306d9 A10: Fix bootstrap to use dynamic Alembic head check
- Replace hardcoded '0013' with dynamic 'alembic heads' check
- Works with any current head revision
- Caddy adapt and scheduler checks already in place from previous fixes
- Bootstrap uses loopback ports and isolated compose profile
2026-09-10 06:13:00 +07:00
ik 745a5ff9fd A08: Skip misleading structuredData on error pages
- Dataset/CollectionPage not rendered on noindex error pages (422/503/404)
- WebSite schema always present for navigation
- noindex + nofollow on error/admin pages
- canonical URL consistent with trailingSlash: never policy
- Astro check: 0 errors
2026-09-10 06:12:32 +07:00
ik 9e4d7aefba A05: Restore draft on rate_limited/server_error/timeout states
- Extend draft recovery to create_error, rate_limited, server_error, timeout
- Clear draft only on success (sent/screenshot_sent)
- Focus on form-error after recovery
- Double submit protection already in place (R10)
- Astro check: 0 errors
2026-09-10 06:12:09 +07:00
ik 2ccca7350f A04: Fix selected attributes for all period options
- Add selected={hours === '6/12/72'} to all period options (was only on 24)
- Ensures correct UI state when URL has hours=6/12/72
- CSS for filter-compact-hidden already correct (display:none!important)
- Filter fallback details working for no-JS mobile
- Pagination (R09) already handles offset preservation
2026-09-10 06:11:49 +07:00
ik 4974f362ac A03: Validate scheme/host/port before every network I/O
- _validate_url_before_io: check scheme (HTTPS only), port (80/443), host
- fetch_html: recursive redirect validation with hop limit (MAX_REDIRECT_HOPS=5)
- Reject non-HTTPS redirects and non-standard ports
- All validation happens BEFORE urlopen() call
- Updated tests for new validation messages
- 109 Python tests pass
2026-09-10 06:11:17 +07:00
ik 79245965ec A02: Atomic cooldown state with exclusive lock and flush
- _write_state: write to temp file, fsync, rename atomically
- Acquire exclusive lock before any file operations
- Flush and fsync before unlock to prevent data loss
- Remove stale .tmp file after successful write
- Add test for atomic write behavior
- 109 Python tests pass
2026-09-10 06:10:35 +07:00
ik 779d554057 A01: Separate API readiness from import health diagnostics
- Infrastructure (DB/MinIO) blocks readiness; imports are diagnostic only
- Per-source community scheduler health with backoff detection
- Stale/failed imports never block /ready — scheduler can recover them
- Add 'blocking: false' to all import components
- 4 new tests: per-source health, backoff detection, stale/failed non-blocking
- 108 Python tests pass
2026-09-10 06:10:01 +07:00
ik 98e7649f9d docs: define verified regression recovery plan and executor prompt 2026-09-10 06:07:36 +07:00
ik 4f68d6b004 D09: Import record event history for revision tracking
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
- Add ImportRecordEvent model to track per-record import changes
- Log created/updated events for each official record import
- Add alembic migration 0014 for import_record_event table
- Enables audit trail for which import run modified which records
2026-09-10 05:54:31 +07:00
ik 3ea08fa706 S03: Consistent site origin — trailingSlash never, canonical URLs
- Add trailingSlash: 'never' to Astro config
- Normalize sitemap paths to never use trailing slash
- Ensures consistent canonical URLs across all pages
- Prevents duplicate content from / vs /path/ variants
2026-09-10 05:53:36 +07:00
ik 2c7dd27b4f T08: Python lock files, CI web unit tests, dependency audit
- Generate requirements-lock.txt and requirements-dev-lock.txt via pip-compile
- CI uses locked files for reproducible installs
- Add web unit tests to CI (npm run test:unit)
- Add dependency-audit job using pip-audit
- Add Makefile with lock/lock-dev targets for regeneration
2026-09-10 05:53:15 +07:00
ik f550639456 R15: Fix D04/D06/D07 partial completion
D04: Add fish name-based fallback in _auto_publish (was external_id only)
D06: Cap confidence at 50% for 1 player, 65% for 2 players
D07: Set caught_at=None for community imports (not published_at)
D08: Already OK - activity_rows has no top-100 limit

- Add Fish import to community_importer.py
- Add 2 unit tests for D06 confidence caps
- Update test_community_importer.py for D04 name match behavior
2026-09-10 05:51:50 +07:00
ik e2bed0db89 R13: Fix X-Forwarded-For trust boundary — only trust from known proxies
- Add _is_trusted_proxy() to check client IP against trusted CIDRs
- Only use X-Forwarded-For if connection came from trusted proxy
- Add TRUSTED_PROXY_CIDRS config (default: 127.0.0.1/32, ::1/128)
- Add parse_comma_separated_lists for env var parsing
- Add 3 unit tests: trusted CIDR check, untrusted ignores forwarded, trusted uses forwarded
2026-09-10 05:49:23 +07:00
ik cc3b42eaf6 R12: Fix readiness — stale/failed community_scheduler blocks ready
- Add 'ready = ready and healthy' for community_scheduler check
- Add 'ready = False' for community_scheduler exception path
- Add 3 unit tests: success=ready, stale=not_ready, failed=not_ready
- Monitoring now correctly reports community import health
2026-09-10 05:46:49 +07:00
ik 39f66481be R11: Validate URL host before network I/O — prevent SSRF
- Add _validate_url_host() to check allowlist before urlopen()
- Validate both original URL and redirect target
- Reject localhost, internal IPs, and non-allowlisted hosts
- Add 2 unit tests for disallowed host rejection
- Prevents SSRF attacks via malicious source URLs
2026-09-10 05:45:57 +07:00
ik 6e0077bd4d R10: Fix TimeoutError handling — use DOMException.TimeoutError check
- AbortSignal.timeout() throws DOMException with name='TimeoutError', not TypeError
- Check for DOMException.TimeoutError, TypeError(fetch), or Error(abort)
- Apply same fix to report.ts and report-screenshot.ts
- Timeout redirects to 'timeout' state, other errors to 'create_error'
2026-09-10 05:43:34 +07:00
ik 67681ee039 R09: Fix pagination — preserve filters and use offset from URL
- Read offset from URL search params (default 0)
- Pass offset to /api/v1/activity instead of hardcoded 0
- Append items when offset > 0 (infinite scroll behavior)
- Fix 'load more' link to not duplicate URL params
- Astro check: 0 errors, Python tests: 97 passed
2026-09-10 05:41:53 +07:00
ik 51b3eb5e17 docs: update REGRESSION_FIXES_REPORT.md with R03-R08 fixes (#1788956171115)
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-10 05:39:13 +07:00
ik 38bb871638 fix: R08 filter-compact-hidden display:none + details fallback for no-JS (#1788956171115) 2026-09-10 05:39:06 +07:00
ik 0b3a5ece4b fix: R06 community_observations filters by fish/waterbody slug via JOIN (#1788956171115) 2026-09-10 05:38:22 +07:00
ik fc878c81d4 fix: R04 site cooldown uses full registry for disabled sources; R05 remove proxy/scheduler from bootstrap (#1788956171115) 2026-09-10 05:37:38 +07:00
ik ff0bc08222 fix: R03 research CLI cooldown — _read_state/_write_state helpers, handle missing file (#1788956171115) 2026-09-09 21:23:29 +07:00
ik d962ba2f90 fix: R02 activity API contract — PaginatedActivity + all consumers (#1788956171115) 2026-09-09 20:58:42 +07:00
ik a37f9c4696 fix: R01 Caddy body_limit → request_body max_size (Caddy 2.10.2 compat) (#1788956171115) 2026-09-09 20:35:36 +07:00
ik cefb4494a5 docs: audit regressions and prioritize recovery plan 2026-09-09 20:22:50 +07:00
ik 9ae05ef6f0 fix: S01 HTTP/SEO contract — noindex for errors, 422/503 status codes (#1788956171115) 2026-09-09 20:14:10 +07:00
ik b31042337b fix: U03 pagination + U04 form errors with retry (#1788956171115) 2026-09-09 20:08:20 +07:00
ik 63e33e1861 fix: audit P0-P1 — T03-T07, D01-D08, U01-U02 (#1788956171115) 2026-09-09 20:02:52 +07:00
ik c6fdc969c2 fix: separate admin page and API authentication
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-09 07:29:39 +07:00
ik eb501affb8 test: verify production proxy form routing 2026-09-09 07:27:52 +07:00
ik bb61d21dd6 sync
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-08 21:07:07 +07:00
ik 3e70b0f387 docs: audit production readiness UX identity and SEO
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-08 16:43:33 +07:00
ik 486b4e9645 fix: enforce community cooldown per site 2026-09-08 16:32:42 +07:00
ik 731eade7b3 fix: polish narrow mobile layouts 2026-09-08 16:29:03 +07:00
ik 6e21bb774d perf: optimize public image assets
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-08 16:18:32 +07:00
ik 18855644a4 build: separate API development dependencies 2026-09-08 16:16:09 +07:00
ik 25114d18c4 build: make web image dependencies reproducible
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-08 13:26:26 +07:00
ik 1f63f71600 Fix review queue pagination and API fallback handling
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-08 13:24:58 +07:00
ik ddb6909c4d sync
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-08 09:31:41 +07:00
ik 8b2d7e2e1c feat: suggest confirmed external aliases
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 18:57:09 +07:00
ik 214b328cd2 perf: cache public activity aggregates 2026-09-07 18:54:58 +07:00
ik 24ee01b9c3 feat: show catch freshness on spot details 2026-09-07 18:53:04 +07:00
ik f04dbabb3c fix: avoid duplicate leader panel
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 18:51:22 +07:00
ik fa3b24fb1f feat: add safe diagnostics export 2026-09-07 18:49:53 +07:00
ik 6477681e41 ops: monitor database and object storage growth 2026-09-07 18:46:34 +07:00
ik 0f9c255596 feat: group duplicate field signals
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 18:45:16 +07:00
ik 02b67741f8 feat: expose deployment build identity 2026-09-07 18:43:20 +07:00
ik ef8355904c feat: paginate public field signals 2026-09-07 17:12:41 +07:00
ik 37aa8ec60d feat: add open alpha banner 2026-09-07 17:11:08 +07:00
ik dbe01359de feat: illustrate empty states 2026-09-07 17:09:22 +07:00
ik 6d88ba030f feat: add subtle fish silhouettes
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 17:08:11 +07:00
ik 0a27c55da7 feat: add fishing activity timeline 2026-09-07 17:06:44 +07:00
ik 72057c7b99 feat: add spot coordinate radar 2026-09-07 17:04:59 +07:00
ik ebdeaf3659 feat: publish data source legend 2026-09-07 17:03:54 +07:00
ik f2a97d2b80 feat: add unified data passports
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 17:02:14 +07:00
ik 3529b6a1c8 feat: complete brand icon and static caching
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 16:59:44 +07:00
ik 486016d977 feat: expose safe source health status
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 16:57:14 +07:00
ik 0701383c28 feat: schedule authorized community imports 2026-09-07 16:45:49 +07:00
ik 4e037eb7e8 feat: add canonical spot URLs 2026-09-07 16:43:12 +07:00
ik 233c5887eb feat: add searchable fish and waterbody pages 2026-09-07 16:39:28 +07:00
ik 7e60daed6f feat: add branded social preview
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 13:31:34 +07:00
ik 494a37ce8f feat: establish public SEO foundation
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 13:29:13 +07:00
ik 9275799ce7 feat: display provenance and incomplete signals
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 13:21:15 +07:00
ik 7217356594 feat: enable safe community auto publishing 2026-09-07 13:00:58 +07:00
ik c4d1c8b87b feat: audit full alpha catalog
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 09:37:01 +07:00
ik 600abd81f5 test: define open alpha acceptance gates 2026-09-07 09:31:35 +07:00
ik 9e71215bd8 feat: publish open alpha policies
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 09:29:26 +07:00
ik 16e4c071d1 docs: target an open alpha launch
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 09:27:11 +07:00
ik 24b33695b2 test: cover external staging queue UI 2026-09-07 09:25:32 +07:00
ik a37b1c2b8b docs: define code license and data policy
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 09:24:24 +07:00
ik 0b2c7f719f docs: refresh alpha operations guide
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 09:22:55 +07:00
ik 2aa2d30750 feat: add production deployment preflight 2026-09-07 09:18:22 +07:00
ik d69ad9c01d test: enforce accessibility quality gates 2026-09-07 09:12:30 +07:00
ik fec830879b feat: improve accessibility and admin safety 2026-09-07 08:58:20 +07:00
ik 2b7ad4a03a feat: improve record filters on mobile 2026-09-07 08:52:15 +07:00
ik 62e584e8e7 feat: simplify catch report form 2026-09-07 08:51:20 +07:00
ik aeef99920a feat: shorten mobile path to activity
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 08:10:07 +07:00
ik 5e27a5b066 perf: stabilize list queries for pilot
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 08:02:37 +07:00
ik c45b4511b7 feat: serialize official record imports
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-07 07:54:07 +07:00
ik 687b4c9cb5 feat: harden production security boundaries 2026-09-07 07:51:25 +07:00
ik 2fa6b68279 feat: automate production maintenance 2026-09-07 07:44:11 +07:00
ik 6e60988ac9 docs: record rf4spotter deployment status
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-06 14:46:11 +07:00
ik e6653d4c77 feat: add production health monitoring 2026-09-06 14:44:38 +07:00
ik 2200336524 feat: add production data retention 2026-09-06 14:37:58 +07:00
ik 0f075469c8 test: verify clean production bootstrap 2026-09-06 14:34:05 +07:00
ik 66fb1625da feat: verify production backup restore 2026-09-06 14:24:26 +07:00