All completion criteria verified. Everything is green. **Phase 105 final verification pass — all criteria verified** - Verified the full implementation in the working tree: `git_sources.include_hidden` column + alembic `0019` (dev DB at head, column present), `iter_importable_files`/`import_sources` flag support with `str(root)`-keyed map used by both walk and progress pre-walk, `GitSourcePatchIn` rename with optional fields, sync/CLI pipeline wiring (OR-collision), and the per-row "Hidden" checkbox + tag + error line on the Sources page - Unit + integration: `uv run pytest` → exit 0 (2148 tests collected, all pass; this sandbox occasionally swallows pytest's final status line — exit codes verified) - Coverage: `uv run pytest --cov=app --cov-report=term-missing` → **TOTAL 99%** (3879 stmts, 15 miss) — >90% gate ✓ - Dedicated E2E: `uv run pytest tests/e2e/test_hidden_folders_toggle.py -v --no-cov` → **6 passed in 23.20s** (DB up, in isolation) - Regression E2E in isolation: `test_source_ignore_paths` 6 passed, `test_git_sources_admin` 6 passed, `test_local_directory_sources` 3 passed, `test_sync_button` 3 passed, `test_smoke` 3 passed - Lint/types: `uv run ruff check .` + `uv run pyright` → clean (0 errors/warnings) **Completion criteria:** (1) checkbox persists via PATCH 200 → "hidden on" tag + GET round-trips `include_hidden: true`; failure path reverts box + `role="alert"` canned message ✓; (2) flag OFF byte-identical (only `visible.md` indexed), ON indexes `.hidden/note.md` into the KB catalog, `EXCLUDED_DIRS` excluded both states ✓; (3) A2: flag OFF → `detail.pruned==1`, doc gone from catalog ✓; (4) PATCH bool-only/list-only/both/neither no-op, phase-89 fixed 422s unchanged, 404, anonymous 403 (incl. bool-only body) ✓; (5) env-fallback rows render no checkbox, WCAG-clean (aria-label, keyboard focus, visible label, text tag) ✓; (6) full gate green ✓; (7) commit left to the harness per instructions (no `git add`/`commit` run; phase files untouched). **Deviations:** none — no defects found; no code changes were needed on this pass. **Next pending phase:** `.agents/phases/todo/98_sync_summary_visibility`.
53 lines
1.8 KiB
Python
53 lines
1.8 KiB
Python
"""git_sources.include_hidden: per-source hidden-folders flag (phase 105)
|
|
|
|
Revision ID: 0019
|
|
Revises: 0018
|
|
Create Date: 2026-09-12
|
|
|
|
Phase 105 (per-source hidden-folders toggle: dot-prefixed paths become
|
|
indexable per input — the owner flips a "Hidden" checkbox next to the
|
|
"Ignore paths" button on the Sources page): when the flag is ON, the
|
|
importer walk (``app.rag.importer.iter_importable_files``) no longer
|
|
skips dot-prefixed path components for that source — files inside
|
|
hidden folders AND hidden files with an importable extension are
|
|
indexed, embedded, and summarized exactly like visible files (A1).
|
|
``EXCLUDED_DIRS`` (``.venv``, ``node_modules``, ``.git``, …) stay
|
|
excluded in BOTH states, and the extension filter always applies. The
|
|
flag takes effect on the NEXT sync (no auto-sync — the ignore-list
|
|
precedent, phase 89); a previously indexed hidden file is pruned on
|
|
the next sync after the flag flips OFF (A2). One additive, fully
|
|
reversible column (A13), no other schema change:
|
|
|
|
* ``git_sources.include_hidden`` — BOOLEAN NOT NULL with server
|
|
default ``false``: every pre-phase-105 row reads ``False`` —
|
|
byte-identical import behavior until the owner flips it (A4).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sqlalchemy as sa
|
|
|
|
from alembic import op
|
|
|
|
revision = "0019"
|
|
down_revision = "0018"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.add_column(
|
|
"git_sources",
|
|
sa.Column(
|
|
"include_hidden",
|
|
sa.Boolean(),
|
|
server_default=sa.text("false"),
|
|
nullable=False,
|
|
),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
# The column is the only 0019 artefact — dropping it leaves
|
|
# 0018's schema byte-identical (A13, fully reversible).
|
|
op.drop_column("git_sources", "include_hidden")
|