DevFeed is a uv/npm monorepo. Python services live in apps/{api,admin-api,user-api,aggregator,notifications,cli}/src/;
apps/web and apps/admin contain the Next.js reader and administration interfaces. Shared backend logic lives in
packages/core and packages/http; shared components, styles, and assets live in packages/ui and packages/theme.
Alembic migrations belong in migrations/, backend tests in tests/, and frontend tests in each app's tests/. See
docs/development.md for architecture and setup.
Use Python 3.12+, uv, and Node.js 22.22.2+ on 22.x, 24.15.0+ on 24.x, or 26+.
uv sync --all-packages --lockedandnpm ci: install locked dependencies.npm run hooks:install: enable scoped pre-commit checks.uv run devfeed db upgrade: migrate the local database.uv run uvicorn devfeed_api.main:app --reload --no-proxy-headers: start the public API.uv run devfeed workeranduv run devfeed scheduler: start background processing.npm run web:dev/npm run admin:dev: start reader/admin interfaces on ports 3000/3001.npm run web:build/npm run admin:build: build production frontends.bash .github/scripts/python-checks.sh: check Python lint, formatting, types, and versions.npm run web:lint/npm run admin:lint: check frontend formatting, ESLint, and TypeScript.
Use four-space Python indentation and two-space TypeScript/JavaScript indentation, with a 100-column formatting target.
Run npm run format for Ruff and Prettier formatting. Follow existing snake_case Python modules, kebab-case frontend
filenames, and PascalCase React components. Edit Python src/ files, not generated editable-install links. After admin
API contract changes, run npm run admin:generate and include generated updates.
Run uv run pytest for backend tests and npm run web:test / npm run admin:test for Vitest suites. Name tests
test_*.py or *.test.ts(x). Add meaningful regression coverage for changed behavior. Backend unit CI enforces the
combined statement and branch minimum configured in pyproject.toml; integration coverage is tracked separately.
Keep backend tests in the domain packages documented in tests/README.md. Add cases to the existing behavior
suite rather than creating files named after a coverage task, percentage, or remaining lines. Keep shared builders
and reusable fixtures in tests/support, and use qualified imports. Preserve explicit integration and
failure_recovery markers when moving cases; directory names do not determine CI selection.
Integration tests require disposable DEVFEED_TEST_DATABASE_URL and DEVFEED_TEST_REDIS_URL: the database
name must end in _test, and Redis must use database 15. Fixtures truncate tables and flush Redis.
Every user-facing change to apps/web must also work in both the Chrome and Microsoft Edge extensions in
apps/extensions. This includes navigation, routes, authentication, feed behavior, layout, and shared components.
Prefer shared reader code over separate implementations, and update extension adapters wherever needed. Never consider
a reader change complete until both extensions have been checked and applicable regression tests have been updated
and run. For browser-visible changes, verify the web app and both built extensions with browser tests; shared imports
alone are not proof of parity. Build both extension packages when preparing a release, and report their validation
and store-publication status separately from the website deployment.
After every implementation task, validate the changed behavior with relevant checks and regression tests, resolve failures, and commit the intended changes. Report the validation performed and any remaining gaps.
Use focused, imperative commit subjects, such as Hide empty sources from reader discovery. Follow
.github/pull_request_template.md: explain the problem and resulting behavior, link applicable issues, report
validation gaps, include UI screenshots, and document migrations or rollout risks. Update relevant documentation and
tests. Before merging, pass CI required and CodeQL checks and resolve review conversations.
Upload UI screenshots using GitHub's native attachment upload in the PR description or a PR comment.
Embed the resulting GitHub user-attachment URLs directly in the description so reviewers can see them.
Never commit PR screenshots or other review-only image artifacts, and never create .github/pr-assets
or another repository directory as a screenshot-hosting workaround. Local screenshots must remain untracked.
If native upload is unavailable, report that limitation; do not substitute committed files or raw repository URLs.
Write release notes for users: describe concrete features, highlights, improvements, and fixes, explaining what users
can do or what behavior changed. Use concise sections such as Enhancements and Fixes, following the style of
Rancher and NetBox release notes. Start directly with these sections; omit generic introductory summaries.
Base entries on the actual changes included in the release.
Keep release preparation, CI results, deployment logs, missing assets, workflow failures, store submission/review status, and agent work notes in the task report rather than public release notes. Omit generic version-bump or package-release bullets and boilerplate such as "No new database migration is required." Include upgrade or compatibility information only when it explains a concrete action users must take.
Use dated changelog headings such as ## 0.0.43 — 2026-09-27; the entries beneath them must describe product changes.
Keep consecutive changelog list items adjacent, with no blank lines between items. When adding an entry, preserve
this compact list formatting; retain blank lines around headings and between release sections.
After editing published release notes, read them back to verify the intended content is live.
Copy .env.example; never commit secrets. Set database and Redis URLs explicitly. See docs/compose.md for the local
stack. Preserve public, user, and admin service boundaries and feed-fetch SSRF protections.