Skip to content

Feature/sdd - #165

Merged
AndrewHanasiro merged 5 commits into
mainfrom
feature/sdd
Jul 30, 2026
Merged

Feature/sdd#165
AndrewHanasiro merged 5 commits into
mainfrom
feature/sdd

Conversation

@AndrewHanasiro

@AndrewHanasiro AndrewHanasiro commented Jul 30, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Added structured logging across authentication, MFA, password reset, user, and organization flows.
    • Added trace and span correlation fields for easier event tracking.
    • Added configurable log levels and masking for email and phone data.
    • Expanded redaction of passwords, tokens, MFA secrets, and other sensitive values.
  • Documentation

    • Added feature specifications, implementation guidance, validation steps, and quality checklists.
    • Updated prerequisites to use Docker and Docker Compose.
  • Chores

    • Updated project tooling and workflow configuration.
    • Removed bundled observability services and related configuration.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This change adds enhanced structured logging with Pino masking, credential redaction, trace correlation, repository and use-case events, updated environment configuration, feature specifications, observability configuration changes, refreshed coverage data, and generated Graphify artifacts.

Changes

Enhanced flow logging

Layer / File(s) Summary
Feature contracts and workflow gates
.specify/*, specs/001-add-flow-logging/*
Adds the enhanced flow logging specification, data model, research, plan, tasks, checklist, quickstart, and related workflow metadata.
Runtime logging and flow instrumentation
src/config/*, src/core/providers/*, src/core/usecases/*, src/presentation/http/server.ts
Adds LOG_LEVEL, Pino masking/redaction, structured repository and use-case logs, and environment-based server startup gating.
Runtime and observability configuration
README.md, docker-compose.yml
Switches prerequisites to Docker and removes the ClickHouse, Uptrace, and OpenTelemetry Collector compose services.
Coverage report refresh
coverage/lcov.info
Refreshes coverage records for logging, repositories, use cases, fixtures, and generators.
Graphify analysis artifacts
graphify-out/*
Adds Graphify reports, manifests, labels, cost data, cache indexes, and AST graph artifacts.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant UseCase
  participant Repository
  participant Pino
  participant OpenTelemetry
  Client->>UseCase: execute authentication or management flow
  UseCase->>Pino: log start, milestone, success, or failure
  UseCase->>Repository: perform operation
  Repository->>Pino: log operation metadata
  Pino->>OpenTelemetry: correlate trace and span context
  OpenTelemetry-->>Pino: export structured record
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided, so the required Proposal and Links sections are missing. Add the template sections with a brief Proposal summary and relevant Links, even if some items are placeholders.
Title check ❓ Inconclusive The title is too vague to describe the changes and does not convey the main feature. Use a descriptive title that names the primary change, such as adding enhanced flow logging and related spec updates.
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/sdd

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.45.0)
graphify-out/graph.html

ast-grep timed out on this file


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 19

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/config/enviroment_config.ts (1)

46-76: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

LOG_LEVEL value is never validated, and the union type is silently widened to string.

verifyMandatoryEnv only asserts presence, so LOG_LEVEL=verbose passes and is handed to pino, which throws on an unknown level at startup. Declaring logLevel: string on Enviroment also discards the union you added on EnvVar.

🛡️ Validate the value and preserve the narrow type
+const LOG_LEVELS = [
+  'trace',
+  'debug',
+  'info',
+  'warn',
+  'error',
+  'fatal',
+] as const
+export type LogLevel = (typeof LOG_LEVELS)[number]
   app: {
     ...
-    logLevel: string
+    logLevel: LogLevel
   }
-      logLevel: process.env.LOG_LEVEL,
+      logLevel: LOG_LEVELS.includes(process.env.LOG_LEVEL as LogLevel)
+        ? (process.env.LOG_LEVEL as LogLevel)
+        : 'info',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/config/enviroment_config.ts` around lines 46 - 76, Update getEnv and the
Enviroment type so LOG_LEVEL is validated against the supported log-level values
before constructing the configuration, rejecting values such as “verbose” with
the existing environment validation error path. Preserve the narrow log-level
union from EnvVar instead of declaring Enviroment.logLevel as string, and ensure
the returned process.env.LOG_LEVEL value is typed accordingly.
🧹 Nitpick comments (6)
src/config/logger.ts (1)

6-6: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

getEnv() is invoked twice and the fallback is now unreachable.

LOG_LEVEL is mandatory in enviroment_config.ts, so getEnv() either throws or returns a truthy logLevel — the production ? 'info' : 'debug' branch is dead. Resolve the env once.

♻️ Suggested cleanup
-export const logger = pino({
-  level: getEnv().app.logLevel || (getEnv().app.enviroment === 'production' ? 'info' : 'debug'),
+const env = getEnv()
+
+export const logger = pino({
+  level: env.app.logLevel,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/config/logger.ts` at line 6, Update the logger configuration’s level
expression to resolve getEnv() once and reuse the resulting environment object,
removing the unreachable production/development fallback while preserving the
mandatory logLevel value.
src/core/providers/mfa.repository.ts (1)

36-36: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Log message doesn't match the statement it precedes.

The immediate query is a duplicate-check select; the insert happens later at line 58 and may never run (the MFA_ALREADY_EXIST throw). Consider 'Database query: check existing MFA strategy' here, and, if useful, a separate debug line at the actual insert.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/providers/mfa.repository.ts` at line 36, Update the debug log in the
strategy-creation flow to describe the preceding duplicate-check select, using
wording such as “check existing MFA strategy” instead of “insert MFA strategy.”
If retaining insert-specific logging, add a separate message immediately before
the actual insert operation, after the MFA_ALREADY_EXIST check.
specs/001-add-flow-logging/research.md (1)

21-29: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Two performance claims here are inaccurate.

fast-redact is fast but not zero-cost, and Pino writes to stdout synchronously by default — there is no "asynchronous batching to Uptrace" unless a transport/worker is configured. Since SC-003 (≤5% latency overhead) rests on these assumptions, consider softening the wording or documenting the transport that actually provides async delivery.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@specs/001-add-flow-logging/research.md` around lines 21 - 29, Correct the
inaccurate performance claims in the research document: remove the assertion
that fast redaction has zero runtime cost, and qualify asynchronous Pino
delivery by documenting the configured transport/worker or stating that stdout
is synchronous by default. Also revise the related SC-003 rationale so the
latency target is not based on unsupported assumptions.
coverage/lcov.info (1)

660-847: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Don't commit the LCOV artifact that overrides .gitignore.

coverage/* and *.lcov are already ignored, but .gitignore explicitly reallows only coverage/lcov.info, so this generated file is tracked and can create large unreviewable coverage churn. If coverage is useful, ignore coverage/ entirely and upload the LCOV artifact in CI / send it to Sonar instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@coverage/lcov.info` around lines 660 - 847, The generated coverage/lcov.info
artifact must not be committed. Remove it from version control and update the
ignore configuration to ignore the coverage directory without explicitly
reallowing coverage/lcov.info; preserve CI/Sonar handling for uploading coverage
artifacts if needed.
graphify-out/graph.html (1)

1-320: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider excluding generated Graphify visualization artifacts from version control.

This entire file is machine-generated output (embedded RAW_NODES/RAW_EDGES/LEGEND data plus rendering script) rather than authored code. Committing large generated HTML/JS artifacts like this bloats the repository and diverges on every regeneration, complicating diffs and reviews.

Consider adding graphify-out/ to .gitignore and instead generating/publishing this report as a CI artifact if it needs to be shared.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@graphify-out/graph.html` around lines 1 - 320, Exclude the machine-generated
Graphify output directory from version control by adding graphify-out/ to the
repository’s .gitignore. Leave the generated graph.html artifact unchanged and
rely on CI artifact publishing or regeneration when the visualization needs to
be shared.
graphify-out/graph.json (1)

1-32267: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Generated Graphify artifact committed to the repo — consider excluding from version control.

This entire 32K+ line file is auto-generated code-graph output (_origin: "ast", confidence scores, and a built_at_commit hash pinning it to a specific commit). Committing regenerable, commit-pinned analysis artifacts of this size causes repository bloat, noisy diffs on every regeneration, and immediate staleness relative to the current commit.

Unless there's a deliberate goal to keep historical graph snapshots in-repo, consider adding graphify-out/ to .gitignore and instead publishing this as a CI build artifact or storing it out-of-repo (e.g., artifact storage, a docs site, or a dedicated branch).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@graphify-out/graph.json` around lines 1 - 32267, Remove the generated
graphify-out artifact from version control and add graphify-out/ to the
repository ignore configuration. Preserve any source or generation workflow
needed to recreate graph.json, but do not commit this regenerable, commit-pinned
output unless historical snapshots are explicitly required.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.specify/memory/constitution.md:
- Line 12: Update the external-services listing in the constitution to replace
the stale “Redis” reference with “Valkey,” or explicitly identify Redis as a
compatibility alias, so it matches the later Valkey cache terminology and
adapter contract.
- Around line 14-15: Unify observability documentation with the runtime’s
selected Pino logger and SigNoz/OTLP exporter. In
.specify/memory/constitution.md lines 14-15, replace the Winston/Uptrace
references; update the Monitoring section at lines 40-42 to name SigNoz; and
revise specs/001-add-flow-logging/plan.md line 9 to remove Uptrace and
consistently reference SigNoz.

In `@graphify-out/.graphify_python`:
- Line 1: Remove machine-local metadata from all listed generated artifacts:
replace or omit the interpreter pointer in graphify-out/.graphify_python;
regenerate the AST cache files at
graphify-out/cache/ast/v0.9.29/a412e829419ad03c761ab7f88fa02dc8bf6a01ce9f40869eafb6c76fe85a5bfa.json,
a9c6383a1eb7ba23b6925a62eae5635e63c836d61b2878ebfc3b28c3f47af35e.json,
ab8e59fa8724ca438acb8add08e834d9cfa0fa1a34f92f7545fddaa27da23343.json,
ae22b7c7ecb6ccd516fed25916e465146432c58f1bef904a92b535ac0bbecfcf.json,
b314d97a20868c731da275a5a30d3a2860e2fb21226f6eee249d500861544ce6.json, and
bd00ea412c1a2894a519eec2bf0067d1150cdd267f1099debc4536f4a5d0f20a.json with IDs
derived from relative paths; and clean
a571e6de0ed5f7e161a81def91f91043506dbf562ac3be4cfa3f4c48c49683ec.json of
absolute IDs, file URLs, and target paths.

In
`@graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json`:
- Line 1: Normalize machine-specific absolute workspace paths in the generated
Graphify caches. In
graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json:1-1,
07e40705140f96139361d29ad46bce8cdb8303339171f45cb1436780d4da58f3.json:1-1, and
08e79622b777468d92f233b7c30b8ed76c9c48ad03597affb7c92c1d49dc681b.json:1-1,
regenerate node IDs using repository-relative paths; in
graphify-out/cache/ast/v0.9.29/107c774c59ce86f256e108b38364b6606584460b17d44294abbbc3de5da6a2a2.json:1-1,
replace the absolute target_file value with its repository-relative path.

In
`@graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json`:
- Line 1: Sanitize generated Graphify artifacts so host-specific absolute
checkout paths are never persisted. In
graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json#L1,
normalize package graph node IDs; apply the same node-ID normalization to
graphify-out/cache/ast/v0.9.29/23a03f849ef54c3f2b89d56f47bc3851236f539e325de0897b699b57dae7be74.json#L1,
graphify-out/cache/ast/v0.9.29/2734a509d4b2f34ee6258475c4fb2e80a6dbfcbc47c8552df5b6278907529250.json#L1,
graphify-out/cache/ast/v0.9.29/2ae70ccc099030710c9a9e142ae83c454ca9f2526d2c0ef94ca42709e5b3342d.json#L1,
graphify-out/cache/ast/v0.9.29/327b9177caee62513cec0e53459a6ac09f569636f9648e8d77834fba89ad6bfd.json#L1,
graphify-out/cache/ast/v0.9.29/3c525c42b7d7f51cc46c1ee2a56c266665067b217ecaf76b5bf03775a9b29c4f.json#L1,
graphify-out/cache/ast/v0.9.29/64bbd0b8aadc612d601eb49036e7574d6546fe9edc0db0156cb303d1b7ab0ef6.json#L1,
graphify-out/cache/ast/v0.9.29/7aefc125bffb446ba63881ed739ddeaacd7402e025fe0782c4b214bb56ca583f.json#L1,
and
graphify-out/cache/ast/v0.9.29/9bd6e6dd116b6b29717310b09e26cfd30acdc302612d8f29f2355d2e7ea476c2.json#L1;
additionally remove the absolute target_file from
graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json#L1
and normalize its node IDs.

In
`@graphify-out/cache/ast/v0.9.29/ca57f68b4280e2fc7dbb48a603a0c4582074460be6ab966f795f4b759013cf4f.json`:
- Line 1: Normalize the AST cache artifact to remove the machine-specific
“/home/andrew/Documents/...” prefix from all node IDs, source_file, target_file,
and related metadata fields. Update the create-new-feature.sh and its symbols
get_highest_from_specs(), clean_branch_name(), and generate_branch_name() to use
repository-relative paths and stable identifiers consistently before committing
the artifact.

In
`@graphify-out/cache/ast/v0.9.29/e7be3b18f45fb4e6fde36ba5f053eb4f1fb5897b61b53b2ef4069c93e8e2e145.json`:
- Line 1: Regenerate the AST cache artifact for the setup-plan.sh entry so node
IDs and target_file metadata no longer contain the machine-specific
“/home/andrew/Documents/...” prefix. Use repository-relative paths and stable
normalized identifiers consistently while preserving the existing node, edge,
and call relationships.

In `@graphify-out/cache/stat-index.json`:
- Line 1: Regenerate the cached stat index so the nested hashes map under the
top-level README.md entry uses the exact case-sensitive key README.md instead of
readme.md, preserving the actual filename casing for cache lookups.

In `@README.md`:
- Around line 57-58: Update the Docker prerequisites section in README.md to
describe the Docker Engine and Docker Compose plugin versions required by the
local scripts’ docker compose command, rather than listing a Docker Desktop
version alongside Compose. Remove the Docker Desktop-specific pin if the
supported Engine/plugin versions cannot be stated.

In `@specs/001-add-flow-logging/data-model.md`:
- Around line 14-15: Update the data model definitions for trace_id and span_id
to mark both fields optional, matching the {} result returned by logger.ts’s
mixin() when trace.getActiveSpan() is absent. Do not require an active span or
treat these fields as universally present.

In `@specs/001-add-flow-logging/plan.md`:
- Around line 68-99: Replace the developer-local file:/// links in the plan’s
MODIFY entries with repository-relative links, such as
../../src/config/logger.ts, using the correct relative path for each referenced
file. Preserve the listed files and descriptions unchanged.
- Line 17: Update the **Storage** deployment assumption in the plan to remove
the claim that ClickHouse and PostgreSQL are provided by Uptrace Docker
services. Describe the actual required deployment prerequisites based on the
current stack context, including only services that must be provisioned
externally or separately.
- Line 35: Update the “Hexagonal Architecture Compliance” plan section to remove
direct concrete logger usage from core use cases and repositories. Define and
inject an abstract logging port into core components, or confine Pino and
src/config/logger.ts usage to presentation/infrastructure adapters, while
preserving logging behavior without core dependencies on configuration or
framework code.

In `@specs/001-add-flow-logging/quickstart.md`:
- Around line 10-30: Update the quickstart steps around the docker compose
startup and Uptrace verification to match the services retained by
docker-compose.yml. Remove the ClickHouse/Uptrace startup and localhost:14318 UI
assumptions, and rewrite Step 3 to verify flow logs through application stdout
as described by tasks.md T-003/Phase 3.

In `@src/config/enviroment_config.ts`:
- Line 33: Update the environment configuration around mandatoryKeys so
LOG_LEVEL remains optional and is not fetched through getEnv() during module
initialization. Derive the logger level directly from process.env.LOG_LEVEL,
validate it using the existing logger-level handling, and apply a sensible
default when it is absent.

In `@src/config/logger.ts`:
- Around line 41-48: Update maskEmail to split the address at the last '@'
rather than destructuring email.split('@'), preserving the entire
domain—including any additional '@' characters—in the masked output while
keeping the existing local-part masking behavior.
- Around line 7-26: Extend the redact.paths configuration in the logger setup to
cover sensitive fields at the deeper nesting levels used by payloads, including
paths such as user.info.password and equivalent password, confirmPassword, code,
token, and secret variants. Preserve the existing top-level and one-level
wildcard entries and the current censor value.

In `@src/core/providers/mfa.repository.ts`:
- Around line 46-48: Remove the empty GA phone-check branch in the MFA
repository, including its note, unless implementing the intended validation is
required by surrounding logic. Preserve the existing strategy handling and
ensure no dead empty conditional remains.

In `@src/core/providers/token.repository.ts`:
- Around line 15-20: Update the debug logging in the token cache invalidation
and token creation methods so completion messages are emitted only after
cache.set and token signing succeed, or rename the pre-operation messages to
indicate they started. Ensure failures do not produce logs claiming successful
completion, using the relevant invalidation method and create method.

---

Outside diff comments:
In `@src/config/enviroment_config.ts`:
- Around line 46-76: Update getEnv and the Enviroment type so LOG_LEVEL is
validated against the supported log-level values before constructing the
configuration, rejecting values such as “verbose” with the existing environment
validation error path. Preserve the narrow log-level union from EnvVar instead
of declaring Enviroment.logLevel as string, and ensure the returned
process.env.LOG_LEVEL value is typed accordingly.

---

Nitpick comments:
In `@coverage/lcov.info`:
- Around line 660-847: The generated coverage/lcov.info artifact must not be
committed. Remove it from version control and update the ignore configuration to
ignore the coverage directory without explicitly reallowing coverage/lcov.info;
preserve CI/Sonar handling for uploading coverage artifacts if needed.

In `@graphify-out/graph.html`:
- Around line 1-320: Exclude the machine-generated Graphify output directory
from version control by adding graphify-out/ to the repository’s .gitignore.
Leave the generated graph.html artifact unchanged and rely on CI artifact
publishing or regeneration when the visualization needs to be shared.

In `@graphify-out/graph.json`:
- Around line 1-32267: Remove the generated graphify-out artifact from version
control and add graphify-out/ to the repository ignore configuration. Preserve
any source or generation workflow needed to recreate graph.json, but do not
commit this regenerable, commit-pinned output unless historical snapshots are
explicitly required.

In `@specs/001-add-flow-logging/research.md`:
- Around line 21-29: Correct the inaccurate performance claims in the research
document: remove the assertion that fast redaction has zero runtime cost, and
qualify asynchronous Pino delivery by documenting the configured
transport/worker or stating that stdout is synchronous by default. Also revise
the related SC-003 rationale so the latency target is not based on unsupported
assumptions.

In `@src/config/logger.ts`:
- Line 6: Update the logger configuration’s level expression to resolve getEnv()
once and reuse the resulting environment object, removing the unreachable
production/development fallback while preserving the mandatory logLevel value.

In `@src/core/providers/mfa.repository.ts`:
- Line 36: Update the debug log in the strategy-creation flow to describe the
preceding duplicate-check select, using wording such as “check existing MFA
strategy” instead of “insert MFA strategy.” If retaining insert-specific
logging, add a separate message immediately before the actual insert operation,
after the MFA_ALREADY_EXIST check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a348fc2c-e8bd-47f5-a25f-4059cce5007e

📥 Commits

Reviewing files that changed from the base of the PR and between 028c459 and c5d2dd7.

📒 Files selected for processing (75)
  • .specify/feature.json
  • .specify/init-options.json
  • .specify/integration.json
  • .specify/integrations/agy.manifest.json
  • .specify/integrations/speckit.manifest.json
  • .specify/memory/constitution.md
  • .specify/workflows/speckit/workflow.yml
  • README.md
  • coverage/lcov.info
  • docker-compose.yml
  • graphify-out/.graphify_labels.json
  • graphify-out/.graphify_labels.json.sig
  • graphify-out/.graphify_python
  • graphify-out/.graphify_root
  • graphify-out/2026-07-29/.graphify_labels.json
  • graphify-out/2026-07-29/GRAPH_REPORT.md
  • graphify-out/2026-07-29/cost.json
  • graphify-out/2026-07-29/graph.json
  • graphify-out/2026-07-29/manifest.json
  • graphify-out/GRAPH_REPORT.md
  • graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json
  • graphify-out/cache/ast/v0.9.29/07e40705140f96139361d29ad46bce8cdb8303339171f45cb1436780d4da58f3.json
  • graphify-out/cache/ast/v0.9.29/08e79622b777468d92f233b7c30b8ed76c9c48ad03597affb7c92c1d49dc681b.json
  • graphify-out/cache/ast/v0.9.29/107c774c59ce86f256e108b38364b6606584460b17d44294abbbc3de5da6a2a2.json
  • graphify-out/cache/ast/v0.9.29/124ca6da475ca52c2294b4e25494fd5851c67da3be60722f5e9b58421a2eb31f.json
  • graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json
  • graphify-out/cache/ast/v0.9.29/23a03f849ef54c3f2b89d56f47bc3851236f539e325de0897b699b57dae7be74.json
  • graphify-out/cache/ast/v0.9.29/2734a509d4b2f34ee6258475c4fb2e80a6dbfcbc47c8552df5b6278907529250.json
  • graphify-out/cache/ast/v0.9.29/2ae70ccc099030710c9a9e142ae83c454ca9f2526d2c0ef94ca42709e5b3342d.json
  • graphify-out/cache/ast/v0.9.29/327b9177caee62513cec0e53459a6ac09f569636f9648e8d77834fba89ad6bfd.json
  • graphify-out/cache/ast/v0.9.29/3c525c42b7d7f51cc46c1ee2a56c266665067b217ecaf76b5bf03775a9b29c4f.json
  • graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json
  • graphify-out/cache/ast/v0.9.29/64bbd0b8aadc612d601eb49036e7574d6546fe9edc0db0156cb303d1b7ab0ef6.json
  • graphify-out/cache/ast/v0.9.29/7aefc125bffb446ba63881ed739ddeaacd7402e025fe0782c4b214bb56ca583f.json
  • graphify-out/cache/ast/v0.9.29/9bd6e6dd116b6b29717310b09e26cfd30acdc302612d8f29f2355d2e7ea476c2.json
  • graphify-out/cache/ast/v0.9.29/a412e829419ad03c761ab7f88fa02dc8bf6a01ce9f40869eafb6c76fe85a5bfa.json
  • graphify-out/cache/ast/v0.9.29/a571e6de0ed5f7e161a81def91f91043506dbf562ac3be4cfa3f4c48c49683ec.json
  • graphify-out/cache/ast/v0.9.29/a9c6383a1eb7ba23b6925a62eae5635e63c836d61b2878ebfc3b28c3f47af35e.json
  • graphify-out/cache/ast/v0.9.29/ab8e59fa8724ca438acb8add08e834d9cfa0fa1a34f92f7545fddaa27da23343.json
  • graphify-out/cache/ast/v0.9.29/ae22b7c7ecb6ccd516fed25916e465146432c58f1bef904a92b535ac0bbecfcf.json
  • graphify-out/cache/ast/v0.9.29/b314d97a20868c731da275a5a30d3a2860e2fb21226f6eee249d500861544ce6.json
  • graphify-out/cache/ast/v0.9.29/bd00ea412c1a2894a519eec2bf0067d1150cdd267f1099debc4536f4a5d0f20a.json
  • graphify-out/cache/ast/v0.9.29/ca57f68b4280e2fc7dbb48a603a0c4582074460be6ab966f795f4b759013cf4f.json
  • graphify-out/cache/ast/v0.9.29/e7be3b18f45fb4e6fde36ba5f053eb4f1fb5897b61b53b2ef4069c93e8e2e145.json
  • graphify-out/cache/ast/v0.9.29/ea41c268b9da009a1d55e9da540c89dbf583c8c67fe780ad2b11e9e1f7853154.json
  • graphify-out/cache/ast/v0.9.29/fc699f9aa32f5f8d8a9b9f564a50442d1c127d16804f7793cd9c343fb29c2ab8.json
  • graphify-out/cache/last_query_stamp
  • graphify-out/cache/stat-index.json
  • graphify-out/cost.json
  • graphify-out/graph.html
  • graphify-out/graph.json
  • graphify-out/manifest.json
  • otel-collector.yaml
  • specs/001-add-flow-logging/checklists/requirements.md
  • specs/001-add-flow-logging/data-model.md
  • specs/001-add-flow-logging/plan.md
  • specs/001-add-flow-logging/quickstart.md
  • specs/001-add-flow-logging/research.md
  • specs/001-add-flow-logging/spec.md
  • specs/001-add-flow-logging/tasks.md
  • src/config/enviroment_config.ts
  • src/config/logger.ts
  • src/core/providers/mfa.repository.ts
  • src/core/providers/token.repository.ts
  • src/core/providers/user.repository.ts
  • src/core/usecases/login.usecase.ts
  • src/core/usecases/logout.usecase.ts
  • src/core/usecases/mfa.usecase.ts
  • src/core/usecases/mfa_choose.usecase.ts
  • src/core/usecases/mfa_code.usecase.ts
  • src/core/usecases/organization.usecase.ts
  • src/core/usecases/reset_password.usecase.ts
  • src/core/usecases/user.usecase.ts
  • src/presentation/http/server.ts
  • uptrace.yml
💤 Files with no reviewable changes (3)
  • uptrace.yml
  • otel-collector.yaml
  • docker-compose.yml


### III. Strict Token & Session Lifecycle
JWT-based session authentication must enforce a strict 1-hour expiration window, support token rotation/refresh mechanics, and utilize a Redis-backed cache blacklist for immediate token invalidation upon logout.
JWT-based session authentication must enforce a strict 1-hour expiration window, support token rotation/refresh mechanics, and utilize a Valkey-backed cache blacklist for immediate token invalidation upon logout.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(constitution\.md|.*cache.*|.*redis.*|.*valkey.*|.*observability.*|.*signoz.*|.*pinecone.*|.*pino.*)$' || true

echo
echo "== constitution mentions =="
if [ -f .specify/memory/constitution.md ]; then
  nl -ba .specify/memory/constitution.md | sed -n '1,220p'
fi

echo
echo "== runtime/config terms =="
rg -n --no-heading -i 'redis|valkey|cache|observability|signoz|pino|pinecone|token blacklist|logout' . --glob '!node_modules/**' --glob '!dist/**' --glob '!build/**' | head -n 200

Repository: auth-plus/auth-plus-authentication

Length of output: 3008


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== constitution content =="
awk '{printf "%6d  %s\n", NR, $0}' .specify/memory/constitution.md | sed -n '1,220p'

echo
echo "== relevant config file =="
awk '{printf "%6d  %s\n", NR, $0}' src/core/config/cache.ts | sed -n '1,220p'

echo
echo "== cache terminology in tracked docs/config/src =="
awk '
  tolower($0) ~ /redis|valkey|cache|token blacklist|logout|observability|signoz|pino|pinecone/ {
    printf "%s: ", FILENAME
    printf "%6d  ", NR
    print $0
  }
' .specify/memory/constitution.md src/core/config/cache.ts 2>/dev/null

echo
echo "== exact grep in tracked files =="
git grep -n -i 'redis\|valkey\|cache blacklist\|observability\|signoz\|pino\|pinecone' -- .specify src || true

Repository: auth-plus/auth-plus-authentication

Length of output: 15962


Keep the cache terminology consistent.

Line 6 still lists Redis among external services, while later rules and the cache config use Valkey, making the adapter contract misleading. Update the stale Redis reference or mark it as a compatibility alias.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.specify/memory/constitution.md at line 12, Update the external-services
listing in the constitution to replace the stale “Redis” reference with
“Valkey,” or explicitly identify Redis as a compatibility alias, so it matches
the later Valkey cache terminology and adapter contract.

Comment on lines 14 to +15
### IV. Deep Observability & Telemetry
All API endpoints, database queries, cache hits/misses, and messaging events MUST be instrumented using OpenTelemetry. Standardized logging (via Winston) and trace spans must be exported to a SigNoz collector to maintain continuous operational visibility.
All API endpoints, database queries, cache hits/misses, and messaging events MUST be instrumented using OpenTelemetry. Standardized logging (via Winston) and trace spans must be exported to an Uptrace collector to maintain continuous operational visibility.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== candidate files =="
git ls-files | rg '(^|/)(constitution\.md|plan\.md|.*signoz.*|.*opentelemetry.*|.*logging.*|.*telemetry.*|winston|pino|uptrace)' || true

echo
echo "== constitution snippet =="
if [ -f .specify/memory/constitution.md ]; then
  nl -ba .specify/memory/constitution.md | sed -n '1,70p'
fi

echo
echo "== plan snippet =="
if [ -f specs/001-add-flow-logging/plan.md ]; then
  nl -ba specs/001-add-flow-logging/plan.md | sed -n '1,80p'
fi

echo
echo "== observability-related string search =="
rg -n -i 'win(ston)?|uptrace|signoz|pino|opentelemetry|tracer|metrics|logs|trace' .specify memory specs --glob '!node_modules' --glob '!dist' --glob '!build' || true

echo
echo "== logging/tracing config references =="
rg -n -i 'logger|winston|pino|opentelemetry|`@opentelemetry`|jaeger|zipkin|signoz|uptrace|fast-redact|signoz-collector|collector|otel' -g '!node_modules' -g '!dist' -g '!build' --glob '!*.lock' --glob '!*.md' .

Repository: auth-plus/auth-plus-authentication

Length of output: 576


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file sizes =="
wc -l .specify/memory/constitution.md specs/001-add-flow-logging/plan.md 2>/dev/null || true

echo
echo "== constitution excerpt =="
awk '{printf "%6d  %s\n", NR, $0}' .specify/memory/constitution.md | sed -n '1,80p'

echo
echo "== plan excerpt =="
awk '{printf "%6d  %s\n", NR, $0}' specs/001-add-flow-logging/plan.md | sed -n '1,100p'

echo
echo "== observability terms in tracked text/spec/config-like files =="
repo_obs_files=$(git ls-files | rg '(^|/)(constitution\.md|plan\.md|requirements\.md|spec\.md|research\.md|tasks\.md|data-model\.md|quickstart\.md|checklists/requirements\.md|.*log.*|.*trace.*|.*telemetry.*|.*observ.*|.*signoz.*|.*uptrace.*|package\.json|lockfile\.yaml|package-lock\.json|pnpm-lock\.yaml|yarn\.lock)$' || true)
echo "$repo_obs_files" | while IFS= read -r f; do
  [ -z "$f" ] && continue
  if rg -q -i 'win(ston)?|uptrace|signoz|pino|opentelemetry|tracer|metrics|logs|trace' "$f"; then
    echo "--- $f"
    rg -n -i 'win(ston)?|uptrace|signoz|pino|opentelemetry|tracer|metrics|logs|trace' "$f" || true
  fi
done

echo
echo "== broader config/code references (non-md tracked) =="
rg -n -i 'logger|winston|pino|opentelemetry|`@opentelemetry`|jaeger|zipkin|signoz|uptrace|fast-redact|signoz-collector|collector|otel' --glob '!*node_modules/*' --glob '!*dist/*' --glob '!*build/*' --glob '!*.lock' --glob '!*.git/*' .

Repository: auth-plus/auth-plus-authentication

Length of output: 50391


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== exact snippets =="
awk '{printf "%6d  %s\n", NR, $0}' .specify/memory/constitution.md | sed -n '10,18p'
awk '{printf "%6d  %s\n", NR, $0}' .specify/memory/constitution.md | sed -n '36,44p'
awk '{printf "%6d  %s\n", NR, $0}' specs/001-add-flow-logging/plan.md | sed -n '6,12p'

echo
echo "== targeted observability dependency/config terms =="
python3 - <<'PY'
import json, pathlib, re
paths=[p for p in pathlib.Path('.').rglob('*') if p.is_file() and not any(part in {'.git','node_modules','dist','build','cache','graphify-out'} for part in p.parts)]
terms={
    "winston": re.compile(r'\bwinston\b|`@opentelemetry/instrumentation-winston`|`@opentelemetry/winston-transport`', re.I),
    "pino": re.compile(r'\bpino\b|`@opentelemetry/instrumentation-pino`|pino-http', re.I),
    "uptrace": re.compile(r'\buptrace\b', re.I),
    "signoz": re.compile(r'\bsignoz\b', re.I),
    "otel": re.compile(r'`@opentelemetry`|exporter-(logs|metrics|trace)-otlp|sdk-node|tracerProvider|resourceDetectors', re.I),
}
for p in sorted(paths):
    try: text= p.read_text(errors='ignore')
    except Exception: continue
    if '{' not in text[:1024] and 'Winston' not in text and 'Uptrace' not in text and 'SigNoz' not in text and '`@opentelemetry`' not in text:
        continue
    print(f'--- {p}')
    for k,v in terms.items():
        for m in v.finditer(text):
            line=text[:m.start()].count('\n')+1
            print(f'  {k}:{line}:{m.group(0)}')

echo
echo "== package.json relevant dependencies =="
if [ -f package.json ]; then
  python3 - <<'PY'
import json
data=json.load(open('package.json'))
vals=data.get('dependencies',{})|data.get('devDependencies',{})
for k,v in sorted(vals.items()):
    if any(x in k.lower() for x in ['opentelemetry','winston','pino','uptrace','signoz','pino-http','winston']):
        print(f'{k}: {v}')
PY
fi

Repository: auth-plus/auth-plus-authentication

Length of output: 2334


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== targeted observability dependency/config terms =="
python3 - <<'PY'
import json, pathlib, re
paths=[p for p in pathlib.Path('.').rglob('*') if p.is_file() and not any(part in {'.git','node_modules','dist','build','cache','graphify-out'} for part in p.parts)]
terms={
    "winston": re.compile(r'\bwinston\b|`@opentelemetry/instrumentation-winston`|`@opentelemetry/winston-transport`|winston-transport', re.I),
    "pino": re.compile(r'\bpino\b|`@opentelemetry/instrumentation-pino`|pino-http\b', re.I),
    "uptrace": re.compile(r'\buptrace\b', re.I),
    "signoz": re.compile(r'\bsignoz\b', re.I),
    "otel": re.compile(r'`@opentelemetry`|exporter-(logs|metrics|trace)-otlp|sdk-node|sdk-trace-base|tracerProvider|resourceDetectors', re.I),
}
for p in sorted(paths):
    try: text= p.read_text(errors='ignore')
    except Exception: continue
    if not any(v.search(text) for v in terms.values()):
        continue
    hits=[]
    for k,v in terms.items():
        for m in v.finditer(text):
            line=text[:m.start()].count('\n')+1
            hits.append((line,k,m.group(0)))
    print(f'--- {p}')
    for line,k,term in hits:
        print(f'  {k}:{line}:{term}')
PY

echo
echo "== package.json relevant dependencies =="
if [ -f package.json ]; then
  python3 - <<'PY'
import json
data=json.load(open('package.json'))
vals=data.get('dependencies',{})|data.get('devDependencies',{})
for k,v in sorted(vals.items()):
    if any(x in k.lower() for x in ['opentelemetry','winston','pino','uptrace','signoz','pino-http','winston']):
        print(f'{k}: {v}')
PY
fi

echo
echo "== tracked source/config files mentioning signoz/uptrace =="
rg -n -i 'signoz|uptrace|pinot' --glob '!node_modules' --glob '!dist' --glob '!build' --glob '!*.lock' --glob '!*.json' --glob '!*.md' . || true

Repository: auth-plus/auth-plus-authentication

Length of output: 50391


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== exact snippets =="
awk '{printf "%6d  %s\n", NR, $0}' .specify/memory/constitution.md | sed -n '10,18p;36,44p'
awk '{printf "%6d  %s\n", NR, $0}' specs/001-add-flow-logging/plan.md | sed -n '6,12p'

echo
echo "== package.json relevant dependencies =="
if [ -f package.json ]; then
  python3 - <<'PY'
import json
data=json.load(open('package.json'))
deps=data.get('dependencies',{})|data.get('devDependencies',{})
for k in sorted(deps):
    if any(x in k.lower() for x in ['opentelemetry','winston','pino','uptrace','signoz','pino-http','winston']):
        print(f'{k}: {deps[k]}')
PY
fi

echo
echo "== focused observability terms in source/config/package files only =="
python3 - <<'PY'
import json, pathlib, re, subprocess
ignore = {'.git','node_modules','dist','build','cache','graphify-out'}
files = subprocess.check_output(['git','ls-files']).decode().splitlines()
terms = {
    "winston": re.compile(r'\bwinston\b|`@opentelemetry/instrumentation-winston`|`@opentelemetry/winston-transport`|winston-transport', re.I),
    "pino": re.compile(mobile r'\bpino\b|`@opentelemetry/instrumentation-pino`|pino-http\b', re.I),
    "signoz": re.compile(r'\bsignoz\b', re.I),
    "uptrace": re.compile(r'\buptrace\b', re.I),
}
for p in files:
    if any(part in ignore for part in p.split('/')):
        continue
    ext = pathlib.Path(p).suffix.lower()
    if p == 'package.json' or ext in {'.ts','.js','.mts','.mjs','.json','.yml','.yaml','.env*'}:
        try:
            text = pathlib.Path(p).read_text(errors='ignore')
        except Exception:
            continue
        for k,v in terms.items():
            for m in v.finditer(text):
                line = text[:m.start()].count('\n')+1
                print(f'{p}:{line}:{k}:{m.group(0)}')
PY

echo
echo "== focused signoz/uptrace occurrences among tracked files =="
rg -n -i '\bsignoz\b|\buptrace\b|\bpino\b|\bwinston\b' --glob '!node_modules' --glob '!dist' --glob '!build' --glob '!cache' --glob '!graphify-out' . | head -n 200 || true

Repository: auth-plus/auth-plus-authentication

Length of output: 3240


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== focused observability terms in tracked non-output files =="
python3 - <<'PY'
import pathlib
import re

terms = {
    "winston": re.compile(r'\bwinston\b|`@opentelemetry/instrumentation-winston`|`@opentelemetry/winston-transport`|winston-transport', re.I),
    "pino": re.compile(r'\bpino\b|`@opentelemetry/instrumentation-pino`|pino-http\b', re.I),
    "signoz": re.compile(r'\bsignoz\b', re.I),
    "uptrace": re.compile(r'\buptrace\b', re.I),
}

for p in pathlib.Path('.').rglob('*'):
    if not p.is_file():
        continue
    bad = {'.git','node_modules','dist','build','cache','graphify-out'}
    if any(part in bad for part in p.parts):
        continue
    rel = str(p)
    ext = p.suffix.lower()
    if rel == 'package.json' or ext in {'.ts','.js','.mts','.mjs','.json','.yml','.yaml'}:
        try:
            text = p.read_text(errors='ignore')
        except Exception:
            continue
        for k, pattern in terms.items():
            for m in pattern.finditer(text):
                line = text[:m.start()].count('\n') + 1
                print(f'{rel}:{line}:{k}:{m.group(0)}')
PY

Repository: auth-plus/auth-plus-authentication

Length of output: 3279


Unify the observability stack references.

The dependencies include both Pino and Winston packages, but the runtime wiring uses Pino and a SigNoz/Otlp export target, while the requirements still promise Winston and/or Uptrace. Pick the intended logger/exporter and update the affected docs.

  • .specify/memory/constitution.md#L15: remove Winston/Uptrace or make the runtime match it.
  • .specify/memory/constitution.md#L42: adjust Monitoring to the selected exporter.
  • specs/001-add-flow-logging/plan.md#L9: keep Uptrace only if that is the selected destination; otherwise revise to SigNoz.
📍 Affects 2 files
  • .specify/memory/constitution.md#L14-L15 (this comment)
  • .specify/memory/constitution.md#L40-L42
  • specs/001-add-flow-logging/plan.md#L9-L9
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.specify/memory/constitution.md around lines 14 - 15, Unify observability
documentation with the runtime’s selected Pino logger and SigNoz/OTLP exporter.
In .specify/memory/constitution.md lines 14-15, replace the Winston/Uptrace
references; update the Monitoring section at lines 40-42 to name SigNoz; and
revise specs/001-add-flow-logging/plan.md line 9 to remove Uptrace and
consistently reference SigNoz.

@@ -0,0 +1 @@
/home/andrew/.local/share/uv/tools/graphifyy/bin/python No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Remove machine-local Graphify metadata from committed artifacts.

The interpreter pointer and AST cache IDs embed /home/andrew/...; one artifact also contains file:///home/andrew/... URLs. This leaks local filesystem information and makes the generated output non-reproducible across checkouts.

  • graphify-out/.graphify_python#L1-L1: replace the absolute interpreter path with portable metadata or omit the file.
  • graphify-out/cache/ast/v0.9.29/a412e829419ad03c761ab7f88fa02dc8bf6a01ce9f40869eafb6c76fe85a5bfa.json#L1-L1: generate IDs from relative paths.
  • graphify-out/cache/ast/v0.9.29/a571e6de0ed5f7e161a81def91f91043506dbf562ac3be4cfa3f4c48c49683ec.json#L1-L1: remove absolute IDs, URLs, and target paths.
  • graphify-out/cache/ast/v0.9.29/a9c6383a1eb7ba23b6925a62eae5635e63c836d61b2878ebfc3b28c3f47af35e.json#L1-L1: generate portable node IDs.
  • graphify-out/cache/ast/v0.9.29/ab8e59fa8724ca438acb8add08e834d9cfa0fa1a34f92f7545fddaa27da23343.json#L1-L1: generate portable node IDs.
  • graphify-out/cache/ast/v0.9.29/ae22b7c7ecb6ccd516fed25916e465146432c58f1bef904a92b535ac0bbecfcf.json#L1-L1: generate portable node IDs.
  • graphify-out/cache/ast/v0.9.29/b314d97a20868c731da275a5a30d3a2860e2fb21226f6eee249d500861544ce6.json#L1-L1: generate portable node IDs.
  • graphify-out/cache/ast/v0.9.29/bd00ea412c1a2894a519eec2bf0067d1150cdd267f1099debc4536f4a5d0f20a.json#L1-L1: generate portable node IDs.
📍 Affects 8 files
  • graphify-out/.graphify_python#L1-L1 (this comment)
  • graphify-out/cache/ast/v0.9.29/a412e829419ad03c761ab7f88fa02dc8bf6a01ce9f40869eafb6c76fe85a5bfa.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/a571e6de0ed5f7e161a81def91f91043506dbf562ac3be4cfa3f4c48c49683ec.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/a9c6383a1eb7ba23b6925a62eae5635e63c836d61b2878ebfc3b28c3f47af35e.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/ab8e59fa8724ca438acb8add08e834d9cfa0fa1a34f92f7545fddaa27da23343.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/ae22b7c7ecb6ccd516fed25916e465146432c58f1bef904a92b535ac0bbecfcf.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/b314d97a20868c731da275a5a30d3a2860e2fb21226f6eee249d500861544ce6.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/bd00ea412c1a2894a519eec2bf0067d1150cdd267f1099debc4536f4a5d0f20a.json#L1-L1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@graphify-out/.graphify_python` at line 1, Remove machine-local metadata from
all listed generated artifacts: replace or omit the interpreter pointer in
graphify-out/.graphify_python; regenerate the AST cache files at
graphify-out/cache/ast/v0.9.29/a412e829419ad03c761ab7f88fa02dc8bf6a01ce9f40869eafb6c76fe85a5bfa.json,
a9c6383a1eb7ba23b6925a62eae5635e63c836d61b2878ebfc3b28c3f47af35e.json,
ab8e59fa8724ca438acb8add08e834d9cfa0fa1a34f92f7545fddaa27da23343.json,
ae22b7c7ecb6ccd516fed25916e465146432c58f1bef904a92b535ac0bbecfcf.json,
b314d97a20868c731da275a5a30d3a2860e2fb21226f6eee249d500861544ce6.json, and
bd00ea412c1a2894a519eec2bf0067d1150cdd267f1099debc4536f4a5d0f20a.json with IDs
derived from relative paths; and clean
a571e6de0ed5f7e161a81def91f91043506dbf562ac3be4cfa3f4c48c49683ec.json of
absolute IDs, file URLs, and target paths.

@@ -0,0 +1 @@
{"nodes": [{"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_md", "label": "tasks-template.md", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L1"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "label": "Tasks: [FEATURE NAME]", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L6"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_format_id_p_story_description", "label": "Format: `[ID] [P?] [Story] Description`", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L16"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_path_conventions", "label": "Path Conventions", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L22"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_1_setup_shared_infrastructure", "label": "Phase 1: Setup (Shared Infrastructure)", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L48"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_2_foundational_blocking_prerequisites", "label": "Phase 2: Foundational (Blocking Prerequisites)", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L58"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_3_user_story_1_title_priority_p1_mvp", "label": "Phase 3: User Story 1 - [Title] (Priority: P1) \ud83c\udfaf MVP", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L77"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_1_optional_only_if_tests_requested", "label": "Tests for User Story 1 (OPTIONAL - only if tests requested) \u26a0\ufe0f", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L83"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_1", "label": "Implementation for User Story 1", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L90"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_4_user_story_2_title_priority_p2", "label": "Phase 4: User Story 2 - [Title] (Priority: P2)", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L103"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_2_optional_only_if_tests_requested", "label": "Tests for User Story 2 (OPTIONAL - only if tests requested) \u26a0\ufe0f", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L109"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_2", "label": "Implementation for User Story 2", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L114"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_5_user_story_3_title_priority_p3", "label": "Phase 5: User Story 3 - [Title] (Priority: P3)", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L125"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_3_optional_only_if_tests_requested", "label": "Tests for User Story 3 (OPTIONAL - only if tests requested) \u26a0\ufe0f", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L131"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_3", "label": "Implementation for User Story 3", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L136"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_n_polish_cross_cutting_concerns", "label": "Phase N: Polish & Cross-Cutting Concerns", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L150"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "label": "Dependencies & Execution Order", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L163"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_dependencies", "label": "Phase Dependencies", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L165"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_user_story_dependencies", "label": "User Story Dependencies", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L174"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_within_each_user_story", "label": "Within Each User Story", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L180"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_opportunities", "label": "Parallel Opportunities", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L188"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_example_user_story_1", "label": "Parallel Example: User Story 1", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L199"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_strategy", "label": "Implementation Strategy", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L213"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_mvp_first_user_story_1_only", "label": "MVP First (User Story 1 Only)", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L215"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_incremental_delivery", "label": "Incremental Delivery", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L223"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_team_strategy", "label": "Parallel Team Strategy", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L231"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_notes", "label": "Notes", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L244"}], "edges": [{"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_md", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L6", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_format_id_p_story_description", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L16", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_path_conventions", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L22", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_1_setup_shared_infrastructure", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L48", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_2_foundational_blocking_prerequisites", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L58", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_3_user_story_1_title_priority_p1_mvp", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L77", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_3_user_story_1_title_priority_p1_mvp", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_1_optional_only_if_tests_requested", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L83", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_3_user_story_1_title_priority_p1_mvp", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_1", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L90", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_4_user_story_2_title_priority_p2", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L103", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_4_user_story_2_title_priority_p2", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_2_optional_only_if_tests_requested", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L109", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_4_user_story_2_title_priority_p2", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_2", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L114", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_5_user_story_3_title_priority_p3", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L125", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_5_user_story_3_title_priority_p3", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_3_optional_only_if_tests_requested", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L131", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_5_user_story_3_title_priority_p3", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_3", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L136", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_n_polish_cross_cutting_concerns", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L150", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L163", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_dependencies", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L165", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_user_story_dependencies", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L174", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_within_each_user_story", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L180", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_opportunities", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L188", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_example_user_story_1", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L199", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_strategy", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L213", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_strategy", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_mvp_first_user_story_1_only", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L215", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_strategy", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_incremental_delivery", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L223", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_strategy", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_team_strategy", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L231", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_notes", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L244", "weight": 1.0}], "input_tokens": 0, "output_tokens": 0} No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Normalize absolute paths across the generated Graphify caches.

These artifacts serialize /home/andrew/Documents/auth-plus-symphony/auth-plus-authentication, making graph references machine-specific and leaking local workspace details.

  • graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json#L1-L1: generate repository-relative node IDs.
  • graphify-out/cache/ast/v0.9.29/07e40705140f96139361d29ad46bce8cdb8303339171f45cb1436780d4da58f3.json#L1-L1: generate repository-relative node IDs.
  • graphify-out/cache/ast/v0.9.29/08e79622b777468d92f233b7c30b8ed76c9c48ad03597affb7c92c1d49dc681b.json#L1-L1: generate repository-relative node IDs.
  • graphify-out/cache/ast/v0.9.29/107c774c59ce86f256e108b38364b6606584460b17d44294abbbc3de5da6a2a2.json#L1-L1: replace the absolute target_file with a repository-relative path.
📍 Affects 4 files
  • graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json#L1-L1 (this comment)
  • graphify-out/cache/ast/v0.9.29/07e40705140f96139361d29ad46bce8cdb8303339171f45cb1436780d4da58f3.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/08e79622b777468d92f233b7c30b8ed76c9c48ad03597affb7c92c1d49dc681b.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/107c774c59ce86f256e108b38364b6606584460b17d44294abbbc3de5da6a2a2.json#L1-L1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json`
at line 1, Normalize machine-specific absolute workspace paths in the generated
Graphify caches. In
graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json:1-1,
07e40705140f96139361d29ad46bce8cdb8303339171f45cb1436780d4da58f3.json:1-1, and
08e79622b777468d92f233b7c30b8ed76c9c48ad03597affb7c92c1d49dc681b.json:1-1,
regenerate node IDs using repository-relative paths; in
graphify-out/cache/ast/v0.9.29/107c774c59ce86f256e108b38364b6606584460b17d44294abbbc3de5da6a2a2.json:1-1,
replace the absolute target_file value with its repository-relative path.

@@ -0,0 +1 @@
{"nodes": [{"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "label": "package.json", "file_type": "code", "source_file": "package.json", "source_location": "L1"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_name", "label": "name", "file_type": "code", "source_file": "package.json", "source_location": "L2"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_version", "label": "version", "file_type": "code", "source_file": "package.json", "source_location": "L3"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_description", "label": "description", "file_type": "code", "source_file": "package.json", "source_location": "L4"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "label": "scripts", "file_type": "code", "source_file": "package.json", "source_location": "L5"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_dev", "label": "dev", "file_type": "code", "source_file": "package.json", "source_location": "L6"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_start", "label": "start", "file_type": "code", "source_file": "package.json", "source_location": "L7"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_lint", "label": "lint", "file_type": "code", "source_file": "package.json", "source_location": "L8"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_lint_check", "label": "lint:check", "file_type": "code", "source_file": "package.json", "source_location": "L9"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_build", "label": "build", "file_type": "code", "source_file": "package.json", "source_location": "L10"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_build_check", "label": "build:check", "file_type": "code", "source_file": "package.json", "source_location": "L11"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_test", "label": "test", "file_type": "code", "source_file": "package.json", "source_location": "L12"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_stryker", "label": "stryker", "file_type": "code", "source_file": "package.json", "source_location": "L13"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_keywords", "label": "keywords", "file_type": "code", "source_file": "package.json", "source_location": "L15"}, {"id": "ref_express", "label": "express", "file_type": "concept", "source_file": "package.json", "source_location": "L15"}, {"id": "ref_auth", "label": "auth", "file_type": "concept", "source_file": "package.json", "source_location": "L15"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_main", "label": "main", "file_type": "code", "source_file": "package.json", "source_location": "L19"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_author", "label": "author", "file_type": "code", "source_file": "package.json", "source_location": "L20"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_license", "label": "license", "file_type": "code", "source_file": "package.json", "source_location": "L21"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_bugs", "label": "bugs", "file_type": "code", "source_file": "package.json", "source_location": "L22"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_bugs_url", "label": "url", "file_type": "code", "source_file": "package.json", "source_location": "L23"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_homepage", "label": "homepage", "file_type": "code", "source_file": "package.json", "source_location": "L25"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_engines", "label": "engines", "file_type": "code", "source_file": "package.json", "source_location": "L26"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_engines_node", "label": "node", "file_type": "code", "source_file": "package.json", "source_location": "L27"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "label": "dependencies", "file_type": "code", "source_file": "package.json", "source_location": "L29"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_api", "label": "@opentelemetry/api", "file_type": "code", "source_file": "package.json", "source_location": "L30"}, {"id": "opentelemetry_api", "label": "@opentelemetry/api", "file_type": "concept", "source_file": "package.json", "source_location": "L30"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_auto_instrumentations_node", "label": "@opentelemetry/auto-instrumentations-node", "file_type": "code", "source_file": "package.json", "source_location": "L31"}, {"id": "opentelemetry_auto_instrumentations_node", "label": "@opentelemetry/auto-instrumentations-node", "file_type": "concept", "source_file": "package.json", "source_location": "L31"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_grpc", "label": "@opentelemetry/exporter-logs-otlp-grpc", "file_type": "code", "source_file": "package.json", "source_location": "L32"}, {"id": "opentelemetry_exporter_logs_otlp_grpc", "label": "@opentelemetry/exporter-logs-otlp-grpc", "file_type": "concept", "source_file": "package.json", "source_location": "L32"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_http", "label": "@opentelemetry/exporter-logs-otlp-http", "file_type": "code", "source_file": "package.json", "source_location": "L33"}, {"id": "opentelemetry_exporter_logs_otlp_http", "label": "@opentelemetry/exporter-logs-otlp-http", "file_type": "concept", "source_file": "package.json", "source_location": "L33"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_metrics_otlp_http", "label": "@opentelemetry/exporter-metrics-otlp-http", "file_type": "code", "source_file": "package.json", "source_location": "L34"}, {"id": "opentelemetry_exporter_metrics_otlp_http", "label": "@opentelemetry/exporter-metrics-otlp-http", "file_type": "concept", "source_file": "package.json", "source_location": "L34"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_grpc", "label": "@opentelemetry/exporter-trace-otlp-grpc", "file_type": "code", "source_file": "package.json", "source_location": "L35"}, {"id": "opentelemetry_exporter_trace_otlp_grpc", "label": "@opentelemetry/exporter-trace-otlp-grpc", "file_type": "concept", "source_file": "package.json", "source_location": "L35"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_http", "label": "@opentelemetry/exporter-trace-otlp-http", "file_type": "code", "source_file": "package.json", "source_location": "L36"}, {"id": "opentelemetry_exporter_trace_otlp_http", "label": "@opentelemetry/exporter-trace-otlp-http", "file_type": "concept", "source_file": "package.json", "source_location": "L36"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_express", "label": "@opentelemetry/instrumentation-express", "file_type": "code", "source_file": "package.json", "source_location": "L37"}, {"id": "opentelemetry_instrumentation_express", "label": "@opentelemetry/instrumentation-express", "file_type": "concept", "source_file": "package.json", "source_location": "L37"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_http", "label": "@opentelemetry/instrumentation-http", "file_type": "code", "source_file": "package.json", "source_location": "L38"}, {"id": "opentelemetry_instrumentation_http", "label": "@opentelemetry/instrumentation-http", "file_type": "concept", "source_file": "package.json", "source_location": "L38"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_pino", "label": "@opentelemetry/instrumentation-pino", "file_type": "code", "source_file": "package.json", "source_location": "L39"}, {"id": "opentelemetry_instrumentation_pino", "label": "@opentelemetry/instrumentation-pino", "file_type": "concept", "source_file": "package.json", "source_location": "L39"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_winston", "label": "@opentelemetry/instrumentation-winston", "file_type": "code", "source_file": "package.json", "source_location": "L40"}, {"id": "opentelemetry_instrumentation_winston", "label": "@opentelemetry/instrumentation-winston", "file_type": "concept", "source_file": "package.json", "source_location": "L40"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_resources", "label": "@opentelemetry/resources", "file_type": "code", "source_file": "package.json", "source_location": "L41"}, {"id": "opentelemetry_resources", "label": "@opentelemetry/resources", "file_type": "concept", "source_file": "package.json", "source_location": "L41"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_logs", "label": "@opentelemetry/sdk-logs", "file_type": "code", "source_file": "package.json", "source_location": "L42"}, {"id": "opentelemetry_sdk_logs", "label": "@opentelemetry/sdk-logs", "file_type": "concept", "source_file": "package.json", "source_location": "L42"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_metrics", "label": "@opentelemetry/sdk-metrics", "file_type": "code", "source_file": "package.json", "source_location": "L43"}, {"id": "opentelemetry_sdk_metrics", "label": "@opentelemetry/sdk-metrics", "file_type": "concept", "source_file": "package.json", "source_location": "L43"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_node", "label": "@opentelemetry/sdk-node", "file_type": "code", "source_file": "package.json", "source_location": "L44"}, {"id": "opentelemetry_sdk_node", "label": "@opentelemetry/sdk-node", "file_type": "concept", "source_file": "package.json", "source_location": "L44"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_semantic_conventions", "label": "@opentelemetry/semantic-conventions", "file_type": "code", "source_file": "package.json", "source_location": "L45"}, {"id": "opentelemetry_semantic_conventions", "label": "@opentelemetry/semantic-conventions", "file_type": "concept", "source_file": "package.json", "source_location": "L45"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_winston_transport", "label": "@opentelemetry/winston-transport", "file_type": "code", "source_file": "package.json", "source_location": "L46"}, {"id": "opentelemetry_winston_transport", "label": "@opentelemetry/winston-transport", "file_type": "concept", "source_file": "package.json", "source_location": "L46"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_valkey_valkey_glide", "label": "@valkey/valkey-glide", "file_type": "code", "source_file": "package.json", "source_location": "L47"}, {"id": "valkey_valkey_glide", "label": "@valkey/valkey-glide", "file_type": "concept", "source_file": "package.json", "source_location": "L47"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_bcrypt", "label": "bcrypt", "file_type": "code", "source_file": "package.json", "source_location": "L48"}, {"id": "bcrypt", "label": "bcrypt", "file_type": "concept", "source_file": "package.json", "source_location": "L48"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_body_parser", "label": "body-parser", "file_type": "code", "source_file": "package.json", "source_location": "L49"}, {"id": "body_parser", "label": "body-parser", "file_type": "concept", "source_file": "package.json", "source_location": "L49"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_cors", "label": "cors", "file_type": "code", "source_file": "package.json", "source_location": "L50"}, {"id": "cors", "label": "cors", "file_type": "concept", "source_file": "package.json", "source_location": "L50"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_dotenv", "label": "dotenv", "file_type": "code", "source_file": "package.json", "source_location": "L51"}, {"id": "dotenv", "label": "dotenv", "file_type": "concept", "source_file": "package.json", "source_location": "L51"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_express", "label": "express", "file_type": "code", "source_file": "package.json", "source_location": "L52"}, {"id": "express", "label": "express", "file_type": "concept", "source_file": "package.json", "source_location": "L52"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_helmet", "label": "helmet", "file_type": "code", "source_file": "package.json", "source_location": "L53"}, {"id": "helmet", "label": "helmet", "file_type": "concept", "source_file": "package.json", "source_location": "L53"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_joi", "label": "joi", "file_type": "code", "source_file": "package.json", "source_location": "L54"}, {"id": "joi", "label": "joi", "file_type": "concept", "source_file": "package.json", "source_location": "L54"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_jsonwebtoken", "label": "jsonwebtoken", "file_type": "code", "source_file": "package.json", "source_location": "L55"}, {"id": "jsonwebtoken", "label": "jsonwebtoken", "file_type": "concept", "source_file": "package.json", "source_location": "L55"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_kafkajs", "label": "kafkajs", "file_type": "code", "source_file": "package.json", "source_location": "L56"}, {"id": "kafkajs", "label": "kafkajs", "file_type": "concept", "source_file": "package.json", "source_location": "L56"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_knex", "label": "knex", "file_type": "code", "source_file": "package.json", "source_location": "L57"}, {"id": "knex", "label": "knex", "file_type": "concept", "source_file": "package.json", "source_location": "L57"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_otpauth", "label": "otpauth", "file_type": "code", "source_file": "package.json", "source_location": "L58"}, {"id": "otpauth", "label": "otpauth", "file_type": "concept", "source_file": "package.json", "source_location": "L58"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pg", "label": "pg", "file_type": "code", "source_file": "package.json", "source_location": "L59"}, {"id": "pg", "label": "pg", "file_type": "concept", "source_file": "package.json", "source_location": "L59"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino", "label": "pino", "file_type": "code", "source_file": "package.json", "source_location": "L60"}, {"id": "pino", "label": "pino", "file_type": "concept", "source_file": "package.json", "source_location": "L60"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino_http", "label": "pino-http", "file_type": "code", "source_file": "package.json", "source_location": "L61"}, {"id": "pino_http", "label": "pino-http", "file_type": "concept", "source_file": "package.json", "source_location": "L61"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_prom_client", "label": "prom-client", "file_type": "code", "source_file": "package.json", "source_location": "L62"}, {"id": "prom_client", "label": "prom-client", "file_type": "concept", "source_file": "package.json", "source_location": "L62"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_swagger_ui_express", "label": "swagger-ui-express", "file_type": "code", "source_file": "package.json", "source_location": "L63"}, {"id": "swagger_ui_express", "label": "swagger-ui-express", "file_type": "concept", "source_file": "package.json", "source_location": "L63"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_winston", "label": "winston", "file_type": "code", "source_file": "package.json", "source_location": "L64"}, {"id": "winston", "label": "winston", "file_type": "concept", "source_file": "package.json", "source_location": "L64"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_zxcvbn", "label": "zxcvbn", "file_type": "code", "source_file": "package.json", "source_location": "L65"}, {"id": "zxcvbn", "label": "zxcvbn", "file_type": "concept", "source_file": "package.json", "source_location": "L65"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "label": "devDependencies", "file_type": "code", "source_file": "package.json", "source_location": "L67"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_cli", "label": "@commitlint/cli", "file_type": "code", "source_file": "package.json", "source_location": "L68"}, {"id": "commitlint_cli", "label": "@commitlint/cli", "file_type": "concept", "source_file": "package.json", "source_location": "L68"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_config_conventional", "label": "@commitlint/config-conventional", "file_type": "code", "source_file": "package.json", "source_location": "L69"}, {"id": "commitlint_config_conventional", "label": "@commitlint/config-conventional", "file_type": "concept", "source_file": "package.json", "source_location": "L69"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_css", "label": "@eslint/css", "file_type": "code", "source_file": "package.json", "source_location": "L70"}, {"id": "eslint_css", "label": "@eslint/css", "file_type": "concept", "source_file": "package.json", "source_location": "L70"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_js", "label": "@eslint/js", "file_type": "code", "source_file": "package.json", "source_location": "L71"}, {"id": "eslint_js", "label": "@eslint/js", "file_type": "concept", "source_file": "package.json", "source_location": "L71"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_json", "label": "@eslint/json", "file_type": "code", "source_file": "package.json", "source_location": "L72"}, {"id": "eslint_json", "label": "@eslint/json", "file_type": "concept", "source_file": "package.json", "source_location": "L72"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_markdown", "label": "@eslint/markdown", "file_type": "code", "source_file": "package.json", "source_location": "L73"}, {"id": "eslint_markdown", "label": "@eslint/markdown", "file_type": "concept", "source_file": "package.json", "source_location": "L73"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_core", "label": "@stryker-mutator/core", "file_type": "code", "source_file": "package.json", "source_location": "L74"}, {"id": "stryker_mutator_core", "label": "@stryker-mutator/core", "file_type": "concept", "source_file": "package.json", "source_location": "L74"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_jest_runner", "label": "@stryker-mutator/jest-runner", "file_type": "code", "source_file": "package.json", "source_location": "L75"}, {"id": "stryker_mutator_jest_runner", "label": "@stryker-mutator/jest-runner", "file_type": "concept", "source_file": "package.json", "source_location": "L75"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_kafka", "label": "@testcontainers/kafka", "file_type": "code", "source_file": "package.json", "source_location": "L76"}, {"id": "testcontainers_kafka", "label": "@testcontainers/kafka", "file_type": "concept", "source_file": "package.json", "source_location": "L76"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_postgresql", "label": "@testcontainers/postgresql", "file_type": "code", "source_file": "package.json", "source_location": "L77"}, {"id": "testcontainers_postgresql", "label": "@testcontainers/postgresql", "file_type": "concept", "source_file": "package.json", "source_location": "L77"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_valkey", "label": "@testcontainers/valkey", "file_type": "code", "source_file": "package.json", "source_location": "L78"}, {"id": "testcontainers_valkey", "label": "@testcontainers/valkey", "file_type": "concept", "source_file": "package.json", "source_location": "L78"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_bcrypt", "label": "@types/bcrypt", "file_type": "code", "source_file": "package.json", "source_location": "L79"}, {"id": "types_bcrypt", "label": "@types/bcrypt", "file_type": "concept", "source_file": "package.json", "source_location": "L79"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_chai", "label": "@types/chai", "file_type": "code", "source_file": "package.json", "source_location": "L80"}, {"id": "types_chai", "label": "@types/chai", "file_type": "concept", "source_file": "package.json", "source_location": "L80"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_cors", "label": "@types/cors", "file_type": "code", "source_file": "package.json", "source_location": "L81"}, {"id": "types_cors", "label": "@types/cors", "file_type": "concept", "source_file": "package.json", "source_location": "L81"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_eslint_plugin_security", "label": "@types/eslint-plugin-security", "file_type": "code", "source_file": "package.json", "source_location": "L82"}, {"id": "types_eslint_plugin_security", "label": "@types/eslint-plugin-security", "file_type": "concept", "source_file": "package.json", "source_location": "L82"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_express", "label": "@types/express", "file_type": "code", "source_file": "package.json", "source_location": "L83"}, {"id": "types_express", "label": "@types/express", "file_type": "concept", "source_file": "package.json", "source_location": "L83"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jest", "label": "@types/jest", "file_type": "code", "source_file": "package.json", "source_location": "L84"}, {"id": "types_jest", "label": "@types/jest", "file_type": "concept", "source_file": "package.json", "source_location": "L84"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jsonwebtoken", "label": "@types/jsonwebtoken", "file_type": "code", "source_file": "package.json", "source_location": "L85"}, {"id": "types_jsonwebtoken", "label": "@types/jsonwebtoken", "file_type": "concept", "source_file": "package.json", "source_location": "L85"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_node", "label": "@types/node", "file_type": "code", "source_file": "package.json", "source_location": "L86"}, {"id": "types_node", "label": "@types/node", "file_type": "concept", "source_file": "package.json", "source_location": "L86"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_supertest", "label": "@types/supertest", "file_type": "code", "source_file": "package.json", "source_location": "L87"}, {"id": "types_supertest", "label": "@types/supertest", "file_type": "concept", "source_file": "package.json", "source_location": "L87"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_swagger_ui_express", "label": "@types/swagger-ui-express", "file_type": "code", "source_file": "package.json", "source_location": "L88"}, {"id": "types_swagger_ui_express", "label": "@types/swagger-ui-express", "file_type": "concept", "source_file": "package.json", "source_location": "L88"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_zxcvbn", "label": "@types/zxcvbn", "file_type": "code", "source_file": "package.json", "source_location": "L89"}, {"id": "types_zxcvbn", "label": "@types/zxcvbn", "file_type": "concept", "source_file": "package.json", "source_location": "L89"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint_parser", "label": "@typescript-eslint/parser", "file_type": "code", "source_file": "package.json", "source_location": "L90"}, {"id": "typescript_eslint_parser", "label": "@typescript-eslint/parser", "file_type": "concept", "source_file": "package.json", "source_location": "L90"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_casual", "label": "casual", "file_type": "code", "source_file": "package.json", "source_location": "L91"}, {"id": "casual", "label": "casual", "file_type": "concept", "source_file": "package.json", "source_location": "L91"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_chai", "label": "chai", "file_type": "code", "source_file": "package.json", "source_location": "L92"}, {"id": "chai", "label": "chai", "file_type": "concept", "source_file": "package.json", "source_location": "L92"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint", "label": "eslint", "file_type": "code", "source_file": "package.json", "source_location": "L93"}, {"id": "eslint", "label": "eslint", "file_type": "concept", "source_file": "package.json", "source_location": "L93"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_security", "label": "eslint-plugin-security", "file_type": "code", "source_file": "package.json", "source_location": "L94"}, {"id": "eslint_plugin_security", "label": "eslint-plugin-security", "file_type": "concept", "source_file": "package.json", "source_location": "L94"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_sonarjs", "label": "eslint-plugin-sonarjs", "file_type": "code", "source_file": "package.json", "source_location": "L95"}, {"id": "eslint_plugin_sonarjs", "label": "eslint-plugin-sonarjs", "file_type": "concept", "source_file": "package.json", "source_location": "L95"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_globals", "label": "globals", "file_type": "code", "source_file": "package.json", "source_location": "L96"}, {"id": "globals", "label": "globals", "file_type": "concept", "source_file": "package.json", "source_location": "L96"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_husky", "label": "husky", "file_type": "code", "source_file": "package.json", "source_location": "L97"}, {"id": "husky", "label": "husky", "file_type": "concept", "source_file": "package.json", "source_location": "L97"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_jest", "label": "jest", "file_type": "code", "source_file": "package.json", "source_location": "L98"}, {"id": "jest", "label": "jest", "file_type": "concept", "source_file": "package.json", "source_location": "L98"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nock", "label": "nock", "file_type": "code", "source_file": "package.json", "source_location": "L99"}, {"id": "nock", "label": "nock", "file_type": "concept", "source_file": "package.json", "source_location": "L99"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nodemon", "label": "nodemon", "file_type": "code", "source_file": "package.json", "source_location": "L100"}, {"id": "nodemon", "label": "nodemon", "file_type": "concept", "source_file": "package.json", "source_location": "L100"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nyc", "label": "nyc", "file_type": "code", "source_file": "package.json", "source_location": "L101"}, {"id": "nyc", "label": "nyc", "file_type": "concept", "source_file": "package.json", "source_location": "L101"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_prettier", "label": "prettier", "file_type": "code", "source_file": "package.json", "source_location": "L102"}, {"id": "prettier", "label": "prettier", "file_type": "concept", "source_file": "package.json", "source_location": "L102"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_supertest", "label": "supertest", "file_type": "code", "source_file": "package.json", "source_location": "L103"}, {"id": "supertest", "label": "supertest", "file_type": "concept", "source_file": "package.json", "source_location": "L103"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_jest", "label": "ts-jest", "file_type": "code", "source_file": "package.json", "source_location": "L104"}, {"id": "ts_jest", "label": "ts-jest", "file_type": "concept", "source_file": "package.json", "source_location": "L104"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_mockito", "label": "ts-mockito", "file_type": "code", "source_file": "package.json", "source_location": "L105"}, {"id": "ts_mockito", "label": "ts-mockito", "file_type": "concept", "source_file": "package.json", "source_location": "L105"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_node", "label": "ts-node", "file_type": "code", "source_file": "package.json", "source_location": "L106"}, {"id": "ts_node", "label": "ts-node", "file_type": "concept", "source_file": "package.json", "source_location": "L106"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript", "label": "typescript", "file_type": "code", "source_file": "package.json", "source_location": "L107"}, {"id": "typescript", "label": "typescript", "file_type": "concept", "source_file": "package.json", "source_location": "L107"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint", "label": "typescript-eslint", "file_type": "code", "source_file": "package.json", "source_location": "L108"}, {"id": "typescript_eslint", "label": "typescript-eslint", "file_type": "concept", "source_file": "package.json", "source_location": "L108"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_w", "label": "w", "file_type": "code", "source_file": "package.json", "source_location": "L109"}, {"id": "w", "label": "w", "file_type": "concept", "source_file": "package.json", "source_location": "L109"}], "edges": [{"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_name", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L2", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_version", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L3", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_description", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L4", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L5", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_dev", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L6", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_start", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L7", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_lint", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L8", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_lint_check", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L9", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_build", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L10", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_build_check", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L11", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_test", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L12", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_stryker", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L13", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_keywords", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L15", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_keywords", "target": "ref_express", "relation": "extends", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L15", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_keywords", "target": "ref_auth", "relation": "extends", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L15", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_main", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L19", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_author", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L20", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_license", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L21", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_bugs", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L22", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_bugs", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_bugs_url", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L23", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_homepage", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L25", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_engines", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L26", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_engines", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_engines_node", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L27", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L29", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_api", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L30", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_api", "target": "opentelemetry_api", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L30", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_auto_instrumentations_node", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L31", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_auto_instrumentations_node", "target": "opentelemetry_auto_instrumentations_node", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L31", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_grpc", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L32", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_grpc", "target": "opentelemetry_exporter_logs_otlp_grpc", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L32", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_http", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L33", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_http", "target": "opentelemetry_exporter_logs_otlp_http", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L33", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_metrics_otlp_http", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L34", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_metrics_otlp_http", "target": "opentelemetry_exporter_metrics_otlp_http", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L34", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_grpc", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L35", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_grpc", "target": "opentelemetry_exporter_trace_otlp_grpc", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L35", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_http", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L36", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_http", "target": "opentelemetry_exporter_trace_otlp_http", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L36", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_express", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L37", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_express", "target": "opentelemetry_instrumentation_express", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L37", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_http", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L38", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_http", "target": "opentelemetry_instrumentation_http", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L38", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_pino", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L39", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_pino", "target": "opentelemetry_instrumentation_pino", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L39", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_winston", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L40", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_winston", "target": "opentelemetry_instrumentation_winston", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L40", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_resources", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L41", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_resources", "target": "opentelemetry_resources", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L41", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_logs", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L42", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_logs", "target": "opentelemetry_sdk_logs", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L42", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_metrics", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L43", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_metrics", "target": "opentelemetry_sdk_metrics", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L43", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_node", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L44", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_node", "target": "opentelemetry_sdk_node", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L44", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_semantic_conventions", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L45", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_semantic_conventions", "target": "opentelemetry_semantic_conventions", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L45", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_winston_transport", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L46", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_winston_transport", "target": "opentelemetry_winston_transport", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L46", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_valkey_valkey_glide", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L47", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_valkey_valkey_glide", "target": "valkey_valkey_glide", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L47", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_bcrypt", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L48", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_bcrypt", "target": "bcrypt", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L48", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_body_parser", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L49", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_body_parser", "target": "body_parser", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L49", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_cors", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L50", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_cors", "target": "cors", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L50", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_dotenv", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L51", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_dotenv", "target": "dotenv", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L51", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_express", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L52", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_express", "target": "express", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L52", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_helmet", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L53", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_helmet", "target": "helmet", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L53", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_joi", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L54", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_joi", "target": "joi", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L54", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_jsonwebtoken", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L55", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_jsonwebtoken", "target": "jsonwebtoken", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L55", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_kafkajs", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L56", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_kafkajs", "target": "kafkajs", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L56", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_knex", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L57", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_knex", "target": "knex", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L57", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_otpauth", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L58", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_otpauth", "target": "otpauth", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L58", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pg", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L59", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pg", "target": "pg", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L59", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L60", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino", "target": "pino", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L60", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino_http", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L61", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino_http", "target": "pino_http", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L61", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_prom_client", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L62", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_prom_client", "target": "prom_client", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L62", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_swagger_ui_express", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L63", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_swagger_ui_express", "target": "swagger_ui_express", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L63", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_winston", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L64", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_winston", "target": "winston", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L64", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_zxcvbn", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L65", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_zxcvbn", "target": "zxcvbn", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L65", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L67", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_cli", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L68", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_cli", "target": "commitlint_cli", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L68", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_config_conventional", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L69", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_config_conventional", "target": "commitlint_config_conventional", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L69", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_css", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L70", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_css", "target": "eslint_css", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L70", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_js", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L71", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_js", "target": "eslint_js", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L71", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_json", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L72", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_json", "target": "eslint_json", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L72", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_markdown", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L73", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_markdown", "target": "eslint_markdown", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L73", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_core", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L74", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_core", "target": "stryker_mutator_core", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L74", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_jest_runner", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L75", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_jest_runner", "target": "stryker_mutator_jest_runner", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L75", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_kafka", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L76", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_kafka", "target": "testcontainers_kafka", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L76", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_postgresql", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L77", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_postgresql", "target": "testcontainers_postgresql", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L77", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_valkey", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L78", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_valkey", "target": "testcontainers_valkey", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L78", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_bcrypt", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L79", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_bcrypt", "target": "types_bcrypt", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L79", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_chai", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L80", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_chai", "target": "types_chai", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L80", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_cors", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L81", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_cors", "target": "types_cors", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L81", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_eslint_plugin_security", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L82", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_eslint_plugin_security", "target": "types_eslint_plugin_security", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L82", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_express", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L83", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_express", "target": "types_express", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L83", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jest", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L84", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jest", "target": "types_jest", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L84", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jsonwebtoken", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L85", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jsonwebtoken", "target": "types_jsonwebtoken", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L85", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_node", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L86", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_node", "target": "types_node", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L86", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_supertest", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L87", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_supertest", "target": "types_supertest", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L87", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_swagger_ui_express", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L88", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_swagger_ui_express", "target": "types_swagger_ui_express", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L88", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_zxcvbn", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L89", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_zxcvbn", "target": "types_zxcvbn", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L89", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint_parser", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L90", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint_parser", "target": "typescript_eslint_parser", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L90", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_casual", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L91", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_casual", "target": "casual", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L91", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_chai", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L92", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_chai", "target": "chai", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L92", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L93", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint", "target": "eslint", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L93", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_security", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L94", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_security", "target": "eslint_plugin_security", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L94", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_sonarjs", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L95", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_sonarjs", "target": "eslint_plugin_sonarjs", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L95", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_globals", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L96", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_globals", "target": "globals", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L96", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_husky", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L97", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_husky", "target": "husky", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L97", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_jest", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L98", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_jest", "target": "jest", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L98", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nock", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L99", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nock", "target": "nock", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L99", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nodemon", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L100", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nodemon", "target": "nodemon", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L100", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nyc", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L101", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nyc", "target": "nyc", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L101", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_prettier", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L102", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_prettier", "target": "prettier", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L102", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_supertest", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L103", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_supertest", "target": "supertest", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L103", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_jest", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L104", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_jest", "target": "ts_jest", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L104", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_mockito", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L105", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_mockito", "target": "ts_mockito", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L105", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_node", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L106", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_node", "target": "ts_node", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L106", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L107", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript", "target": "typescript", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L107", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L108", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint", "target": "typescript_eslint", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L108", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_w", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L109", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_w", "target": "w", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L109", "weight": 1.0, "context": "import"}]} No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Sanitize absolute paths before committing Graphify output.

All affected artifacts embed the developer’s local checkout path in generated identifiers; graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json also persists an absolute target_file. Emit repository-relative paths or exclude host-specific caches from version control.

  • graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json#L1: normalize package graph node IDs.
  • graphify-out/cache/ast/v0.9.29/23a03f849ef54c3f2b89d56f47bc3851236f539e325de0897b699b57dae7be74.json#L1: normalize quickstart graph node IDs.
  • graphify-out/cache/ast/v0.9.29/2734a509d4b2f34ee6258475c4fb2e80a6dbfcbc47c8552df5b6278907529250.json#L1: normalize template graph node IDs.
  • graphify-out/cache/ast/v0.9.29/2ae70ccc099030710c9a9e142ae83c454ca9f2526d2c0ef94ca42709e5b3342d.json#L1: normalize research graph node IDs.
  • graphify-out/cache/ast/v0.9.29/327b9177caee62513cec0e53459a6ac09f569636f9648e8d77834fba89ad6bfd.json#L1: normalize README graph node IDs.
  • graphify-out/cache/ast/v0.9.29/3c525c42b7d7f51cc46c1ee2a56c266665067b217ecaf76b5bf03775a9b29c4f.json#L1: normalize shell-script graph node IDs.
  • graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json#L1: remove the absolute target_file and normalize node IDs.
  • graphify-out/cache/ast/v0.9.29/64bbd0b8aadc612d601eb49036e7574d6546fe9edc0db0156cb303d1b7ab0ef6.json#L1: normalize TypeScript configuration graph node IDs.
  • graphify-out/cache/ast/v0.9.29/7aefc125bffb446ba63881ed739ddeaacd7402e025fe0782c4b214bb56ca583f.json#L1: normalize plan-template graph node IDs.
  • graphify-out/cache/ast/v0.9.29/9bd6e6dd116b6b29717310b09e26cfd30acdc302612d8f29f2355d2e7ea476c2.json#L1: normalize data-model graph node IDs.
📍 Affects 10 files
  • graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json#L1-L1 (this comment)
  • graphify-out/cache/ast/v0.9.29/23a03f849ef54c3f2b89d56f47bc3851236f539e325de0897b699b57dae7be74.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/2734a509d4b2f34ee6258475c4fb2e80a6dbfcbc47c8552df5b6278907529250.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/2ae70ccc099030710c9a9e142ae83c454ca9f2526d2c0ef94ca42709e5b3342d.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/327b9177caee62513cec0e53459a6ac09f569636f9648e8d77834fba89ad6bfd.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/3c525c42b7d7f51cc46c1ee2a56c266665067b217ecaf76b5bf03775a9b29c4f.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/64bbd0b8aadc612d601eb49036e7574d6546fe9edc0db0156cb303d1b7ab0ef6.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/7aefc125bffb446ba63881ed739ddeaacd7402e025fe0782c4b214bb56ca583f.json#L1-L1
  • graphify-out/cache/ast/v0.9.29/9bd6e6dd116b6b29717310b09e26cfd30acdc302612d8f29f2355d2e7ea476c2.json#L1-L1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json`
at line 1, Sanitize generated Graphify artifacts so host-specific absolute
checkout paths are never persisted. In
graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json#L1,
normalize package graph node IDs; apply the same node-ID normalization to
graphify-out/cache/ast/v0.9.29/23a03f849ef54c3f2b89d56f47bc3851236f539e325de0897b699b57dae7be74.json#L1,
graphify-out/cache/ast/v0.9.29/2734a509d4b2f34ee6258475c4fb2e80a6dbfcbc47c8552df5b6278907529250.json#L1,
graphify-out/cache/ast/v0.9.29/2ae70ccc099030710c9a9e142ae83c454ca9f2526d2c0ef94ca42709e5b3342d.json#L1,
graphify-out/cache/ast/v0.9.29/327b9177caee62513cec0e53459a6ac09f569636f9648e8d77834fba89ad6bfd.json#L1,
graphify-out/cache/ast/v0.9.29/3c525c42b7d7f51cc46c1ee2a56c266665067b217ecaf76b5bf03775a9b29c4f.json#L1,
graphify-out/cache/ast/v0.9.29/64bbd0b8aadc612d601eb49036e7574d6546fe9edc0db0156cb303d1b7ab0ef6.json#L1,
graphify-out/cache/ast/v0.9.29/7aefc125bffb446ba63881ed739ddeaacd7402e025fe0782c4b214bb56ca583f.json#L1,
and
graphify-out/cache/ast/v0.9.29/9bd6e6dd116b6b29717310b09e26cfd30acdc302612d8f29f2355d2e7ea476c2.json#L1;
additionally remove the absolute target_file from
graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json#L1
and normalize its node IDs.

'DATABASE_DATABASE',
'DATABASE_PORT',
'CACHE_URL',
'LOG_LEVEL',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify LOG_LEVEL is provided everywhere getEnv() is exercised.
fd -H -t f -e yml -e yaml -e env -e example --exec rg -n --with-filename 'LOG_LEVEL' {} \; 2>/dev/null
rg -n 'LOG_LEVEL' -g '!coverage/**' -g '!graphify-out/**' .
fd -H -t f -g '.env*' -g 'docker-compose*'
rg -n 'NODE_ENV|env:' docker-compose.yml

Repository: auth-plus/auth-plus-authentication

Length of output: 511


🏁 Script executed:

#!/bin/bash
set -u

echo "== candidate files =="
git ls-files | rg '(^docker-compose|compose|\.env|src/config/enviroment_config\.ts|logger)' || true

echo "== enviroment_config outline =="
ast-grep outline src/config/enviroment_config.ts --view expanded || true

echo "== enviroment_config relevant lines =="
cat -n src/config/enviroment_config.ts | sed -n '1,95p'

echo "== logger references =="
fd -H -t f src -g 'logger.ts' -x sh -c 'echo "--- $1"; cat -n "$1" | sed -n "1,120p"' sh {}

echo "== getEnv call sites =="
rg -n 'getEnv\(\)|process\.env\.LOG_LEVEL|LOG_LEVEL' -g '!coverage/**' -g '!graphify-out/**' .

Repository: auth-plus/auth-plus-authentication

Length of output: 5054


🏁 Script executed:

#!/bin/bash
set -u

echo "== docker-compose env references =="
cat -n docker-compose.yml | sed -n '1,180p'

echo "== logger.ts =="
cat -n src/config/logger.ts | sed -n '1,80p'

echo "== server.ts =="
cat -n src/presentation/http/server.ts | sed -n '1,80p'

echo "== index.ts =="
cat -n src/core/index.ts | sed -n '1,90p'

echo "== package scripts =="
json --indent 4 .package.json 2>/dev/null || sed -n '1,120p' package.json

Repository: auth-plus/auth-plus-authentication

Length of output: 14418


🌐 Web query:

pino logger allowed levels trace debug info warn error fatal

💡 Result:

Pino uses a hierarchical logging system based on numerical values to determine which logs are processed. The standard logging levels, ordered from lowest severity to highest, are trace, debug, info, warn, error, and fatal [1][2][3]. The logger can also be set to silent, which disables all logging [1][2]. Each level is associated with a specific numerical value [1][2]: Level: trace | Value: 10 Level: debug | Value: 20 Level: info | Value: 30 Level: warn | Value: 40 Level: error | Value: 50 Level: fatal | Value: 60 Level: silent | Value: Infinity Pino processes logs based on a minimum threshold [1][2]. When you set the logger's level (e.g., via the level option in the constructor or by setting logger.level), Pino will only output logs with a value greater than or equal to the threshold associated with that level [1][4][5]. For example, if the level is set to info (30), Pino will log info, warn, error, and fatal messages, but will ignore trace and debug messages [1][2][3]. Additional custom levels can be defined using the customLevels option if needed [1][2].

Citations:


Avoid forcing LOG_LEVEL through getEnv() at module load.

With LOG_LEVEL mandatory, any local, test, or compose environment without it now throws during module evaluation. Keep LOG_LEVEL optional in mandatoryKeys and derive/validate the logger level from process.env.LOG_LEVEL with a sensible default; otherwise existing envs without it will fail to initialize.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/config/enviroment_config.ts` at line 33, Update the environment
configuration around mandatoryKeys so LOG_LEVEL remains optional and is not
fetched through getEnv() during module initialization. Derive the logger level
directly from process.env.LOG_LEVEL, validate it using the existing logger-level
handling, and apply a sensible default when it is absent.

Comment thread src/config/logger.ts
Comment on lines +7 to +26
serializers: {
email: (val) => (typeof val === 'string' ? maskEmail(val) : val),
phone: (val) => (typeof val === 'string' ? maskPhone(val) : val),
},
redact: {
paths: [
'password',
'confirmPassword',
'code',
'token',
'secret',
'mfaList[*].secret',
'*.password',
'*.confirmPassword',
'*.code',
'*.token',
'*.secret',
],
censor: '[REDACTED]',
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

pino redact paths nested wildcard depth fast-redact intermediate wildcard support

💡 Result:

Pino's redaction functionality, which relies on the fast-redact library, supports single-level wildcards but does not provide native support for recursive or deep wildcards (often denoted as) [1][2][3]. Key points regarding wildcard usage in Pino and fast-redact include: 1. No Recursive Wildcard Support: There is no recursive wildcard operator (e.g.,) that automatically traverses arbitrary nesting depths [2]. Attempting to use or similar patterns will typically result in the pattern being treated as a literal string or failing to match [2]. 2. Intermediate Wildcard Support: fast-redact does support intermediate wildcards (e.g., a..b) [3][4]. When an asterisk is placed in an intermediate or first position, the library will redact the specified paths for every object found at that level within the parent [3][5]. 3. Manual Depth Handling: Because recursive wildcards are unavailable, you must explicitly define paths for each expected level of nesting to ensure complete coverage [2][6]. A common pattern to achieve this is to programmatically generate an array of paths covering the required depths [2]: const depth = (field) => ['', '.', '..', '...*'].map((p) => `${p}.${field}`); const redactPaths = [...depth('password')]; 4. Performance Considerations: While static paths have negligible overhead, using wildcards—especially intermediate ones—introduces a non-trivial performance cost relative to explicit paths [1][3]. Benchmarks indicate that intermediate wildcard redaction can be significantly more expensive than static path redaction [3][5]. 5. Limitations: Issues have been noted where complex or deeply nested patterns (e.g., 3+ consecutive wildcards) may fail to redact fields correctly depending on the version and implementation, often requiring manual, explicit depth listing for reliability [7][6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate logger.ts =="
fd -a 'logger\.ts$' . | sed 's#^\./##'

echo "== read src/config/logger.ts with line numbers =="
cat -n src/config/logger.ts | sed -n '1,120p'

echo "== package pino/fast-redact versions =="
if [ -f package.json ]; then
  jq '.dependencies, .devDependencies | to_entries[]? | select(.value?|test("pino|fast-redact";"i"))[]?' package.json || true
fi
if [ -f package-lock.json ]; then
  jq '.packages."node_modules/pino".version, .packages."node_modules/fast-redact".version' package-lock.json 2>/dev/null || true
fi

echo "== logger usages with email/password nesting examples =="
rg -n --glob '!node_modules' --glob '!dist' --glob '!build' "logger\.[A-Za-z]+\(|pino\(|serialize|email:|password|confirmPassword|code|token|secret|mfaList" . \
  | head -n 300

Repository: auth-plus/auth-plus-authentication

Length of output: 31468


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate installed pino package =="
find / -path '*node_modules/pino*' -maxdepth 3 -type f 2>/dev/null | head -n 20 || true
find /usr/local/lib /usr/lib /root -path '*node_modules/pino*' -maxdepth 5 -type f 2>/dev/null | head -n 20 || true

echo "== inspect package-lock pin for pino =="
python3 - <<'PY'
import json
p=json.load(open('package-lock.json'))
for name in ['pino-std-serializers','fast-redact']:
    pkg=p.get('packages',{}).get('node_modules/'+name)
    print(name, pkg and pkg.get('version'), pkg and pkg.get('resolved'))
PY

echo "== search all logger imports/usages with context =="
rg -n --glob '!node_modules' --glob '!dist' --glob '!build' --glob '!coverage' --glob '!graph.svg' 'from ["'"'"]\.\./config/logger["'"'"]|from ["'"'"]\.\./src/config/logger["'"'"]|logger\.[A-Za-z]+\(' . \
  | head -n 400

Repository: auth-plus/auth-plus-authentication

Length of output: 14111


Add depth coverage for sensitive fields

Pino’s redaction only supports paths of known depth; the existing *.password and *.token entries won’t catch user.info.password or similar deeper payload shapes. Add the expected nesting levels for sensitive fields, or reshape the logged objects so sensitive values are always at covered paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/config/logger.ts` around lines 7 - 26, Extend the redact.paths
configuration in the logger setup to cover sensitive fields at the deeper
nesting levels used by payloads, including paths such as user.info.password and
equivalent password, confirmPassword, code, token, and secret variants. Preserve
the existing top-level and one-level wildcard entries and the current censor
value.

Comment thread src/config/logger.ts
Comment on lines +41 to +48
export function maskEmail(email: string): string {
if (!email || !email.includes('@')) return email;
const [local, domain] = email.split('@');
if (local.length <= 2) {
return `${local[0]}***@${domain}`;
}
return `${local[0]}***${local[local.length - 1]}@${domain}`;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

maskEmail truncates addresses containing more than one @.

email.split('@') destructured into two variables discards everything after the second @, so the masked output is a different (wrong) address in logs. Split on the last @ instead.

🐛 Proposed fix
 export function maskEmail(email: string): string {
-  if (!email || !email.includes('@')) return email;
-  const [local, domain] = email.split('@');
+  if (!email) return email;
+  const at = email.lastIndexOf('@');
+  if (at <= 0) return email;
+  const local = email.slice(0, at);
+  const domain = email.slice(at + 1);
   if (local.length <= 2) {
     return `${local[0]}***@${domain}`;
   }
   return `${local[0]}***${local[local.length - 1]}@${domain}`;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function maskEmail(email: string): string {
if (!email || !email.includes('@')) return email;
const [local, domain] = email.split('@');
if (local.length <= 2) {
return `${local[0]}***@${domain}`;
}
return `${local[0]}***${local[local.length - 1]}@${domain}`;
}
export function maskEmail(email: string): string {
if (!email) return email;
const at = email.lastIndexOf('@');
if (at <= 0) return email;
const local = email.slice(0, at);
const domain = email.slice(at + 1);
if (local.length <= 2) {
return `${local[0]}***@${domain}`;
}
return `${local[0]}***${local[local.length - 1]}@${domain}`;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/config/logger.ts` around lines 41 - 48, Update maskEmail to split the
address at the last '@' rather than destructuring email.split('@'), preserving
the entire domain—including any additional '@' characters—in the masked output
while keeping the existing local-part masking behavior.

Comment on lines +46 to +48
if (strategy === Strategy.GA && user.info.phone == null) {
// Note: check user info here if applicable, but original code was using user.info.phone for Strategy.PHONE:
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Empty if block — dead code left behind.

This branch has no body, no throw, and no side effect; it only carries a note. It also violates the standard no-empty lint rule, which conflicts with T016 in tasks.md claiming lint passes. Remove it, or implement the intended GA validation.

🧹 Proposed removal
-    if (strategy === Strategy.GA && user.info.phone == null) {
-      // Note: check user info here if applicable, but original code was using user.info.phone for Strategy.PHONE:
-    }
     if (strategy === Strategy.PHONE && user.info.phone == null) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (strategy === Strategy.GA && user.info.phone == null) {
// Note: check user info here if applicable, but original code was using user.info.phone for Strategy.PHONE:
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/providers/mfa.repository.ts` around lines 46 - 48, Remove the empty
GA phone-check branch in the MFA repository, including its note, unless
implementing the intended validation is required by surrounding logic. Preserve
the existing strategy handling and ensure no dead empty conditional remains.

Comment on lines +15 to +20
logger.debug({ cacheKeyPattern: 'invalidate:*', action: 'set' }, 'Cache operation executed')
await this.cache.set(`invalidate:${token}`, token, this.TTL)
}

create(user: User): string {
logger.debug({ action: 'signToken', userId: user.id }, 'JWT token signed')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Log completion only after the operation succeeds.

Both messages claim completion before cache.set / sign runs. A failure produces a false success record; rename these as “started” or emit them after success.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/providers/token.repository.ts` around lines 15 - 20, Update the
debug logging in the token cache invalidation and token creation methods so
completion messages are emitted only after cache.set and token signing succeed,
or rename the pre-operation messages to indicate they started. Ensure failures
do not produce logs claiming successful completion, using the relevant
invalidation method and create method.

@AndrewHanasiro
AndrewHanasiro merged commit 52f315e into main Jul 30, 2026
4 of 7 checks passed
@AndrewHanasiro
AndrewHanasiro deleted the feature/sdd branch July 30, 2026 03:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant