mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-12 03:56:15 -08:00
* fix(lint): resolve module-boundary and prefer-inject errors Retag workspace-shell-util as type:data-access to match its injectable services that depend on @iptvnator/services, and convert RemoteControlService to inject(HttpClient). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(lint): enforce max-lines 400 with generated baseline Add a max-lines ESLint error (hard cap 400 raw lines per TypeScript file) per the repo file-size rule. The 134 pre-existing offenders are baselined in tools/eslint/max-lines-baseline.mjs, regenerable via generate-max-lines-baseline.mjs; the list should only shrink. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(ci): enforce lint on PRs and guard coverage policy drift - Add a Lint job to ci.yml running nx run-many -t lint --all, so module-boundary tags, legacy-alias bans, and max-lines gate merges. - Fix the root lint script (was linting only electron-backend). - Add tools/coverage/check-coverage-policy.mjs: fails CI when a project with a test target is missing from coverage-policy.json; wired into coverage:ci as coverage:policy:check. - Run Tier B/C unit tests in CI without coverage (list derived from the policy), so website/packaging/remote-control tests run on PRs. - Replace the hand-picked 16-project test:unit:ci list with --all. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: document CI lint enforcement and coverage policy guard Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ci): address bot review feedback on policy guard and baseline generator - Drive Tier B/C validation from each policy entry's validationCommand (falling back to nx test), skipping projects with an e2e target since the E2E workflow already runs them (Codex). - Fail when a Tier A entry has no test target (Greptile, adapted: checking all entries against test targets would false-positive on the intentionally spec-less e2e/mock-server tiers). - Guard against missing JSON array in nx show projects output (Greptile). - Scan .tsx files in the max-lines baseline generator to match the ESLint rule's file patterns (Greptile). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
98 lines
3.5 KiB
Markdown
98 lines
3.5 KiB
Markdown
# Nx Workspace Boundaries
|
|
|
|
This document records the current monorepo boundary conventions for IPTVnator.
|
|
|
|
## Fresh Worktree Bootstrap
|
|
|
|
Install dependencies before using Nx discovery or targets:
|
|
|
|
```bash
|
|
pnpm install --frozen-lockfile
|
|
pnpm nx show projects
|
|
```
|
|
|
|
`pnpm nx show projects` depends on the workspace-local Nx packages under
|
|
`node_modules`. In a fresh worktree without dependencies it will fail before it
|
|
can inspect project metadata.
|
|
|
|
## Project Tags
|
|
|
|
Every Nx project should carry three tag families in `project.json`:
|
|
|
|
1. `scope:*` - ownership area, for example `scope:portal`, `scope:workspace`,
|
|
`scope:shared`, `scope:electron`, `scope:e2e`, or `scope:dev-tools`.
|
|
2. `domain:*` - product/runtime domain, for example `domain:xtream`,
|
|
`domain:stalker`, `domain:m3u`, `domain:playback`, `domain:web`, or
|
|
`domain:shared-runtime`.
|
|
3. `type:*` - architectural role, for example `type:app`, `type:e2e`,
|
|
`type:dev-app`, `type:feature`, `type:ui`, `type:data-access`,
|
|
`type:util`, `type:tool`, or `type:website`.
|
|
|
|
`eslint.config.mjs` uses these tags with `@nx/enforce-module-boundaries`.
|
|
When adding a project, choose tags before adding imports so dependency direction
|
|
is clear from the start.
|
|
|
|
## Import Aliases
|
|
|
|
Use scoped `@iptvnator/*` aliases from `tsconfig.base.json`.
|
|
|
|
Examples:
|
|
|
|
```ts
|
|
import { SettingsStore } from '@iptvnator/services';
|
|
import { Playlist } from '@iptvnator/shared/interfaces';
|
|
import { DialogService } from '@iptvnator/ui/components';
|
|
```
|
|
|
|
Do not introduce legacy bare aliases such as:
|
|
|
|
- `components`
|
|
- `m3u-state`
|
|
- `m3u-utils`
|
|
- `services`
|
|
- `shared-interfaces`
|
|
- `shared-portals`
|
|
- `remote-control`
|
|
- `database`
|
|
- `database-schema`
|
|
- `database-path-utils`
|
|
- `workspace-dashboard-feature`
|
|
- `workspace-dashboard-data-access`
|
|
|
|
The lint config blocks these aliases so new code uses the same visible
|
|
namespace and ownership convention.
|
|
|
|
Buildable libraries that have a local `package.json` should use the same public
|
|
name as their scoped alias. Nx uses `package.json.name` when it rewrites
|
|
buildable dependency paths to `dist/` during `@nx/js:tsc` builds.
|
|
|
|
## Dependency Direction
|
|
|
|
- `type:feature` may use `type:feature`, `type:ui`, `type:data-access`, and
|
|
`type:util`.
|
|
- `type:ui` may use `type:ui`, `type:data-access`, and `type:util`.
|
|
- `type:data-access` may use `type:data-access` and `type:util`.
|
|
- `type:util` may use only `type:util`.
|
|
|
|
If a change needs a dependency in the opposite direction, move the shared
|
|
contract into a lower-level library instead of weakening boundaries.
|
|
|
|
Portal collection orchestration that reads/writes favorites, recent items, live
|
|
playback, or EPG data belongs in `libs/portal/shared/data-access`, not
|
|
`libs/portal/shared/util`. That keeps pure collection helpers importable by
|
|
Xtream/Stalker data-access libraries while allowing shared UI to use
|
|
provider-specific collection services without creating cycles.
|
|
|
|
Note: `workspace-shell-util` (`libs/workspace/shell/util`) is tagged
|
|
`type:data-access` despite its path. It exports injectable services such as
|
|
`WorkspaceStartupPreferencesService` that depend on `@iptvnator/services`, and
|
|
it must stay eagerly importable from `apps/web/src/app/app.routes.ts` without
|
|
pulling the lazy-loaded workspace shell feature bundle into the initial chunk.
|
|
|
|
## CI Enforcement
|
|
|
|
The `Lint` job in `.github/workflows/ci.yml` runs
|
|
`pnpm nx run-many --target=lint --all` on every PR, so
|
|
`@nx/enforce-module-boundaries` violations, legacy bare-alias imports, and
|
|
`max-lines` violations fail CI. Run `pnpm run lint` locally before pushing.
|