Update external_data submodule to 0a53315 (XWA 50pt data + new expansions, legacy -> Darker333 master) - #131
Open
Franc3s-bot wants to merge 192 commits into
Open
Update external_data submodule to 0a53315 (XWA 50pt data + new expansions, legacy -> Darker333 master)#131Franc3s-bot wants to merge 192 commits into
Franc3s-bot wants to merge 192 commits into
Conversation
…cespo#46) Fixed the backend import issues with faction char and improved the startup script to avoid opening new windows and handle dynamic ports.
…provements # Conflicts: # backend/analytics/factions.py # backend/analytics/ships.py
…CORS completely for dashboard
…R crash on extreme filters
… with search bar - Add GET /api/tournaments/locations endpoint returning distinct locations - Split location filter into 3 dynamic sub-filters (Continent, Country, City) - Countries update based on selected Continents, Cities based on selected Countries - Add mini search bar to filter location entries - Remove duplicate Unknown entries from continent list
…tructure - Move ShipChassisFilter below Faction on ships, cards, lists, squadrons pages - Remove accordion expand/collapse; make it a flat static section - Ship icons in filter inherit text color (uncolored) - Faction symbols remain colored next to ship names - Respects specificity hierarchy: Sort By > Faction > Ship Chassis
Closes Francespo#37. This PR fixes three critical bugs in the analytics modules: 1. **Tournament filters ignored**: Added centralized location filtering via �pply_tournament_filters() and updated SQL filters. 2. **Lists count 0**: Added lists aggregation to core.py. 3. **Frontend filters ignored**: Merged main, resolved UI conflicts, and fixed a Svelte a11y bug (�11y_consider_explicit_label) that caused a 500 error.
# Conflicts: # backend/analytics/factions.py # backend/analytics/ships.py
…provements # Conflicts: # backend/analytics/ships.py # backend/api/ships.py # frontend/src/routes/lists/+page.svelte # frontend/src/routes/ships/+page.svelte
…ion bugs (Francespo#45) Closes Francespo#42. ## Technical Changes - Replaced SSR data loading in `+page.ts` with reactive client-side `$effect` fetching to resolve route navigation desync and crashes. - Replaced hardcoded 'XWA / Analysis Mode' title with the `<ContentSourceToggle />` component in the header. - Implemented reactive data fetching based on the global `filters.dataSource` state to seamlessly switch between XWA and Legacy data sets without requiring a page reload.
Closes Francespo#38 ## Summary Adds the Ships / Chassis page with filtering capabilities and fixes the hover scaling behavior on ship cards. ## Changes ### Backend - **New** `backend/routers/ships.py`: FastAPI router exposing `GET /api/ships` with optional `faction` and `source` query params. - **Modified** `backend/main.py`: Registers the ships router under `/api` prefix. - **Fixed** `backend/utils/xwing_data/core.py`: Corrected `ROOT_DIR` path (`parents[4]` to `parents[3]`). ### Frontend - **New** `frontend/src/routes/ships/+page.svelte`: Ships page with chassis filter dropdown, faction filter, responsive card grid, and **hover scale on entire card container** (not inner icon). - **Modified** `frontend/src/routes/+layout.svelte`: Added navigation bar with Ships link. - **Modified** `frontend/vite.config.js`: API proxy to FastAPI backend. ## Technical Rationale The hover scaling fix places `transform: scale(1.06)` on the outer `.ship-card` container rather than inner icon wrappers, ensuring the entire card elevates uniformly on hover.
# Conflicts: # frontend/src/routes/squadrons/+page.svelte
Closes Francespo#43. - Alphabetized SortSelector options list. - Changed SVG arrows to use distinct upward/downward pointing icons. - Updated Squadrons page to use SortSelector component. - Used getFactionLabel instead of raw faction key in SquadronRowCard.
Removes remaining garbage files and logs from main.
Closes Francespo#44. Identified 6 missing ship icons in xwing-miniatures.css by comparing with JSON data. Added mappings for ieininterceptor, delta7baethersprite, cr90corelliancorvette, iesebomber, and upsilonclassshuttle. Trident remains without icon as per user feedback. --------- Co-authored-by: Francesco Esposito <95753785+Francespo@users.noreply.github.com>
…rancespo#57) ## Description This PR fixes the accidental creation of a local font directory in the frontend and establishes a single source of truth using a symlink. - Migrated centered xwing-miniatures.css to external_data/xwing-miniatures-font/dist/. - Removed local rontend/static/fonts/xwing-miniatures-font/ directory. - Created a directory junction (symlink) pointing to the source in external_data. - Squashed branch history into a single clean commit. Co-authored-by: Francesco Esposito <95753785+Francespo@users.noreply.github.com>
Closes Francespo#52. \n\n### Changes Made:\n- **Standardized Labeling**: All unknown tournament formats and scenarios now use the label 'Unknown'.\n- **Fixed UNK Badges**: Verified that unknown formats correctly display the 'UNK' badge in the Tournament Browser list.\n- **Sidebar UI Polish**:\n - Restored horizontal dividers between all major filter sections.\n - Fixed double divider issue when Active Filters list is empty.\n - Restored bottom borders for accordion items.\n - Standardized vertical spacing across all sections (Date, Location, Format, Platform, Search, and Sort) by removing redundant margins and padding for a clean, contiguous look. --------- Co-authored-by: Francesco Esposito <95753785+Francespo@users.noreply.github.com>
Resolve pre-existing LSP/static-analysis warnings across 4 files: - backend/api/tournaments.py (34 errors) - backend/scripts/scrape_tournaments.py (17 errors) - backend/api/formatters.py + backend/api/schemas.py (10 errors) - frontend/vite.config.js (3 implicit-any errors) Includes two real bug fixes surfaced during type cleanup: - Match(...) and PlayerStanding(...) constructors in scrape_tournaments.py were missing tournament_id, silently writing NULL FKs in the dict-based save path and the _write_sqlite artifact path.
Replaces PR Francespo#92's partial fix with a from-scratch mobile shell, a centralized filter URL-sync layer, and a stack of targeted perf and responsiveness fixes. The 5 filterable routes no longer maintain their own URL-building logic; the store owns it. Mobile shell (new components): - MobileTopBar: sticky top chrome for <md viewports (hamburger + brand) - MobileNavDrawer: left-edge nav drawer, focus-trapped, ARIA dialog, sourced from Sidebar.NAV_LINKS module export - MobileFilterDrawer: right-edge filter sheet accepting a children + optional footer snippet - MobileFilterTrigger: FAB with active-filter count badge, <lg only - DebouncedTextInput: 250ms-debounced search input Filter system (filters.svelte.ts): - toSearchParams(routeId): per-route whitelist serializer with deterministic key order (round-trip identity for the echo guard) - applyFromSearchParams(params): URL -> store, partial-update only - selectedFactions / sortBy / sortDirection: moved from route-local state into the store - activeChips: (was a getter that re-ran per access) URL sync (lib/sync/urlSync.svelte.ts): - scheduleSync(delayMs?, overlay?): debounced goto() with echo guard, URL-key round-trip identity, replaceState + keepFocus + noScroll - clearPendingSync(): called by onNavigate in +layout.svelte so fast route switches do not corrupt the destination URL Route rewrites (cards, lists, ships, squadrons, tournaments): - Per-field URL-building (20-64 lines each) replaced with 5-10 line thin effect using filters.toSearchParams + scheduleSync - route-local selectedFactions / sortBy / sortDirection removed - echo-guard logic lives in urlSync, not in each route - ~200 lines of duplicated URL plumbing deleted across 5 files Per-route perf + responsive fixes: - ships: 5 inline style attributes per card collapsed to 1 (with CSS custom properties); font-size: 10rem -> clamp(3rem, 18vw, 8rem) - squadron/[signature]: 6-col pilot table collapses to stacked card layout on <sm - ship/[xws]: right-edge gradient fade hints at horizontal scroll on <sm - cards: dynamic import('$app/navigation') -> static goto import in tab handlers - +page.svelte (dashboard): chartAction uses chart.update(newConfig) instead of destroy/recreate; chart.js auto-import hoisted to module - TournamentFilters: $derived(() => fn()) misuse -> $derived.by Misc: - Sidebar: NAV_LINKS exported as the single source of truth for nav entries (consumed by both desktop sidebar and mobile drawer) - FilterPanel: rewritten to desktop-only with a children snippet; routes pass the same snippet to MobileFilterDrawer for mobile - MobileFilterDrawer / MobileNavDrawer: migrated from deprecated $app/stores to $app/state - +layout.svelte: client-only $effect calls filters.applyFromSearchParams on mount, onNavigate cancels pending syncs Touch targets: hamburger, nav links, FAB, sort direction button, content-source toggle, drawer close buttons all >= 44x44. Active filter count visible on the FAB badge and the drawer header. Behavior: empty filters.sortBy / sortDirection produce empty URL params which the backend fills with its own Query() defaults (cards/ships/squadrons/lists: 'Popularity' or 'Games'; tournaments: 'Date'), so first-visit sort order is preserved.
The backend's startup cache prewarm was racing with db-seed's pg_restore. The backend depends_on db-seed used condition: service_started, which fires as soon as the db-seed container starts (before the dump is actually loaded). The prewarm then computed analytics against an empty database and cached empty results, which the cache never invalidated (scrape_meta is missing from the dump, so the version-based invalidation never fires). Add a healthcheck to db-seed that polls the `list` table for a non-zero row count, and change the backend to depend on service_healthy. This ensures the dump is fully restored before the backend (and its prewarm) starts, so the cache is seeded with real data on the first run.
Allows choosing the Vite dev server port on startup: bash scripts/local_dev/up.sh --port 4444 bash scripts/local_dev/up.sh --port=4444 Default is unchanged (3333). Validates the port is a number between 1 and 65535 and rejects unknown arguments. Also adds --help / -h. The four hardcoded 3333 references (ORIGIN, vite --port, healthcheck URL, log-parser fallback) now use $VITE_PORT / $DEFAULT_PORT.
- Add min-w-0 to main and card to prevent flex overflow on mobile - Split layout into mobile (2-row) and desktop (3-column) at sm breakpoint - Mobile: title + format chip + player count inline, date + location below - Desktop: format badge column, info column, player count column - Format label/color hoisted to @const per iteration for clarity - Ensure 44px min tap target, proper truncation, no horizontal scroll
…tion, stats fix, upgrades Round 13–22 frontend improvements: Browser pages (tournaments, squadrons, lists, cards, ships): - Remove DATE label from tournament rows; wrap location in styled pill - Replace boxed 'N x FOUND' pills with faded-text below title (no box) - Remove ActiveChips from main content; active filters only in sidebar - Fix squadron count to show backend total (8663) instead of page capacity - Apply custom Toggle to all checkboxes (squadrons, lists, cards, ships) - Add SortBy component to every list section across all browser pages Filter system: - Create Toggle component (squared, 2px-radius, black bg, white check) - Fix multi-select format bug (isFormatsAtDefault URL round-trip) - Fix urlSync echo loop and stale-URL race condition - Fix overlay-merge loop in urlSync (params.set multi-value bug) - Add Format count badge to TournamentFilters label - Add overflow-x-hidden to FilterPanel, MobileFilterDrawer, layout Ship detail page: - Add FactionIcon component (plain '?' for unknown factions, XWing glyph for known) - Replace 21 callsites with FactionIcon across 14 files - Fix match score colors (winner green pill, loser red, tie grey) - Fix Gauntlet 5-color gradient (start%/end% hard-stop syntax) - Fix ships page filter to honor selectedChips (frontend bug) - Remove all glows from ship detail hero card Sort and layout: - Remove SortSelector from filter panels (replaced by inline SortBy) - Add SortBy to dashboard sections, pilot detail, upgrade detail, etc. - Fix SortBy labels: 'Popularity' → 'Games'/'Lists' - Remove rounded rectangle wrapper from dashboard SortBy - Fix Cards page SortBy to match filter dropdown options - Remove 'Compatibility' option from pilot detail Top Configurations Back navigation: - BackLink uses history.back() with href fallback for fresh tabs - All 6 detail pages benefit automatically (useHistory=true default) Stats and data: - Backend: fix ship_list_filter_clause with mode=all for AND semantics - Backend: add list_id to PlayerStandingData schema - Backend: add win_rate to aggregate_list_stats output - Backend: clamp swiss_wins/losses/rank default from -1 to 0 - Data migration script for clamping negative stats - Fix squadron win rate (was always 0% — use backend win_rate field) Miscellaneous: - Fix multi-faction ship gradient on ships browser page - Fix content-source filter on pilot detail page - Mobile: add Epic toggle to top bar, TournamentFilters to drawer - Desktop sidebar: XWA/LEGACY/Epic compact toggle - Add info tooltip to Tournament Filters label - Fix horizontal scrollbar in filter column - Remove all glows from ship detail hero card
All conflicts resolved in favor of dev (HEAD) which has the superior architecture: normalized list table, SQL GROUP BY queries, filter_helpers, ScrapeMeta model, BaseScraper type hints, coerce_list_json, pool tuning, and the full mobile-first UI rebuild. Upstream changes (minor: duplicate imports, pyright annotations already present in dev) are subsets of what dev already contains. Conflict files: - .devcontainer/ (2): node feature versions, gemini-cli vs sshd - .gitignore: slim/deepwork + playwright paths vs duplicate node_modules - backend/analytics/ (5): SQL GROUP BY vs Python-loop aggregation - backend/api/ (4): normalized list table queries vs legacy Python loops - backend/infra (3): ScrapeMeta model, pool_size, coerce_list_json import - backend/scripts/ (2): list table persistence, BaseScraper types - frontend/+page.svelte: meta-snapshot URL builder (HEAD's params approach)
Co-authored-by: GitHub Copilot <copilot@users.noreply.github.com> Co-authored-by: Frances-bot <263591795+Franc3s-bot@users.noreply.github.com>
58,603 playerstanding rows had swiss_wins=-1, swiss_losses=-1 as scraper sentinels (rollbetter). COALESCE(..., 0) does not help since -1 is not NULL, causing negative game counts and broken winrates. Wrap all COALESCE in SUM() with GREATEST(0, ...) across: - core.py (pilots + upgrades queries) - ships.py - squadrons.py - lists.py - factions.py (Python-side max(0, ...)) Database rows also cleaned to 0.
…tream local-dev scripts
Preview deployments were failing because the SSR API routes used the public backend URL (e.g. https://127.api.dev.m3tacron.com/api) which: 1. Requires DNS wildcard records that may not match Coolify's generated domain pattern (127.dev.api.m3tacron.com vs 127.api.dev.m3tacron.com) 2. Causes HTTP->HTTPS redirect loops when url.protocol is http: behind a reverse proxy (Traefik) Now preview deployments talk directly to the backend container via the internal Docker Compose network (http://backend:8888/api), which is faster, simpler, and works regardless of external DNS configuration.
SvelteKit's url.hostname is derived from the ORIGIN env var, not the actual request Host header. When ORIGIN=https://dev.m3tacron.com is set for preview deployments, url.hostname resolves to dev.m3tacron.com instead of 127.dev.m3tacron.com, causing the host-based preview URL matching to fail. Now we check ENV_VAR_SOURCE=preview or COOLIFY_BRANCH.startsWith('pull/') to detect preview deployments and route API calls to the internal Docker network (http://backend:8888/api) before host matching.
- docker-compose.local.yml: use ${POSTGRES_PORT:-5435} and ${BACKEND_PORT:-8890} env vars
- up.sh: read BACKEND_PORT/POSTGRES_PORT/VITE_PORT from env, pass through to healthcheck and Vite
- status.sh: health probes use env vars instead of hardcoded ports
- pyproject.toml: set explicit setuptools package discovery (include backend* only)
- Retry submodule init once on failure - Fall back to copying external_data/ from source checkout if clone fails twice - Clean error reporting at each step
- Remove verify*.png screenshots, commit_message.json, .slim/codemap.json - Expand .gitignore: .slim/ (not just deepwork), verify*.png, commit_message.json
- Starts Docker stack (postgres + backend), waits for health, then Vite in foreground - Configurable ports via --port, --backend-port, --postgres-port or env vars - Registered as 'launch' service in paseo.json
Preview deployments set COOLIFY_URL to the correct PR-specific URL (e.g. https://128.dev.m3tacron.com). By using ORIGIN=, production uses its explicit ORIGIN value while previews automatically get the correct PR URL from COOLIFY_URL.
- Add launch.sh as primary quick start (foreground, agent-friendly) - Document parameterized ports (BACKEND_PORT, POSTGRES_PORT, VITE_PORT) - Add Paseo worktree integration section (worktree_setup.sh, parallel worktrees) - Add submodule fallback troubleshooting - Fix statement_timeout (120s, not 60s) - Reorder helper commands table
…endent - ensure-setup.sh: single source of truth for dependency setup (submodules, venv, npm, dump, SSH key) - launch.sh: calls ensure-setup.sh then launches stack - worktree_setup.sh: thin wrapper around ensure-setup.sh - Paseo hook and launch both share the same setup logic
- Removed .agents/skills/m3tacron/ssh_key from git tracking - Added ssh_key and ssh_key.pub to .gitignore secrets section - Key was exposed in git history — MUST be rotated on the server
- seed.sh: default key path ~/.ssh/m3tacron_audit_bot - ensure-setup.sh: remove SSH key copy logic - paseo.json: remove key override from seed, remove .ssh from teardown - m3tacron skill: document key setup as machine prerequisite - local-dev skill: update prereqs and data locations
- launch.sh/up.sh: auto-detect tailnet hostname via tailscale CLI - VITE_ALLOWED_HOSTS includes tailnet hostname for CORS - ORIGIN set to tailnet URL so SvelteKit works for other users - Banner shows both local and tailnet URLs - status.sh: show tailnet access URLs - local-dev skill: document tailnet access section
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.
Updates the
external_datasubmodule pointer toFrancespo/xwing-unified-datacommit0a53315.Includes:
26501161: gregkash16 master base + 36 open J1mBob PRs (fixes, new cards, image links) + fork history preserved. Ric Olié now 11 pts / 16 loadout (50-point scale, was 4/12 on 20-pt scale).Darker333/xwing-data2-legacymaster (dbb1dd6) withbranch = mastertracking instead of a pinned commit.Verification: JSON valid, merge conflicts resolved, working tree clean.